Changeset - 790da8154ef8
[Not reviewed]
default
0 8 0
Mads Kiilerich - 11 years ago 2015-04-28 16:55:05
madski@unity3d.com
tests: minimize the amount of references to rc and the past
8 files changed with 42 insertions and 42 deletions:
0 comments (0 inline, 0 general)
kallithea/tests/fixtures/journal_dump.csv
Show inline comments
 
@@ -1401,635 +1401,635 @@ user_log_id,user_id,username,repository_
 
1461,250,dessp,184,fork-aaa-project,"",user_forked_repo:fork-fork-aaa-project,2012-10-08 12:34:18.383393
 
1462,250,dessp,277,fork-fork-aaa-project,"",user_created_fork:fork-fork-aaa-project,2012-10-08 12:34:18.392037
 
1463,250,dessp,278,bla,"",started_following_repo,2012-10-08 12:35:59.034211
 
1464,250,dessp,278,bla,"",user_created_repo,2012-10-08 12:35:59.046964
 
1465,250,dessp,278,bla,"",push_local:d67d6b2cd83c926cc98b7338dd375c0d7dc224ed,2012-10-08 12:36:23.610968
 
1466,251,vaueff,279,meinsisses,"",started_following_repo,2012-10-08 17:11:28.309493
 
1467,251,vaueff,206,test-sls,"",user_forked_repo:meinsisses,2012-10-08 17:11:28.333732
 
1468,251,vaueff,279,meinsisses,"",user_created_fork:meinsisses,2012-10-08 17:11:28.34374
 
1469,3,demo,280,HelloWorld,"",started_following_repo,2012-10-08 17:19:57.672859
 
1470,3,demo,280,HelloWorld,"",user_created_repo,2012-10-08 17:19:57.685128
 
1471,3,demo,127,my-super-rep,"",user_commented_pull_request:62,2012-10-08 17:37:04.554118
 
1472,3,demo,127,my-super-rep,"",user_closed_pull_request:62,2012-10-08 17:37:04.56515
 
1473,3,demo,249,abcdefg,"",user_commented_revision:ef6c825bc5699b95a31ae3075693b12693a623e2,2012-10-08 17:38:13.042926
 
1474,254,yujiro,281,yujirotest,"",started_following_repo,2012-10-09 06:59:18.412429
 
1475,254,yujiro,281,yujirotest,"",user_created_repo,2012-10-09 06:59:18.424128
 
1476,254,yujiro,282,fork-amabあああ,"",started_following_repo,2012-10-09 07:03:34.289292
 
1477,254,yujiro,122,amab,"",user_forked_repo:fork-amabあああ,2012-10-09 07:03:34.308792
 
1478,254,yujiro,282,fork-amabあああ,"",user_created_fork:fork-amabあああ,2012-10-09 07:03:34.320104
 
1479,254,yujiro,172,go,"",started_following_repo,2012-10-09 07:09:23.727527
 
1480,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:fba17a64fa4978bfea19222da5e64a18cfddeecd,2012-10-09 08:44:14.777602
 
1481,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:fba17a64fa4978bfea19222da5e64a18cfddeecd,2012-10-09 08:44:52.916854
 
1482,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:30853f4bde2f2b6f0a7126392b9b1b4c5ea37e0a,2012-10-09 08:45:16.42599
 
1483,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:30853f4bde2f2b6f0a7126392b9b1b4c5ea37e0a,2012-10-09 08:45:38.745859
 
1484,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:30853f4bde2f2b6f0a7126392b9b1b4c5ea37e0a,2012-10-09 08:45:52.328248
 
1485,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:30853f4bde2f2b6f0a7126392b9b1b4c5ea37e0a,2012-10-09 08:46:01.737145
 
1486,255,che,283,test-zh-tw,"",started_following_repo,2012-10-09 10:33:51.971598
 
1487,255,che,283,test-zh-tw,"",user_created_repo,2012-10-09 10:33:51.983333
 
1488,255,che,283,test-zh-tw,"61.56.13.120, 61.56.15.166","push:ea3aa785b5f361e36ccdbb8201fa809cf0e9b371,bf62637068b19308263d2ed9cdd1b43ae3d88757",2012-10-09 10:36:13.255622
 
1489,3,demo,284,fork-django,"",started_following_repo,2012-10-09 20:17:50.071294
 
1490,3,demo,110,django,"",user_forked_repo:fork-django,2012-10-09 20:17:57.420156
 
1491,3,demo,284,fork-django,"",user_created_fork:fork-django,2012-10-09 20:17:57.434345
 
1492,3,demo,285,github-killer,"",started_following_repo,2012-10-09 21:05:48.6309
 
1493,3,demo,285,github-killer,"",user_created_repo,2012-10-09 21:05:48.644556
 
1494,3,demo,285,github-killer,188.25.172.123,push:df73f912eb7cd583d1fda6a4ef19c1ab1dbc6f92,2012-10-09 21:06:55.345622
 
1495,3,demo,285,aloha,"",user_updated_repo,2012-10-09 21:13:16.792012
 
1496,3,demo,127,my-super-rep,"",user_commented_revision:5d80e28538141e322b317168e2367fb03178d58c,2012-10-09 22:39:42.201647
 
1497,3,demo,286,http-mercurial.selenic.com-hg,"",started_following_repo,2012-10-10 02:37:22.675764
 
1498,3,demo,286,http-mercurial.selenic.com-hg,"",user_created_repo,2012-10-10 02:37:22.693066
 
1499,3,demo,287,fork-http-mercurial.selenic.com-hg,"",started_following_repo,2012-10-10 02:38:04.918464
 
1500,3,demo,286,http-mercurial.selenic.com-hg,"",user_forked_repo:fork-http-mercurial.selenic.com-hg,2012-10-10 02:38:05.085956
 
1501,3,demo,287,fork-http-mercurial.selenic.com-hg,"",user_created_fork:fork-http-mercurial.selenic.com-hg,2012-10-10 02:38:05.094152
 
1502,3,demo,287,fork-http-mercurial.selenic.com-hg,"",push_local:9ce0ab91b57ea15f5e8569ef7304ce58c9acf477,2012-10-10 02:39:19.103663
 
1503,3,demo,286,http-mercurial.selenic.com-hg,"",user_commented_pull_request:66,2012-10-10 02:42:42.025549
 
1504,3,demo,286,http-mercurial.selenic.com-hg,"",user_closed_pull_request:66,2012-10-10 02:42:42.034609
 
1505,3,demo,287,fork-http-mercurial.selenic.com-hg,"",user_commented_revision:9ce0ab91b57ea15f5e8569ef7304ce58c9acf477,2012-10-10 02:44:45.999905
 
1506,3,demo,287,fork-http-mercurial.selenic.com-hg,"",user_commented_revision:9ce0ab91b57ea15f5e8569ef7304ce58c9acf477,2012-10-10 02:44:51.716813
 
1507,256,dg_test,288,dgtestrepo,"",started_following_repo,2012-10-10 04:48:48.801476
 
1508,256,dg_test,288,dgtestrepo,"",user_created_repo,2012-10-10 04:48:48.813822
 
1509,256,dg_test,288,dgtestrepo,59.167.167.230,push:27ab7e76abe80344db6a250d3a8979117907704a,2012-10-10 04:49:46.01297
 
1510,256,dg_test,289,fork-dgtestrepo,"",started_following_repo,2012-10-10 04:50:15.108071
 
1511,256,dg_test,288,dgtestrepo,"",user_forked_repo:fork-dgtestrepo,2012-10-10 04:50:15.127777
 
1512,256,dg_test,289,fork-dgtestrepo,"",user_created_fork:fork-dgtestrepo,2012-10-10 04:50:15.141651
 
1513,1,default,289,fork-dgtestrepo,59.167.167.230,pull,2012-10-10 04:50:29.22472
 
1514,256,dg_test,289,fork-dgtestrepo,59.167.167.230,push:36da9693f7e90974c46bf83c9abdb4803fac13ff,2012-10-10 04:50:59.757989
 
1515,256,dg_test,288,dgtestrepo,"",user_commented_pull_request:67,2012-10-10 04:51:51.635244
 
1516,256,dg_test,288,dgtestrepo,"",user_commented_pull_request:67,2012-10-10 04:52:13.711421
 
1517,256,dg_test,288,dgtestrepo,"",user_commented_pull_request:67,2012-10-10 04:54:11.518751
 
1518,256,dg_test,288,dgtestrepo,"",user_commented_pull_request:67,2012-10-10 06:35:30.952227
 
1519,1,default,289,fork-dgtestrepo,59.167.167.230,pull,2012-10-10 12:39:46.774029
 
1520,256,dg_test,288,dgtestrepo,59.167.167.230,push:36da9693f7e90974c46bf83c9abdb4803fac13ff,2012-10-10 12:40:26.181044
 
1521,256,dg_test,288,dgtestrepo,"",user_commented_pull_request:67,2012-10-10 12:41:54.987689
 
1522,256,dg_test,288,dgtestrepo,"",user_commented_pull_request:67,2012-10-10 12:42:03.057669
 
1523,256,dg_test,257,fork-unity-test-trunk,"",user_commented_pull_request:63,2012-10-10 12:47:14.298864
 
1524,256,dg_test,288,dgtestrepo,"",user_commented_revision:36da9693f7e90974c46bf83c9abdb4803fac13ff,2012-10-10 12:49:30.180636
 
1525,256,dg_test,288,dgtestrepo,"",user_commented_pull_request:67,2012-10-10 12:50:11.880937
 
1526,256,dg_test,288,dgtestrepo,"",user_closed_pull_request:67,2012-10-10 12:50:11.885641
 
1527,256,dg_test,290,dg1,"",started_following_repo,2012-10-10 13:00:18.072553
 
1528,256,dg_test,290,dg1,"",user_created_repo,2012-10-10 13:00:18.084695
 
1529,256,dg_test,291,fork-dg1,"",started_following_repo,2012-10-10 13:00:31.045836
 
1530,256,dg_test,290,dg1,"",user_forked_repo:fork-dg1,2012-10-10 13:00:31.064079
 
1531,256,dg_test,291,fork-dg1,"",user_created_fork:fork-dg1,2012-10-10 13:00:31.073556
 
1538,256,dg_test,290,dg1,"",user_commented_pull_request:68,2012-10-10 13:04:05.221925
 
1532,256,dg_test,290,dg1,59.167.167.230,push:c8996239abf9263cdee5b15234372e3a6e793e44,2012-10-10 13:01:40.777662
 
1533,256,dg_test,292,fork-dg11,"",started_following_repo,2012-10-10 13:02:33.177064
 
1534,256,dg_test,290,dg1,"",user_forked_repo:fork-dg11,2012-10-10 13:02:33.193349
 
1535,256,dg_test,292,fork-dg11,"",user_created_fork:fork-dg11,2012-10-10 13:02:33.207706
 
1536,1,default,292,fork-dg11,59.167.167.230,pull,2012-10-10 13:02:44.944887
 
1537,256,dg_test,292,fork-dg11,59.167.167.230,push:667a6c5db8f25896ef1cadd1f5138898026f068e,2012-10-10 13:03:21.048735
 
1540,256,dg_test,290,dg1,59.167.167.230,push:667a6c5db8f25896ef1cadd1f5138898026f068e,2012-10-10 13:04:47.505397
 
1541,256,dg_test,290,dg1,"",user_commented_revision:667a6c5db8f25896ef1cadd1f5138898026f068e,2012-10-10 13:09:03.381076
 
1539,256,dg_test,290,dg1,"",user_closed_pull_request:68,2012-10-10 13:04:05.229068
 
1542,256,dg_test,288,dgtestrepo,"",user_commented_revision:36da9693f7e90974c46bf83c9abdb4803fac13ff,2012-10-10 13:20:40.664276
 
1543,3,demo,38,code-review-test,"",user_commented_revision:6d7db5794e8cad7da042b6ae6238116c6e59a4d2,2012-10-10 21:33:13.589618
 
1544,1,default,122,amab,75.128.117.162,pull,2012-10-11 04:26:13.01088
 
1545,3,demo,294,fork-aloha,"",started_following_repo,2012-10-11 10:49:27.293629
 
1546,3,demo,285,aloha,"",user_forked_repo:fork-aloha,2012-10-11 10:49:27.403491
 
1547,3,demo,294,fork-aloha,"",user_created_fork:fork-aloha,2012-10-11 10:49:27.417952
 
1548,2,admin,,"","",admin_created_user:user_rc_1,2012-10-11 12:16:48.505211
 
1549,2,admin,,"","",admin_created_user:user_rc_2,2012-10-11 12:17:03.054922
 
1550,3,demo,34,a,"",user_commented_revision:f437e821a406d35b1e231c5a81e82853f8ed6436,2012-10-11 12:17:37.00837
 
1551,3,demo,34,a,"",user_commented_revision:f437e821a406d35b1e231c5a81e82853f8ed6436,2012-10-11 12:17:46.881784
 
1552,3,demo,34,a,"",user_commented_revision:f437e821a406d35b1e231c5a81e82853f8ed6436,2012-10-11 12:23:44.417665
 
1553,3,demo,122,amab,"",push_local:796c02c902e1098268c622e34e9526b7424c2f0a,2012-10-11 14:24:20.208902
 
1554,3,demo,295,test333,"",started_following_repo,2012-10-11 14:33:32.412381
 
1555,3,demo,295,test333,"",user_created_repo,2012-10-11 14:33:32.424562
 
1556,3,demo,285,aloha,"",push_local:b59aa4775f36a3f553d2d9b9296b9272106b920d,2012-10-11 14:34:31.082462
 
1557,3,demo,295,test333,62.153.70.3,"push:ee67bac620f0c1823f863be9e829efd5e3b34f42,a3c1ca826d1cc57132141e70ee7e9f77ecef43fe",2012-10-11 14:36:48.814768
 
1558,3,demo,285,aloha,"",push_local:3266a55348986338e8cffb2b8605ba754a54497f,2012-10-11 14:37:57.513628
 
1559,3,demo,285,aloha,"",push_local:8411bc8656efd477e0c817ebbbf448fe5ca0d5fa,2012-10-11 14:38:33.492779
 
1560,3,demo,285,aloha,"",user_updated_repo,2012-10-11 14:43:08.034646
 
1561,3,demo,285,aloha,"",user_updated_repo,2012-10-11 14:43:52.370534
 
1562,260,kudtest,296,fork-amab-kud,"",started_following_repo,2012-10-11 15:02:21.701772
 
1563,260,kudtest,122,amab,"",user_forked_repo:fork-amab-kud,2012-10-11 15:02:21.721067
 
1564,260,kudtest,296,fork-amab-kud,"",user_created_fork:fork-amab-kud,2012-10-11 15:02:21.738079
 
1565,3,demo,297,mytest,"",started_following_repo,2012-10-11 17:35:37.595048
 
1566,3,demo,297,mytest,"",user_created_repo,2012-10-11 17:35:37.607661
 
1567,3,demo,297,mytest,"",push_local:e9c241d5215f8bdfa8b0cabab229952b2740ee98,2012-10-11 17:37:50.954858
 
1568,3,demo,297,mytest,"",user_updated_repo,2012-10-11 17:39:13.548988
 
1569,37,tester,99,another-fork-to-check-code-review,"",user_commented_revision:fba17a64fa4978bfea19222da5e64a18cfddeecd,2012-10-11 19:10:15.328087
 
1570,37,tester,201,tord,"",user_commented_revision:35b3ebc8e1c23902eb97031f42f666df0835c5be,2012-10-11 19:19:55.616125
 
1571,37,tester,99,another-fork-to-check-code-review,"",user_commented_revision:fba17a64fa4978bfea19222da5e64a18cfddeecd,2012-10-11 19:24:45.086999
 
1572,37,tester,99,another-fork-to-check-code-review,"",user_commented_revision:fba17a64fa4978bfea19222da5e64a18cfddeecd,2012-10-11 19:25:23.183406
 
1573,3,demo,43,bar,78.62.141.189,"push:cda1756acf28cae40e103db3792e4ac92c68d65a,3eab1e3601763da599d27541408fca1e12a09b02",2012-10-11 21:35:28.229244
 
1574,3,demo,298,a-foo,"",started_following_repo,2012-10-12 15:29:23.1832
 
1575,3,demo,298,a-foo,"",user_created_repo,2012-10-12 15:29:23.195979
 
1576,3,demo,298,a-foo,"",stopped_following_repo,2012-10-12 15:30:16.975594
 
1577,3,demo,298,a-foo,"",started_following_repo,2012-10-12 15:30:19.49313
 
1578,3,demo,285,aloha,"",user_commented_revision:8411bc8656efd477e0c817ebbbf448fe5ca0d5fa,2012-10-12 16:04:13.119321
 
1579,3,demo,299,test12345,"",started_following_repo,2012-10-13 02:45:09.148642
 
1580,3,demo,299,test12345,"",user_created_repo,2012-10-13 02:45:09.15792
 
1581,3,demo,300,TestTest,"",started_following_repo,2012-10-13 21:11:45.72971
 
1582,3,demo,300,TestTest,"",user_created_repo,2012-10-13 21:11:45.738999
 
1583,1,default,68,aaa-project,213.197.188.148,pull,2012-10-15 08:27:45.007378
 
1584,3,demo,301,fork-glib,"",started_following_repo,2012-10-16 08:31:44.802094
 
1585,3,demo,54,glib,"",user_forked_repo:fork-glib,2012-10-16 08:31:51.952999
 
1586,3,demo,301,fork-glib,"",user_created_fork:fork-glib,2012-10-16 08:31:51.967931
 
1587,3,demo,285,aloha,78.29.10.71,push:c7feb9671fc451e40758b9ed10496d854ba18a40,2012-10-16 08:34:12.115912
 
1588,270,raoul1,302,TestRaoul,"",started_following_repo,2012-10-16 09:24:57.710057
 
1589,270,raoul1,302,TestRaoul,"",user_created_repo,2012-10-16 09:24:57.725416
 
1590,270,raoul1,302,TestRaoul,"",user_updated_repo,2012-10-16 09:25:13.334125
 
1591,270,raoul1,302,TestRaoul,"",user_updated_repo,2012-10-16 09:27:33.159359
 
1592,271,raoul2,302,TestRaoul,"",user_updated_repo,2012-10-16 09:30:24.581076
 
1593,3,demo,68,aaa-project,"",user_commented_revision:0c33fa58efc5a5541d8d3f1a3d3b77367e3d94f5,2012-10-16 10:14:32.596831
 
1594,272,jamesc,303,Magical-Cheese-Repo,"",started_following_repo,2012-10-16 12:10:35.216711
 
1595,272,jamesc,303,Magical-Cheese-Repo,"",user_created_repo,2012-10-16 12:10:35.231231
 
1596,272,jamesc,304,Cheese-Fork,"",started_following_repo,2012-10-16 12:11:16.231228
 
1597,272,jamesc,303,Magical-Cheese-Repo,"",user_forked_repo:Cheese-Fork,2012-10-16 12:11:16.248472
 
1598,272,jamesc,304,Cheese-Fork,"",user_created_fork:Cheese-Fork,2012-10-16 12:11:16.2598
 
1599,272,jamesc,304,Cheese-Fork,"",push_local:47c7945748501f71737af1e83f5036cd17bde506,2012-10-16 12:13:20.106608
 
1600,3,demo,,sproject,"",started_following_repo,2012-10-16 14:07:45.531949
 
1601,3,demo,,sproject,"",user_created_repo,2012-10-16 14:07:45.550972
 
1602,3,demo,,sproject,"",user_deleted_repo,2012-10-16 14:12:00.222929
 
1603,3,demo,35,fork-Something22,"",user_updated_repo,2012-10-16 14:16:04.092997
 
1604,3,demo,306,testflow,"",started_following_repo,2012-10-16 18:58:10.988582
 
1605,3,demo,306,testflow,"",user_created_repo,2012-10-16 18:58:11.002092
 
1665,3,demo,268,foofootest,"",user_updated_repo,2012-10-17 20:41:34.07778
 
1666,1,default,266,fork-mercurial-trunk,78.53.4.31,pull,2012-10-18 00:34:23.822311
 
1667,1,default,265,mercurial-trunk,78.53.4.31,pull,2012-10-18 00:35:14.549948
 
1668,3,demo,34,a,"",push_local:a778c8853f594759661bf6e8fa9933dbd0c06390,2012-10-18 06:49:15.999219
 
1669,3,demo,314,Test123654,"",started_following_repo,2012-10-18 09:13:40.498593
 
1670,3,demo,314,Test123654,"",user_created_repo,2012-10-18 09:13:40.514075
 
1671,3,demo,315,fork-a-foo,"",started_following_repo,2012-10-18 10:55:34.287082
 
1672,3,demo,298,a-foo,"",user_forked_repo:fork-a-foo,2012-10-18 10:55:34.304187
 
1673,3,demo,315,fork-a-foo,"",user_created_fork:fork-a-foo,2012-10-18 10:55:34.313058
 
1674,279,sugia,316,Llskdjfsldkfjl,"",started_following_repo,2012-10-19 08:20:45.345545
 
1675,279,sugia,316,Llskdjfsldkfjl,"",user_created_repo,2012-10-19 08:20:45.355759
 
1676,279,sugia,316,Llskdjfsldkfjl,"",user_updated_repo,2012-10-19 08:21:47.944967
 
1677,3,demo,317,foo-baz,"",started_following_repo,2012-10-19 14:14:29.057573
 
1678,3,demo,317,foo-baz,"",user_created_repo,2012-10-19 14:14:29.070434
 
1679,3,demo,38,code-review-test,"",user_commented_revision:6d7db5794e8cad7da042b6ae6238116c6e59a4d2,2012-10-19 16:10:33.532318
 
1680,3,demo,249,abcdefg,"",user_commented_revision:ef6c825bc5699b95a31ae3075693b12693a623e2,2012-10-19 21:10:05.655859
 
1681,3,demo,249,abcdefg,"",user_commented_revision:ef6c825bc5699b95a31ae3075693b12693a623e2,2012-10-19 21:10:17.138554
 
1607,3,demo,306,testflow,69.36.131.254,"push:139bacf66d2ae74543bf01385d53434b5e619324,c9828e4c945cbbc0b98ebcb3633960a7495d6526",2012-10-16 20:15:52.423766
 
1608,3,demo,307,zippo,"",started_following_repo,2012-10-16 21:57:00.837578
 
1609,3,demo,307,zippo,"",user_created_repo,2012-10-16 21:57:00.852928
 
1610,3,demo,307,zippo,"",user_updated_repo,2012-10-16 21:58:05.136205
 
1611,3,demo,307,zippo,"",user_updated_repo,2012-10-16 21:58:17.135464
 
1612,1,default,306,testflow,92.225.130.117,pull,2012-10-16 23:26:14.536761
 
1613,3,demo,230,eks1,"",user_commented_revision:7be3eb971e236dd0c1d7b7c4637e7fab9c0a8eff,2012-10-17 10:01:12.801645
 
1614,3,demo,230,eks1,"",user_commented_revision:7be3eb971e236dd0c1d7b7c4637e7fab9c0a8eff,2012-10-17 10:01:24.827945
 
1615,3,demo,308,fork-abcdefg,"",started_following_repo,2012-10-17 10:46:38.608309
 
1616,3,demo,249,abcdefg,"",user_forked_repo:fork-abcdefg,2012-10-17 10:46:38.625094
 
1617,3,demo,308,fork-abcdefg,"",user_created_fork:fork-abcdefg,2012-10-17 10:46:38.636906
 
1618,3,demo,308,fork-abcdefg,"",push_local:89b42b250956797b6bad5c7edbf873efe1b03d75,2012-10-17 10:47:28.606347
 
1619,3,demo,249,abcdefg,"",user_commented_pull_request:69,2012-10-17 10:51:05.868185
 
1620,2,admin,249,abcdefg,"",user_commented_pull_request:69,2012-10-17 15:34:01.14742
 
1621,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:125ff5654b72009b251706d7ee93051853f066b6,2012-10-17 15:36:37.784768
 
1622,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:125ff5654b72009b251706d7ee93051853f066b6,2012-10-17 15:37:36.599064
 
1623,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:125ff5654b72009b251706d7ee93051853f066b6,2012-10-17 15:38:14.176552
 
1624,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:125ff5654b72009b251706d7ee93051853f066b6,2012-10-17 15:38:41.016672
 
1625,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:1bd18c415eec578b5a8cc3bb61c65e554f4674e1,2012-10-17 15:39:31.815756
 
1626,276,niels,309,fork-bla,"",started_following_repo,2012-10-17 16:14:16.700471
 
1627,276,niels,278,bla,"",user_forked_repo:fork-bla,2012-10-17 16:14:16.804166
 
1628,276,niels,309,fork-bla,"",user_created_fork:fork-bla,2012-10-17 16:14:16.818566
 
1629,3,demo,249,abcdefg,"",user_commented_pull_request:69,2012-10-17 16:21:09.732638
 
1630,3,demo,249,abcdefg,"",user_closed_pull_request:69,2012-10-17 16:21:09.743958
 
1631,3,demo,310,ForkMe,"",started_following_repo,2012-10-17 16:39:43.040558
 
1632,3,demo,310,ForkMe,"",user_created_repo,2012-10-17 16:39:43.051548
 
1633,3,demo,310,ForkMe,20.132.68.148,"push:20867b19ea55d7afa34238c5b42e8f0cf9336fb9,57b41cfbab38011c7d95d929afe8c54d41d229c7,c473af323363c2ce57b1dd3baaf671eabbbe3d9b,11d5db13f3886df26fa9052d664dd99c7ad7a32f,d7d1bb376a19e46ce927520f6863c286aae3d118,160f86cca435674ce9fbd7fb34a7eb1684cd753e,44d8bad99c89ba30af51c0fb96d0c4f5ff679b67,12253658153cfdcab846f64b91f13f56631abae1,ec85db68de4419c2cdaa9e9a4c0cd0a12e161c9e,98e055683c7acd57b6393fffb5bc9ef7fd8386aa,9fd9140573cfccdb795905c962d515fd199024a1",2012-10-17 16:40:52.585834
 
1634,3,demo,311,ForkForForkMe,"",started_following_repo,2012-10-17 16:41:54.089171
 
1635,3,demo,310,ForkMe,"",user_forked_repo:ForkForForkMe,2012-10-17 16:41:54.105915
 
1636,3,demo,311,ForkForForkMe,"",user_created_fork:ForkForForkMe,2012-10-17 16:41:54.119943
 
1637,1,default,311,ForkForForkMe,20.132.68.148,pull,2012-10-17 16:42:50.019391
 
1638,3,demo,311,ForkForForkMe,20.132.68.148,push:7f7a317f656658d18438fa4f2effca0cfe1bee77,2012-10-17 16:43:30.115193
 
1639,3,demo,310,ForkMe,"",user_commented_pull_request:70,2012-10-17 16:45:19.643124
 
1640,3,demo,310,ForkMe,"",user_closed_pull_request:70,2012-10-17 16:45:19.651818
 
1641,1,default,310,ForkMe,20.132.68.148,pull,2012-10-17 16:55:41.290306
 
1642,1,default,311,ForkForForkMe,20.132.68.148,pull,2012-10-17 17:01:31.007755
 
1643,1,default,310,ForkMe,20.132.68.148,pull,2012-10-17 17:02:42.098164
 
1644,1,default,311,ForkForForkMe,20.132.68.148,pull,2012-10-17 17:05:59.739608
 
1645,3,demo,311,ForkForForkMe,20.132.68.148,"push:3ebc10c9b1ea1d26ff9ede63104d6ab24bf6d37d,e2687070a7d4092aafde9343ad79c57c39ec016f",2012-10-17 17:17:21.346216
 
1646,1,default,310,ForkMe,20.132.68.148,pull,2012-10-17 17:17:56.010058
 
1647,3,demo,312,pepepe,"",started_following_repo,2012-10-17 17:20:14.076678
 
1648,3,demo,312,pepepe,"",user_created_repo,2012-10-17 17:20:14.089715
 
1649,3,demo,311,ForkForForkMe,20.132.68.148,"push:37298d3eed24e9209bfaf5b43bda114b28d99363,1dc8b7b3029c583069aa80ebc5b570c11cea998b",2012-10-17 17:20:19.128212
 
1650,3,demo,312,pepepe,"",push_local:72fc0eb74ecaffd64c3594744f8ad0634f68ab2b,2012-10-17 17:20:35.135261
 
1651,3,demo,312,pepepe,"",user_commented_revision:72fc0eb74ecaffd64c3594744f8ad0634f68ab2b,2012-10-17 17:20:53.662433
 
1652,3,demo,313,fork-pepepe,"",started_following_repo,2012-10-17 17:21:29.352267
 
1653,3,demo,312,pepepe,"",user_forked_repo:fork-pepepe,2012-10-17 17:21:29.36938
 
1654,3,demo,313,fork-pepepe,"",user_created_fork:fork-pepepe,2012-10-17 17:21:29.382134
 
1655,3,demo,313,fork-pepepe,"",push_local:d96f66d613e7c90004b0be702fa00acb5c64d22b,2012-10-17 17:22:27.210919
 
1656,1,default,311,ForkForForkMe,20.132.68.148,pull,2012-10-17 17:22:51.855061
 
1657,3,demo,312,pepepe,"",user_commented_pull_request:71,2012-10-17 17:23:15.633271
 
1658,3,demo,312,pepepe,"",user_closed_pull_request:71,2012-10-17 17:23:15.639775
 
1659,1,default,310,ForkMe,20.132.68.148,pull,2012-10-17 19:44:37.643519
 
1660,1,default,311,ForkForForkMe,20.132.68.148,pull,2012-10-17 19:49:02.152121
 
1661,1,default,311,ForkForForkMe,20.132.68.148,pull,2012-10-17 19:51:33.051372
 
1662,1,default,310,ForkMe,20.132.68.148,pull,2012-10-17 20:02:23.092402
 
1663,1,default,311,ForkForForkMe,20.132.68.148,pull,2012-10-17 20:21:12.146576
 
1664,3,demo,269,fork-foofootest,"",user_updated_repo,2012-10-17 20:39:09.557172
 
1682,3,demo,249,abcdefg,"",user_commented_revision:5d80e28538141e322b317168e2367fb03178d58c,2012-10-19 21:11:07.868323
 
1683,280,SylvainC,318,testrcd99,"",started_following_repo,2012-10-19 22:52:25.55997
 
1684,280,SylvainC,318,testrcd99,"",user_created_repo,2012-10-19 22:52:25.572046
 
1685,281,coderazor,38,code-review-test,"",user_commented_pull_request:65,2012-10-19 23:15:14.542145
 
1686,281,coderazor,38,code-review-test,"",user_commented_pull_request:65,2012-10-19 23:16:01.295617
 
1687,281,coderazor,38,code-review-test,"",user_commented_pull_request:65,2012-10-19 23:20:08.509514
 
1688,281,coderazor,319,fork1-code-review-test,"",started_following_repo,2012-10-20 00:46:43.404342
 
1689,281,coderazor,38,code-review-test,"",user_forked_repo:fork1-code-review-test,2012-10-20 00:46:43.464675
 
1690,281,coderazor,319,fork1-code-review-test,"",user_created_fork:fork1-code-review-test,2012-10-20 00:46:43.473779
 
1691,281,coderazor,319,fork1-code-review-test,"",push_local:98690895f701c1827ea962fe81985b6094a3f00e,2012-10-20 00:48:45.66637
 
1692,281,coderazor,319,fork1-code-review-test,"",push_local:b364947ef413a4b2f43bb76ba221d47c1794a8e1,2012-10-20 00:49:40.078971
 
1693,281,coderazor,319,fork1-code-review-test,"",user_commented_revision:b364947ef413a4b2f43bb76ba221d47c1794a8e1,2012-10-20 00:50:35.035023
 
1694,281,coderazor,38,code-review-test,"",user_commented_pull_request:72,2012-10-20 00:54:57.701596
 
1695,281,coderazor,38,code-review-test,"",user_commented_pull_request:72,2012-10-20 00:55:44.681278
 
1696,281,coderazor,38,code-review-test,"",user_commented_pull_request:72,2012-10-20 00:55:59.492315
 
1697,281,coderazor,319,fork1-code-review-test,"",push_local:e216971a777e3132487405dd2c8e093f66788765,2012-10-20 00:59:53.583102
 
1698,281,coderazor,38,code-review-test,"",user_commented_pull_request:72,2012-10-20 01:01:16.602261
 
1699,281,coderazor,38,code-review-test,"",user_commented_pull_request:72,2012-10-20 01:03:46.692176
 
1700,281,coderazor,38,code-review-test,"",user_commented_pull_request:73,2012-10-20 01:06:18.310904
 
1701,281,coderazor,38,code-review-test,"",user_commented_pull_request:72,2012-10-20 01:07:52.891399
 
1702,281,coderazor,38,code-review-test,"",user_closed_pull_request:72,2012-10-20 01:07:52.900684
 
1703,283,vaidasn,320,svn2git.git,"",started_following_repo,2012-10-20 19:40:57.345453
 
1704,283,vaidasn,320,svn2git.git,"",user_created_repo,2012-10-20 19:40:57.365761
 
1705,3,demo,321,Mecurial-Test,"",started_following_repo,2012-10-22 06:13:45.980502
 
1706,3,demo,321,Mecurial-Test,"",user_created_repo,2012-10-22 06:13:45.997596
 
1707,3,demo,321,Mecurial-Test,69.196.152.196,push:e66dfe4e33871da460d3807c8b015863bf7240b7,2012-10-22 06:54:33.247493
 
1708,3,demo,321,Mecurial-Test,"",user_updated_repo,2012-10-22 06:56:19.772283
 
1709,3,demo,321,Mecurial-Test,69.196.152.196,push:eee6785689defc10df9fe6e8d0921facaab0e176,2012-10-22 07:08:00.585766
 
1710,3,demo,321,Mecurial-Test,69.196.152.196,push:fd10c02cfbfbf4a7d7659c67998c6f95da5dc4de,2012-10-22 07:10:59.095472
 
1711,254,yujiro,322,fork-code-review-dev,"",started_following_repo,2012-10-22 10:01:47.558754
 
1712,254,yujiro,173,code-review-dev,"",user_forked_repo:fork-code-review-dev,2012-10-22 10:01:47.58102
 
1713,254,yujiro,322,fork-code-review-dev,"",user_created_fork:fork-code-review-dev,2012-10-22 10:01:47.59189
 
1714,285,zza,323,TestZZa,"",started_following_repo,2012-10-22 11:36:34.479105
 
1715,285,zza,323,TestZZa,"",user_created_repo,2012-10-22 11:36:34.488683
 
1716,285,zza,323,TestZZa,"",user_updated_repo,2012-10-22 11:37:27.008002
 
1717,285,zza,323,TestZZa,"",user_updated_repo,2012-10-22 11:37:40.09398
 
1718,3,demo,285,aloha,"",push_local:f6aea433e6b6cb05d4af9ac74bac0da5fd09c8ba,2012-10-22 12:50:54.991895
 
1719,1,default,321,Mecurial-Test,67.70.161.159,pull,2012-10-22 15:41:30.593105
 
1720,3,demo,321,Mecurial-Test,67.70.161.159,push:041e48fd7acad4c27385c27a4789d3d5cc7ccbea,2012-10-22 16:39:38.382409
 
1721,1,default,321,Mecurial-Test,69.196.152.196,pull,2012-10-22 23:13:11.713227
 
1722,3,demo,325,testkyro,"",started_following_repo,2012-10-23 13:27:46.011096
 
1723,3,demo,325,testkyro,"",user_created_repo,2012-10-23 13:27:46.024014
 
1724,3,demo,325,testkyro,"",user_updated_repo,2012-10-23 13:28:29.072813
 
1725,3,demo,326,ReallyCoolProject,"",started_following_repo,2012-10-23 14:22:15.477077
 
1726,3,demo,326,ReallyCoolProject,"",user_created_repo,2012-10-23 14:22:15.492068
 
1727,3,demo,326,ReallyCoolProject,"",push_local:262220ea2a60e92577f2193cd9ee4f9707760fb5,2012-10-23 14:23:56.826353
 
1728,288,kiall,327,kiall-test,"",started_following_repo,2012-10-23 15:50:27.397495
 
1729,288,kiall,327,kiall-test,"",user_created_repo,2012-10-23 15:50:27.42126
 
1730,288,kiall,329,fork-aaa-projects,"",started_following_repo,2012-10-23 15:53:23.020591
 
1731,288,kiall,68,aaa-project,"",user_forked_repo:fork-aaa-projects,2012-10-23 15:53:23.043059
 
1732,288,kiall,329,fork-aaa-projects,"",user_created_fork:fork-aaa-projects,2012-10-23 15:53:23.052289
 
1733,288,kiall,328,kiall-nova,"",started_following_repo,2012-10-23 15:53:45.417443
 
1734,288,kiall,328,kiall-nova,"",user_created_repo,2012-10-23 15:53:45.434684
 
1735,288,kiall,329,fork-aaa-projects,"",push_local:417cac332ab3512a08d5454cfcbffc21471e1f6f,2012-10-23 15:53:50.165591
 
1736,3,demo,330,z123,"",started_following_repo,2012-10-23 15:58:30.652495
 
1737,3,demo,330,z123,"",user_created_repo,2012-10-23 15:58:30.665854
 
1738,3,demo,330,z123,"",push_local:0ba461ee4cd15d51f416b1073d4389574150f5ca,2012-10-23 15:59:26.238194
 
1739,3,demo,330,z123,"",user_updated_repo,2012-10-23 16:01:08.667715
 
1740,288,kiall,331,kiall-hg,"",started_following_repo,2012-10-23 16:01:24.811434
 
1741,288,kiall,331,kiall-hg,"",user_created_repo,2012-10-23 16:01:24.820628
 
1742,1,default,330,z123,80.149.98.186,pull,2012-10-23 16:02:35.273406
 
1743,3,demo,330,z123,80.149.98.186,push:b89e8c4620b21ec38d159c644b173a1c93efafea,2012-10-23 16:04:08.66449
 
1744,3,demo,330,z123,"",user_commented_revision:b89e8c4620b21ec38d159c644b173a1c93efafea,2012-10-23 16:04:55.372793
 
1745,2,admin,,"","",admin_updated_user:kiall,2012-10-23 16:05:04.180487
 
1746,3,demo,330,z123,"",stopped_following_repo,2012-10-23 16:16:39.414967
 
1747,3,demo,34,a,"",push_local:106ab79178979f8e464e5cc8f432347f8c203dde,2012-10-23 16:24:17.669006
 
1748,3,demo,332,IAmTesting-this,"",started_following_repo,2012-10-23 18:51:16.88748
 
1749,3,demo,332,IAmTesting-this,"",user_created_repo,2012-10-23 18:51:16.902186
 
1750,3,demo,333,IAmTesting_this,"",started_following_repo,2012-10-23 19:15:24.347861
 
1751,3,demo,333,IAmTesting_this,"",user_created_repo,2012-10-23 19:15:24.361363
 
1752,3,demo,333,IAmTesting_this,"",user_updated_repo,2012-10-23 19:35:36.723229
 
1753,1,default,333,IAmTesting_this,194.117.18.103,push:31ca1f206de23b0d257dcbb323f9ba94e142ceb5,2012-10-23 19:59:07.360826
 
1754,3,demo,334,Test1qwerty,"",started_following_repo,2012-10-23 20:56:13.001385
 
1755,3,demo,334,Test1qwerty,"",user_created_repo,2012-10-23 20:56:13.014633
 
1756,3,demo,334,Test1qwerty,"",push_local:5957aa6f6f14241663b8b1a0ca050e43c3d3ca27,2012-10-23 20:57:25.88513
 
1757,3,demo,335,git,"",started_following_repo,2012-10-23 21:49:35.974797
 
1758,3,demo,335,git,"",user_created_repo,2012-10-23 21:49:35.994798
 
1759,3,demo,336,fork-cruel-test-2,"",started_following_repo,2012-10-23 23:49:23.770508
 
1760,3,demo,174,releases/cruel-test-2,"",user_forked_repo:fork-cruel-test-2,2012-10-23 23:49:23.85229
 
1761,3,demo,336,fork-cruel-test-2,"",user_created_fork:fork-cruel-test-2,2012-10-23 23:49:23.867582
 
1762,3,demo,337,why-testing,"",started_following_repo,2012-10-23 23:53:03.878941
 
1763,3,demo,337,why-testing,"",user_created_repo,2012-10-23 23:53:03.893321
 
1764,3,demo,338,temp11,"",started_following_repo,2012-10-24 10:43:46.379754
 
1765,3,demo,338,temp11,"",user_created_repo,2012-10-24 10:43:46.391127
 
1766,3,demo,339,test123,"",started_following_repo,2012-10-24 14:10:41.927001
 
1767,3,demo,339,test123,"",user_created_repo,2012-10-24 14:10:41.936239
 
1768,3,demo,339,releases/test123,"",user_updated_repo,2012-10-24 14:10:57.739304
 
1769,2,admin,339,releases/test123,146.48.87.66,push:87e9dcd8d3e375c218fdb747da52dc1551a93dc7,2012-10-24 14:12:02.63513
 
1770,292,Airframe,340,Testtestac,"",started_following_repo,2012-10-24 17:09:26.37836
 
1771,292,Airframe,340,Testtestac,"",user_created_repo,2012-10-24 17:09:26.387917
 
1772,293,imbehind,190,xxx,"",user_commented_revision:008d9c6f7c92636aaeda6f182bffecac6a464dd3,2012-10-24 20:38:59.535098
 
1773,3,demo,341,MicTest,"",started_following_repo,2012-10-24 20:59:34.176289
 
1774,3,demo,341,MicTest,"",user_created_repo,2012-10-24 20:59:34.186308
 
1775,3,demo,341,MicTest,"",push_local:327bf84d0d633a66f0c7ff4533de2415c9ff5a88,2012-10-24 21:00:28.379598
 
1776,295,mhassanzadeh,342,ttest,"",started_following_repo,2012-10-25 10:50:06.001658
 
1777,295,mhassanzadeh,342,ttest,"",user_created_repo,2012-10-25 10:50:06.011192
 
1807,306,foobar,,foobar,"",user_forked_repo:fork-foobar,2012-10-30 05:39:47.942232
 
1809,306,foobar,,foobar,24.67.50.255,push:0e3a7dcdd90bdb2a1f6dbe85e7b574e4f6304207,2012-10-30 05:50:43.083487
 
1781,3,demo,,fork-rawr,"",user_deleted_repo,2012-10-25 15:14:56.164313
 
1782,3,demo,343,test_git_repo,"",started_following_repo,2012-10-26 13:31:41.642802
 
1783,3,demo,343,test_git_repo,"",user_created_repo,2012-10-26 13:31:41.653854
 
1784,2,admin,99,another-fork-to-check-code-review,"",user_commented_revision:d5422faf648cc589425cd3b0dbf1f6dbf93036a0,2012-10-27 15:38:54.924143
 
1785,3,demo,344,sadfasdf,"",started_following_repo,2012-10-28 11:41:22.491275
 
1786,3,demo,344,sadfasdf,"",user_created_repo,2012-10-28 11:41:22.503388
 
1787,3,demo,345,fork-dvorak,"",started_following_repo,2012-10-29 09:43:08.276759
 
1788,3,demo,129,dvorak,"",user_forked_repo:fork-dvorak,2012-10-29 09:43:08.321733
 
1789,3,demo,345,fork-dvorak,"",user_created_fork:fork-dvorak,2012-10-29 09:43:08.329436
 
1790,3,demo,346,my-test-repo,"",started_following_repo,2012-10-29 09:45:29.684135
 
1791,3,demo,346,my-test-repo,"",user_created_repo,2012-10-29 09:45:29.694219
 
1792,3,demo,347,fork-aaa-project111,"",started_following_repo,2012-10-29 09:50:58.797507
 
1793,3,demo,68,aaa-project,"",user_forked_repo:fork-aaa-project111,2012-10-29 09:50:58.809098
 
1794,3,demo,347,fork-aaa-project111,"",user_created_fork:fork-aaa-project111,2012-10-29 09:50:58.816283
 
1795,2,admin,348,group/I-am-a-very-long-repository-name,"",started_following_repo,2012-10-29 15:51:18.519038
 
1796,2,admin,348,group/I-am-a-very-long-repository-name,"",admin_created_repo,2012-10-29 15:51:18.528651
 
1797,3,demo,34,a-very-long-usper-loooong-name-that-is-to-long,"",user_updated_repo,2012-10-29 17:32:06.365281
 
1798,3,demo,350,misisko-repo,"",started_following_repo,2012-10-29 20:19:56.180975
 
1799,3,demo,350,misisko-repo,"",user_created_repo,2012-10-29 20:19:56.190032
 
1800,3,demo,350,misisko-repo,195.168.239.153,push:34bd2e2b6cf2abdb0e026182b9342f95d8f6f440,2012-10-29 20:21:33.067763
 
1801,3,demo,350,misisko-repo,"",user_commented_revision:34bd2e2b6cf2abdb0e026182b9342f95d8f6f440,2012-10-29 20:23:32.816207
 
1802,2,admin,350,misisko-repo,"",push_local:89a041cce422153ba0716a2beb2b5711ee4f4280,2012-10-29 21:23:56.649892
 
1806,306,foobar,,fork-foobar,"",started_following_repo,2012-10-30 05:39:47.86196
 
1808,306,foobar,,fork-foobar,"",user_created_fork:fork-foobar,2012-10-30 05:39:47.956653
 
1811,306,foobar,,fork-foobar,"",user_deleted_repo,2012-10-30 05:56:06.059093
 
1803,306,foobar,,foobar,"",started_following_repo,2012-10-30 05:36:49.915108
 
1804,306,foobar,,foobar,"",user_created_repo,2012-10-30 05:36:49.929097
 
1805,306,foobar,,foobar,24.67.50.255,push:3b0ad3c9b89dec8bcac5ec8bc9846f307dd5f291,2012-10-30 05:38:30.960676
 
1810,306,foobar,,foobar,24.67.50.255,push:5066e223f81d3983b9bc4d959c509bbce326474c,2012-10-30 05:53:14.168715
 
1812,306,foobar,,foobar,"",user_deleted_repo,2012-10-30 05:56:35.211293
 
1813,3,demo,354,DibaDaba,"",started_following_repo,2012-10-30 10:55:03.068862
 
1814,3,demo,354,DibaDaba,"",user_created_repo,2012-10-30 10:55:03.088077
 
1815,3,demo,354,DibaDaba,"",push_local:cf41636a602d2a69128cc58fdf441857afb83827,2012-10-30 10:56:16.451197
 
1816,3,demo,354,DibaDaba,"",user_updated_repo,2012-10-30 11:05:50.836108
 
1817,3,demo,354,DibaDaba,"",push_local:15453a2035510dcefbc8b7f3e45b916003ae4a0f,2012-10-30 11:18:42.79919
 
1818,3,demo,355,Test-RohdeCode,"",started_following_repo,2012-10-30 21:07:27.016976
 
1819,3,demo,355,Test-RohdeCode,"",user_created_repo,2012-10-30 21:07:27.040381
 
1820,3,demo,355,Test-RohdeCode,"",push_local:a2c7c944a5bae039181a84bec8bc89a9bb4ac68c,2012-10-31 10:52:21.038578
 
1821,3,demo,355,Test-RohdeCode,"",push_local:303c0051c7a04b5a4f77654d8cfeb09a61322e15,2012-10-31 16:32:16.917289
 
1822,3,demo,356,testdzone,"",started_following_repo,2012-11-02 15:51:18.982652
 
1823,3,demo,356,testdzone,"",user_created_repo,2012-11-02 15:51:18.994144
 
1824,3,demo,357,firs,"",started_following_repo,2012-11-04 00:37:08.689703
 
1825,3,demo,357,firs,"",user_created_repo,2012-11-04 00:37:08.700977
 
1826,316,theo,358,brightandshiny,"",started_following_repo,2012-11-04 14:17:04.270938
 
1827,316,theo,358,brightandshiny,"",user_created_repo,2012-11-04 14:17:04.286049
 
1828,316,theo,358,brightandshiny,87.165.13.203,"push:831fd48093c38f64bb541a4c12bec45d27c13f9d,0177264991ad113c2dbeed00716738931bc0222f",2012-11-04 14:21:33.759458
 
1829,3,demo,45,group/fork-bootstrap,"",started_following_repo,2012-11-04 18:25:45.459487
 
1830,3,demo,45,group/fork-bootstrap,"",stopped_following_repo,2012-11-04 18:25:48.166886
 
1831,3,demo,45,group/fork-bootstrap,"",started_following_repo,2012-11-04 18:25:51.905362
 
1832,3,demo,45,group/fork-bootstrap,"",stopped_following_repo,2012-11-04 18:25:54.406445
 
1833,3,demo,227,fork-aaa-project-2,"",user_commented_revision:bc829c34912709c7d129e5dae9a3e5ff46e77fc7,2012-11-05 18:37:48.772572
 
1834,3,demo,227,fork-aaa-project-2,"",user_commented_revision:bc829c34912709c7d129e5dae9a3e5ff46e77fc7,2012-11-05 18:38:42.521316
 
1835,3,demo,359,MyUberRepo,"",started_following_repo,2012-11-05 22:04:02.939575
 
1836,3,demo,359,MyUberRepo,"",user_created_repo,2012-11-05 22:04:02.95609
 
1837,3,demo,359,MyUberRepo,"",push_local:a67ddbdca6d533e0cd43175068cc12f526b2f95f,2012-11-05 22:07:40.846096
 
1838,3,demo,360,marese_test,"",started_following_repo,2012-11-05 22:10:35.535744
 
1839,3,demo,360,marese_test,"",user_created_repo,2012-11-05 22:10:35.547878
 
1840,3,demo,361,test-23,"",started_following_repo,2012-11-06 04:01:46.385817
 
1841,3,demo,361,test-23,"",user_created_repo,2012-11-06 04:01:46.410423
 
1842,3,demo,361,test-23,"",push_local:7d8547b154a01c7055a09292e871e80f3c6b574b,2012-11-06 04:03:03.320736
 
1843,3,demo,361,test-23,"",user_commented_revision:7d8547b154a01c7055a09292e871e80f3c6b574b,2012-11-06 04:07:20.51212
 
1844,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:fba17a64fa4978bfea19222da5e64a18cfddeecd,2012-11-06 04:12:51.753053
 
1845,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:fba17a64fa4978bfea19222da5e64a18cfddeecd,2012-11-06 04:13:30.727101
 
1846,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:fba17a64fa4978bfea19222da5e64a18cfddeecd,2012-11-06 04:15:29.032768
 
1847,3,demo,68,aaa-project,"",user_commented_revision:0c33fa58efc5a5541d8d3f1a3d3b77367e3d94f5,2012-11-06 04:17:16.091927
 
1848,3,demo,249,abcdefg,"",user_commented_revision:5d80e28538141e322b317168e2367fb03178d58c,2012-11-06 06:10:53.372505
 
1849,3,demo,362,Marcin,"",started_following_repo,2012-11-06 10:45:38.505485
 
1850,3,demo,362,Marcin,"",user_created_repo,2012-11-06 10:45:38.518969
 
1851,3,demo,362,hidden/Marcin,"",user_updated_repo,2012-11-06 10:45:46.281581
 
1849,3,demo,362,Username,"",started_following_repo,2012-11-06 10:45:38.505485
 
1850,3,demo,362,Username,"",user_created_repo,2012-11-06 10:45:38.518969
 
1851,3,demo,362,hidden/Username,"",user_updated_repo,2012-11-06 10:45:46.281581
 
1852,3,demo,177,blah,62.200.22.2,push:b369fb18c8d61fe0d3b14c417466680230cabe46,2012-11-06 10:47:55.655029
 
1853,3,demo,99,another-fork-to-check-code-review,"",user_commented_revision:d5422faf648cc589425cd3b0dbf1f6dbf93036a0,2012-11-06 13:12:05.517155
 
1854,3,demo,38,code-review-test,"",user_commented_revision:6d7db5794e8cad7da042b6ae6238116c6e59a4d2,2012-11-06 16:12:59.38977
 
1855,3,demo,363,utf8-test,"",started_following_repo,2012-11-06 16:52:34.020264
 
1856,3,demo,363,utf8-test,"",user_created_repo,2012-11-06 16:52:34.036171
 
1857,3,demo,363,utf8-test,178.6.80.143,push:e9e69068b8277c8e857984fb44e54d4e057710bd,2012-11-06 16:54:30.357337
 
1858,320,blahblub,364,abc_test,"",started_following_repo,2012-11-06 22:06:45.476725
 
1859,320,blahblub,364,abc_test,"",user_created_repo,2012-11-06 22:06:45.488546
 
1860,320,blahblub,364,abc_test,81.190.220.154,"push:e05d82d631f4a61972c2c76eb5b473c55ee6133f,dccf54ebc0638183872cfd9d35f0f49aa44ad4bc",2012-11-06 22:07:39.657839
 
1861,320,blahblub,364,abc_test,81.190.220.154,push:8ef2f06b68eb25067c4ca3a9c73c89bb681f031b,2012-11-06 22:09:18.572762
 
1862,3,demo,365,testing_do,"",started_following_repo,2012-11-07 00:19:56.15291
 
1863,3,demo,365,testing_do,"",user_created_repo,2012-11-07 00:19:56.165626
 
1864,3,demo,365,testing_do,"",user_updated_repo,2012-11-07 00:21:24.482025
 
1865,3,demo,321,Mecurial-Test,"",user_commented_revision:041e48fd7acad4c27385c27a4789d3d5cc7ccbea,2012-11-07 01:16:37.129361
 
1866,321,ifco89,284,fork-django,"",user_commented_revision:129f1ac8484d63c2e61a44fb2a18dd17246c1c4d,2012-11-07 01:26:40.887017
 
1867,3,demo,284,fork-django,"",user_commented_revision:c5d6f6d6829e730bdddf63c1252304f0c49a9053,2012-11-07 01:27:33.995596
 
1868,3,demo,68,aaa-project,"",push_local:5ecd97456233badb3680873dc5b7d4bfb52ede79,2012-11-07 06:43:22.378406
 
1869,3,demo,319,fork1-code-review-test,"",user_commented_revision:e216971a777e3132487405dd2c8e093f66788765,2012-11-07 08:44:19.419642
 
1870,3,demo,366,test123123,"",started_following_repo,2012-11-07 14:16:13.029479
 
1871,3,demo,366,test123123,"",user_created_repo,2012-11-07 14:16:13.04346
 
1872,323,didi,364,abc_test,"",user_commented_revision:8ef2f06b68eb25067c4ca3a9c73c89bb681f031b,2012-11-07 15:45:10.378961
 
1873,324,tutty,367,fork-bootstrap,"",started_following_repo,2012-11-07 16:00:47.116111
 
1874,324,tutty,36,bootstrap,"",user_forked_repo:fork-bootstrap,2012-11-07 16:00:48.378051
 
1875,324,tutty,367,fork-bootstrap,"",user_created_fork:fork-bootstrap,2012-11-07 16:00:48.393002
 
1876,3,demo,68,aaa-project,"",user_commented_revision:b4bf1f77b1288a24eb395537319b4f3155cffa71,2012-11-08 18:41:07.016059
 
1877,3,demo,68,aaa-project,"",user_commented_revision:b4bf1f77b1288a24eb395537319b4f3155cffa71,2012-11-08 18:41:34.311311
 
1878,3,demo,68,aaa-project,"",user_commented_revision:b4bf1f77b1288a24eb395537319b4f3155cffa71,2012-11-08 18:41:38.071834
 
1879,3,demo,368,Repotest,"",started_following_repo,2012-11-09 10:40:40.804085
 
1880,3,demo,368,Repotest,"",user_created_repo,2012-11-09 10:40:40.813114
 
1881,3,demo,369,fork-HelloWorld,"",started_following_repo,2012-11-10 19:57:46.238558
 
1882,3,demo,280,HelloWorld,"",user_forked_repo:fork-HelloWorld,2012-11-10 19:57:46.306001
 
1883,3,demo,369,fork-HelloWorld,"",user_created_fork:fork-HelloWorld,2012-11-10 19:57:46.320675
 
1884,3,demo,370,fork-django-more,"",started_following_repo,2012-11-11 01:18:51.709667
 
1885,3,demo,110,django,"",user_forked_repo:fork-django-more,2012-11-11 01:18:58.716934
 
1886,3,demo,370,fork-django-more,"",user_created_fork:fork-django-more,2012-11-11 01:18:58.731127
 
1887,3,demo,371,hgh,"",started_following_repo,2012-11-12 06:07:06.509759
 
1888,3,demo,371,hgh,"",user_created_repo,2012-11-12 06:07:06.525795
 
1889,3,demo,371,hgh,"",push_local:b43f437976ff61a8fa37709f105091ffd00bbd2c,2012-11-12 06:08:34.009007
 
1890,3,demo,371,hgh,"",push_local:93c5a23d3cbde4c6dbd21d722eb1beff90a1d67c,2012-11-12 06:09:44.749181
 
1891,3,demo,371,hgh,"",push_local:d3e97cf131b0feaa586272d88e71e97a65564806,2012-11-12 06:13:04.240444
 
1892,336,demodemo,373,test-for,"",started_following_repo,2012-11-12 18:29:12.02868
 
1893,336,demodemo,373,test-for,"",user_created_repo,2012-11-12 18:29:12.041121
 
1894,336,demodemo,374,fork-test-for,"",started_following_repo,2012-11-12 18:29:25.869055
 
1895,336,demodemo,373,test-for,"",user_forked_repo:fork-test-for,2012-11-12 18:29:25.922561
 
1896,336,demodemo,374,fork-test-for,"",user_created_fork:fork-test-for,2012-11-12 18:29:25.936869
 
1897,336,demodemo,374,fork-test-for,101.140.96.42,push:a7495b86f0bfc299740cdbfbbca1b9d5ca1f62de,2012-11-12 18:31:51.107494
 
1898,2,admin,376,linux-kernel,"",started_following_repo,2012-11-13 22:14:17.466937
 
1899,342,gauravve,377,myrep,"",started_following_repo,2012-11-14 12:12:46.280751
 
1900,342,gauravve,377,myrep,"",user_created_repo,2012-11-14 12:12:46.296606
 
1901,343,yasser.a,125,test-to-end-all-tests,"",user_commented_revision:fb4eb182028a674ae250430c04305e9b3fbe508e,2012-11-14 16:17:28.970017
 
772,2,admin,,cruel-test,"",started_following_repo,2012-08-28 10:23:44.560576
 
1902,254,yujiro,378,arai-new-repo,"",started_following_repo,2012-11-15 02:39:50.649631
 
1903,254,yujiro,378,arai-new-repo,"",user_created_repo,2012-11-15 02:39:50.667177
 
1904,254,yujiro,378,arai-new-repo,182.171.245.184,push:6beb6da3b0e27eb1401090e122f7675d56e07fc1,2012-11-15 02:45:25.207338
 
1905,3,demo,381,test01012145,"",started_following_repo,2012-11-16 13:02:38.980282
 
1906,3,demo,381,test01012145,"",user_created_repo,2012-11-16 13:02:38.989119
 
1907,3,demo,381,test01012145,"",push_local:225a9898957de5f78ac2aa8e4d46a80eed3ee6d5,2012-11-16 13:04:53.384353
 
1908,3,demo,382,aaa-repo-fork,"",started_following_repo,2012-11-17 12:58:42.919876
 
1909,3,demo,67,group/aaa-repo,"",user_forked_repo:aaa-repo-fork,2012-11-17 12:58:42.981111
 
1910,3,demo,382,aaa-repo-fork,"",user_created_fork:aaa-repo-fork,2012-11-17 12:58:42.992071
 
1911,3,demo,382,aaa-repo-fork,"",user_updated_repo,2012-11-17 12:59:32.084662
 
1912,2,admin,,"","",admin_updated_user:kiall,2012-11-17 21:52:15.776253
 
1913,3,demo,268,foofootest,"",user_commented_revision:4bc0645c20363db85c9a5050a85c2c05a1991765,2012-11-20 12:19:44.614295
 
1914,3,demo,383,aaa-test-repo,"",started_following_repo,2012-11-20 12:27:16.120325
 
1915,3,demo,383,aaa-test-repo,"",user_created_repo,2012-11-20 12:27:16.130553
 
1916,3,demo,383,aaa-test-repo,"",push_local:fb2f5ae9a806abe4cb03fe7b11d4ad21a836f7b6,2012-11-20 12:27:41.98988
 
1917,3,demo,384,aaa-test-repo2,"",started_following_repo,2012-11-20 12:31:43.009679
 
1918,3,demo,384,aaa-test-repo2,"",user_created_repo,2012-11-20 12:31:43.019015
 
1919,3,demo,384,aaa-test-repo2,"",push_local:83a7be8f9d651912ee343067bd392678fbebe3e8,2012-11-20 12:32:34.336741
 
1920,3,demo,385,aaa-test-repo2-fork,"",started_following_repo,2012-11-20 12:58:25.715274
 
1921,3,demo,384,aaa-test-repo2,"",user_forked_repo:aaa-test-repo2-fork,2012-11-20 12:58:25.729374
 
1922,3,demo,385,aaa-test-repo2-fork,"",user_created_fork:aaa-test-repo2-fork,2012-11-20 12:58:25.737204
 
1923,3,demo,385,aaa-test-repo2-fork,"",push_local:af794c0c7cf39be92c6b59bb8b7871d313b1d248,2012-11-20 12:58:59.668087
 
1924,3,demo,384,aaa-test-repo2,"",user_commented_pull_request:74,2012-11-20 13:25:32.773937
 
1925,3,demo,384,aaa-test-repo2,"",user_commented_pull_request:74,2012-11-20 13:33:39.823854
 
1926,3,demo,384,aaa-test-repo2,"",user_closed_pull_request:74,2012-11-20 13:33:39.828583
 
1927,3,demo,385,aaa-test-repo2-fork,"",push_local:67120aaf6ddd81cd2aabde6adc22e7ca90d15d12,2012-11-20 18:41:48.280705
 
1928,3,demo,384,aaa-test-repo2,81.178.131.20,"push:af794c0c7cf39be92c6b59bb8b7871d313b1d248,67120aaf6ddd81cd2aabde6adc22e7ca90d15d12",2012-11-20 20:01:34.101349
 
1929,3,demo,385,aaa-test-repo2-fork,"",push_local:5ece07f12c61645049e7d2d3d33797942b16cba5,2012-11-20 20:10:49.816215
 
1930,3,demo,385,aaa-test-repo2-fork,"",push_local:fd8a6936e27e3c31684155790f78effb33e6cc5c,2012-11-20 20:24:06.305599
 
1931,3,demo,384,aaa-test-repo2,81.178.131.20,push:5ece07f12c61645049e7d2d3d33797942b16cba5,2012-11-20 20:49:00.180794
 
1932,3,demo,384,aaa-test-repo2,81.178.131.20,push:fd8a6936e27e3c31684155790f78effb33e6cc5c,2012-11-20 21:28:16.281326
 
1933,3,demo,384,aaa-test-repo2,"",user_commented_pull_request:75,2012-11-21 01:38:22.165876
 
1934,3,demo,384,aaa-test-repo2,"",user_closed_pull_request:75,2012-11-21 01:38:22.175975
 
1935,3,demo,385,aaa-test-repo2-fork,"",push_local:586be5737b6b185d37ab249e028470417698b44d,2012-11-21 01:42:21.540009
 
1936,3,demo,385,aaa-test-repo2-fork,"",push_local:b836457cf5b358555c26193e67770d56e2345f4c,2012-11-21 01:50:03.178941
 
1937,3,demo,384,aaa-test-repo2,81.178.131.20,"push:586be5737b6b185d37ab249e028470417698b44d,b836457cf5b358555c26193e67770d56e2345f4c",2012-11-21 02:01:01.40853
 
1938,3,demo,34,a-very-long-usper-loooong-name-that-is-to-long,"",push_local:ff712eae5a99bede2bf710d86f86b0b534fbf089,2012-11-21 02:09:50.150788
 
1939,3,demo,68,aaa-project,"",user_commented_revision:b4bf1f77b1288a24eb395537319b4f3155cffa71,2012-11-21 08:36:43.456525
 
1940,3,demo,384,aaa-test-repo2,"",user_commented_revision:b836457cf5b358555c26193e67770d56e2345f4c,2012-11-21 12:03:06.317362
 
1941,3,demo,385,aaa-test-repo2-fork,"",push_local:d38a759ba1f79489db44854c9ddf06986f7e2b72,2012-11-21 12:17:04.303085
 
1942,3,demo,385,aaa-test-repo2-fork,"",user_commented_revision:d38a759ba1f79489db44854c9ddf06986f7e2b72,2012-11-21 12:17:47.536221
 
1943,3,demo,34,a-very-long-usper-loooong-name-that-is-to-long,"",user_commented_revision:f437e821a406d35b1e231c5a81e82853f8ed6436,2012-11-21 14:27:15.134067
 
1944,3,demo,386,I-am-a-very-long-repository-name-fork,"",started_following_repo,2012-11-21 15:31:17.25368
 
1945,3,demo,348,group/I-am-a-very-long-repository-name,"",user_forked_repo:I-am-a-very-long-repository-name-fork,2012-11-21 15:31:17.271794
 
1946,3,demo,386,I-am-a-very-long-repository-name-fork,"",user_created_fork:I-am-a-very-long-repository-name-fork,2012-11-21 15:31:17.283533
 
1947,3,demo,385,aaa-test-repo2-fork,"",user_commented_revision:d38a759ba1f79489db44854c9ddf06986f7e2b72,2012-11-21 16:35:17.484282
 
1948,3,demo,385,aaa-test-repo2-fork,"",push_local:96abb74e8e96a81a7dc5d472c70158da5318a623,2012-11-21 16:35:50.796373
 
1949,3,demo,385,aaa-test-repo2-fork,"",user_commented_revision:96abb74e8e96a81a7dc5d472c70158da5318a623,2012-11-21 16:36:25.797019
 
1950,2,admin,68,aaa-project,"",push_local:7db38281c68497cee8dc4510d77e03fbb4d6c395,2012-11-21 18:34:44.97296
 
1951,2,admin,68,aaa-project,"",push_local:de5af01cc0f75ab84966b11806c343000eeeb5d8,2012-11-21 18:36:10.869973
 
1952,3,demo,387,new-group-test-repos1,"",started_following_repo,2012-11-21 21:05:48.945007
 
1953,3,demo,387,new-group-test-repos1,"",user_created_repo,2012-11-21 21:05:48.953815
 
1954,3,demo,388,Logarithmic,"",started_following_repo,2012-11-22 11:30:39.744224
 
1955,3,demo,388,Logarithmic,"",user_created_repo,2012-11-22 11:30:39.761413
 
1956,3,demo,388,Logarithmic,"",push_local:72dd1a9ceecfcf9832e41dd66d355d5c63546b67,2012-11-22 11:35:30.523613
 
1957,3,demo,388,Logarithmic,"",push_local:fdb124c2a063a7ce15a1b3e42cdfa30a5bf19fcb,2012-11-22 11:52:07.237429
 
1958,364,hs_rcdemo,389,hsio_test,"",started_following_repo,2012-11-22 14:32:05.148189
 
1959,364,hs_rcdemo,389,hsio_test,"",user_created_repo,2012-11-22 14:32:05.163464
 
1960,364,hs_rcdemo,389,hsio_test,"",push_local:8777c89c909bfba8eaae07cf596cce85190d7789,2012-11-22 14:33:30.066876
 
1961,364,hs_rcdemo,389,hsio_test,"",user_updated_repo,2012-11-22 14:45:19.518307
 
1962,3,demo,390,ycxs,"",started_following_repo,2012-11-23 08:00:34.880042
 
1963,3,demo,390,ycxs,"",user_created_repo,2012-11-23 08:00:34.889356
 
1964,3,demo,110,django,"",user_commented_revision:129f1ac8484d63c2e61a44fb2a18dd17246c1c4d,2012-11-23 22:54:06.842764
 
1965,3,demo,68,aaa-project,"",user_commented_revision:de5af01cc0f75ab84966b11806c343000eeeb5d8,2012-11-25 18:05:15.626452
 
1966,373,roger,391,roger,"",started_following_repo,2012-11-27 10:19:17.098535
 
1967,373,roger,391,roger,"",user_created_repo,2012-11-27 10:19:17.110165
 
1968,373,roger,391,roger,195.67.17.194,push:3deefa3d90eb91fbfe7c7d97579842d26ffab526,2012-11-27 10:20:14.448706
 
1969,373,roger,394,roger-fork,"",started_following_repo,2012-11-27 10:44:06.565014
 
1970,373,roger,391,roger,"",user_forked_repo:roger-fork,2012-11-27 10:44:06.582941
 
1971,373,roger,394,roger-fork,"",user_created_fork:roger-fork,2012-11-27 10:44:06.591697
 
1972,373,roger,394,roger-fork,195.67.17.194,push:ef5703075e9bd3b498d0398be689c6ecc2aa68f2,2012-11-27 10:46:44.898629
 
1973,373,roger,391,roger,"",user_commented_pull_request:77,2012-11-27 10:49:00.02305
 
1974,373,roger,394,roger-fork,195.67.17.194,push:1f3690bd18da15796e2379ea2f82d510dbbfd634,2012-11-27 10:52:51.819376
 
1975,373,roger,391,roger,"",user_commented_pull_request:78,2012-11-27 10:55:01.836362
 
1976,373,roger,391,roger,"",user_closed_pull_request:78,2012-11-27 10:55:01.843519
 
1977,373,roger,391,roger,"",user_commented_pull_request:77,2012-11-27 10:55:43.206231
 
1978,373,roger,391,roger,"",user_updated_repo,2012-11-27 10:56:53.018675
 
1979,373,roger,391,roger,"",user_updated_repo,2012-11-27 11:02:27.558462
 
1980,373,roger,394,roger-fork,195.67.17.194,push:3a6d267941eeb0a8cd7be18d619d6fe370216f00,2012-11-27 11:04:37.480288
 
1981,374,roger2,391,roger,"",user_commented_pull_request:79,2012-11-27 11:05:56.858694
 
1982,374,roger2,391,roger,"",user_commented_pull_request:79,2012-11-27 11:06:02.182164
 
1983,374,roger2,391,roger,"",user_commented_pull_request:79,2012-11-27 11:06:38.109374
 
1984,374,roger2,391,roger,"",user_commented_pull_request:79,2012-11-27 11:07:34.474704
 
1985,374,roger2,391,roger,"",user_closed_pull_request:79,2012-11-27 11:07:34.485308
 
1986,373,roger,394,roger-fork,195.67.17.194,push:12cd31bebc666a85f8a0f0742093d5cd9ea585c4,2012-11-27 11:09:08.04061
 
1987,373,roger,395,rogerfork2,"",started_following_repo,2012-11-27 11:11:04.332674
 
1988,373,roger,391,roger,"",user_forked_repo:rogerfork2,2012-11-27 11:11:04.348686
 
1989,373,roger,395,rogerfork2,"",user_created_fork:rogerfork2,2012-11-27 11:11:04.359388
 
1990,373,roger,395,rogerfork2,195.67.17.194,"push:ef5703075e9bd3b498d0398be689c6ecc2aa68f2,1f3690bd18da15796e2379ea2f82d510dbbfd634,3a6d267941eeb0a8cd7be18d619d6fe370216f00,12cd31bebc666a85f8a0f0742093d5cd9ea585c4",2012-11-27 11:11:18.920484
 
1991,373,roger,391,roger,"",user_commented_pull_request:80,2012-11-27 11:12:23.228709
 
1992,373,roger,391,roger,"",user_commented_pull_request:80,2012-11-27 11:12:55.017541
 
1993,373,roger,391,roger,"",user_closed_pull_request:80,2012-11-27 11:12:55.027814
 
1994,3,demo,385,aaa-test-repo2-fork,"",push_local:872eeeb3a8a2783129bfd7d988323f5addac7ab1,2012-11-27 11:48:48.630984
 
1995,3,demo,384,aaa-test-repo2,"",user_commented_pull_request:76,2012-11-27 11:50:01.915064
 
1996,3,demo,384,aaa-test-repo2,"",user_commented_pull_request:76,2012-11-27 11:50:12.991796
 
1997,3,demo,384,aaa-test-repo2,"",user_closed_pull_request:76,2012-11-27 11:50:12.99591
 
1998,3,demo,396,тестовый-сервер,"",started_following_repo,2012-11-28 07:53:39.536654
 
1999,3,demo,396,тестовый-сервер,"",user_created_repo,2012-11-28 07:53:39.550591
 
2000,3,demo,397,simple-dev-fork,"",started_following_repo,2012-11-28 09:13:25.051649
 
2001,3,demo,210,simple-dev,"",user_forked_repo:simple-dev-fork,2012-11-28 09:13:25.106104
 
2002,3,demo,397,simple-dev-fork,"",user_created_fork:simple-dev-fork,2012-11-28 09:13:25.114908
 
2003,3,demo,385,aaa-test-repo2-fork,"",user_commented_revision:96abb74e8e96a81a7dc5d472c70158da5318a623,2012-11-28 12:24:53.581825
 
2004,3,demo,385,aaa-test-repo2-fork,"",user_commented_revision:872eeeb3a8a2783129bfd7d988323f5addac7ab1,2012-11-28 12:25:16.961119
 
2005,3,demo,398,aaa-project-fork-fork,"",started_following_repo,2012-11-29 14:08:09.275983
 
2006,3,demo,68,aaa-project,"",user_forked_repo:aaa-project-fork-fork,2012-11-29 14:08:09.413733
 
2007,3,demo,398,aaa-project-fork-fork,"",user_created_fork:aaa-project-fork-fork,2012-11-29 14:08:09.427854
 
2008,3,demo,68,aaa-project,"",user_updated_repo,2012-11-29 14:09:10.934065
 
2009,3,demo,68,aaa-project,"",user_updated_repo,2012-11-29 14:09:24.706033
 
2010,3,demo,399,tra,"",started_following_repo,2012-11-29 14:11:48.839858
 
2011,3,demo,399,tra,"",user_created_repo,2012-11-29 14:11:48.85278
 
2012,3,demo,42,foo,"",user_commented_revision:1b9a14ca778d48ebef5643f7aa2ce142f3a27617,2012-11-29 20:05:08.767523
 
2013,3,demo,42,foo,"",push_local:bb4dab01c0bd4241b903a4dc84a79c70a01b0f6b,2012-11-29 20:06:18.477822
 
2014,1,default,159,group/Test-for-code-review,"",push_local:eaca071ebe45eaf5fc6631b15d7cf079a0d5aaf1,2012-11-29 23:52:50.718898
 
2015,375,paul,400,hophop,"",started_following_repo,2012-11-30 08:50:31.403305
 
2016,375,paul,400,hophop,"",user_created_repo,2012-11-30 08:50:31.416463
 
2017,375,paul,400,hophop,"",push_local:558613aaa69def5e130b8f9583de37f911a80dd8,2012-11-30 08:51:37.956737
 
2018,375,paul,401,flepflep,"",started_following_repo,2012-11-30 08:52:56.146141
 
2019,375,paul,400,hophop,"",user_forked_repo:flepflep,2012-11-30 08:52:56.162784
 
2020,375,paul,401,flepflep,"",user_created_fork:flepflep,2012-11-30 08:52:56.171068
 
2021,375,paul,400,hophop,213.154.235.68,push:0c64f45ec8f43a5267d593a2af65c3b9965c312c,2012-11-30 08:54:23.238053
 
2022,376,mrntest,402,mrntest,"",started_following_repo,2012-11-30 10:10:14.463671
 
2023,376,mrntest,402,mrntest,"",user_created_repo,2012-11-30 10:10:14.475507
 
2024,1,default,159,group/Test-for-code-review,"",push_local:da1270d35961130d6fe12ba4777f412dabb533f7,2012-11-30 18:39:23.68212
 
2025,3,demo,177,blah,"",user_updated_repo,2012-11-30 21:43:04.925873
 
2026,1,default,159,group/Test-for-code-review,"",push_local:3bfcf2015dcc85f3334a4439099b1f4fe2ab87cc,2012-12-01 04:40:25.326381
 
2027,3,demo,385,aaa-test-repo2-fork,"",push_local:8caf16b59f0ac54d002daeaf54208319a055829a,2012-12-01 12:40:27.987379
 
2028,3,demo,385,aaa-test-repo2-fork,"",user_commented_revision:8caf16b59f0ac54d002daeaf54208319a055829a,2012-12-01 12:40:35.315142
 
2029,3,demo,403,aaa-test-repo2-fork1,"",started_following_repo,2012-12-01 12:43:30.698526
 
2030,3,demo,384,aaa-test-repo2,"",user_forked_repo:aaa-test-repo2-fork1,2012-12-01 12:43:30.7817
 
2031,3,demo,403,aaa-test-repo2-fork1,"",user_created_fork:aaa-test-repo2-fork1,2012-12-01 12:43:30.789849
 
2032,3,demo,403,aaa-test-repo2-fork1,"",push_local:7d46cab71f090b82e40f82aa164a237bffae8ca8,2012-12-01 12:43:54.847211
 
2033,3,demo,384,aaa-test-repo2,"",user_commented_pull_request:81,2012-12-01 12:45:15.004235
 
2034,3,demo,384,aaa-test-repo2,"",user_closed_pull_request:81,2012-12-01 12:45:15.01175
 
2035,1,default,159,group/Test-for-code-review,"",push_local:88f2b300127f7249d6b2ac03d4e368cd7a043073,2012-12-02 06:49:39.201427
 
2036,380,han,42,foo,"",user_commented_revision:ca953e8c5c1ada44e9a8f945a0a6999d2f44310d,2012-12-03 05:54:40.845102
 
2037,380,han,42,foo,"",user_commented_revision:ca953e8c5c1ada44e9a8f945a0a6999d2f44310d,2012-12-03 05:54:52.733614
 
2038,380,han,42,foo,"",user_commented_revision:ca953e8c5c1ada44e9a8f945a0a6999d2f44310d,2012-12-03 05:55:06.032348
 
2039,380,han,184,fork-aaa-project,"",user_commented_revision:e3fef0be8dc20eb1fa68fc45292d9d66de1cc67f,2012-12-03 05:55:57.293424
 
2040,380,han,184,fork-aaa-project,"",user_commented_revision:e3fef0be8dc20eb1fa68fc45292d9d66de1cc67f,2012-12-03 05:56:05.503132
 
2041,380,han,184,fork-aaa-project,"",user_commented_revision:e3fef0be8dc20eb1fa68fc45292d9d66de1cc67f,2012-12-03 05:56:11.78452
 
2042,381,tmilos,265,mercurial-trunk,"",user_commented_revision:b3f0f9a39c4e1d0250048cd803ab03542d6f140a,2012-12-03 08:18:24.126434
 
2043,381,tmilos,265,mercurial-trunk,"",user_commented_revision:b3f0f9a39c4e1d0250048cd803ab03542d6f140a,2012-12-03 08:18:53.783535
 
2044,3,demo,68,aaa-project,"",user_commented_revision:0c33fa58efc5a5541d8d3f1a3d3b77367e3d94f5,2012-12-03 13:51:26.584571
 
2045,3,demo,384,aaa-test-repo2,"",user_updated_repo,2012-12-03 13:59:51.134475
 
2046,3,demo,68,aaa-project,"",user_updated_repo,2012-12-03 14:12:42.587904
 
2047,3,demo,404,Test-Repo-5,"",started_following_repo,2012-12-03 19:58:28.17924
 
2048,3,demo,404,Test-Repo-5,"",admin_created_repo,2012-12-03 19:58:28.215537
 
2049,3,demo,382,aaa-repo-fork,"",push_local:d49133c59d2b74bf5754fab639520fe0f15f660b,2012-12-03 23:45:38.954154
 
2050,5,natosha.bard,405,test-largefiles-push,"",started_following_repo,2012-12-04 14:15:02.062567
 
2051,5,natosha.bard,405,test-largefiles-push,"",admin_created_repo,2012-12-04 14:15:02.07345
 
2052,5,natosha.bard,405,test-largefiles-push,62.116.219.97,push:3055a4c8ccb9b695a7973aa25aa118b0dde122e4,2012-12-04 14:15:19.101956
 
2053,5,natosha.bard,405,test-largefiles-push,62.116.219.97,push:88adc5944c74488164ae575511429ed582a72e17,2012-12-04 14:40:10.373812
 
2054,384,test1234,406,test123456,"",started_following_repo,2012-12-04 16:07:07.967514
 
2055,384,test1234,406,test123456,"",admin_created_repo,2012-12-04 16:07:07.987393
 
2058,5,natosha.bard,408,test-repo-natosha,"",started_following_repo,2012-12-04 20:41:39.763055
 
2059,5,natosha.bard,408,test-repo-natosha,"",admin_created_repo,2012-12-04 20:41:39.775062
 
2056,5,natosha.bard,,hg,"",started_following_repo,2012-12-04 20:40:00.327829
 
2057,5,natosha.bard,,hg,"",admin_created_repo,2012-12-04 20:40:00.342796
 
2060,5,natosha.bard,,hg,"",user_deleted_repo,2012-12-04 20:42:03.236535
 
2062,5,natosha.bard,409,test-repo-natosha-fork,"",started_following_repo,2012-12-04 20:43:25.363199
 
2063,5,natosha.bard,408,test-repo-natosha,"",user_forked_repo:test-repo-natosha-fork,2012-12-04 20:43:25.413303
 
2064,5,natosha.bard,409,test-repo-natosha-fork,"",user_created_fork:test-repo-natosha-fork,2012-12-04 20:43:25.421503
 
2065,5,natosha.bard,409,test-repo-natosha-fork,62.116.219.97,"push:132a288f32d5b70a9170e504028c693cfffc5c39,fac6d36d04cb1838cd10bdcecd487567787fb853,e83c482c6c5fd60f14d1a5f5cf9b4f7b2a2eb3cb,ce2c709a8e908747376a3fda6059c1f81de321e7,45bd0cd7ca04f8cda0a61cddded8838dd312675a,35ba170c0f82dba18f0207ef4bd93216e6de8bbf,407209261f6373b4b3f35e343d1498b63263d38e,6f79c32c0bdfb304b984b5e6ba318cc63032cfa4,54cedee86e5126188b0dcfbd7015bcdca7f6c2e2,b0affcb67cba58db03ca3e443105fbaabd1bc88a,4c29668ca316422891e28c55bd794eee52823554,6180dcb29ec531c5d7457005ef142ea304ef49d8,2c63896783e31908f18088a7e9c583de6ec530bf,b3ec0b5fd7771b401392a83f47e0c2360e7f6d90,e689b0d9154605b8b04989c4fdd36e76d6cf26b8,b74361cf7c0ad6930a865e7eada13e2d2d6ed380,f94ead93406764ffd0c3febfc2ea70d36a2a28bb,848345a8d6adaa58704baecbb7567b275df3cc9d,0c10cf8191469e7c3c8844922e17e71a176cb7cb",2012-12-04 20:44:13.658236
 
2066,1,default,159,group/Test-for-code-review,"",push_local:b77f1d54f1d18c22e497f1d9d502e0d540506d21,2012-12-05 00:22:33.617864
 
2067,3,demo,410,aaa-project-fork-fork-fork-fork-fork-blah,"",started_following_repo,2012-12-05 10:07:05.333082
 
2068,3,demo,398,aaa-project-fork-fork,"",user_forked_repo:aaa-project-fork-fork-fork-fork-fork-blah,2012-12-05 10:07:05.47808
 
2069,3,demo,410,aaa-project-fork-fork-fork-fork-fork-blah,"",user_created_fork:aaa-project-fork-fork-fork-fork-fork-blah,2012-12-05 10:07:05.487482
 
2070,387,ssssss,411,sss-test,"",started_following_repo,2012-12-05 13:33:27.008097
 
2071,387,ssssss,411,sss-test,"",admin_created_repo,2012-12-05 13:33:27.018183
 
2072,387,ssssss,411,sss-test,"",user_updated_repo,2012-12-05 13:37:35.771478
 
2073,387,ssssss,411,sss-test,"",user_updated_repo,2012-12-05 13:38:00.979078
 
2074,387,ssssss,411,sss-test,"",user_updated_repo,2012-12-05 13:38:05.497667
 
2075,387,ssssss,411,sss-test,"",user_updated_repo,2012-12-05 13:38:12.513828
 
2076,387,ssssss,173,code-review-dev,"",started_following_repo,2012-12-05 13:46:51.940453
 
2077,387,ssssss,173,code-review-dev,"",stopped_following_repo,2012-12-05 13:46:54.738489
 
2078,387,ssssss,411,sss-test,109.195.177.171,push:7d42587da267871709bc82e462018b8b7d66a4a7,2012-12-05 13:59:09.546916
 
2079,387,ssssss,411,sss-test,109.195.177.171,push:bb869421c7c8f88590536d559cebd3ee5e9c3aa7,2012-12-05 14:00:27.04582
 
2080,387,ssssss,411,sss-test,"",user_updated_repo,2012-12-05 14:03:48.47955
 
2081,389,wwwwww,412,sss-test-fork,"",started_following_repo,2012-12-05 14:05:13.355226
 
2082,389,wwwwww,411,sss-test,"",user_forked_repo:sss-test-fork,2012-12-05 14:05:13.663527
 
2083,389,wwwwww,412,sss-test-fork,"",user_created_fork:sss-test-fork,2012-12-05 14:05:13.678367
 
2084,389,wwwwww,412,sss-test-fork,"",user_updated_repo,2012-12-05 14:05:56.566769
 
2085,389,wwwwww,412,sss-test-fork,109.195.177.171,push:20bd46e65a056aef107cc060d16c97b1ef2cc211,2012-12-05 14:07:21.399133
 
2086,389,wwwwww,412,sss-test-fork,"",user_commented_revision:20bd46e65a056aef107cc060d16c97b1ef2cc211,2012-12-05 14:16:56.716099
 
2087,387,ssssss,411,sss-test,"",user_updated_repo,2012-12-05 14:20:41.385001
 
2088,389,wwwwww,411,sss-test,109.195.177.171,push:20bd46e65a056aef107cc060d16c97b1ef2cc211,2012-12-05 14:20:54.878385
 
2089,387,ssssss,411,sss-test,"",user_updated_repo,2012-12-05 14:21:15.330812
 
2090,389,wwwwww,412,sss-test-fork,109.195.177.171,push:1203172be2e12aa31ec40ba4d07b75a3e17bd63f,2012-12-05 14:23:18.297453
 
2091,389,wwwwww,412,sss-test-fork,"",user_commented_revision:1203172be2e12aa31ec40ba4d07b75a3e17bd63f,2012-12-05 14:23:34.233486
 
2092,5,natosha.bard,413,natosha-repo1,"",started_following_repo,2012-12-05 16:46:55.328513
 
2093,5,natosha.bard,413,natosha-repo1,"",admin_created_repo,2012-12-05 16:46:55.342146
 
2094,5,natosha.bard,413,natosha-repo1,62.116.219.97,"push:6fbe2a2357168359aacbc524f4acd805dff72327,5787c391ba8f9d67b4e96f47d71adab79b693a30",2012-12-05 16:47:09.181828
 
2095,5,natosha.bard,414,natosha-repo1-fork,"",started_following_repo,2012-12-05 16:47:24.080447
 
2096,5,natosha.bard,413,natosha-repo1,"",user_forked_repo:natosha-repo1-fork,2012-12-05 16:47:24.101525
 
2097,5,natosha.bard,414,natosha-repo1-fork,"",user_created_fork:natosha-repo1-fork,2012-12-05 16:47:24.113866
 
2098,5,natosha.bard,414,natosha-repo1-fork,62.116.219.97,"push:a25c825fd81d069596d614efcf92505aed46227a,ac513595518923aca8b39f0a1c33c4c6e0f9d83a,d395e22e8e16373a1fffbe66b322581d69a7db17",2012-12-05 16:47:44.701535
 
2099,2,admin,38,code-review-test,"",user_commented_pull_request:73,2012-12-05 17:23:18.059481
kallithea/tests/functional/test_login.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
from __future__ import with_statement
 
import mock
 
from kallithea.tests import *
 
from kallithea.tests.fixture import Fixture
 
from kallithea.lib.utils2 import generate_api_key
 
from kallithea.lib.auth import check_password
 
from kallithea.lib import helpers as h
 
from kallithea.model.api_key import ApiKeyModel
 
from kallithea.model import validators
 
from kallithea.model.db import User, Notification
 
from kallithea.model.meta import Session
 

	
 
fixture = Fixture()
 

	
 

	
 
class TestLoginController(TestController):
 

	
 
    def tearDown(self):
 
        for n in Notification.query().all():
 
            Session().delete(n)
 

	
 
        Session().commit()
 
        self.assertEqual(Notification.query().all(), [])
 

	
 
    def test_index(self):
 
        response = self.app.get(url(controller='login', action='index'))
 
        self.assertEqual(response.status, '200 OK')
 
        # Test response...
 

	
 
    def test_login_admin_ok(self):
 
        response = self.app.post(url(controller='login', action='index'),
 
                                 {'username': 'test_admin',
 
                                  'password': 'test12'})
 
        self.assertEqual(response.status, '302 Found')
 
        self.assertEqual(response.session['authuser'].get('username'),
 
                         'test_admin')
 
        response = response.follow()
 
        response.mustcontain('/%s' % HG_REPO)
 

	
 
    def test_login_regular_ok(self):
 
        response = self.app.post(url(controller='login', action='index'),
 
                                 {'username': 'test_regular',
 
                                  'password': 'test12'})
 

	
 
        self.assertEqual(response.status, '302 Found')
 
        self.assertEqual(response.session['authuser'].get('username'),
 
                         'test_regular')
 
        response = response.follow()
 
        response.mustcontain('/%s' % HG_REPO)
 

	
 
    def test_login_ok_came_from(self):
 
        test_came_from = '/_admin/users'
 
        response = self.app.post(url(controller='login', action='index',
 
                                     came_from=test_came_from),
 
                                 {'username': 'test_admin',
 
                                  'password': 'test12'})
 
        self.assertEqual(response.status, '302 Found')
 
        response = response.follow()
 

	
 
        self.assertEqual(response.status, '200 OK')
 
        response.mustcontain('Users Administration')
 

	
 
    @parameterized.expand([
 
          ('data:text/html,<script>window.alert("xss")</script>',),
 
          ('mailto:test@example.com',),
 
          ('file:///etc/passwd',),
 
          ('ftp://some.ftp.server',),
 
          ('http://other.domain',),
 
    ])
 
    def test_login_bad_came_froms(self, url_came_from):
 
        response = self.app.post(url(controller='login', action='index',
 
                                     came_from=url_came_from),
 
                                 {'username': 'test_admin',
 
                                  'password': 'test12'})
 
        self.assertEqual(response.status, '302 Found')
 
        self.assertEqual(response._environ['paste.testing_variables']
 
                         ['tmpl_context'].came_from, '/')
 
        response = response.follow()
 

	
 
        self.assertEqual(response.status, '200 OK')
 

	
 
    def test_login_short_password(self):
 
        response = self.app.post(url(controller='login', action='index'),
 
                                 {'username': 'test_admin',
 
                                  'password': 'as'})
 
        self.assertEqual(response.status, '200 OK')
 

	
 
        response.mustcontain('Enter 3 characters or more')
 

	
 
    def test_login_wrong_username_password(self):
 
        response = self.app.post(url(controller='login', action='index'),
 
                                 {'username': 'error',
 
                                  'password': 'test12'})
 

	
 
        response.mustcontain('invalid user name')
 
        response.mustcontain('invalid password')
 

	
 
    #==========================================================================
 
    # REGISTRATIONS
 
    #==========================================================================
 
    def test_register(self):
 
        response = self.app.get(url(controller='login', action='register'))
 
        response.mustcontain('Sign Up')
 

	
 
    def test_register_err_same_username(self):
 
        uname = 'test_admin'
 
        response = self.app.post(url(controller='login', action='register'),
 
                                            {'username': uname,
 
                                             'password': 'test12',
 
                                             'password_confirmation': 'test12',
 
                                             'email': 'goodmail@domain.com',
 
                                             'firstname': 'test',
 
                                             'lastname': 'test'})
 

	
 
        msg = validators.ValidUsername()._messages['username_exists']
 
        msg = h.html_escape(msg % {'username': uname})
 
        response.mustcontain(msg)
 

	
 
    def test_register_err_same_email(self):
 
        response = self.app.post(url(controller='login', action='register'),
 
                                            {'username': 'test_admin_0',
 
                                             'password': 'test12',
 
                                             'password_confirmation': 'test12',
 
                                             'email': 'test_admin@mail.com',
 
                                             'firstname': 'test',
 
                                             'lastname': 'test'})
 

	
 
        msg = validators.UniqSystemEmail()()._messages['email_taken']
 
        response.mustcontain(msg)
 

	
 
    def test_register_err_same_email_case_sensitive(self):
 
        response = self.app.post(url(controller='login', action='register'),
 
                                            {'username': 'test_admin_1',
 
                                             'password': 'test12',
 
                                             'password_confirmation': 'test12',
 
                                             'email': 'TesT_Admin@mail.COM',
 
                                             'firstname': 'test',
 
                                             'lastname': 'test'})
 
        msg = validators.UniqSystemEmail()()._messages['email_taken']
 
        response.mustcontain(msg)
 

	
 
    def test_register_err_wrong_data(self):
 
        response = self.app.post(url(controller='login', action='register'),
 
                                            {'username': 'xs',
 
                                             'password': 'test',
 
                                             'password_confirmation': 'test',
 
                                             'email': 'goodmailm',
 
                                             'firstname': 'test',
 
                                             'lastname': 'test'})
 
        self.assertEqual(response.status, '200 OK')
 
        response.mustcontain('An email address must contain a single @')
 
        response.mustcontain('Enter a value 6 characters long or more')
 

	
 
    def test_register_err_username(self):
 
        response = self.app.post(url(controller='login', action='register'),
 
                                            {'username': 'error user',
 
                                             'password': 'test12',
 
                                             'password_confirmation': 'test12',
 
                                             'email': 'goodmailm',
 
                                             'firstname': 'test',
 
                                             'lastname': 'test'})
 

	
 
        response.mustcontain('An email address must contain a single @')
 
        response.mustcontain('Username may only contain '
 
                'alphanumeric characters underscores, '
 
                'periods or dashes and must begin with '
 
                'alphanumeric character')
 

	
 
    def test_register_err_case_sensitive(self):
 
        usr = 'Test_Admin'
 
        response = self.app.post(url(controller='login', action='register'),
 
                                            {'username': usr,
 
                                             'password': 'test12',
 
                                             'password_confirmation': 'test12',
 
                                             'email': 'goodmailm',
 
                                             'firstname': 'test',
 
                                             'lastname': 'test'})
 

	
 
        response.mustcontain('An email address must contain a single @')
 
        msg = validators.ValidUsername()._messages['username_exists']
 
        msg = h.html_escape(msg % {'username': usr})
 
        response.mustcontain(msg)
 

	
 
    def test_register_special_chars(self):
 
        response = self.app.post(url(controller='login', action='register'),
 
                                        {'username': 'xxxaxn',
 
                                         'password': 'ąćźżąśśśś',
 
                                         'password_confirmation': 'ąćźżąśśśś',
 
                                         'email': 'goodmailm@test.plx',
 
                                         'firstname': 'test',
 
                                         'lastname': 'test'})
 

	
 
        msg = validators.ValidPassword()._messages['invalid_password']
 
        response.mustcontain(msg)
 

	
 
    def test_register_password_mismatch(self):
 
        response = self.app.post(url(controller='login', action='register'),
 
                                            {'username': 'xs',
 
                                             'password': '123qwe',
 
                                             'password_confirmation': 'qwe123',
 
                                             'email': 'goodmailm@test.plxa',
 
                                             'firstname': 'test',
 
                                             'lastname': 'test'})
 
        msg = validators.ValidPasswordsMatch()._messages['password_mismatch']
 
        response.mustcontain(msg)
 

	
 
    def test_register_ok(self):
 
        username = 'test_regular4'
 
        password = 'qweqwe'
 
        email = 'marcin@test.com'
 
        email = 'username@test.com'
 
        name = 'testname'
 
        lastname = 'testlastname'
 

	
 
        response = self.app.post(url(controller='login', action='register'),
 
                                            {'username': username,
 
                                             'password': password,
 
                                             'password_confirmation': password,
 
                                             'email': email,
 
                                             'firstname': name,
 
                                             'lastname': lastname,
 
                                             'admin': True})  # This should be overriden
 
        self.assertEqual(response.status, '302 Found')
 
        self.checkSessionFlash(response, 'You have successfully registered into Kallithea')
 

	
 
        ret = Session().query(User).filter(User.username == 'test_regular4').one()
 
        self.assertEqual(ret.username, username)
 
        self.assertEqual(check_password(password, ret.password), True)
 
        self.assertEqual(ret.email, email)
 
        self.assertEqual(ret.name, name)
 
        self.assertEqual(ret.lastname, lastname)
 
        self.assertNotEqual(ret.api_key, None)
 
        self.assertEqual(ret.admin, False)
 

	
 
    def test_forgot_password_wrong_mail(self):
 
        bad_email = 'marcin@wrongmail.org'
 
        bad_email = 'username@wrongmail.org'
 
        response = self.app.post(
 
                        url(controller='login', action='password_reset'),
 
                            {'email': bad_email, }
 
        )
 

	
 
        msg = validators.ValidSystemEmail()._messages['non_existing_email']
 
        msg = h.html_escape(msg % {'email': bad_email})
 
        response.mustcontain()
 

	
 
    def test_forgot_password(self):
 
        response = self.app.get(url(controller='login',
 
                                    action='password_reset'))
 
        self.assertEqual(response.status, '200 OK')
 

	
 
        username = 'test_password_reset_1'
 
        password = 'qweqwe'
 
        email = 'marcin@python-works.com'
 
        email = 'username@python-works.com'
 
        name = 'passwd'
 
        lastname = 'reset'
 

	
 
        new = User()
 
        new.username = username
 
        new.password = password
 
        new.email = email
 
        new.name = name
 
        new.lastname = lastname
 
        new.api_key = generate_api_key(username)
 
        Session().add(new)
 
        Session().commit()
 

	
 
        response = self.app.post(url(controller='login',
 
                                     action='password_reset'),
 
                                 {'email': email, })
 

	
 
        self.checkSessionFlash(response, 'Your password reset link was sent')
 

	
 
        response = response.follow()
 

	
 
        # BAD KEY
 

	
 
        key = "bad"
 
        response = self.app.get(url(controller='login',
 
                                    action='password_reset_confirmation',
 
                                    key=key))
 
        self.assertEqual(response.status, '302 Found')
 
        self.assertTrue(response.location.endswith(url('reset_password')))
 

	
 
        # GOOD KEY
 

	
 
        key = User.get_by_username(username).api_key
 
        response = self.app.get(url(controller='login',
 
                                    action='password_reset_confirmation',
 
                                    key=key))
 
        self.assertEqual(response.status, '302 Found')
 
        self.assertTrue(response.location.endswith(url('login_home')))
 

	
 
        self.checkSessionFlash(response,
 
                               ('Your password reset was successful, '
 
                                'new password has been sent to your email'))
 

	
 
        response = response.follow()
 

	
 
    def _get_api_whitelist(self, values=None):
 
        config = {'api_access_controllers_whitelist': values or []}
 
        return config
 

	
 
    @parameterized.expand([
 
        ('none', None),
 
        ('empty_string', ''),
 
        ('fake_number', '123456'),
 
        ('proper_api_key', None)
 
    ])
 
    def test_access_not_whitelisted_page_via_api_key(self, test_name, api_key):
 
        whitelist = self._get_api_whitelist([])
 
        with mock.patch('kallithea.CONFIG', whitelist):
 
            self.assertEqual([],
 
                             whitelist['api_access_controllers_whitelist'])
 
            if test_name == 'proper_api_key':
 
                #use builtin if api_key is None
 
                api_key = User.get_first_admin().api_key
 

	
 
            with fixture.anon_access(False):
 
                self.app.get(url(controller='changeset',
 
                                 action='changeset_raw',
 
                                 repo_name=HG_REPO, revision='tip', api_key=api_key),
 
                             status=302)
 

	
 
    @parameterized.expand([
 
        ('none', None, 302),
 
        ('empty_string', '', 302),
 
        ('fake_number', '123456', 302),
 
        ('proper_api_key', None, 200)
 
    ])
 
    def test_access_whitelisted_page_via_api_key(self, test_name, api_key, code):
 
        whitelist = self._get_api_whitelist(['ChangesetController:changeset_raw'])
 
        with mock.patch('kallithea.CONFIG', whitelist):
 
            self.assertEqual(['ChangesetController:changeset_raw'],
 
                             whitelist['api_access_controllers_whitelist'])
 
            if test_name == 'proper_api_key':
 
                api_key = User.get_first_admin().api_key
 

	
 
            with fixture.anon_access(False):
 
                self.app.get(url(controller='changeset',
 
                                 action='changeset_raw',
 
                                 repo_name=HG_REPO, revision='tip', api_key=api_key),
 
                             status=code)
 

	
 
    def test_access_page_via_extra_api_key(self):
 
        whitelist = self._get_api_whitelist(['ChangesetController:changeset_raw'])
 
        with mock.patch('kallithea.CONFIG', whitelist):
 
            self.assertEqual(['ChangesetController:changeset_raw'],
 
                             whitelist['api_access_controllers_whitelist'])
 

	
 
            new_api_key = ApiKeyModel().create(TEST_USER_ADMIN_LOGIN, u'test')
 
            Session().commit()
 
            with fixture.anon_access(False):
 
                self.app.get(url(controller='changeset',
 
                                 action='changeset_raw',
 
                                 repo_name=HG_REPO, revision='tip', api_key=new_api_key.api_key),
 
                             status=200)
 

	
 
    def test_access_page_via_expired_api_key(self):
 
        whitelist = self._get_api_whitelist(['ChangesetController:changeset_raw'])
 
        with mock.patch('kallithea.CONFIG', whitelist):
 
            self.assertEqual(['ChangesetController:changeset_raw'],
 
                             whitelist['api_access_controllers_whitelist'])
 

	
 
            new_api_key = ApiKeyModel().create(TEST_USER_ADMIN_LOGIN, u'test')
 
            Session().commit()
 
            #patch the api key and make it expired
 
            new_api_key.expires = 0
 
            Session().add(new_api_key)
 
            Session().commit()
 
            with fixture.anon_access(False):
 
                self.app.get(url(controller='changeset',
 
                                 action='changeset_raw',
 
                                 repo_name=HG_REPO, revision='tip',
 
                                 api_key=new_api_key.api_key),
 
                             status=302)
kallithea/tests/other/manual_test_vcs_operations.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.tests.test_scm_operations
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
Test suite for making push/pull operations.
 

	
 
Run it in two terminals::
 
 paster serve test.ini
 
 KALLITHEA_WHOOSH_TEST_DISABLE=1 KALLITHEA_NO_TMP_PATH=1 nosetests kallithea/tests/other/manual_test_vcs_operations.py
 

	
 
You must have git > 1.8.1 for tests to work fine
 

	
 
This file was forked by the Kallithea project in July 2014.
 
Original author and date, and relevant copyright and licensing information is below:
 
:created_on: Dec 30, 2010
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 

	
 
"""
 

	
 
import tempfile
 
import time
 
from os.path import join as jn
 

	
 
from tempfile import _RandomNameSequence
 
from subprocess import Popen, PIPE
 

	
 
from kallithea.tests import *
 
from kallithea.model.db import User, Repository, UserIpMap, CacheInvalidation
 
from kallithea.model.meta import Session
 
from kallithea.model.repo import RepoModel
 
from kallithea.model.user import UserModel
 

	
 
DEBUG = True
 
HOST = '127.0.0.1:5000'  # test host
 

	
 

	
 
class Command(object):
 

	
 
    def __init__(self, cwd):
 
        self.cwd = cwd
 

	
 
    def execute(self, cmd, *args):
 
        """
 
        Runs command on the system with given ``args``.
 
        """
 

	
 
        command = cmd + ' ' + ' '.join(args)
 
        if DEBUG:
 
            print '*** CMD %s ***' % command
 
        p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, cwd=self.cwd)
 
        stdout, stderr = p.communicate()
 
        if DEBUG:
 
            print 'stdout:', repr(stdout)
 
            print 'stderr:', repr(stderr)
 
        return stdout, stderr
 

	
 

	
 
def _get_tmp_dir():
 
    return tempfile.mkdtemp(prefix='rc_integration_test')
 

	
 

	
 
def _construct_url(repo, dest=None, **kwargs):
 
    if dest is None:
 
        #make temp clone
 
        dest = _get_tmp_dir()
 
    params = {
 
        'user': TEST_USER_ADMIN_LOGIN,
 
        'passwd': TEST_USER_ADMIN_PASS,
 
        'host': HOST,
 
        'cloned_repo': repo,
 
        'dest': dest
 
    }
 
    params.update(**kwargs)
 
    if params['user'] and params['passwd']:
 
        _url = 'http://%(user)s:%(passwd)s@%(host)s/%(cloned_repo)s %(dest)s' % params
 
    else:
 
        _url = 'http://(host)s/%(cloned_repo)s %(dest)s' % params
 
    return _url
 

	
 

	
 
def _add_files_and_push(vcs, DEST, **kwargs):
 
    """
 
    Generate some files, add it to DEST repo and push back
 
    vcs is git or hg and defines what VCS we want to make those files for
 

	
 
    :param vcs:
 
    :param DEST:
 
    """
 
    # commit some stuff into this repo
 
    cwd = path = jn(DEST)
 
    #added_file = jn(path, '%ssetupążźć.py' % _RandomNameSequence().next())
 
    added_file = jn(path, '%ssetup.py' % _RandomNameSequence().next())
 
    Command(cwd).execute('touch %s' % added_file)
 
    Command(cwd).execute('%s add %s' % (vcs, added_file))
 

	
 
    for i in xrange(kwargs.get('files_no', 3)):
 
        cmd = """echo 'added_line%s' >> %s""" % (i, added_file)
 
        Command(cwd).execute(cmd)
 
        author_str = 'Marcin Kuźminski <me@email.com>'
 
        author_str = 'User ǝɯɐᴎ <me@email.com>'
 
        if vcs == 'hg':
 
            cmd = """hg commit -m 'commited new %s' -u '%s' %s """ % (
 
                i, author_str, added_file
 
            )
 
        elif vcs == 'git':
 
            cmd = """EMAIL="me@email.com" git commit -m 'commited new %s' --author '%s' %s """ % (
 
                i, author_str, added_file
 
            )
 
        Command(cwd).execute(cmd)
 

	
 
    # PUSH it back
 
    _REPO = None
 
    if vcs == 'hg':
 
        _REPO = HG_REPO
 
    elif vcs == 'git':
 
        _REPO = GIT_REPO
 

	
 
    kwargs['dest'] = ''
 
    clone_url = _construct_url(_REPO, **kwargs)
 
    if 'clone_url' in kwargs:
 
        clone_url = kwargs['clone_url']
 
    stdout = stderr = None
 
    if vcs == 'hg':
 
        stdout, stderr = Command(cwd).execute('hg push --verbose', clone_url)
 
    elif vcs == 'git':
 
        stdout, stderr = Command(cwd).execute('git push --verbose', clone_url + " master")
 

	
 
    return stdout, stderr
 

	
 

	
 
def set_anonymous_access(enable=True):
 
    user = User.get_by_username(User.DEFAULT_USER)
 
    user.active = enable
 
    Session().add(user)
 
    Session().commit()
 
    print '\tanonymous access is now:', enable
 
    if enable != User.get_by_username(User.DEFAULT_USER).active:
 
        raise Exception('Cannot set anonymous access')
 

	
 

	
 
#==============================================================================
 
# TESTS
 
#==============================================================================
 

	
 

	
 
def _check_proper_git_push(stdout, stderr):
 
    #WTF Git stderr is output ?!
 
    assert 'fatal' not in stderr
 
    assert 'rejected' not in stderr
 
    assert 'Pushing to' in stderr
 
    assert 'master -> master' in stderr
 

	
 

	
 
class TestVCSOperations(BaseTestCase):
 

	
 
    @classmethod
 
    def setup_class(cls):
 
        #DISABLE ANONYMOUS ACCESS
 
        set_anonymous_access(False)
 

	
 
    def setUp(self):
 
        r = Repository.get_by_repo_name(GIT_REPO)
 
        Repository.unlock(r)
 
        r.enable_locking = False
 
        Session().add(r)
 
        Session().commit()
 

	
 
        r = Repository.get_by_repo_name(HG_REPO)
 
        Repository.unlock(r)
 
        r.enable_locking = False
 
        Session().add(r)
 
        Session().commit()
 

	
 
    def test_clone_hg_repo_by_admin(self):
 
        clone_url = _construct_url(HG_REPO)
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 

	
 
        assert 'requesting all changes' in stdout
 
        assert 'adding changesets' in stdout
 
        assert 'adding manifests' in stdout
 
        assert 'adding file changes' in stdout
 

	
 
        assert stderr == ''
 

	
 
    def test_clone_git_repo_by_admin(self):
 
        clone_url = _construct_url(GIT_REPO)
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 

	
 
        assert 'Cloning into' in stdout + stderr
 
        assert stderr == '' or stdout == ''
 

	
 
    def test_clone_wrong_credentials_hg(self):
 
        clone_url = _construct_url(HG_REPO, passwd='bad!')
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 
        assert 'abort: authorization failed' in stderr
 

	
 
    def test_clone_wrong_credentials_git(self):
 
        clone_url = _construct_url(GIT_REPO, passwd='bad!')
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 
        assert 'fatal: Authentication failed' in stderr
 

	
 
    def test_clone_git_dir_as_hg(self):
 
        clone_url = _construct_url(GIT_REPO)
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 
        assert 'HTTP Error 404: Not Found' in stderr
 

	
 
    def test_clone_hg_repo_as_git(self):
 
        clone_url = _construct_url(HG_REPO)
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 
        assert 'not found' in stderr
 

	
 
    def test_clone_non_existing_path_hg(self):
 
        clone_url = _construct_url('trololo')
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 
        assert 'HTTP Error 404: Not Found' in stderr
 

	
 
    def test_clone_non_existing_path_git(self):
 
        clone_url = _construct_url('trololo')
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 
        assert 'not found' in stderr
 

	
 
    def test_push_new_file_hg(self):
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(HG_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 

	
 
        stdout, stderr = _add_files_and_push('hg', DEST)
 

	
 
        assert 'pushing to' in stdout
 
        assert 'Repository size' in stdout
 
        assert 'Last revision is now' in stdout
 

	
 
    def test_push_new_file_git(self):
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(GIT_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 

	
 
        # commit some stuff into this repo
 
        stdout, stderr = _add_files_and_push('git', DEST)
 

	
 
        print [(x.repo_full_path,x.repo_path) for x in Repository.get_all()]
 
        _check_proper_git_push(stdout, stderr)
 

	
 
    def test_push_invalidates_cache_hg(self):
 
        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
 
                                               ==HG_REPO).scalar()
 
        if not key:
 
            key = CacheInvalidation(HG_REPO, HG_REPO)
 

	
 
        key.cache_active = True
 
        Session().add(key)
 
        Session().commit()
 

	
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(HG_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 

	
 
        stdout, stderr = _add_files_and_push('hg', DEST, files_no=1)
 

	
 
        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
 
                                               ==HG_REPO).one()
 
        self.assertEqual(key.cache_active, False)
 

	
 
    def test_push_invalidates_cache_git(self):
 
        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
 
                                               ==GIT_REPO).scalar()
 
        if not key:
 
            key = CacheInvalidation(GIT_REPO, GIT_REPO)
 

	
 
        key.cache_active = True
 
        Session().add(key)
 
        Session().commit()
 

	
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(GIT_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 

	
 
        # commit some stuff into this repo
 
        stdout, stderr = _add_files_and_push('git', DEST, files_no=1)
 
        _check_proper_git_push(stdout, stderr)
 

	
 
        key = CacheInvalidation.query().filter(CacheInvalidation.cache_key
 
                                               ==GIT_REPO).one()
 
        print CacheInvalidation.get_all()
 
        self.assertEqual(key.cache_active, False)
 

	
 
    def test_push_wrong_credentials_hg(self):
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(HG_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 

	
 
        stdout, stderr = _add_files_and_push('hg', DEST, user='bad',
 
                                             passwd='name')
 

	
 
        assert 'abort: authorization failed' in stderr
 

	
 
    def test_push_wrong_credentials_git(self):
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(GIT_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 

	
 
        stdout, stderr = _add_files_and_push('git', DEST, user='bad',
 
                                             passwd='name')
 

	
 
        assert 'fatal: Authentication failed' in stderr
 

	
 
    def test_push_back_to_wrong_url_hg(self):
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(HG_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 

	
 
        stdout, stderr = _add_files_and_push('hg', DEST,
 
                                    clone_url='http://127.0.0.1:5000/tmp',)
 

	
 
        assert 'HTTP Error 404: Not Found' in stderr
 

	
 
    def test_push_back_to_wrong_url_git(self):
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(GIT_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 

	
 
        stdout, stderr = _add_files_and_push('git', DEST,
 
                                    clone_url='http://127.0.0.1:5000/tmp',)
 

	
 
        assert 'not found' in stderr
 

	
 
    def test_clone_and_create_lock_hg(self):
 
        # enable locking
 
        r = Repository.get_by_repo_name(HG_REPO)
 
        r.enable_locking = True
 
        Session().add(r)
 
        Session().commit()
 
        # clone
 
        clone_url = _construct_url(HG_REPO)
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 

	
 
        #check if lock was made
 
        r = Repository.get_by_repo_name(HG_REPO)
 
        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
 

	
 
    def test_clone_and_create_lock_git(self):
 
        # enable locking
 
        r = Repository.get_by_repo_name(GIT_REPO)
 
        r.enable_locking = True
 
        Session().add(r)
 
        Session().commit()
 
        # clone
 
        clone_url = _construct_url(GIT_REPO)
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 

	
 
        #check if lock was made
 
        r = Repository.get_by_repo_name(GIT_REPO)
 
        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
 

	
 
    def test_clone_after_repo_was_locked_hg(self):
 
        #lock repo
 
        r = Repository.get_by_repo_name(HG_REPO)
 
        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
 
        #pull fails since repo is locked
 
        clone_url = _construct_url(HG_REPO)
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 
        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
 
                % (HG_REPO, TEST_USER_ADMIN_LOGIN))
 
        assert msg in stderr
 

	
 
    def test_clone_after_repo_was_locked_git(self):
 
        #lock repo
 
        r = Repository.get_by_repo_name(GIT_REPO)
 
        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
 
        #pull fails since repo is locked
 
        clone_url = _construct_url(GIT_REPO)
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 
        msg = ("""The requested URL returned error: 423""")
 
        assert msg in stderr
 

	
 
    def test_push_on_locked_repo_by_other_user_hg(self):
 
        #clone some temp
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(HG_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 

	
 
        #lock repo
 
        r = Repository.get_by_repo_name(HG_REPO)
 
        # let this user actually push !
 
        RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
 
                                          perm='repository.write')
 
        Session().commit()
 
        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
 

	
 
        #push fails repo is locked by other user !
 
        stdout, stderr = _add_files_and_push('hg', DEST,
 
                                             user=TEST_USER_REGULAR_LOGIN,
 
                                             passwd=TEST_USER_REGULAR_PASS)
 
        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
 
                % (HG_REPO, TEST_USER_ADMIN_LOGIN))
 
        assert msg in stderr
 

	
 
    def test_push_on_locked_repo_by_other_user_git(self):
 
        #clone some temp
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(GIT_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 

	
 
        #lock repo
 
        r = Repository.get_by_repo_name(GIT_REPO)
 
        # let this user actually push !
 
        RepoModel().grant_user_permission(repo=r, user=TEST_USER_REGULAR_LOGIN,
 
                                          perm='repository.write')
 
        Session().commit()
 
        Repository.lock(r, User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id)
 

	
 
        #push fails repo is locked by other user !
 
        stdout, stderr = _add_files_and_push('git', DEST,
 
                                             user=TEST_USER_REGULAR_LOGIN,
 
                                             passwd=TEST_USER_REGULAR_PASS)
 
        err = 'Repository `%s` locked by user `%s`' % (GIT_REPO, TEST_USER_ADMIN_LOGIN)
 
        assert err in stderr
 

	
 
        #TODO: fix this somehow later on Git, Git is stupid and even if we throw
 
        #back 423 to it, it makes ANOTHER request and we fail there with 405 :/
 

	
 
        msg = ("""abort: HTTP Error 423: Repository `%s` locked by user `%s`"""
 
                % (GIT_REPO, TEST_USER_ADMIN_LOGIN))
 
        #msg = "405 Method Not Allowed"
 
        #assert msg in stderr
 

	
 
    def test_push_unlocks_repository_hg(self):
 
        # enable locking
 
        r = Repository.get_by_repo_name(HG_REPO)
 
        r.enable_locking = True
 
        Session().add(r)
 
        Session().commit()
 
        #clone some temp
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(HG_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 

	
 
        #check for lock repo after clone
 
        r = Repository.get_by_repo_name(HG_REPO)
 
        uid = User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
 
        assert r.locked[0] == uid
 

	
 
        #push is ok and repo is now unlocked
 
        stdout, stderr = _add_files_and_push('hg', DEST)
 
        assert ('remote: Released lock on repo `%s`' % HG_REPO) in stdout
 
        #we need to cleanup the Session Here !
 
        Session.remove()
 
        r = Repository.get_by_repo_name(HG_REPO)
 
        assert r.locked == [None, None]
 

	
 
    #TODO: fix me ! somehow during tests hooks don't get called on Git
 
    def test_push_unlocks_repository_git(self):
 
        # enable locking
 
        r = Repository.get_by_repo_name(GIT_REPO)
 
        r.enable_locking = True
 
        Session().add(r)
 
        Session().commit()
 
        #clone some temp
 
        DEST = _get_tmp_dir()
 
        clone_url = _construct_url(GIT_REPO, dest=DEST)
 
        stdout, stderr = Command('/tmp').execute('git clone', clone_url)
 

	
 
        #check for lock repo after clone
 
        r = Repository.get_by_repo_name(GIT_REPO)
 
        assert r.locked[0] == User.get_by_username(TEST_USER_ADMIN_LOGIN).user_id
 

	
 
        #push is ok and repo is now unlocked
 
        stdout, stderr = _add_files_and_push('git', DEST)
 
        _check_proper_git_push(stdout, stderr)
 

	
 
        #assert ('remote: Released lock on repo `%s`' % GIT_REPO) in stdout
 
        #we need to cleanup the Session Here !
 
        Session.remove()
 
        r = Repository.get_by_repo_name(GIT_REPO)
 
        assert r.locked == [None, None]
 

	
 
    def test_ip_restriction_hg(self):
 
        user_model = UserModel()
 
        try:
 
            user_model.add_extra_ip(TEST_USER_ADMIN_LOGIN, '10.10.10.10/32')
 
            Session().commit()
 
            clone_url = _construct_url(HG_REPO)
 
            stdout, stderr = Command('/tmp').execute('hg clone', clone_url)
 
            assert 'abort: HTTP Error 403: Forbidden' in stderr
kallithea/tests/other/test_libs.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.tests.test_libs
 
~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
Package for testing various lib/helper functions in kallithea
 

	
 
This file was forked by the Kallithea project in July 2014.
 
Original author and date, and relevant copyright and licensing information is below:
 
:created_on: Jun 9, 2011
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 

	
 
from __future__ import with_statement
 
import datetime
 
import hashlib
 
import mock
 
from kallithea.tests import *
 
from kallithea.lib.utils2 import AttributeDict
 
from kallithea.model.db import Repository
 

	
 
proto = 'http'
 
TEST_URLS = [
 
    ('%s://127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
     '%s://127.0.0.1' % proto),
 
    ('%s://marcink@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
    ('%s://username@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
     '%s://127.0.0.1' % proto),
 
    ('%s://marcink:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
    ('%s://username:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
     '%s://127.0.0.1' % proto),
 
    ('%s://127.0.0.1:8080' % proto, ['%s://' % proto, '127.0.0.1', '8080'],
 
     '%s://127.0.0.1:8080' % proto),
 
    ('%s://domain.org' % proto, ['%s://' % proto, 'domain.org'],
 
     '%s://domain.org' % proto),
 
    ('%s://user:pass@domain.org:8080' % proto, ['%s://' % proto, 'domain.org',
 
                                                '8080'],
 
     '%s://domain.org:8080' % proto),
 
]
 

	
 
proto = 'https'
 
TEST_URLS += [
 
    ('%s://127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
     '%s://127.0.0.1' % proto),
 
    ('%s://marcink@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
    ('%s://username@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
     '%s://127.0.0.1' % proto),
 
    ('%s://marcink:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
    ('%s://username:pass@127.0.0.1' % proto, ['%s://' % proto, '127.0.0.1'],
 
     '%s://127.0.0.1' % proto),
 
    ('%s://127.0.0.1:8080' % proto, ['%s://' % proto, '127.0.0.1', '8080'],
 
     '%s://127.0.0.1:8080' % proto),
 
    ('%s://domain.org' % proto, ['%s://' % proto, 'domain.org'],
 
     '%s://domain.org' % proto),
 
    ('%s://user:pass@domain.org:8080' % proto, ['%s://' % proto, 'domain.org',
 
                                                '8080'],
 
     '%s://domain.org:8080' % proto),
 
]
 

	
 

	
 
class TestLibs(BaseTestCase):
 

	
 
    @parameterized.expand(TEST_URLS)
 
    def test_uri_filter(self, test_url, expected, expected_creds):
 
        from kallithea.lib.utils2 import uri_filter
 
        self.assertEqual(uri_filter(test_url), expected)
 

	
 
    @parameterized.expand(TEST_URLS)
 
    def test_credentials_filter(self, test_url, expected, expected_creds):
 
        from kallithea.lib.utils2 import credentials_filter
 
        self.assertEqual(credentials_filter(test_url), expected_creds)
 

	
 
    @parameterized.expand([('t', True),
 
                           ('true', True),
 
                           ('y', True),
 
                           ('yes', True),
 
                           ('on', True),
 
                           ('1', True),
 
                           ('Y', True),
 
                           ('yeS', True),
 
                           ('Y', True),
 
                           ('TRUE', True),
 
                           ('T', True),
 
                           ('False', False),
 
                           ('F', False),
 
                           ('FALSE', False),
 
                           ('0', False),
 
                           ('-1', False),
 
                           ('', False)
 
    ])
 
    def test_str2bool(self, str_bool, expected):
 
        from kallithea.lib.utils2 import str2bool
 
        self.assertEqual(str2bool(str_bool), expected)
 

	
 
    def test_mention_extractor(self):
 
        from kallithea.lib.utils2 import extract_mentioned_users
 
        sample = (
 
            "@first hi there @marcink here's my email marcin@email.com "
 
            "@first hi there @world here's my email username@email.com "
 
            "@lukaszb check @one_more22 it pls @ ttwelve @D[] @one@two@three "
 
            "@MARCIN    @maRCiN @2one_more22 @john please see this http://org.pl "
 
            "@UPPER    @cAmEL @2one_more22 @john please see this http://org.pl "
 
            "@marian.user just do it @marco-polo and next extract @marco_polo "
 
            "user.dot  hej ! not-needed maril@domain.org"
 
        )
 

	
 
        s = sorted([
 
            '2one_more22', 'first', 'marcink', 'lukaszb', 'one', 'one_more22', 'MARCIN', 'maRCiN', 'john',
 
            'marian.user', 'marco-polo', 'marco_polo'], key=lambda k: k.lower())
 
            '2one_more22', 'first', 'lukaszb', 'one', 'one_more22', 'UPPER', 'cAmEL', 'john',
 
            'marian.user', 'marco-polo', 'marco_polo', 'world'], key=lambda k: k.lower())
 
        self.assertEqual(s, extract_mentioned_users(sample))
 

	
 
    @parameterized.expand([
 
        (dict(), u'just now'),
 
        (dict(seconds= -1), u'1 second ago'),
 
        (dict(seconds= -60 * 2), u'2 minutes ago'),
 
        (dict(hours= -1), u'1 hour ago'),
 
        (dict(hours= -24), u'1 day ago'),
 
        (dict(hours= -24 * 5), u'5 days ago'),
 
        (dict(months= -1), u'1 month ago'),
 
        (dict(months= -1, days= -2), u'1 month and 2 days ago'),
 
        (dict(months= -1, days= -20), u'1 month and 19 days ago'),
 
        (dict(years= -1, months= -1), u'1 year and 1 month ago'),
 
        (dict(years= -1, months= -10), u'1 year and 10 months ago'),
 
        (dict(years= -2, months= -4), u'2 years and 4 months ago'),
 
        (dict(years= -2, months= -11), u'2 years and 11 months ago'),
 
        (dict(years= -3, months= -2), u'3 years and 2 months ago'),
 
    ])
 
    def test_age(self, age_args, expected):
 
        from kallithea.lib.utils2 import age
 
        from dateutil import relativedelta
 
        n = datetime.datetime(year=2012, month=5, day=17)
 
        delt = lambda *args, **kwargs: relativedelta.relativedelta(*args, **kwargs)
 
        self.assertEqual(age(n + delt(**age_args), now=n), expected)
 

	
 
    @parameterized.expand([
 
        (dict(), u'just now'),
 
        (dict(seconds= -1), u'1 second ago'),
 
        (dict(seconds= -60 * 2), u'2 minutes ago'),
 
        (dict(hours= -1), u'1 hour ago'),
 
        (dict(hours= -24), u'1 day ago'),
 
        (dict(hours= -24 * 5), u'5 days ago'),
 
        (dict(months= -1), u'1 month ago'),
 
        (dict(months= -1, days= -2), u'1 month ago'),
 
        (dict(months= -1, days= -20), u'1 month ago'),
 
        (dict(years= -1, months= -1), u'13 months ago'),
 
        (dict(years= -1, months= -10), u'22 months ago'),
 
        (dict(years= -2, months= -4), u'2 years ago'),
 
        (dict(years= -2, months= -11), u'3 years ago'),
 
        (dict(years= -3, months= -2), u'3 years ago'),
 
        (dict(years= -4, months= -8), u'5 years ago'),
 
    ])
 
    def test_age_short(self, age_args, expected):
 
        from kallithea.lib.utils2 import age
 
        from dateutil import relativedelta
 
        n = datetime.datetime(year=2012, month=5, day=17)
 
        delt = lambda *args, **kwargs: relativedelta.relativedelta(*args, **kwargs)
 
        self.assertEqual(age(n + delt(**age_args), show_short_version=True, now=n), expected)
 

	
 
    @parameterized.expand([
 
        (dict(), u'just now'),
 
        (dict(seconds=1), u'in 1 second'),
 
        (dict(seconds=60 * 2), u'in 2 minutes'),
 
        (dict(hours=1), u'in 1 hour'),
 
        (dict(hours=24), u'in 1 day'),
 
        (dict(hours=24 * 5), u'in 5 days'),
 
        (dict(months=1), u'in 1 month'),
 
        (dict(months=1, days=1), u'in 1 month and 1 day'),
 
        (dict(years=1, months=1), u'in 1 year and 1 month')
 
    ])
 
    def test_age_in_future(self, age_args, expected):
 
        from kallithea.lib.utils2 import age
 
        from dateutil import relativedelta
 
        n = datetime.datetime(year=2012, month=5, day=17)
 
        delt = lambda *args, **kwargs: relativedelta.relativedelta(*args, **kwargs)
 
        self.assertEqual(age(n + delt(**age_args), now=n), expected)
 

	
 
    def test_tag_exctrator(self):
 
        sample = (
 
            "hello pta[tag] gog [[]] [[] sda ero[or]d [me =>>< sa]"
 
            "[requires] [stale] [see<>=>] [see => http://url.com]"
 
            "[requires => url] [lang => python] [just a tag]"
 
            "[,d] [ => ULR ] [obsolete] [desc]]"
 
        )
 
        from kallithea.lib.helpers import desc_stylize
 
        res = desc_stylize(sample)
 
        self.assertTrue('<div class="metatag" tag="tag">tag</div>' in res)
 
        self.assertTrue('<div class="metatag" tag="obsolete">obsolete</div>' in res)
 
        self.assertTrue('<div class="metatag" tag="stale">stale</div>' in res)
 
        self.assertTrue('<div class="metatag" tag="lang">python</div>' in res)
 
        self.assertTrue('<div class="metatag" tag="requires">requires =&gt; <a href="/url">url</a></div>' in res)
 
        self.assertTrue('<div class="metatag" tag="tag">tag</div>' in res)
 

	
 
    def test_alternative_gravatar(self):
 
        from kallithea.lib.helpers import gravatar_url
 
        _md5 = lambda s: hashlib.md5(s).hexdigest()
 

	
 
        #mock pylons.url
 
        class fake_url(object):
 
            @classmethod
 
            def current(cls, *args, **kwargs):
 
                return 'https://server.com'
 

	
 
        #mock pylons.tmpl_context
 
        def fake_tmpl_context(_url):
 
            _c = AttributeDict()
 
            _c.visual = AttributeDict()
 
            _c.visual.use_gravatar = True
 
            _c.visual.gravatar_url = _url
 

	
 
            return _c
 

	
 

	
 
        with mock.patch('pylons.url', fake_url):
 
            fake = fake_tmpl_context(_url='http://test.com/{email}')
 
            with mock.patch('pylons.tmpl_context', fake):
 
                    from pylons import url
 
                    assert url.current() == 'https://server.com'
 
                    grav = gravatar_url(email_address='test@foo.com', size=24)
 
                    assert grav == 'http://test.com/test@foo.com'
 

	
 
            fake = fake_tmpl_context(_url='http://test.com/{email}')
 
            with mock.patch('pylons.tmpl_context', fake):
 
                grav = gravatar_url(email_address='test@foo.com', size=24)
 
                assert grav == 'http://test.com/test@foo.com'
 

	
 
            fake = fake_tmpl_context(_url='http://test.com/{md5email}')
 
            with mock.patch('pylons.tmpl_context', fake):
 
                em = 'test@foo.com'
 
                grav = gravatar_url(email_address=em, size=24)
 
                assert grav == 'http://test.com/%s' % (_md5(em))
 

	
 
            fake = fake_tmpl_context(_url='http://test.com/{md5email}/{size}')
 
            with mock.patch('pylons.tmpl_context', fake):
 
                em = 'test@foo.com'
 
                grav = gravatar_url(email_address=em, size=24)
 
                assert grav == 'http://test.com/%s/%s' % (_md5(em), 24)
 

	
 
            fake = fake_tmpl_context(_url='{scheme}://{netloc}/{md5email}/{size}')
 
            with mock.patch('pylons.tmpl_context', fake):
 
                em = 'test@foo.com'
 
                grav = gravatar_url(email_address=em, size=24)
 
                assert grav == 'https://server.com/%s/%s' % (_md5(em), 24)
 

	
 
    @parameterized.expand([
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '', 'http://vps1:8000/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '/rc', 'http://vps1:8000/rc/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/rc', 'http://user@vps1:8000/rc/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '/rc', 'http://marcink@vps1:8000/rc/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/rc/', 'http://user@vps1:8000/rc/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '/rc/', 'http://marcink@vps1:8000/rc/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'username'}, '', 'http://username@vps1:8000/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '/prefix', 'http://vps1:8000/prefix/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/prefix', 'http://user@vps1:8000/prefix/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'username'}, '/prefix', 'http://username@vps1:8000/prefix/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/prefix/', 'http://user@vps1:8000/prefix/group/repo1'),
 
        (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'username'}, '/prefix/', 'http://username@vps1:8000/prefix/group/repo1'),
 
        ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {}, '', 'http://vps1:8000/_23'),
 
        ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/_23'),
 
        ('http://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/_23'),
 
        ('http://{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://vps1:8000/_23'),
 
        ('https://{user}@proxy1.server.com/{repo}', 'group/repo1', {'user': 'marcink'}, '', 'https://marcink@proxy1.server.com/group/repo1'),
 
        ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'username'}, '', 'http://username@vps1:8000/_23'),
 
        ('http://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'username'}, '', 'http://username@vps1:8000/_23'),
 
        ('http://{netloc}/_{repoid}', 'group/repo1', {'user': 'username'}, '', 'http://vps1:8000/_23'),
 
        ('https://{user}@proxy1.server.com/{repo}', 'group/repo1', {'user': 'username'}, '', 'https://username@proxy1.server.com/group/repo1'),
 
        ('https://{user}@proxy1.server.com/{repo}', 'group/repo1', {}, '', 'https://proxy1.server.com/group/repo1'),
 
        ('https://proxy1.server.com/{user}/{repo}', 'group/repo1', {'user': 'marcink'}, '', 'https://proxy1.server.com/marcink/group/repo1'),
 
        ('https://proxy1.server.com/{user}/{repo}', 'group/repo1', {'user': 'username'}, '', 'https://proxy1.server.com/username/group/repo1'),
 
    ])
 
    def test_clone_url_generator(self, tmpl, repo_name, overrides, prefix, expected):
 
        from kallithea.lib.utils2 import get_clone_url
 
        clone_url = get_clone_url(uri_tmpl=tmpl, qualifed_home_url='http://vps1:8000'+prefix,
 
                                  repo_name=repo_name, repo_id=23, **overrides)
 
        self.assertEqual(clone_url, expected)
 

	
 
    def _quick_url(self, text, tmpl="""<a class="revision-link" href="%s">%s</a>""", url_=None):
 
        """
 
        Changes `some text url[foo]` => `some text <a href="/">foo</a>
 

	
 
        :param text:
 
        """
 
        import re
 
        # quickly change expected url[] into a link
 
        URL_PAT = re.compile(r'(?:url\[)(.+?)(?:\])')
 

	
 
        def url_func(match_obj):
 
            _url = match_obj.groups()[0]
 
            return tmpl % (url_ or '/some-url', _url)
 
        return URL_PAT.sub(url_func, text)
 

	
 
    @parameterized.expand([
 
      ("",
 
       ""),
 
      ("git-svn-id: https://svn.apache.org/repos/asf/libcloud/trunk@1441655 13f79535-47bb-0310-9956-ffa450edef68",
 
       "git-svn-id: https://svn.apache.org/repos/asf/libcloud/trunk@1441655 13f79535-47bb-0310-9956-ffa450edef68"),
 
      ("from rev 000000000000",
 
       "from rev url[000000000000]"),
 
      ("from rev 000000000000123123 also rev 000000000000",
 
       "from rev url[000000000000123123] also rev url[000000000000]"),
 
      ("this should-000 00",
 
       "this should-000 00"),
 
      ("longtextffffffffff rev 123123123123",
 
       "longtextffffffffff rev url[123123123123]"),
 
      ("rev ffffffffffffffffffffffffffffffffffffffffffffffffff",
 
       "rev ffffffffffffffffffffffffffffffffffffffffffffffffff"),
 
      ("ffffffffffff some text traalaa",
 
       "url[ffffffffffff] some text traalaa"),
 
       ("""Multi line
 
       123123123123
 
       some text 123123123123
 
       sometimes !
 
       """,
 
       """Multi line
 
       url[123123123123]
 
       some text url[123123123123]
 
       sometimes !
 
       """)
 
    ])
 
    def test_urlify_changesets(self, sample, expected):
 
        def fake_url(self, *args, **kwargs):
 
            return '/some-url'
 

	
 
        expected = self._quick_url(expected)
 

	
 
        with mock.patch('pylons.url', fake_url):
 
            from kallithea.lib.helpers import urlify_changesets
 
            self.assertEqual(urlify_changesets(sample, 'repo_name'), expected)
 

	
 
    @parameterized.expand([
 
      ("",
 
       "",
 
       ""),
 
      ("https://svn.apache.org/repos",
 
       "url[https://svn.apache.org/repos]",
 
       "https://svn.apache.org/repos"),
 
      ("http://svn.apache.org/repos",
 
       "url[http://svn.apache.org/repos]",
 
       "http://svn.apache.org/repos"),
 
      ("from rev a also rev http://google.com",
 
       "from rev a also rev url[http://google.com]",
 
       "http://google.com"),
 
       ("""Multi line
 
       https://foo.bar.com
 
       some text lalala""",
 
       """Multi line
 
       url[https://foo.bar.com]
 
       some text lalala""",
 
       "https://foo.bar.com")
 
    ])
 
    def test_urlify_test(self, sample, expected, url_):
 
        from kallithea.lib.helpers import urlify_text
 
        expected = self._quick_url(expected,
 
                                   tmpl="""<a href="%s">%s</a>""", url_=url_)
 
        self.assertEqual(urlify_text(sample), expected)
 

	
 
    @parameterized.expand([
 
      ("", None),
 
      ("/_2", '2'),
 
      ("_2", '2'),
 
      ("/_2/", '2'),
 
      ("_2/", '2'),
 

	
 
      ("/_21", '21'),
 
      ("_21", '21'),
 
      ("/_21/", '21'),
 
      ("_21/", '21'),
 

	
 
      ("/_21/foobar", '21'),
 
      ("_21/121", '21'),
 
      ("/_21/_12", '21'),
 
      ("_21/rc/foo", '21'),
 
      ("_21/prefix/foo", '21'),
 
    ])
 
    def test_get_repo_by_id(self, test, expected):
 
        from kallithea.lib.utils import _extract_id_from_repo_name
 
        _test = _extract_id_from_repo_name(test)
 
        self.assertEqual(_test, expected, msg='url:%s, got:`%s` expected: `%s`'
 
                                              % (test, _test, expected))
kallithea/tests/scripts/create_rc.sh
Show inline comments
 
#!/bin/sh
 
psql -U postgres -h localhost -c 'drop database if exists kallithea;'
 
psql -U postgres -h localhost -c 'create database kallithea;'
 
paster setup-db rc.ini --force-yes --user=username --password=qweqwe --email=username@example.com --repos=/home/username/repos --no-public-access
 
paster setup-db server.ini --force-yes --user=username --password=qweqwe --email=username@example.com --repos=/home/username/repos --no-public-access
 
API_KEY=`psql -R " " -A -U postgres -h localhost -c "select api_key from users where admin=TRUE" -d kallithea | awk '{print $2}'`
 
echo "run those after running server"
 
paster serve rc.ini --pid-file=rc.pid --daemon
 
paster serve server.ini --pid-file=server.pid --daemon
 
sleep 3
 
kallithea-api --apikey=$API_KEY --apihost=http://127.0.0.1:5001 create_user username:demo1 password:qweqwe email:demo1@example.com
 
kallithea-api --apikey=$API_KEY --apihost=http://127.0.0.1:5001 create_user username:demo2 password:qweqwe email:demo2@example.com
 
kallithea-api --apikey=$API_KEY --apihost=http://127.0.0.1:5001 create_user username:demo3 password:qweqwe email:demo3@example.com
 
kallithea-api --apikey=$API_KEY --apihost=http://127.0.0.1:5001 create_user_group group_name:demo12
 
kallithea-api --apikey=$API_KEY --apihost=http://127.0.0.1:5001 add_user_to_user_group usergroupid:demo12 userid:demo1
 
kallithea-api --apikey=$API_KEY --apihost=http://127.0.0.1:5001 add_user_to_user_group usergroupid:demo12 userid:demo2
 
echo "killing server"
 
kill `cat rc.pid`
 
rm rc.pid
 
kill `cat server.pid`
 
rm server.pid
kallithea/tests/scripts/test_concurency.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.tests.test_hg_operations
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
Test suite for making push/pull operations
 

	
 
This file was forked by the Kallithea project in July 2014.
 
Original author and date, and relevant copyright and licensing information is below:
 
:created_on: Dec 30, 2010
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 

	
 
"""
 

	
 
import os
 
import sys
 
import shutil
 
import logging
 
from os.path import join as jn
 
from os.path import dirname as dn
 

	
 
from tempfile import _RandomNameSequence
 
from subprocess import Popen, PIPE
 

	
 
from paste.deploy import appconfig
 
from sqlalchemy import engine_from_config
 

	
 
from kallithea.lib.utils import add_cache
 
from kallithea.model import init_model
 
from kallithea.model import meta
 
from kallithea.model.db import User, Repository
 
from kallithea.lib.auth import get_crypt_password
 

	
 
from kallithea.tests import TESTS_TMP_PATH, HG_REPO
 
from kallithea.config.environment import load_environment
 

	
 
rel_path = dn(dn(dn(dn(os.path.abspath(__file__)))))
 
conf = appconfig('config:rc.ini', relative_to=rel_path)
 
conf = appconfig('config:development.ini', relative_to=rel_path)
 
load_environment(conf.global_conf, conf.local_conf)
 

	
 
add_cache(conf)
 

	
 
USER = 'test_admin'
 
PASS = 'test12'
 
HOST = 'rc.local'
 
HOST = 'server.local'
 
METHOD = 'pull'
 
DEBUG = True
 
log = logging.getLogger(__name__)
 

	
 

	
 
class Command(object):
 

	
 
    def __init__(self, cwd):
 
        self.cwd = cwd
 

	
 
    def execute(self, cmd, *args):
 
        """Runs command on the system with given ``args``.
 
        """
 

	
 
        command = cmd + ' ' + ' '.join(args)
 
        log.debug('Executing %s' % command)
 
        if DEBUG:
 
            print command
 
        p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, cwd=self.cwd)
 
        stdout, stderr = p.communicate()
 
        if DEBUG:
 
            print stdout, stderr
 
        return stdout, stderr
 

	
 

	
 
def get_session():
 
    engine = engine_from_config(conf, 'sqlalchemy.db1.')
 
    init_model(engine)
 
    sa = meta.Session
 
    return sa
 

	
 

	
 
def create_test_user(force=True):
 
    print 'creating test user'
 
    sa = get_session()
 

	
 
    user = sa.query(User).filter(User.username == USER).scalar()
 

	
 
    if force and user is not None:
 
        print 'removing current user'
 
        for repo in sa.query(Repository).filter(Repository.user == user).all():
 
            sa.delete(repo)
 
        sa.delete(user)
 
        sa.commit()
 

	
 
    if user is None or force:
 
        print 'creating new one'
 
        new_usr = User()
 
        new_usr.username = USER
 
        new_usr.password = get_crypt_password(PASS)
 
        new_usr.email = 'mail@mail.com'
 
        new_usr.name = 'test'
 
        new_usr.lastname = 'lasttestname'
 
        new_usr.active = True
 
        new_usr.admin = True
 
        sa.add(new_usr)
 
        sa.commit()
 

	
 
    print 'done'
 

	
 

	
 
def create_test_repo(force=True):
 
    print 'creating test repo'
 
    from kallithea.model.repo import RepoModel
 
    sa = get_session()
 

	
 
    user = sa.query(User).filter(User.username == USER).scalar()
 
    if user is None:
 
        raise Exception('user not found')
 

	
 
    repo = sa.query(Repository).filter(Repository.repo_name == HG_REPO).scalar()
 

	
 
    if repo is None:
 
        print 'repo not found creating'
 

	
 
        form_data = {'repo_name': HG_REPO,
 
                     'repo_type': 'hg',
 
                     'private':False,
 
                     'clone_uri': '' }
 
        rm = RepoModel(sa)
 
        rm.base_path = '/home/hg'
 
        rm.create(form_data, user)
 

	
 
    print 'done'
 

	
 

	
 
def set_anonymous_access(enable=True):
 
    sa = get_session()
 
    user = sa.query(User).filter(User.username == 'default').one()
 
    user.active = enable
 
    sa.add(user)
 
    sa.commit()
 

	
 

	
 
def get_anonymous_access():
 
    sa = get_session()
 
    return sa.query(User).filter(User.username == 'default').one().active
 

	
 

	
 
#==============================================================================
 
# TESTS
 
#==============================================================================
 
def test_clone_with_credentials(no_errors=False, repo=HG_REPO, method=METHOD,
 
                                seq=None, backend='hg'):
 
    cwd = path = jn(TESTS_TMP_PATH, repo)
 

	
 
    if seq is None:
 
        seq = _RandomNameSequence().next()
 

	
 
    try:
 
        shutil.rmtree(path, ignore_errors=True)
 
        os.makedirs(path)
 
        #print 'made dirs %s' % jn(path)
 
    except OSError:
 
        raise
 

	
 
    clone_url = 'http://%(user)s:%(pass)s@%(host)s/%(cloned_repo)s' % \
 
                  {'user': USER,
 
                   'pass': PASS,
 
                   'host': HOST,
 
                   'cloned_repo': repo, }
 

	
 
    dest = path + seq
 
    if method == 'pull':
 
        stdout, stderr = Command(cwd).execute(backend, method, '--cwd', dest, clone_url)
 
    else:
 
        stdout, stderr = Command(cwd).execute(backend, method, clone_url, dest)
 
        print stdout,'sdasdsadsa'
 
        if not no_errors:
 
            if backend == 'hg':
 
                assert """adding file changes""" in stdout, 'no messages about cloning'
 
                assert """abort""" not in stderr , 'got error from clone'
 
            elif backend == 'git':
 
                assert """Cloning into""" in stdout, 'no messages about cloning'
 

	
 
if __name__ == '__main__':
 
    try:
 
        create_test_user(force=False)
 
        seq = None
 
        import time
 

	
 
        try:
 
            METHOD = sys.argv[3]
 
        except IndexError:
 
            pass
 

	
 
        try:
 
            backend = sys.argv[4]
 
        except IndexError:
 
            backend = 'hg'
 

	
 
        if METHOD == 'pull':
 
            seq = _RandomNameSequence().next()
 
            test_clone_with_credentials(repo=sys.argv[1], method='clone',
 
                                        seq=seq, backend=backend)
 
        s = time.time()
 
        for i in range(1, int(sys.argv[2]) + 1):
 
            print 'take', i
 
            test_clone_with_credentials(repo=sys.argv[1], method=METHOD,
 
                                        seq=seq, backend=backend)
 
        print 'time taken %.3f' % (time.time() - s)
 
    except Exception, e:
 
        sys.exit('stop on %s' % e)
kallithea/tests/scripts/test_crawler.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.tests.test_crawer
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
Test for crawling a project for memory usage
 
This should be runned just as regular script together
 
with a watch script that will show memory usage.
 

	
 
watch -n1 ./kallithea/tests/mem_watch
 

	
 
This file was forked by the Kallithea project in July 2014.
 
Original author and date, and relevant copyright and licensing information is below:
 
:created_on: Apr 21, 2010
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 

	
 

	
 
import cookielib
 
import urllib
 
import urllib2
 
import time
 
import os
 
import sys
 
from os.path import join as jn
 
from os.path import dirname as dn
 

	
 
__here__ = os.path.abspath(__file__)
 
__root__ = dn(dn(dn(__here__)))
 
sys.path.append(__root__)
 

	
 
from kallithea.lib import vcs
 
from kallithea.lib.compat import OrderedSet
 
from kallithea.lib.vcs.exceptions import RepositoryError
 

	
 
PASES = 3
 
HOST = 'http://127.0.0.1'
 
PORT = 5000
 
BASE_URI = '%s:%s/' % (HOST, PORT)
 

	
 
if len(sys.argv) == 2:
 
    BASE_URI = sys.argv[1]
 

	
 
if not BASE_URI.endswith('/'):
 
    BASE_URI += '/'
 

	
 
print 'Crawling @ %s' % BASE_URI
 
BASE_URI += '%s'
 
PROJECT_PATH = jn('/', 'home', 'marcink', 'repos')
 
PROJECT_PATH = jn('/', 'home', 'username', 'repos')
 
PROJECTS = [
 
    #'linux-magx-pbranch',
 
    'CPython',
 
    'kallithea',
 
]
 

	
 

	
 
cj = cookielib.FileCookieJar('/tmp/rc_test_cookie.txt')
 
o = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
 
o.addheaders = [
 
    ('User-agent', 'kallithea-crawler'),
 
    ('Accept-Language', 'en - us, en;q = 0.5')
 
]
 

	
 
urllib2.install_opener(o)
 

	
 

	
 
def _get_repo(proj):
 
    if isinstance(proj, basestring):
 
        repo = vcs.get_repo(jn(PROJECT_PATH, proj))
 
        proj = proj
 
    else:
 
        repo = proj
 
        proj = repo.name
 

	
 
    return repo, proj
 

	
 

	
 
def test_changelog_walk(proj, pages=100):
 
    repo, proj = _get_repo(proj)
 

	
 
    total_time = 0
 
    for i in range(1, pages):
 

	
 
        page = '/'.join((proj, 'changelog',))
 

	
 
        full_uri = (BASE_URI % page) + '?' + urllib.urlencode({'page': i})
 
        s = time.time()
 
        f = o.open(full_uri)
 

	
 
        assert f.url == full_uri, 'URL:%s does not match %s' % (f.url, full_uri)
 

	
 
        size = len(f.read())
 
        e = time.time() - s
 
        total_time += e
 
        print 'visited %s size:%s req:%s ms' % (full_uri, size, e)
 

	
 
    print 'total_time', total_time
 
    print 'average on req', total_time / float(pages)
 

	
 

	
 
def test_changeset_walk(proj, limit=None):
 
    repo, proj = _get_repo(proj)
 

	
 
    print 'processing', jn(PROJECT_PATH, proj)
 
    total_time = 0
 

	
 
    cnt = 0
 
    for i in repo:
 
        cnt += 1
 
        raw_cs = '/'.join((proj, 'changeset', i.raw_id))
 
        if limit and limit == cnt:
 
            break
 

	
 
        full_uri = (BASE_URI % raw_cs)
 
        print '%s visiting %s\%s' % (cnt, full_uri, i)
 
        s = time.time()
 
        f = o.open(full_uri)
 
        size = len(f.read())
 
        e = time.time() - s
 
        total_time += e
 
        print '%s visited %s\%s size:%s req:%s ms' % (cnt, full_uri, i, size, e)
 

	
 
    print 'total_time', total_time
 
    print 'average on req', total_time / float(cnt)
 

	
 

	
 
def test_files_walk(proj, limit=100):
 
    repo, proj = _get_repo(proj)
 

	
 
    print 'processing', jn(PROJECT_PATH, proj)
 
    total_time = 0
 

	
 
    paths_ = OrderedSet([''])
 
    try:
 
        tip = repo.get_changeset('tip')
 
        for topnode, dirs, files in tip.walk('/'):
 

	
 
            for dir in dirs:
 
                paths_.add(dir.path)
 
                for f in dir:
 
                    paths_.add(f.path)
 

	
 
            for f in files:
 
                paths_.add(f.path)
 

	
 
    except RepositoryError, e:
 
        pass
 

	
 
    cnt = 0
 
    for f in paths_:
 
        cnt += 1
 
        if limit and limit == cnt:
 
            break
 

	
 
        file_path = '/'.join((proj, 'files', 'tip', f))
 
        full_uri = (BASE_URI % file_path)
 
        print '%s visiting %s' % (cnt, full_uri)
 
        s = time.time()
 
        f = o.open(full_uri)
 
        size = len(f.read())
 
        e = time.time() - s
 
        total_time += e
 
        print '%s visited OK size:%s req:%s ms' % (cnt, size, e)
 

	
 
    print 'total_time', total_time
 
    print 'average on req', total_time / float(cnt)
 

	
 
if __name__ == '__main__':
 
    for path in PROJECTS:
 
        repo = vcs.get_repo(jn(PROJECT_PATH, path))
 
        for i in range(PASES):
 
            print 'PASS %s/%s' % (i, PASES)
 
            test_changelog_walk(repo, pages=80)
 
            test_changeset_walk(repo, limit=100)
 
            test_files_walk(repo, limit=100)
kallithea/tests/vcs/test_utils.py
Show inline comments
 
from __future__ import with_statement
 

	
 
import os
 
import mock
 
import time
 
import shutil
 
import tempfile
 
import datetime
 
from kallithea.lib.vcs.utils.compat import unittest
 
from kallithea.lib.vcs.utils.paths import get_dirs_for_path
 
from kallithea.lib.vcs.utils.helpers import get_dict_for_attrs
 
from kallithea.lib.vcs.utils.helpers import get_scm
 
from kallithea.lib.vcs.utils.helpers import get_scms_for_path
 
from kallithea.lib.vcs.utils.helpers import get_total_seconds
 
from kallithea.lib.vcs.utils.helpers import parse_changesets
 
from kallithea.lib.vcs.utils.helpers import parse_datetime
 
from kallithea.lib.vcs.utils import author_email, author_name
 
from kallithea.lib.vcs.utils.paths import get_user_home
 
from kallithea.lib.vcs.exceptions import VCSError
 

	
 
from kallithea.tests.vcs.conf import TEST_HG_REPO, TEST_GIT_REPO, TEST_TMP_PATH
 

	
 

	
 
class PathsTest(unittest.TestCase):
 

	
 
    def _test_get_dirs_for_path(self, path, expected):
 
        """
 
        Tests if get_dirs_for_path returns same as expected.
 
        """
 
        expected = sorted(expected)
 
        result = sorted(get_dirs_for_path(path))
 
        self.assertEqual(result, expected,
 
            msg="%s != %s which was expected result for path %s"
 
            % (result, expected, path))
 

	
 
    def test_get_dirs_for_path(self):
 
        path = 'foo/bar/baz/file'
 
        paths_and_results = (
 
            ('foo/bar/baz/file', ['foo', 'foo/bar', 'foo/bar/baz']),
 
            ('foo/bar/', ['foo', 'foo/bar']),
 
            ('foo/bar', ['foo']),
 
        )
 
        for path, expected in paths_and_results:
 
            self._test_get_dirs_for_path(path, expected)
 

	
 

	
 
    def test_get_scm(self):
 
        self.assertEqual(('hg', TEST_HG_REPO), get_scm(TEST_HG_REPO))
 
        self.assertEqual(('git', TEST_GIT_REPO), get_scm(TEST_GIT_REPO))
 

	
 
    def test_get_two_scms_for_path(self):
 
        multialias_repo_path = os.path.join(TEST_TMP_PATH, 'hg-git-repo-2')
 
        if os.path.isdir(multialias_repo_path):
 
            shutil.rmtree(multialias_repo_path)
 

	
 
        os.mkdir(multialias_repo_path)
 

	
 
        self.assertRaises(VCSError, get_scm, multialias_repo_path)
 

	
 
    def test_get_scm_error_path(self):
 
        self.assertRaises(VCSError, get_scm, 'err')
 

	
 
    def test_get_scms_for_path(self):
 
        dirpath = tempfile.gettempdir()
 
        new = os.path.join(dirpath, 'vcs-scms-for-path-%s' % time.time())
 
        os.mkdir(new)
 
        self.assertEqual(get_scms_for_path(new), [])
 

	
 
        os.mkdir(os.path.join(new, '.tux'))
 
        self.assertEqual(get_scms_for_path(new), [])
 

	
 
        os.mkdir(os.path.join(new, '.git'))
 
        self.assertEqual(set(get_scms_for_path(new)), set(['git']))
 

	
 
        os.mkdir(os.path.join(new, '.hg'))
 
        self.assertEqual(set(get_scms_for_path(new)), set(['git', 'hg']))
 

	
 

	
 
class TestParseChangesets(unittest.TestCase):
 

	
 
    def test_main_is_returned_correctly(self):
 
        self.assertEqual(parse_changesets('123456'), {
 
            'start': None,
 
            'main': '123456',
 
            'end': None,
 
        })
 

	
 
    def test_start_is_returned_correctly(self):
 
        self.assertEqual(parse_changesets('aaabbb..'), {
 
            'start': 'aaabbb',
 
            'main': None,
 
            'end': None,
 
        })
 

	
 
    def test_end_is_returned_correctly(self):
 
        self.assertEqual(parse_changesets('..cccddd'), {
 
            'start': None,
 
            'main': None,
 
            'end': 'cccddd',
 
        })
 

	
 
    def test_that_two_or_three_dots_are_allowed(self):
 
        text1 = 'a..b'
 
        text2 = 'a...b'
 
        self.assertEqual(parse_changesets(text1), parse_changesets(text2))
 

	
 
    def test_that_input_is_stripped_first(self):
 
        text1 = 'a..bb'
 
        text2 = '  a..bb\t\n\t '
 
        self.assertEqual(parse_changesets(text1), parse_changesets(text2))
 

	
 
    def test_that_exception_is_raised(self):
 
        text = '123456.789012' # single dot is not recognized
 
        with self.assertRaises(ValueError):
 
            parse_changesets(text)
 

	
 
    def test_non_alphanumeric_raises_exception(self):
 
        with self.assertRaises(ValueError):
 
            parse_changesets('aaa@bbb')
 

	
 

	
 
class TestParseDatetime(unittest.TestCase):
 

	
 
    def test_datetime_text(self):
 
        self.assertEqual(parse_datetime('2010-04-07 21:29:41'),
 
            datetime.datetime(2010, 4, 7, 21, 29, 41))
 

	
 
    def test_no_seconds(self):
 
        self.assertEqual(parse_datetime('2010-04-07 21:29'),
 
            datetime.datetime(2010, 4, 7, 21, 29))
 

	
 
    def test_date_only(self):
 
        self.assertEqual(parse_datetime('2010-04-07'),
 
            datetime.datetime(2010, 4, 7))
 

	
 
    def test_another_format(self):
 
        self.assertEqual(parse_datetime('04/07/10 21:29:41'),
 
            datetime.datetime(2010, 4, 7, 21, 29, 41))
 

	
 
    def test_now(self):
 
        self.assertTrue(parse_datetime('now') - datetime.datetime.now() <
 
            datetime.timedelta(seconds=1))
 

	
 
    def test_today(self):
 
        today = datetime.date.today()
 
        self.assertEqual(parse_datetime('today'),
 
            datetime.datetime(*today.timetuple()[:3]))
 

	
 
    def test_yesterday(self):
 
        yesterday = datetime.date.today() - datetime.timedelta(days=1)
 
        self.assertEqual(parse_datetime('yesterday'),
 
            datetime.datetime(*yesterday.timetuple()[:3]))
 

	
 
    def test_tomorrow(self):
 
        tomorrow = datetime.date.today() + datetime.timedelta(days=1)
 
        args = tomorrow.timetuple()[:3] + (23, 59, 59)
 
        self.assertEqual(parse_datetime('tomorrow'), datetime.datetime(*args))
 

	
 
    def test_days(self):
 
        timestamp = datetime.datetime.today() - datetime.timedelta(days=3)
 
        args = timestamp.timetuple()[:3] + (0, 0, 0, 0)
 
        expected = datetime.datetime(*args)
 
        self.assertEqual(parse_datetime('3d'), expected)
 
        self.assertEqual(parse_datetime('3 d'), expected)
 
        self.assertEqual(parse_datetime('3 day'), expected)
 
        self.assertEqual(parse_datetime('3 days'), expected)
 

	
 
    def test_weeks(self):
 
        timestamp = datetime.datetime.today() - datetime.timedelta(days=3 * 7)
 
        args = timestamp.timetuple()[:3] + (0, 0, 0, 0)
 
        expected = datetime.datetime(*args)
 
        self.assertEqual(parse_datetime('3w'), expected)
 
        self.assertEqual(parse_datetime('3 w'), expected)
 
        self.assertEqual(parse_datetime('3 week'), expected)
 
        self.assertEqual(parse_datetime('3 weeks'), expected)
 

	
 
    def test_mixed(self):
 
        timestamp = datetime.datetime.today() - datetime.timedelta(days=2 * 7 + 3)
 
        args = timestamp.timetuple()[:3] + (0, 0, 0, 0)
 
        expected = datetime.datetime(*args)
 
        self.assertEqual(parse_datetime('2w3d'), expected)
 
        self.assertEqual(parse_datetime('2w 3d'), expected)
 
        self.assertEqual(parse_datetime('2w 3 days'), expected)
 
        self.assertEqual(parse_datetime('2 weeks 3 days'), expected)
 

	
 

	
 
class TestAuthorExtractors(unittest.TestCase):
 
    TEST_AUTHORS = [('Marcin Kuzminski <marcin@python-works.com>',
 
                    ('Marcin Kuzminski', 'marcin@python-works.com')),
 
                  ('Marcin Kuzminski Spaces < marcin@python-works.com >',
 
                    ('Marcin Kuzminski Spaces', 'marcin@python-works.com')),
 
                  ('Marcin Kuzminski <marcin.kuzminski@python-works.com>',
 
                    ('Marcin Kuzminski', 'marcin.kuzminski@python-works.com')),
 
                  ('mrf RFC_SPEC <marcin+kuzminski@python-works.com>',
 
                    ('mrf RFC_SPEC', 'marcin+kuzminski@python-works.com')),
 
    TEST_AUTHORS = [("Username Last'o'Name <username@python-works.com>",
 
                    ("Username Last'o'Name", "username@python-works.com")),
 
                  ("Username Last'o'Name Spaces < username@python-works.com >",
 
                    ("Username Last'o'Name Spaces", "username@python-works.com")),
 
                  ("Username Last'o'Name <username.lastname@python-works.com>",
 
                    ("Username Last'o'Name", "username.lastname@python-works.com")),
 
                  ('mrf RFC_SPEC <username+lastname@python-works.com>',
 
                    ('mrf RFC_SPEC', 'username+lastname@python-works.com')),
 
                  ('username <user@email.com>',
 
                    ('username', 'user@email.com')),
 
                  ('username <user@email.com',
 
                   ('username', 'user@email.com')),
 
                  ('broken missing@email.com',
 
                   ('broken', 'missing@email.com')),
 
                  ('<justemail@mail.com>',
 
                   ('', 'justemail@mail.com')),
 
                  ('justname',
 
                   ('justname', '')),
 
                  ('Mr Double Name withemail@email.com ',
 
                   ('Mr Double Name', 'withemail@email.com')),
 
                  ]
 

	
 
    def test_author_email(self):
 

	
 
        for test_str, result in self.TEST_AUTHORS:
 
            self.assertEqual(result[1], author_email(test_str))
 

	
 

	
 
    def test_author_name(self):
 

	
 
        for test_str, result in self.TEST_AUTHORS:
 
            self.assertEqual(result[0], author_name(test_str))
 

	
 

	
 
class TestGetDictForAttrs(unittest.TestCase):
 

	
 
    def test_returned_dict_has_expected_attrs(self):
 
        obj = mock.Mock()
 
        obj.NOT_INCLUDED = 'this key/value should not be included'
 
        obj.CONST = True
 
        obj.foo = 'aaa'
 
        obj.attrs = {'foo': 'bar'}
 
        obj.date = datetime.datetime(2010, 12, 31)
 
        obj.count = 1001
 

	
 
        self.assertEqual(get_dict_for_attrs(obj, ['CONST', 'foo', 'attrs',
 
            'date', 'count']), {
 
            'CONST': True,
 
            'foo': 'aaa',
 
            'attrs': {'foo': 'bar'},
 
            'date': datetime.datetime(2010, 12, 31),
 
            'count': 1001,
 
        })
 

	
 

	
 
class TestGetTotalSeconds(unittest.TestCase):
 

	
 
    def assertTotalSecondsEqual(self, timedelta, expected_seconds):
 
        result = get_total_seconds(timedelta)
 
        self.assertEqual(result, expected_seconds,
 
            "We computed %s seconds for %s but expected %s"
 
            % (result, timedelta, expected_seconds))
 

	
 
    def test_get_total_seconds_returns_proper_value(self):
 
        self.assertTotalSecondsEqual(datetime.timedelta(seconds=1001), 1001)
 

	
 
    def test_get_total_seconds_returns_proper_value_for_partial_seconds(self):
 
        self.assertTotalSecondsEqual(datetime.timedelta(seconds=50.65), 50.65)
 

	
 

	
 
class TestGetUserHome(unittest.TestCase):
 

	
 
    @mock.patch.object(os, 'environ', {})
 
    def test_defaults_to_none(self):
 
        self.assertEqual(get_user_home(), '')
 

	
 
    @mock.patch.object(os, 'environ', {'HOME': '/home/foobar'})
 
    def test_unix_like(self):
 
        self.assertEqual(get_user_home(), '/home/foobar')
 

	
 
    @mock.patch.object(os, 'environ', {'USERPROFILE': '/Users/foobar'})
 
    def test_windows_like(self):
 
        self.assertEqual(get_user_home(), '/Users/foobar')
 

	
 
    @mock.patch.object(os, 'environ', {'HOME': '/home/foobar',
 
        'USERPROFILE': '/Users/foobar'})
 
    def test_prefers_home_over_userprofile(self):
 
        self.assertEqual(get_user_home(), '/home/foobar')
 

	
 

	
 
if __name__ == '__main__':
 
    unittest.main()
0 comments (0 inline, 0 general)