test_pagure_lib_git.py 101 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2018 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. from __future__ import unicode_literals
  8. __requires__ = ['SQLAlchemy >= 0.8']
  9. import pkg_resources
  10. import datetime
  11. import os
  12. import shutil
  13. import sys
  14. import tempfile
  15. import time
  16. import unittest
  17. import pygit2
  18. import six
  19. from mock import patch, MagicMock
  20. sys.path.insert(0, os.path.join(os.path.dirname(
  21. os.path.abspath(__file__)), '..'))
  22. import pagure.lib.git
  23. import tests
  24. from pagure.lib.repo import PagureRepo
  25. class PagureLibGittests(tests.Modeltests):
  26. """ Tests for pagure.lib.git """
  27. def test_write_gitolite_acls(self):
  28. """ Test the write_gitolite_acls function of pagure.lib.git.
  29. when the new uesr is an made an admin """
  30. tests.create_projects(self.session)
  31. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  32. # Add an user to a project
  33. # The user will be an admin of the project
  34. msg = pagure.lib.query.add_user_to_project(
  35. session=self.session,
  36. project=repo,
  37. new_user='foo',
  38. user='pingou',
  39. )
  40. self.session.commit()
  41. self.assertEqual(msg, 'User added')
  42. # Add a forked project
  43. item = pagure.lib.model.Project(
  44. user_id=1, # pingou
  45. name='test3',
  46. description='test project #2',
  47. is_fork=True,
  48. parent_id=1,
  49. hook_token='aaabbbvvv',
  50. )
  51. self.session.add(item)
  52. self.session.commit()
  53. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  54. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  55. helper.write_gitolite_acls(
  56. self.session, configfile=outputconf, project=-1)
  57. self.assertTrue(os.path.exists(outputconf))
  58. with open(outputconf) as stream:
  59. data = stream.read()
  60. exp = """repo test
  61. R = @all
  62. RW+ = pingou
  63. RW+ = foo
  64. repo docs/test
  65. R = @all
  66. RW+ = pingou
  67. RW+ = foo
  68. repo tickets/test
  69. RW+ = pingou
  70. RW+ = foo
  71. repo requests/test
  72. RW+ = pingou
  73. RW+ = foo
  74. repo test2
  75. R = @all
  76. RW+ = pingou
  77. repo docs/test2
  78. R = @all
  79. RW+ = pingou
  80. repo tickets/test2
  81. RW+ = pingou
  82. repo requests/test2
  83. RW+ = pingou
  84. repo somenamespace/test3
  85. R = @all
  86. RW+ = pingou
  87. repo docs/somenamespace/test3
  88. R = @all
  89. RW+ = pingou
  90. repo tickets/somenamespace/test3
  91. RW+ = pingou
  92. repo requests/somenamespace/test3
  93. RW+ = pingou
  94. repo forks/pingou/test3
  95. R = @all
  96. RW+ = pingou
  97. repo docs/forks/pingou/test3
  98. R = @all
  99. RW+ = pingou
  100. repo tickets/forks/pingou/test3
  101. RW+ = pingou
  102. repo requests/forks/pingou/test3
  103. RW+ = pingou
  104. # end of body
  105. """
  106. #print data
  107. self.assertEqual(data, exp)
  108. os.unlink(outputconf)
  109. self.assertFalse(os.path.exists(outputconf))
  110. def test_write_gitolite_acls_preconf(self):
  111. """ Test the write_gitolite_acls function of pagure.lib.git with
  112. a preconf set """
  113. tests.create_projects(self.session)
  114. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  115. preconf = os.path.join(self.path, 'header_gitolite')
  116. with open(preconf, 'w') as stream:
  117. stream.write('# this is a header that is manually added')
  118. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  119. helper.write_gitolite_acls(
  120. self.session,
  121. outputconf,
  122. project=-1,
  123. preconf=preconf
  124. )
  125. self.assertTrue(os.path.exists(outputconf))
  126. with open(outputconf) as stream:
  127. data = stream.read()
  128. exp = """# this is a header that is manually added
  129. # end of header
  130. repo test
  131. R = @all
  132. RW+ = pingou
  133. repo docs/test
  134. R = @all
  135. RW+ = pingou
  136. repo tickets/test
  137. RW+ = pingou
  138. repo requests/test
  139. RW+ = pingou
  140. repo test2
  141. R = @all
  142. RW+ = pingou
  143. repo docs/test2
  144. R = @all
  145. RW+ = pingou
  146. repo tickets/test2
  147. RW+ = pingou
  148. repo requests/test2
  149. RW+ = pingou
  150. repo somenamespace/test3
  151. R = @all
  152. RW+ = pingou
  153. repo docs/somenamespace/test3
  154. R = @all
  155. RW+ = pingou
  156. repo tickets/somenamespace/test3
  157. RW+ = pingou
  158. repo requests/somenamespace/test3
  159. RW+ = pingou
  160. # end of body
  161. """
  162. #print data
  163. self.assertEqual(data.split('\n'), exp.split('\n'))
  164. os.unlink(outputconf)
  165. self.assertFalse(os.path.exists(outputconf))
  166. def test_write_gitolite_acls_preconf_postconf(self):
  167. """ Test the write_gitolite_acls function of pagure.lib.git with
  168. a postconf set """
  169. tests.create_projects(self.session)
  170. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  171. preconf = os.path.join(self.path, 'header_gitolite')
  172. with open(preconf, 'w') as stream:
  173. stream.write('# this is a header that is manually added')
  174. postconf = os.path.join(self.path, 'footer_gitolite')
  175. with open(postconf, 'w') as stream:
  176. stream.write('# end of generated configuration')
  177. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  178. helper.write_gitolite_acls(
  179. self.session,
  180. outputconf,
  181. project=-1,
  182. preconf=preconf,
  183. postconf=postconf
  184. )
  185. self.assertTrue(os.path.exists(outputconf))
  186. with open(outputconf) as stream:
  187. data = stream.read()
  188. exp = """# this is a header that is manually added
  189. # end of header
  190. repo test
  191. R = @all
  192. RW+ = pingou
  193. repo docs/test
  194. R = @all
  195. RW+ = pingou
  196. repo tickets/test
  197. RW+ = pingou
  198. repo requests/test
  199. RW+ = pingou
  200. repo test2
  201. R = @all
  202. RW+ = pingou
  203. repo docs/test2
  204. R = @all
  205. RW+ = pingou
  206. repo tickets/test2
  207. RW+ = pingou
  208. repo requests/test2
  209. RW+ = pingou
  210. repo somenamespace/test3
  211. R = @all
  212. RW+ = pingou
  213. repo docs/somenamespace/test3
  214. R = @all
  215. RW+ = pingou
  216. repo tickets/somenamespace/test3
  217. RW+ = pingou
  218. repo requests/somenamespace/test3
  219. RW+ = pingou
  220. # end of body
  221. # end of generated configuration
  222. """
  223. #print data
  224. self.assertEqual(data, exp)
  225. os.unlink(outputconf)
  226. self.assertFalse(os.path.exists(outputconf))
  227. def test_write_gitolite_acls_postconf(self):
  228. """ Test the write_gitolite_acls function of pagure.lib.git with
  229. a preconf and a postconf set """
  230. tests.create_projects(self.session)
  231. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  232. postconf = os.path.join(self.path, 'footer_gitolite')
  233. with open(postconf, 'w') as stream:
  234. stream.write('# end of generated configuration')
  235. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  236. helper.write_gitolite_acls(
  237. self.session,
  238. outputconf,
  239. project=-1,
  240. postconf=postconf
  241. )
  242. self.assertTrue(os.path.exists(outputconf))
  243. with open(outputconf) as stream:
  244. data = stream.read()
  245. exp = """repo test
  246. R = @all
  247. RW+ = pingou
  248. repo docs/test
  249. R = @all
  250. RW+ = pingou
  251. repo tickets/test
  252. RW+ = pingou
  253. repo requests/test
  254. RW+ = pingou
  255. repo test2
  256. R = @all
  257. RW+ = pingou
  258. repo docs/test2
  259. R = @all
  260. RW+ = pingou
  261. repo tickets/test2
  262. RW+ = pingou
  263. repo requests/test2
  264. RW+ = pingou
  265. repo somenamespace/test3
  266. R = @all
  267. RW+ = pingou
  268. repo docs/somenamespace/test3
  269. R = @all
  270. RW+ = pingou
  271. repo tickets/somenamespace/test3
  272. RW+ = pingou
  273. repo requests/somenamespace/test3
  274. RW+ = pingou
  275. # end of body
  276. # end of generated configuration
  277. """
  278. #print data
  279. self.assertEqual(data, exp)
  280. os.unlink(outputconf)
  281. self.assertFalse(os.path.exists(outputconf))
  282. def test_write_gitolite_acls_deploykeys(self):
  283. """ Test write_gitolite_acls function to add deploy keys. """
  284. tests.create_projects(self.session)
  285. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  286. # Add two deploy keys (one readonly one push)
  287. pingou = pagure.lib.query.get_user(self.session, 'pingou')
  288. msg1 = pagure.lib.query.add_sshkey_to_project_or_user(
  289. session=self.session,
  290. project=repo,
  291. ssh_key='ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q==',
  292. pushaccess=False,
  293. creator=pingou
  294. )
  295. msg2 = pagure.lib.query.add_sshkey_to_project_or_user(
  296. session=self.session,
  297. project=repo,
  298. ssh_key='ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9Xwc2RDzPBhlEDARfHldGjudIVoa04tqT1JVKGQmyllTFz7Rb8CngQL3e7zyNzotnhwYKHdoiLlPkVEiDee4dWMUe48ilqId+FJZQGhyv8fu4BoFdE1AJUVylzmltbLg14VqG5gjTpXgtlrEva9arKwBMHJjRYc8ScaSn3OgyQw==',
  299. pushaccess=True,
  300. creator=pingou
  301. )
  302. self.session.commit()
  303. self.assertEqual(msg1, 'SSH key added')
  304. self.assertEqual(msg2, 'SSH key added')
  305. # Add a forked project
  306. item = pagure.lib.model.Project(
  307. user_id=1, # pingou
  308. name='test3',
  309. description='test project #2',
  310. is_fork=True,
  311. parent_id=1,
  312. hook_token='aaabbbvvv',
  313. )
  314. self.session.add(item)
  315. self.session.commit()
  316. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  317. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  318. helper.write_gitolite_acls(self.session, outputconf, project=-1)
  319. self.assertTrue(os.path.exists(outputconf))
  320. with open(outputconf) as stream:
  321. data = stream.read()
  322. exp = """repo test
  323. R = @all
  324. RW+ = pingou
  325. R = deploykey_test_1
  326. RW+ = deploykey_test_2
  327. repo docs/test
  328. R = @all
  329. RW+ = pingou
  330. R = deploykey_test_1
  331. RW+ = deploykey_test_2
  332. repo tickets/test
  333. RW+ = pingou
  334. R = deploykey_test_1
  335. RW+ = deploykey_test_2
  336. repo requests/test
  337. RW+ = pingou
  338. R = deploykey_test_1
  339. RW+ = deploykey_test_2
  340. repo test2
  341. R = @all
  342. RW+ = pingou
  343. repo docs/test2
  344. R = @all
  345. RW+ = pingou
  346. repo tickets/test2
  347. RW+ = pingou
  348. repo requests/test2
  349. RW+ = pingou
  350. repo somenamespace/test3
  351. R = @all
  352. RW+ = pingou
  353. repo docs/somenamespace/test3
  354. R = @all
  355. RW+ = pingou
  356. repo tickets/somenamespace/test3
  357. RW+ = pingou
  358. repo requests/somenamespace/test3
  359. RW+ = pingou
  360. repo forks/pingou/test3
  361. R = @all
  362. RW+ = pingou
  363. repo docs/forks/pingou/test3
  364. R = @all
  365. RW+ = pingou
  366. repo tickets/forks/pingou/test3
  367. RW+ = pingou
  368. repo requests/forks/pingou/test3
  369. RW+ = pingou
  370. # end of body
  371. """
  372. #print data
  373. self.assertEqual(data, exp)
  374. os.unlink(outputconf)
  375. self.assertFalse(os.path.exists(outputconf))
  376. def test_write_gitolite_acls_ticket(self):
  377. """ Test the write_gitolite_acls function of pagure.lib.git.
  378. when the new uesr is just a ticketer """
  379. tests.create_projects(self.session)
  380. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  381. # Add an user to a project
  382. # The user will be an admin of the project
  383. msg = pagure.lib.query.add_user_to_project(
  384. session=self.session,
  385. project=repo,
  386. new_user='foo',
  387. user='pingou',
  388. access='ticket'
  389. )
  390. self.session.commit()
  391. self.assertEqual(msg, 'User added')
  392. # Add a forked project
  393. item = pagure.lib.model.Project(
  394. user_id=1, # pingou
  395. name='test3',
  396. description='test project #2',
  397. is_fork=True,
  398. parent_id=1,
  399. hook_token='aaabbbvvv',
  400. )
  401. self.session.add(item)
  402. self.session.commit()
  403. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  404. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  405. helper.write_gitolite_acls(self.session, outputconf, project=-1)
  406. self.assertTrue(os.path.exists(outputconf))
  407. with open(outputconf) as stream:
  408. data = stream.read()
  409. exp = """repo test
  410. R = @all
  411. RW+ = pingou
  412. repo docs/test
  413. R = @all
  414. RW+ = pingou
  415. repo tickets/test
  416. RW+ = pingou
  417. repo requests/test
  418. RW+ = pingou
  419. repo test2
  420. R = @all
  421. RW+ = pingou
  422. repo docs/test2
  423. R = @all
  424. RW+ = pingou
  425. repo tickets/test2
  426. RW+ = pingou
  427. repo requests/test2
  428. RW+ = pingou
  429. repo somenamespace/test3
  430. R = @all
  431. RW+ = pingou
  432. repo docs/somenamespace/test3
  433. R = @all
  434. RW+ = pingou
  435. repo tickets/somenamespace/test3
  436. RW+ = pingou
  437. repo requests/somenamespace/test3
  438. RW+ = pingou
  439. repo forks/pingou/test3
  440. R = @all
  441. RW+ = pingou
  442. repo docs/forks/pingou/test3
  443. R = @all
  444. RW+ = pingou
  445. repo tickets/forks/pingou/test3
  446. RW+ = pingou
  447. repo requests/forks/pingou/test3
  448. RW+ = pingou
  449. # end of body
  450. """
  451. #print data
  452. self.assertEqual(data, exp)
  453. os.unlink(outputconf)
  454. self.assertFalse(os.path.exists(outputconf))
  455. def test_write_gitolite_acls_commit(self):
  456. """ Test the write_gitolite_acls function of pagure.lib.git.
  457. when the new uesr is just a committer """
  458. tests.create_projects(self.session)
  459. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  460. # Add an user to a project
  461. # The user will be an admin of the project
  462. msg = pagure.lib.query.add_user_to_project(
  463. session=self.session,
  464. project=repo,
  465. new_user='foo',
  466. user='pingou',
  467. access='commit'
  468. )
  469. self.session.commit()
  470. self.assertEqual(msg, 'User added')
  471. # Add a forked project
  472. item = pagure.lib.model.Project(
  473. user_id=1, # pingou
  474. name='test3',
  475. description='test project #2',
  476. is_fork=True,
  477. parent_id=1,
  478. hook_token='aaabbbvvv',
  479. )
  480. self.session.add(item)
  481. self.session.commit()
  482. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  483. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  484. helper.write_gitolite_acls(self.session, outputconf, project=-1)
  485. self.assertTrue(os.path.exists(outputconf))
  486. with open(outputconf) as stream:
  487. data = stream.read()
  488. exp = """repo test
  489. R = @all
  490. RW+ = pingou
  491. RW+ = foo
  492. repo docs/test
  493. R = @all
  494. RW+ = pingou
  495. RW+ = foo
  496. repo tickets/test
  497. RW+ = pingou
  498. RW+ = foo
  499. repo requests/test
  500. RW+ = pingou
  501. RW+ = foo
  502. repo test2
  503. R = @all
  504. RW+ = pingou
  505. repo docs/test2
  506. R = @all
  507. RW+ = pingou
  508. repo tickets/test2
  509. RW+ = pingou
  510. repo requests/test2
  511. RW+ = pingou
  512. repo somenamespace/test3
  513. R = @all
  514. RW+ = pingou
  515. repo docs/somenamespace/test3
  516. R = @all
  517. RW+ = pingou
  518. repo tickets/somenamespace/test3
  519. RW+ = pingou
  520. repo requests/somenamespace/test3
  521. RW+ = pingou
  522. repo forks/pingou/test3
  523. R = @all
  524. RW+ = pingou
  525. repo docs/forks/pingou/test3
  526. R = @all
  527. RW+ = pingou
  528. repo tickets/forks/pingou/test3
  529. RW+ = pingou
  530. repo requests/forks/pingou/test3
  531. RW+ = pingou
  532. # end of body
  533. """
  534. #print data
  535. self.assertEqual(data, exp)
  536. os.unlink(outputconf)
  537. self.assertFalse(os.path.exists(outputconf))
  538. def test_write_gitolite_acls_groups(self):
  539. """ Test the write_gitolite_acls function of pagure.lib.git with
  540. groups as admin
  541. """
  542. tests.create_projects(self.session)
  543. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  544. # Add a couple of groups
  545. # They would be admins
  546. msg = pagure.lib.query.add_group(
  547. self.session,
  548. group_name='sysadmin',
  549. display_name='sysadmin group',
  550. description=None,
  551. group_type='user',
  552. user='pingou',
  553. is_admin=False,
  554. blacklist=[],
  555. )
  556. self.session.commit()
  557. self.assertEqual(msg, 'User `pingou` added to the group `sysadmin`.')
  558. msg = pagure.lib.query.add_group(
  559. self.session,
  560. group_name='devs',
  561. display_name='devs group',
  562. description=None,
  563. group_type='user',
  564. user='pingou',
  565. is_admin=False,
  566. blacklist=[],
  567. )
  568. self.session.commit()
  569. self.assertEqual(msg, 'User `pingou` added to the group `devs`.')
  570. # Associate these groups to a project
  571. msg = pagure.lib.query.add_group_to_project(
  572. session=self.session,
  573. project=repo,
  574. new_group='sysadmin',
  575. user='pingou',
  576. )
  577. self.session.commit()
  578. self.assertEqual(msg, 'Group added')
  579. msg = pagure.lib.query.add_group_to_project(
  580. session=self.session,
  581. project=repo,
  582. new_group='devs',
  583. user='pingou',
  584. )
  585. self.session.commit()
  586. self.assertEqual(msg, 'Group added')
  587. # Add an user to a project
  588. msg = pagure.lib.query.add_user_to_project(
  589. session=self.session,
  590. project=repo,
  591. new_user='foo',
  592. user='pingou',
  593. )
  594. self.session.commit()
  595. self.assertEqual(msg, 'User added')
  596. # Add a forked project
  597. item = pagure.lib.model.Project(
  598. user_id=1, # pingou
  599. name='test2',
  600. description='test project #2',
  601. is_fork=True,
  602. parent_id=1,
  603. hook_token='aaabbbvvv',
  604. )
  605. self.session.add(item)
  606. self.session.commit()
  607. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  608. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  609. helper.write_gitolite_acls(self.session, outputconf, project=-1)
  610. self.assertTrue(os.path.exists(outputconf))
  611. with open(outputconf) as stream:
  612. data = stream.read()
  613. exp = """@devs = pingou
  614. @sysadmin = pingou
  615. # end of groups
  616. repo test
  617. R = @all
  618. RW+ = @devs @sysadmin
  619. RW+ = pingou
  620. RW+ = foo
  621. repo docs/test
  622. R = @all
  623. RW+ = @devs @sysadmin
  624. RW+ = pingou
  625. RW+ = foo
  626. repo tickets/test
  627. RW+ = @devs @sysadmin
  628. RW+ = pingou
  629. RW+ = foo
  630. repo requests/test
  631. RW+ = @devs @sysadmin
  632. RW+ = pingou
  633. RW+ = foo
  634. repo test2
  635. R = @all
  636. RW+ = pingou
  637. repo docs/test2
  638. R = @all
  639. RW+ = pingou
  640. repo tickets/test2
  641. RW+ = pingou
  642. repo requests/test2
  643. RW+ = pingou
  644. repo somenamespace/test3
  645. R = @all
  646. RW+ = pingou
  647. repo docs/somenamespace/test3
  648. R = @all
  649. RW+ = pingou
  650. repo tickets/somenamespace/test3
  651. RW+ = pingou
  652. repo requests/somenamespace/test3
  653. RW+ = pingou
  654. repo forks/pingou/test2
  655. R = @all
  656. RW+ = pingou
  657. repo docs/forks/pingou/test2
  658. R = @all
  659. RW+ = pingou
  660. repo tickets/forks/pingou/test2
  661. RW+ = pingou
  662. repo requests/forks/pingou/test2
  663. RW+ = pingou
  664. # end of body
  665. """
  666. #print data
  667. self.assertEqual(data.split('\n'), exp.split('\n'))
  668. os.unlink(outputconf)
  669. self.assertFalse(os.path.exists(outputconf))
  670. def test_write_gitolite_acls_groups_ticket(self):
  671. """ Test the write_gitolite_acls function of pagure.lib.git with
  672. groups as ticketers
  673. """
  674. tests.create_projects(self.session)
  675. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  676. # Add a couple of groups
  677. # They would be ticketers
  678. msg = pagure.lib.query.add_group(
  679. self.session,
  680. group_name='sysadmin',
  681. display_name='sysadmin group',
  682. description=None,
  683. group_type='user',
  684. user='pingou',
  685. is_admin=False,
  686. blacklist=[],
  687. )
  688. self.session.commit()
  689. self.assertEqual(msg, 'User `pingou` added to the group `sysadmin`.')
  690. msg = pagure.lib.query.add_group(
  691. self.session,
  692. group_name='devs',
  693. display_name='devs group',
  694. description=None,
  695. group_type='user',
  696. user='pingou',
  697. is_admin=False,
  698. blacklist=[],
  699. )
  700. self.session.commit()
  701. self.assertEqual(msg, 'User `pingou` added to the group `devs`.')
  702. # Associate these groups to a project
  703. msg = pagure.lib.query.add_group_to_project(
  704. session=self.session,
  705. project=repo,
  706. new_group='sysadmin',
  707. user='pingou',
  708. access='ticket',
  709. )
  710. self.session.commit()
  711. self.assertEqual(msg, 'Group added')
  712. msg = pagure.lib.query.add_group_to_project(
  713. session=self.session,
  714. project=repo,
  715. new_group='devs',
  716. user='pingou',
  717. access='ticket'
  718. )
  719. self.session.commit()
  720. self.assertEqual(msg, 'Group added')
  721. # Add an user to a project
  722. msg = pagure.lib.query.add_user_to_project(
  723. session=self.session,
  724. project=repo,
  725. new_user='foo',
  726. user='pingou',
  727. )
  728. self.session.commit()
  729. self.assertEqual(msg, 'User added')
  730. # Add a forked project
  731. item = pagure.lib.model.Project(
  732. user_id=1, # pingou
  733. name='test2',
  734. description='test project #2',
  735. is_fork=True,
  736. parent_id=1,
  737. hook_token='aaabbbvvv',
  738. )
  739. self.session.add(item)
  740. self.session.commit()
  741. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  742. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  743. helper.write_gitolite_acls(self.session, outputconf, project=-1)
  744. self.assertTrue(os.path.exists(outputconf))
  745. with open(outputconf) as stream:
  746. data = stream.read()
  747. exp = """@devs = pingou
  748. @sysadmin = pingou
  749. # end of groups
  750. repo test
  751. R = @all
  752. RW+ = pingou
  753. RW+ = foo
  754. repo docs/test
  755. R = @all
  756. RW+ = pingou
  757. RW+ = foo
  758. repo tickets/test
  759. RW+ = pingou
  760. RW+ = foo
  761. repo requests/test
  762. RW+ = pingou
  763. RW+ = foo
  764. repo test2
  765. R = @all
  766. RW+ = pingou
  767. repo docs/test2
  768. R = @all
  769. RW+ = pingou
  770. repo tickets/test2
  771. RW+ = pingou
  772. repo requests/test2
  773. RW+ = pingou
  774. repo somenamespace/test3
  775. R = @all
  776. RW+ = pingou
  777. repo docs/somenamespace/test3
  778. R = @all
  779. RW+ = pingou
  780. repo tickets/somenamespace/test3
  781. RW+ = pingou
  782. repo requests/somenamespace/test3
  783. RW+ = pingou
  784. repo forks/pingou/test2
  785. R = @all
  786. RW+ = pingou
  787. repo docs/forks/pingou/test2
  788. R = @all
  789. RW+ = pingou
  790. repo tickets/forks/pingou/test2
  791. RW+ = pingou
  792. repo requests/forks/pingou/test2
  793. RW+ = pingou
  794. # end of body
  795. """
  796. #print data
  797. self.assertEqual(data.split('\n'), exp.split('\n'))
  798. os.unlink(outputconf)
  799. self.assertFalse(os.path.exists(outputconf))
  800. def test_write_gitolite_acls_groups_commit(self):
  801. """ Test the write_gitolite_acls function of pagure.lib.git with
  802. groups as committers
  803. """
  804. tests.create_projects(self.session)
  805. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  806. # Add a couple of groups
  807. # They would be committers
  808. msg = pagure.lib.query.add_group(
  809. self.session,
  810. group_name='sysadmin',
  811. display_name='sysadmin group',
  812. description=None,
  813. group_type='user',
  814. user='pingou',
  815. is_admin=False,
  816. blacklist=[],
  817. )
  818. self.session.commit()
  819. self.assertEqual(msg, 'User `pingou` added to the group `sysadmin`.')
  820. msg = pagure.lib.query.add_group(
  821. self.session,
  822. group_name='devs',
  823. display_name='devs group',
  824. description=None,
  825. group_type='user',
  826. user='pingou',
  827. is_admin=False,
  828. blacklist=[],
  829. )
  830. self.session.commit()
  831. self.assertEqual(msg, 'User `pingou` added to the group `devs`.')
  832. # Associate these groups to a project
  833. msg = pagure.lib.query.add_group_to_project(
  834. session=self.session,
  835. project=repo,
  836. new_group='sysadmin',
  837. user='pingou',
  838. access='commit'
  839. )
  840. self.session.commit()
  841. self.assertEqual(msg, 'Group added')
  842. msg = pagure.lib.query.add_group_to_project(
  843. session=self.session,
  844. project=repo,
  845. new_group='devs',
  846. user='pingou',
  847. access='commit'
  848. )
  849. self.session.commit()
  850. self.assertEqual(msg, 'Group added')
  851. # Add an user to a project
  852. msg = pagure.lib.query.add_user_to_project(
  853. session=self.session,
  854. project=repo,
  855. new_user='foo',
  856. user='pingou',
  857. )
  858. self.session.commit()
  859. self.assertEqual(msg, 'User added')
  860. # Add a forked project
  861. item = pagure.lib.model.Project(
  862. user_id=1, # pingou
  863. name='test2',
  864. description='test project #2',
  865. is_fork=True,
  866. parent_id=1,
  867. hook_token='aaabbbvvv',
  868. )
  869. self.session.add(item)
  870. self.session.commit()
  871. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  872. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  873. helper.write_gitolite_acls(self.session, outputconf, project=-1)
  874. self.assertTrue(os.path.exists(outputconf))
  875. with open(outputconf) as stream:
  876. data = stream.read()
  877. exp = """@devs = pingou
  878. @sysadmin = pingou
  879. # end of groups
  880. repo test
  881. R = @all
  882. RW+ = @devs @sysadmin
  883. RW+ = pingou
  884. RW+ = foo
  885. repo docs/test
  886. R = @all
  887. RW+ = @devs @sysadmin
  888. RW+ = pingou
  889. RW+ = foo
  890. repo tickets/test
  891. RW+ = @devs @sysadmin
  892. RW+ = pingou
  893. RW+ = foo
  894. repo requests/test
  895. RW+ = @devs @sysadmin
  896. RW+ = pingou
  897. RW+ = foo
  898. repo test2
  899. R = @all
  900. RW+ = pingou
  901. repo docs/test2
  902. R = @all
  903. RW+ = pingou
  904. repo tickets/test2
  905. RW+ = pingou
  906. repo requests/test2
  907. RW+ = pingou
  908. repo somenamespace/test3
  909. R = @all
  910. RW+ = pingou
  911. repo docs/somenamespace/test3
  912. R = @all
  913. RW+ = pingou
  914. repo tickets/somenamespace/test3
  915. RW+ = pingou
  916. repo requests/somenamespace/test3
  917. RW+ = pingou
  918. repo forks/pingou/test2
  919. R = @all
  920. RW+ = pingou
  921. repo docs/forks/pingou/test2
  922. R = @all
  923. RW+ = pingou
  924. repo tickets/forks/pingou/test2
  925. RW+ = pingou
  926. repo requests/forks/pingou/test2
  927. RW+ = pingou
  928. # end of body
  929. """
  930. #print data
  931. self.assertEqual(data.split('\n'), exp.split('\n'))
  932. os.unlink(outputconf)
  933. self.assertFalse(os.path.exists(outputconf))
  934. def test_write_gitolite_project_pr_only(self):
  935. """ Test the write_gitolite_acls function of pagure.lib.git.
  936. when the project enforces the PR approach.
  937. """
  938. tests.create_projects(self.session)
  939. repo = pagure.lib.query._get_project(self.session, 'test')
  940. # Make the project enforce the PR workflow
  941. settings = repo.settings
  942. settings['pull_request_access_only'] = True
  943. repo.settings = settings
  944. self.session.add(repo)
  945. self.session.commit()
  946. # Add an user to a project
  947. # The user will be an admin of the project
  948. msg = pagure.lib.query.add_user_to_project(
  949. session=self.session,
  950. project=repo,
  951. new_user='foo',
  952. user='pingou',
  953. )
  954. self.session.commit()
  955. self.assertEqual(msg, 'User added')
  956. # Add a forked project
  957. item = pagure.lib.model.Project(
  958. user_id=1, # pingou
  959. name='test3',
  960. description='test project #2',
  961. is_fork=True,
  962. parent_id=1,
  963. hook_token='aaabbbvvv',
  964. )
  965. self.session.add(item)
  966. self.session.commit()
  967. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  968. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  969. helper.write_gitolite_acls(self.session, outputconf, project=-1)
  970. self.assertTrue(os.path.exists(outputconf))
  971. with open(outputconf) as stream:
  972. data = stream.read()
  973. exp = """repo docs/test
  974. R = @all
  975. RW+ = pingou
  976. RW+ = foo
  977. repo tickets/test
  978. RW+ = pingou
  979. RW+ = foo
  980. repo requests/test
  981. RW+ = pingou
  982. RW+ = foo
  983. repo test2
  984. R = @all
  985. RW+ = pingou
  986. repo docs/test2
  987. R = @all
  988. RW+ = pingou
  989. repo tickets/test2
  990. RW+ = pingou
  991. repo requests/test2
  992. RW+ = pingou
  993. repo somenamespace/test3
  994. R = @all
  995. RW+ = pingou
  996. repo docs/somenamespace/test3
  997. R = @all
  998. RW+ = pingou
  999. repo tickets/somenamespace/test3
  1000. RW+ = pingou
  1001. repo requests/somenamespace/test3
  1002. RW+ = pingou
  1003. repo forks/pingou/test3
  1004. R = @all
  1005. RW+ = pingou
  1006. repo docs/forks/pingou/test3
  1007. R = @all
  1008. RW+ = pingou
  1009. repo tickets/forks/pingou/test3
  1010. RW+ = pingou
  1011. repo requests/forks/pingou/test3
  1012. RW+ = pingou
  1013. # end of body
  1014. """
  1015. #print data
  1016. self.assertEqual(data, exp)
  1017. os.unlink(outputconf)
  1018. self.assertFalse(os.path.exists(outputconf))
  1019. @patch.dict('pagure.config.config', {'PR_ONLY': True})
  1020. def test_write_gitolite_global_pr_only(self):
  1021. """ Test the write_gitolite_acls function of pagure.lib.git.
  1022. when the pagure instance enforces the PR approach.
  1023. """
  1024. tests.create_projects(self.session)
  1025. repo = pagure.lib.query._get_project(self.session, 'test')
  1026. self.assertFalse(repo.settings['pull_request_access_only'])
  1027. # Add an user to a project
  1028. # The user will be an admin of the project
  1029. msg = pagure.lib.query.add_user_to_project(
  1030. session=self.session,
  1031. project=repo,
  1032. new_user='foo',
  1033. user='pingou',
  1034. )
  1035. self.session.commit()
  1036. self.assertEqual(msg, 'User added')
  1037. # Add a forked project
  1038. item = pagure.lib.model.Project(
  1039. user_id=1, # pingou
  1040. name='test3',
  1041. description='test project #2',
  1042. is_fork=True,
  1043. parent_id=1,
  1044. hook_token='aaabbbvvv',
  1045. )
  1046. self.session.add(item)
  1047. self.session.commit()
  1048. outputconf = os.path.join(self.path, 'test_gitolite.conf')
  1049. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  1050. helper.write_gitolite_acls(self.session, outputconf, project=-1)
  1051. self.assertTrue(os.path.exists(outputconf))
  1052. with open(outputconf) as stream:
  1053. data = stream.read()
  1054. exp = """repo docs/test
  1055. R = @all
  1056. RW+ = pingou
  1057. RW+ = foo
  1058. repo tickets/test
  1059. RW+ = pingou
  1060. RW+ = foo
  1061. repo requests/test
  1062. RW+ = pingou
  1063. RW+ = foo
  1064. repo docs/test2
  1065. R = @all
  1066. RW+ = pingou
  1067. repo tickets/test2
  1068. RW+ = pingou
  1069. repo requests/test2
  1070. RW+ = pingou
  1071. repo docs/somenamespace/test3
  1072. R = @all
  1073. RW+ = pingou
  1074. repo tickets/somenamespace/test3
  1075. RW+ = pingou
  1076. repo requests/somenamespace/test3
  1077. RW+ = pingou
  1078. repo forks/pingou/test3
  1079. R = @all
  1080. RW+ = pingou
  1081. repo docs/forks/pingou/test3
  1082. R = @all
  1083. RW+ = pingou
  1084. repo tickets/forks/pingou/test3
  1085. RW+ = pingou
  1086. repo requests/forks/pingou/test3
  1087. RW+ = pingou
  1088. # end of body
  1089. """
  1090. #print data
  1091. self.assertEqual(data, exp)
  1092. os.unlink(outputconf)
  1093. self.assertFalse(os.path.exists(outputconf))
  1094. @patch('pagure.lib.notify.send_email')
  1095. def test_update_git(self, email_f):
  1096. """ Test the update_git of pagure.lib.git. """
  1097. email_f.return_value = True
  1098. # Create project
  1099. item = pagure.lib.model.Project(
  1100. user_id=1, # pingou
  1101. name='test_ticket_repo',
  1102. description='test project for ticket',
  1103. hook_token='aaabbbwww',
  1104. )
  1105. self.session.add(item)
  1106. self.session.commit()
  1107. # Create repo
  1108. self.gitrepo = os.path.join(self.path, 'repos', 'tickets',
  1109. 'test_ticket_repo.git')
  1110. pygit2.init_repository(self.gitrepo, bare=True)
  1111. repo = pagure.lib.query.get_authorized_project(self.session, 'test_ticket_repo')
  1112. # Create an issue to play with
  1113. msg = pagure.lib.query.new_issue(
  1114. session=self.session,
  1115. repo=repo,
  1116. title='Test issue',
  1117. content='We should work on this',
  1118. user='pingou',
  1119. )
  1120. self.assertEqual(msg.title, 'Test issue')
  1121. issue = pagure.lib.query.search_issues(self.session, repo, issueid=1)
  1122. pagure.lib.git.update_git(issue, repo).get()
  1123. repo = pygit2.Repository(self.gitrepo)
  1124. commit = repo.revparse_single('HEAD')
  1125. # Use patch to validate the repo
  1126. commit_patch = pagure.lib.git.commit_to_patch(repo, commit)
  1127. exp = r"""Mon Sep 17 00:00:00 2001
  1128. From: pagure <pagure>
  1129. Subject: Updated issue <hash>: Test issue
  1130. ---
  1131. diff --git a/123 b/456
  1132. new file mode 100644
  1133. index 0000000..60f7480
  1134. --- /dev/null
  1135. +++ b/456
  1136. @@ -0,0 +1,29 @@
  1137. +{
  1138. + "assignee": null,
  1139. + "blocks": [],
  1140. + "close_status": null,
  1141. + "closed_at": null,
  1142. + "comments": [],
  1143. + "content": "We should work on this",
  1144. + "custom_fields": [],
  1145. + "date_created": null,
  1146. + "depends": [],
  1147. + "id": 1,
  1148. + "last_updated": null,
  1149. + "milestone": null,
  1150. + "priority": null,
  1151. + "private": false,
  1152. + "status": "Open",
  1153. + "tags": [],
  1154. + "title": "Test issue",
  1155. + "user": {
  1156. + "default_email": "bar@pingou.com",
  1157. + "emails": [
  1158. + "bar@pingou.com",
  1159. + "foo@pingou.com"
  1160. + ],
  1161. + "fullname": "PY C",
  1162. + "name": "pingou"
  1163. + }
  1164. +}
  1165. \ No newline at end of file
  1166. """
  1167. npatch = []
  1168. for row in commit_patch.split('\n'):
  1169. if row.startswith('Date:'):
  1170. continue
  1171. elif row.startswith('From '):
  1172. row = row.split(' ', 2)[2]
  1173. elif row.startswith('diff --git '):
  1174. row = row.split(' ')
  1175. row[2] = 'a/123'
  1176. row[3] = 'b/456'
  1177. row = ' '.join(row)
  1178. elif 'Updated issue' in row:
  1179. row = row.split()
  1180. row[3] = '<hash>:'
  1181. row = ' '.join(row)
  1182. elif 'date_created' in row:
  1183. t = row.split(': ')[0]
  1184. row = '%s: null,' % t
  1185. elif 'last_updated' in row:
  1186. t = row.split(': ')[0]
  1187. row = '%s: null,' % t
  1188. elif 'closed_at' in row:
  1189. t = row.split(': ')[0]
  1190. row = '%s: null,' % t
  1191. elif 'closed_by' in row:
  1192. continue
  1193. elif row.startswith('index 00'):
  1194. row = 'index 0000000..60f7480'
  1195. elif row.startswith('+++ b/'):
  1196. row = '+++ b/456'
  1197. npatch.append(row)
  1198. commit_patch = '\n'.join(npatch)
  1199. #print commit_patch
  1200. self.assertEqual(commit_patch, exp)
  1201. # Enforce having a different last_updated field
  1202. # This is required as the test run fine and fast with sqlite but is
  1203. # much slower with postgresql so we end-up with an updated
  1204. # last_updated in postgresql but not with sqlite
  1205. time.sleep(1)
  1206. # Test again after adding a comment
  1207. # We need to make sure we wait for worker to commit the comment
  1208. with patch('pagure.lib.git._maybe_wait', tests.definitely_wait):
  1209. msg = pagure.lib.query.add_issue_comment(
  1210. session=self.session,
  1211. issue=issue,
  1212. comment='Hey look a comment!',
  1213. user='foo',
  1214. )
  1215. self.session.commit()
  1216. self.assertEqual(msg, 'Comment added')
  1217. # Use patch to validate the repo
  1218. repo = pygit2.Repository(self.gitrepo)
  1219. commit = repo.revparse_single('HEAD')
  1220. commit_patch = pagure.lib.git.commit_to_patch(repo, commit)
  1221. exp = r"""Mon Sep 17 00:00:00 2001
  1222. From: pagure <pagure>
  1223. Subject: Updated issue <hash>: Test issue
  1224. ---
  1225. diff --git a/123 b/456
  1226. index 458821a..77674a8
  1227. --- a/123
  1228. +++ b/456
  1229. @@ -4,13 +4,32 @@
  1230. "close_status": null,
  1231. "closed_at": null,
  1232. - "comments": [],
  1233. + "comments": [
  1234. + {
  1235. + "comment": "Hey look a comment!",
  1236. + "date_created": null,
  1237. + "edited_on": null,
  1238. + "editor": null,
  1239. + "id": 1,
  1240. + "notification": false,
  1241. + "parent": null,
  1242. + "reactions": {},
  1243. + "user": {
  1244. + "default_email": "foo@bar.com",
  1245. + "emails": [
  1246. + "foo@bar.com"
  1247. + ],
  1248. + "fullname": "foo bar",
  1249. + "name": "foo"
  1250. + }
  1251. + }
  1252. + ],
  1253. "content": "We should work on this",
  1254. "custom_fields": [],
  1255. "date_created": null,
  1256. "depends": [],
  1257. "id": 1,
  1258. - "last_updated": "<date>",
  1259. + "last_updated": "<date>",
  1260. "milestone": null,
  1261. "priority": null,
  1262. "private": false,
  1263. """
  1264. npatch = []
  1265. for row in commit_patch.split('\n'):
  1266. if row.startswith('Date:'):
  1267. continue
  1268. elif row.startswith('From '):
  1269. row = row.split(' ', 2)[2]
  1270. elif row.startswith('diff --git '):
  1271. row = row.split(' ')
  1272. row[2] = 'a/123'
  1273. row[3] = 'b/456'
  1274. row = ' '.join(row)
  1275. elif 'Updated issue' in row:
  1276. row = row.split()
  1277. row[3] = '<hash>:'
  1278. row = ' '.join(row)
  1279. elif 'date_created' in row:
  1280. t = row.split(': ')[0]
  1281. row = '%s: null,' % t
  1282. elif 'closed_at' in row:
  1283. t = row.split(': ')[0]
  1284. row = '%s: null,' % t
  1285. elif 'closed_by' in row:
  1286. continue
  1287. elif row.startswith('index'):
  1288. row = 'index 458821a..77674a8'
  1289. elif row.startswith('--- a/'):
  1290. row = '--- a/123'
  1291. elif row.startswith('+++ b/'):
  1292. row = '+++ b/456'
  1293. elif 'last_updated' in row:
  1294. t = row.split(': ')[0]
  1295. row = '%s: "<date>",' % t
  1296. npatch.append(row)
  1297. commit_patch = '\n'.join(npatch)
  1298. # print commit_patch
  1299. self.assertEqual(commit_patch, exp)
  1300. def test_clean_git(self):
  1301. """ Test the clean_git method of pagure.lib.git. """
  1302. self.test_update_git()
  1303. gitpath = os.path.join(self.path, 'repos', 'tickets',
  1304. 'test_ticket_repo.git')
  1305. gitrepo = pygit2.init_repository(gitpath, bare=True)
  1306. # Get the uid of the ticket created
  1307. commit = gitrepo.revparse_single('HEAD')
  1308. patch = pagure.lib.git.commit_to_patch(gitrepo, commit)
  1309. hash_file = None
  1310. for row in patch.split('\n'):
  1311. if row.startswith('+++ b/'):
  1312. hash_file = row.split('+++ b/')[-1]
  1313. break
  1314. # The only file in git is the one of that ticket
  1315. files = [entry.name for entry in commit.tree]
  1316. self.assertEqual(files, [hash_file])
  1317. repo = pagure.lib.query.get_authorized_project(self.session, 'test_ticket_repo')
  1318. issue = pagure.lib.query.search_issues(self.session, repo, issueid=1)
  1319. pagure.lib.git.clean_git(repo, issue.repotype, issue.uid).get()
  1320. # No more files in the git repo
  1321. commit = gitrepo.revparse_single('HEAD')
  1322. files = [entry.name for entry in commit.tree]
  1323. self.assertEqual(files, [])
  1324. @patch('pagure.lib.notify.send_email')
  1325. def test_update_git_requests(self, email_f):
  1326. """ Test the update_git of pagure.lib.git for pull-requests. """
  1327. email_f.return_value = True
  1328. # Create project
  1329. item = pagure.lib.model.Project(
  1330. user_id=1, # pingou
  1331. name='test_ticket_repo',
  1332. description='test project for ticket',
  1333. hook_token='aaabbbxxx',
  1334. )
  1335. self.session.add(item)
  1336. self.session.commit()
  1337. # Create repo
  1338. self.gitrepo = os.path.join(self.path, 'repos', 'requests',
  1339. 'test_ticket_repo.git')
  1340. pygit2.init_repository(self.gitrepo, bare=True)
  1341. # Create a PR to play with
  1342. repo = pagure.lib.query.get_authorized_project(self.session, 'test_ticket_repo')
  1343. # Create an issue to play with
  1344. req = pagure.lib.query.new_pull_request(
  1345. session=self.session,
  1346. repo_from=repo,
  1347. branch_from='feature',
  1348. repo_to=repo,
  1349. branch_to='master',
  1350. title='test PR',
  1351. user='pingou',
  1352. requestuid='foobar',
  1353. requestid=None,
  1354. status='Open',
  1355. notify=True
  1356. )
  1357. self.assertEqual(req.id, 1)
  1358. self.assertEqual(req.title, 'test PR')
  1359. request = repo.requests[0]
  1360. self.assertEqual(request.title, 'test PR')
  1361. pagure.lib.git.update_git(request, request.project).get()
  1362. repo = pygit2.Repository(self.gitrepo)
  1363. commit = repo.revparse_single('HEAD')
  1364. # Use patch to validate the repo
  1365. patch = pagure.lib.git.commit_to_patch(repo, commit)
  1366. exp = r"""Mon Sep 17 00:00:00 2001
  1367. From: pagure <pagure>
  1368. Subject: Updated pull-request <hash>: test PR
  1369. ---
  1370. diff --git a/123 b/456
  1371. new file mode 100644
  1372. index 0000000..60f7480
  1373. --- /dev/null
  1374. +++ b/456
  1375. @@ -0,0 +1,144 @@
  1376. +{
  1377. + "assignee": null,
  1378. + "branch": "master",
  1379. + "branch_from": "feature",
  1380. + "cached_merge_status": "unknown",
  1381. + "closed_at": null,
  1382. + "closed_by": null,
  1383. + "comments": [],
  1384. + "commit_start": null,
  1385. + "commit_stop": null,
  1386. + "date_created": null,
  1387. + "id": 1,
  1388. + "initial_comment": null,
  1389. + "last_updated": null,
  1390. + "project": {
  1391. + "access_groups": {
  1392. + "admin": [],
  1393. + "commit": [],
  1394. + "ticket": []
  1395. + },
  1396. + "access_users": {
  1397. + "admin": [],
  1398. + "commit": [],
  1399. + "owner": [
  1400. + "pingou"
  1401. + ],
  1402. + "ticket": []
  1403. + },
  1404. + "close_status": [],
  1405. + "custom_keys": [],
  1406. + "date_created": null,
  1407. + "date_modified": null,
  1408. + "description": "test project for ticket",
  1409. + "fullname": "test_ticket_repo",
  1410. + "id": 1,
  1411. + "milestones": {},
  1412. + "name": "test_ticket_repo",
  1413. + "namespace": null,
  1414. + "parent": null,
  1415. + "priorities": {},
  1416. + "settings": {
  1417. + "Enforce_signed-off_commits_in_pull-request": false,
  1418. + "Minimum_score_to_merge_pull-request": -1,
  1419. + "Only_assignee_can_merge_pull-request": false,
  1420. + "Web-hooks": null,
  1421. + "always_merge": false,
  1422. + "disable_non_fast-forward_merges": false,
  1423. + "fedmsg_notifications": true,
  1424. + "issue_tracker": true,
  1425. + "issue_tracker_read_only": false,
  1426. + "issues_default_to_private": false,
  1427. + "notify_on_commit_flag": false,
  1428. + "notify_on_pull-request_flag": false,
  1429. + "open_metadata_access_to_all": false,
  1430. + "project_documentation": false,
  1431. + "pull_request_access_only": false,
  1432. + "pull_requests": true,
  1433. + "stomp_notifications": true
  1434. + },
  1435. + "tags": [],
  1436. + "url_path": "test_ticket_repo",
  1437. + "user": {
  1438. + "default_email": "bar@pingou.com",
  1439. + "emails": [
  1440. + "bar@pingou.com",
  1441. + "foo@pingou.com"
  1442. + ],
  1443. + "fullname": "PY C",
  1444. + "name": "pingou"
  1445. + }
  1446. + },
  1447. + "remote_git": null,
  1448. + "repo_from": {
  1449. + "access_groups": {
  1450. + "admin": [],
  1451. + "commit": [],
  1452. + "ticket": []
  1453. + },
  1454. + "access_users": {
  1455. + "admin": [],
  1456. + "commit": [],
  1457. + "owner": [
  1458. + "pingou"
  1459. + ],
  1460. + "ticket": []
  1461. + },
  1462. + "close_status": [],
  1463. + "custom_keys": [],
  1464. + "date_created": null,
  1465. + "date_modified": null,
  1466. + "description": "test project for ticket",
  1467. + "fullname": "test_ticket_repo",
  1468. + "id": 1,
  1469. + "milestones": {},
  1470. + "name": "test_ticket_repo",
  1471. + "namespace": null,
  1472. + "parent": null,
  1473. + "priorities": {},
  1474. + "settings": {
  1475. + "Enforce_signed-off_commits_in_pull-request": false,
  1476. + "Minimum_score_to_merge_pull-request": -1,
  1477. + "Only_assignee_can_merge_pull-request": false,
  1478. + "Web-hooks": null,
  1479. + "always_merge": false,
  1480. + "disable_non_fast-forward_merges": false,
  1481. + "fedmsg_notifications": true,
  1482. + "issue_tracker": true,
  1483. + "issue_tracker_read_only": false,
  1484. + "issues_default_to_private": false,
  1485. + "notify_on_commit_flag": false,
  1486. + "notify_on_pull-request_flag": false,
  1487. + "open_metadata_access_to_all": false,
  1488. + "project_documentation": false,
  1489. + "pull_request_access_only": false,
  1490. + "pull_requests": true,
  1491. + "stomp_notifications": true
  1492. + },
  1493. + "tags": [],
  1494. + "url_path": "test_ticket_repo",
  1495. + "user": {
  1496. + "default_email": "bar@pingou.com",
  1497. + "emails": [
  1498. + "bar@pingou.com",
  1499. + "foo@pingou.com"
  1500. + ],
  1501. + "fullname": "PY C",
  1502. + "name": "pingou"
  1503. + }
  1504. + },
  1505. + "status": "Open",
  1506. + "threshold_reached": null,
  1507. + "title": "test PR",
  1508. + "uid": "foobar",
  1509. + "updated_on": null,
  1510. + "user": {
  1511. + "default_email": "bar@pingou.com",
  1512. + "emails": [
  1513. + "bar@pingou.com",
  1514. + "foo@pingou.com"
  1515. + ],
  1516. + "fullname": "PY C",
  1517. + "name": "pingou"
  1518. + }
  1519. +}
  1520. \ No newline at end of file
  1521. """
  1522. npatch = []
  1523. for row in patch.split('\n'):
  1524. if row.startswith('Date:'):
  1525. continue
  1526. elif row.startswith('From '):
  1527. row = row.split(' ', 2)[2]
  1528. elif row.startswith('diff --git '):
  1529. row = row.split(' ')
  1530. row[2] = 'a/123'
  1531. row[3] = 'b/456'
  1532. row = ' '.join(row)
  1533. elif 'Updated pull-request' in row:
  1534. row = row.split()
  1535. row[3] = '<hash>:'
  1536. row = ' '.join(row)
  1537. elif 'date_created' in row:
  1538. t = row.split(': ')[0]
  1539. row = '%s: null,' % t
  1540. elif 'date_modified' in row:
  1541. t = row.split(': ')[0]
  1542. row = '%s: null,' % t
  1543. elif 'last_updated' in row:
  1544. t = row.split(': ')[0]
  1545. row = '%s: null,' % t
  1546. elif 'updated_on' in row:
  1547. t = row.split(': ')[0]
  1548. row = '%s: null,' % t
  1549. elif row.startswith('index 00'):
  1550. row = 'index 0000000..60f7480'
  1551. elif row.startswith('+++ b/'):
  1552. row = '+++ b/456'
  1553. npatch.append(row)
  1554. patch = '\n'.join(npatch)
  1555. print(patch)
  1556. self.assertEqual(patch, exp)
  1557. def test_update_ticket_from_git_no_priority(self):
  1558. """ Test the update_ticket_from_git method from pagure.lib.git. """
  1559. tests.create_projects(self.session)
  1560. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  1561. # Before
  1562. self.assertEqual(len(repo.issues), 0)
  1563. self.assertEqual(repo.issues, [])
  1564. data = {
  1565. "status": "Open", "title": "foo", "comments": [],
  1566. "content": "bar", "date_created": "1426500263",
  1567. "user": {
  1568. "name": "pingou", "emails": ["pingou@fedoraproject.org"]},
  1569. "milestone": "Next Release",
  1570. "priority": 1,
  1571. }
  1572. # Invalid project
  1573. self.assertRaises(
  1574. pagure.exceptions.PagureException,
  1575. pagure.lib.git.update_ticket_from_git,
  1576. self.session,
  1577. reponame='foobar',
  1578. namespace=None,
  1579. username=None,
  1580. issue_uid='foobar',
  1581. json_data=data,
  1582. agent='pingou',
  1583. )
  1584. # Create the issue
  1585. data = {
  1586. "status": "Open", "title": "foo", "comments": [],
  1587. "content": "bar", "date_created": "1426500263",
  1588. "user": {
  1589. "name": "pingou", "emails": ["pingou@fedoraproject.org"]},
  1590. "milestone": "Next Release",
  1591. }
  1592. pagure.lib.git.update_ticket_from_git(
  1593. self.session, reponame='test', namespace=None, username=None,
  1594. issue_uid='foobar', json_data=data, agent='pingou',
  1595. )
  1596. self.session.commit()
  1597. # Edit the issue
  1598. data = {
  1599. "status": "Open", "title": "foo", "comments": [],
  1600. "content": "bar", "date_created": "1426500263",
  1601. "user": {
  1602. "name": "pingou", "emails": ["pingou@fedoraproject.org"]},
  1603. "milestone": "Next Release",
  1604. "priority": 1,
  1605. }
  1606. pagure.lib.git.update_ticket_from_git(
  1607. self.session, reponame='test', namespace=None, username=None,
  1608. issue_uid='foobar', json_data=data, agent='pingou',
  1609. )
  1610. self.session.commit()
  1611. # Data contained a priority but not the project, so bailing
  1612. self.assertEqual(len(repo.issues), 1)
  1613. self.assertEqual(repo.issues[0].id, 1)
  1614. self.assertEqual(repo.issues[0].uid, 'foobar')
  1615. self.assertEqual(repo.issues[0].title, 'foo')
  1616. self.assertEqual(repo.issues[0].depending_text, [])
  1617. self.assertEqual(repo.issues[0].blocking_text, [])
  1618. self.assertEqual(repo.issues[0].milestone, 'Next Release')
  1619. self.assertEqual(repo.issues[0].priority, None)
  1620. self.assertEqual(
  1621. repo.milestones,
  1622. {'Next Release': {'active': True, 'date': None}})
  1623. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  1624. def test_update_ticket_from_git_close_ticket(self):
  1625. """ Test the update_ticket_from_git method from pagure.lib.git. """
  1626. tests.create_projects(self.session)
  1627. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  1628. # Before
  1629. self.assertEqual(len(repo.issues), 0)
  1630. self.assertEqual(repo.issues, [])
  1631. # Create the issue
  1632. data = {
  1633. "status": "Open",
  1634. "title": "foo",
  1635. "comments": [],
  1636. "content": "bar",
  1637. "date_created": "1426500263",
  1638. "user": {
  1639. "name": "foo",
  1640. "emails": ["foo@fedoraproject.org"]
  1641. },
  1642. "milestone": "Next Release",
  1643. }
  1644. pagure.lib.git.update_ticket_from_git(
  1645. self.session, reponame='test', namespace=None, username=None,
  1646. issue_uid='foobar', json_data=data, agent='pingou',
  1647. )
  1648. self.session.commit()
  1649. # Edit the issue
  1650. data = {
  1651. "status": "Closed",
  1652. "close_status": "Fixed",
  1653. "title": "foo",
  1654. "comments": [],
  1655. "content": "bar",
  1656. "date_created": "1426500263",
  1657. "user": {
  1658. "name": "foo",
  1659. "emails": ["foo@fedoraproject.org"]
  1660. },
  1661. "milestone": "Next Release",
  1662. }
  1663. pagure.lib.git.update_ticket_from_git(
  1664. self.session, reponame='test', namespace=None, username=None,
  1665. issue_uid='foobar', json_data=data, agent='pingou',
  1666. )
  1667. self.session.commit()
  1668. self.assertEqual(len(repo.issues), 1)
  1669. self.assertEqual(repo.issues[0].id, 1)
  1670. self.assertEqual(repo.issues[0].uid, 'foobar')
  1671. self.assertEqual(repo.issues[0].title, 'foo')
  1672. self.assertEqual(repo.issues[0].depending_text, [])
  1673. self.assertEqual(repo.issues[0].blocking_text, [])
  1674. self.assertEqual(repo.issues[0].milestone, 'Next Release')
  1675. self.assertEqual(repo.issues[0].priority, None)
  1676. self.assertEqual(
  1677. repo.milestones,
  1678. {'Next Release': {'active': True, 'date': None}})
  1679. self.assertEqual(repo.issues[0].status, 'Closed')
  1680. self.assertEqual(repo.issues[0].close_status, 'Fixed')
  1681. self.assertIsNotNone(repo.issues[0].closed_at)
  1682. self.assertEqual(
  1683. repo.issues[0].comments[-1].comment,
  1684. '**Metadata Update from @pingou**:\n'
  1685. '- Issue close_status updated to: Fixed\n'
  1686. '- Issue status updated to: Closed (was: Open)'
  1687. )
  1688. def test_update_ticket_from_git(self):
  1689. """ Test the update_ticket_from_git method from pagure.lib.git. """
  1690. tests.create_projects(self.session)
  1691. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  1692. # Set some priorities to the project
  1693. repo.priorities = {'1': 'High', '2': 'Normal'}
  1694. self.session.add(repo)
  1695. self.session.commit()
  1696. # Before
  1697. self.assertEqual(len(repo.issues), 0)
  1698. self.assertEqual(repo.issues, [])
  1699. data = {
  1700. "status": "Open", "title": "foo", "comments": [],
  1701. "content": "bar", "date_created": "1426500263",
  1702. "user": {
  1703. "name": "pingou", "emails": ["pingou@fedoraproject.org"]},
  1704. "milestone": "Next Release",
  1705. "priority": 1,
  1706. }
  1707. self.assertRaises(
  1708. pagure.exceptions.PagureException,
  1709. pagure.lib.git.update_ticket_from_git,
  1710. self.session,
  1711. reponame='foobar',
  1712. namespace=None,
  1713. username=None,
  1714. issue_uid='foobar',
  1715. json_data=data,
  1716. agent='pingou',
  1717. )
  1718. pagure.lib.git.update_ticket_from_git(
  1719. self.session, reponame='test', namespace=None, username=None,
  1720. issue_uid='foobar', json_data=data, agent='pingou',
  1721. )
  1722. self.session.commit()
  1723. # After 1 insertion
  1724. self.assertEqual(len(repo.issues), 1)
  1725. self.assertEqual(repo.issues[0].id, 1)
  1726. self.assertEqual(repo.issues[0].uid, 'foobar')
  1727. self.assertEqual(repo.issues[0].title, 'foo')
  1728. self.assertEqual(repo.issues[0].depending_text, [])
  1729. self.assertEqual(repo.issues[0].blocking_text, [])
  1730. self.assertEqual(repo.issues[0].milestone, 'Next Release')
  1731. self.assertEqual(repo.issues[0].priority, 1)
  1732. self.assertIsNone(repo.issues[0].closed_at)
  1733. self.assertEqual(
  1734. repo.milestones,
  1735. {'Next Release': {'active': True, 'date': None}})
  1736. data["title"] = "fake issue for tests"
  1737. pagure.lib.git.update_ticket_from_git(
  1738. self.session, reponame='test', namespace=None, username=None,
  1739. issue_uid='foobar', json_data=data, agent='pingou',
  1740. )
  1741. self.session.commit()
  1742. # After edit
  1743. self.assertEqual(len(repo.issues), 1)
  1744. self.assertEqual(repo.issues[0].id, 1)
  1745. self.assertEqual(repo.issues[0].uid, 'foobar')
  1746. self.assertEqual(repo.issues[0].title, 'fake issue for tests')
  1747. self.assertEqual(repo.issues[0].depending_text, [])
  1748. self.assertEqual(repo.issues[0].blocking_text, [])
  1749. self.assertEqual(repo.issues[0].priority, 1)
  1750. self.assertIsNone(repo.issues[0].closed_at)
  1751. data = {
  1752. "status": "Open", "title": "Rename pagure", "private": False,
  1753. "content": "This is too much of a conflict with the book",
  1754. "user": {
  1755. "fullname": "Pierre-YvesChibon",
  1756. "name": "pingou",
  1757. "default_email": "pingou@fedoraproject.org",
  1758. "emails": ["pingou@fedoraproject.org"]
  1759. },
  1760. "id": 20,
  1761. "blocks": [1],
  1762. "depends": [3, 4],
  1763. "date_created": "1426595224",
  1764. "milestone": "Future",
  1765. "priority": 1,
  1766. "comments": [
  1767. {
  1768. "comment": "Nirik:\r\n\r\n- sourceforge++ \r\n- "
  1769. "gitmaker\r\n- mastergit \r\n- hostomatic\r\n- "
  1770. "gitcorp\r\n- git-keiretsu \r\n- gitbuffet\r\n- "
  1771. "cogitator\r\n- cogitate\r\n\r\nrandomuser:\r\n\r\n- "
  1772. "COLLABORATRON5000\r\n- git-sm\\u00f6rg\\u00e5sbord\r\n- "
  1773. "thislittlegittywenttomarket\r\n- git-o-rama\r\n- "
  1774. "gitsundheit",
  1775. "date_created": "1426595224", "id": 250, "parent": None,
  1776. "user": {
  1777. "fullname": "Pierre-YvesChibon",
  1778. "name": "pingou",
  1779. "default_email": "pingou@fedoraproject.org",
  1780. "emails": ["pingou@fedoraproject.org"]
  1781. }
  1782. },
  1783. {
  1784. "comment": "Nirik:\r\n\r\n- sourceforge++ \r\n- "
  1785. "gitmaker\r\n- mastergit \r\n- hostomatic\r\n- "
  1786. "gitcorp\r\n- git-keiretsu \r\n- gitbuffet\r\n- "
  1787. "cogitator\r\n- cogitate\r\n\r\nrandomuser:\r\n\r\n- "
  1788. "COLLABORATRON5000\r\n- git-sm\\u00f6rg\\u00e5sbord\r\n- "
  1789. "thislittlegittywenttomarket\r\n- git-o-rama\r\n- "
  1790. "gitsundheit",
  1791. "date_created": "1426595340", "id": 324, "parent": None,
  1792. "user": {
  1793. "fullname": "Ralph Bean",
  1794. "name": "ralph",
  1795. "default_email": "ralph@fedoraproject.org",
  1796. "emails": ["ralph@fedoraproject.org"]
  1797. }
  1798. }
  1799. ]
  1800. }
  1801. pagure.lib.git.update_ticket_from_git(
  1802. self.session, reponame='test', namespace=None, username=None,
  1803. issue_uid='foobar2', json_data=data, agent='pingou',
  1804. )
  1805. # After second insertion
  1806. self.assertEqual(len(repo.issues), 2)
  1807. self.assertEqual(repo.issues[0].uid, 'foobar')
  1808. self.assertEqual(repo.issues[0].title, 'fake issue for tests')
  1809. self.assertEqual(repo.issues[0].depending_text, [20])
  1810. self.assertEqual(repo.issues[0].blocking_text, [])
  1811. self.assertIsNone(repo.issues[0].closed_at)
  1812. # New one
  1813. self.assertEqual(repo.issues[1].uid, 'foobar2')
  1814. self.assertEqual(repo.issues[1].title, 'Rename pagure')
  1815. self.assertEqual(repo.issues[1].depending_text, [])
  1816. self.assertEqual(repo.issues[1].blocking_text, [1])
  1817. self.assertEqual(repo.issues[1].milestone, 'Future')
  1818. self.assertIsNone(repo.issues[1].closed_at)
  1819. self.assertDictEqual(
  1820. repo.milestones,
  1821. {
  1822. 'Future': {'active': True, 'date': None},
  1823. 'Next Release': {'active': True, 'date': None}
  1824. }
  1825. )
  1826. def test_update_request_from_git(self):
  1827. """ Test the update_request_from_git method from pagure.lib.git. """
  1828. tests.create_projects(self.session)
  1829. tests.create_projects_git(os.path.join(self.path, 'repos'))
  1830. repo = pagure.lib.query._get_project(self.session, 'test')
  1831. namespaced_repo = pagure.lib.query._get_project(self.session, 'test3', namespace='somenamespace')
  1832. # Before
  1833. self.assertEqual(len(repo.requests), 0)
  1834. self.assertEqual(repo.requests, [])
  1835. self.assertEqual(len(namespaced_repo.requests), 0)
  1836. self.assertEqual(namespaced_repo.requests, [])
  1837. data = {
  1838. "status": True,
  1839. "uid": "d4182a2ac2d541d884742d3037c26e56",
  1840. "project": {
  1841. "custom_keys": [],
  1842. "parent": None,
  1843. "settings": {
  1844. "issue_tracker": True,
  1845. "project_documentation": True,
  1846. "pull_requests": True,
  1847. },
  1848. "name": "test",
  1849. "date_created": "1426500194",
  1850. "tags": [],
  1851. "user": {
  1852. "fullname": "Pierre-YvesChibon",
  1853. "name": "pingou",
  1854. "default_email": "pingou@fedoraproject.org",
  1855. "emails": [
  1856. "pingou@fedoraproject.org"
  1857. ]
  1858. },
  1859. "id": 1,
  1860. "description": "test project"
  1861. },
  1862. "commit_stop": "eface8e13bc2a08a3fb22af9a72a8c90e36b8b89",
  1863. "user": {
  1864. "fullname": "Pierre-YvesChibon",
  1865. "name": "pingou",
  1866. "default_email": "pingou@fedoraproject.org",
  1867. "emails": ["pingou@fedoraproject.org"]
  1868. },
  1869. "id": 7,
  1870. "comments": [
  1871. {
  1872. "comment": "really?",
  1873. "user": {
  1874. "fullname": "Pierre-YvesChibon",
  1875. "name": "pingou",
  1876. "default_email": "pingou@fedoraproject.org",
  1877. "emails": ["pingou@fedoraproject.org"]
  1878. },
  1879. "parent": None,
  1880. "date_created": "1426843778",
  1881. "commit": "fa72f315373ec5f98f2b08c8ffae3645c97aaad2",
  1882. "line": 5,
  1883. "id": 1,
  1884. "filename": "test"
  1885. },
  1886. {
  1887. "comment": "Again ?",
  1888. "user": {
  1889. "fullname": "Pierre-YvesChibon",
  1890. "name": "pingou",
  1891. "default_email": "pingou@fedoraproject.org",
  1892. "emails": [
  1893. "pingou@fedoraproject.org"
  1894. ]
  1895. },
  1896. "parent": None,
  1897. "date_created": "1426866781",
  1898. "commit": "94ebaf900161394059478fd88aec30e59092a1d7",
  1899. "line": 5,
  1900. "id": 2,
  1901. "filename": "test2"
  1902. },
  1903. {
  1904. "comment": "Should be fine in fact",
  1905. "user": {
  1906. "fullname": "Pierre-YvesChibon",
  1907. "name": "pingou",
  1908. "default_email": "pingou@fedoraproject.org",
  1909. "emails": [
  1910. "pingou@fedoraproject.org"
  1911. ]
  1912. },
  1913. "parent": None,
  1914. "date_created": "1426866950",
  1915. "commit": "94ebaf900161394059478fd88aec30e59092a1d7",
  1916. "line": 5,
  1917. "id": 3,
  1918. "filename": "test2"
  1919. }
  1920. ],
  1921. "branch_from": "master",
  1922. "title": "test request",
  1923. "commit_start": "788efeaaf86bde8618f594a8181abb402e1dd904",
  1924. "repo_from": {
  1925. "parent": {
  1926. "custom_keys": [],
  1927. "parent": None,
  1928. "name": "test",
  1929. "date_created": "1426500194",
  1930. "tags": [],
  1931. "user": {
  1932. "fullname": "Pierre-YvesChibon",
  1933. "name": "pingou",
  1934. "default_email": "pingou@fedoraproject.org",
  1935. "emails": [
  1936. "pingou@fedoraproject.org"
  1937. ]
  1938. },
  1939. "settings": {
  1940. "issue_tracker": True,
  1941. "project_documentation": True,
  1942. "pull_requests": True,
  1943. },
  1944. "id": 1,
  1945. "description": "test project"
  1946. },
  1947. "settings": {
  1948. "issue_tracker": True,
  1949. "project_documentation": True,
  1950. "pull_requests": True,
  1951. },
  1952. "name": "test",
  1953. "date_created": "1426843440",
  1954. "custom_keys": [],
  1955. "tags": [],
  1956. "user": {
  1957. "fullname": "fake user",
  1958. "name": "fake",
  1959. "default_email": "fake@fedoraproject.org",
  1960. "emails": [
  1961. "fake@fedoraproject.org"
  1962. ]
  1963. },
  1964. "id": 6,
  1965. "description": "test project"
  1966. },
  1967. "branch": "master",
  1968. "date_created": "1426843732"
  1969. }
  1970. self.assertRaises(
  1971. pagure.exceptions.PagureException,
  1972. pagure.lib.git.update_request_from_git,
  1973. self.session,
  1974. reponame='foobar',
  1975. namespace=None,
  1976. username=None,
  1977. request_uid='d4182a2ac2d541d884742d3037c26e56',
  1978. json_data=data,
  1979. )
  1980. pagure.lib.git.update_request_from_git(
  1981. self.session,
  1982. reponame='test',
  1983. namespace=None,
  1984. username=None,
  1985. request_uid='d4182a2ac2d541d884742d3037c26e56',
  1986. json_data=data,
  1987. )
  1988. self.session.commit()
  1989. # After 1 st insertion
  1990. self.assertEqual(len(repo.requests), 1)
  1991. self.assertEqual(repo.requests[0].id, 7)
  1992. self.assertEqual(
  1993. repo.requests[0].uid, 'd4182a2ac2d541d884742d3037c26e56')
  1994. self.assertEqual(repo.requests[0].title, 'test request')
  1995. self.assertEqual(len(repo.requests[0].comments), 3)
  1996. data = {
  1997. "status": True,
  1998. "uid": "d4182a2ac2d541d884742d3037c26e57",
  1999. "project": {
  2000. "parent": None,
  2001. "name": "test",
  2002. "custom_keys": [],
  2003. "date_created": "1426500194",
  2004. "tags": [],
  2005. "user": {
  2006. "fullname": "Pierre-YvesChibon",
  2007. "name": "pingou",
  2008. "default_email": "pingou@fedoraproject.org",
  2009. "emails": [
  2010. "pingou@fedoraproject.org"
  2011. ]
  2012. },
  2013. "settings": {
  2014. "issue_tracker": True,
  2015. "project_documentation": True,
  2016. "pull_requests": True,
  2017. },
  2018. "id": 1,
  2019. "description": "test project"
  2020. },
  2021. "commit_stop": "eface8e13bc2a08a3fb22af9a72a8c90e36b8b89",
  2022. "user": {
  2023. "fullname": "Pierre-YvesChibon",
  2024. "name": "pingou",
  2025. "default_email": "pingou@fedoraproject.org",
  2026. "emails": ["pingou@fedoraproject.org"]
  2027. },
  2028. "id": 4,
  2029. "comments": [],
  2030. "branch_from": "master",
  2031. "title": "test request #2",
  2032. "commit_start": "788efeaaf86bde8618f594a8181abb402e1dd904",
  2033. "repo_from": {
  2034. "parent": {
  2035. "parent": None,
  2036. "name": "test",
  2037. "custom_keys": [],
  2038. "date_created": "1426500194",
  2039. "tags": [],
  2040. "user": {
  2041. "fullname": "Pierre-YvesChibon",
  2042. "name": "pingou",
  2043. "default_email": "pingou@fedoraproject.org",
  2044. "emails": [
  2045. "pingou@fedoraproject.org"
  2046. ]
  2047. },
  2048. "settings": {
  2049. "issue_tracker": True,
  2050. "project_documentation": True,
  2051. "pull_requests": True,
  2052. },
  2053. "id": 1,
  2054. "description": "test project"
  2055. },
  2056. "settings": {
  2057. "issue_tracker": True,
  2058. "project_documentation": True,
  2059. "pull_requests": True,
  2060. },
  2061. "name": "test",
  2062. "date_created": "1426843440",
  2063. "custom_keys": [],
  2064. "tags": [],
  2065. "user": {
  2066. "fullname": "fake user",
  2067. "name": "fake",
  2068. "default_email": "fake@fedoraproject.org",
  2069. "emails": [
  2070. "fake@fedoraproject.org"
  2071. ]
  2072. },
  2073. "project_docs": True,
  2074. "id": 6,
  2075. "description": "test project"
  2076. },
  2077. "branch": "master",
  2078. "date_created": "1426843745"
  2079. }
  2080. pagure.lib.git.update_request_from_git(
  2081. self.session,
  2082. reponame='test',
  2083. namespace=None,
  2084. username=None,
  2085. request_uid='d4182a2ac2d541d884742d3037c26e57',
  2086. json_data=data,
  2087. )
  2088. self.session.commit()
  2089. # After 2 nd insertion
  2090. self.assertEqual(len(repo.requests), 2)
  2091. self.assertEqual(repo.requests[0].id, 7)
  2092. self.assertEqual(
  2093. repo.requests[0].uid, 'd4182a2ac2d541d884742d3037c26e56')
  2094. self.assertEqual(repo.requests[0].title, 'test request')
  2095. self.assertEqual(len(repo.requests[0].comments), 3)
  2096. # 2 entry
  2097. self.assertEqual(repo.requests[1].id, 4)
  2098. self.assertEqual(
  2099. repo.requests[1].uid, 'd4182a2ac2d541d884742d3037c26e57')
  2100. self.assertEqual(repo.requests[1].title, 'test request #2')
  2101. self.assertEqual(len(repo.requests[1].comments), 0)
  2102. data = {
  2103. "status": True,
  2104. "uid": "d4182a2ac2d541d884742d3037c26e58",
  2105. "project": {
  2106. "parent": None,
  2107. "name": "test3",
  2108. "custom_keys": [],
  2109. "namespace": "somenamespace",
  2110. "date_created": "1426500194",
  2111. "tags": [],
  2112. "user": {
  2113. "fullname": "Pierre-YvesChibon",
  2114. "name": "pingou",
  2115. "default_email": "pingou@fedoraproject.org",
  2116. "emails": [
  2117. "pingou@fedoraproject.org"
  2118. ]
  2119. },
  2120. "settings": {
  2121. "issue_tracker": True,
  2122. "project_documentation": True,
  2123. "pull_requests": True,
  2124. },
  2125. "id": 3,
  2126. "description": "namespaced test project"
  2127. },
  2128. "commit_stop": "eface8e13bc2a08a3fb22af9a72a8c90e36b8b89",
  2129. "user": {
  2130. "fullname": "Pierre-YvesChibon",
  2131. "name": "pingou",
  2132. "default_email": "pingou@fedoraproject.org",
  2133. "emails": ["pingou@fedoraproject.org"]
  2134. },
  2135. "id": 5,
  2136. "comments": [],
  2137. "branch_from": "master",
  2138. "title": "test request to namespaced repo",
  2139. "commit_start": "788efeaaf86bde8618f594a8181abb402e1dd904",
  2140. "repo_from": {
  2141. "parent": {
  2142. "parent": None,
  2143. "name": "test",
  2144. "custom_keys": [],
  2145. "date_created": "1426500194",
  2146. "tags": [],
  2147. "user": {
  2148. "fullname": "Pierre-YvesChibon",
  2149. "name": "pingou",
  2150. "default_email": "pingou@fedoraproject.org",
  2151. "emails": [
  2152. "pingou@fedoraproject.org"
  2153. ]
  2154. },
  2155. "settings": {
  2156. "issue_tracker": True,
  2157. "project_documentation": True,
  2158. "pull_requests": True,
  2159. },
  2160. "id": 1,
  2161. "description": "test project"
  2162. },
  2163. "settings": {
  2164. "issue_tracker": True,
  2165. "project_documentation": True,
  2166. "pull_requests": True,
  2167. },
  2168. "name": "test",
  2169. "date_created": "1426843440",
  2170. "custom_keys": [],
  2171. "tags": [],
  2172. "user": {
  2173. "fullname": "fake user",
  2174. "name": "fake",
  2175. "default_email": "fake@fedoraproject.org",
  2176. "emails": [
  2177. "fake@fedoraproject.org"
  2178. ]
  2179. },
  2180. "project_docs": True,
  2181. "id": 6,
  2182. "description": "test project"
  2183. },
  2184. "branch": "master",
  2185. "date_created": "1426843745"
  2186. }
  2187. pagure.lib.git.update_request_from_git(
  2188. self.session,
  2189. reponame='test3',
  2190. namespace='somenamespace',
  2191. username=None,
  2192. request_uid='d4182a2ac2d541d884742d3037c26e58',
  2193. json_data=data,
  2194. )
  2195. self.session.commit()
  2196. self.assertEqual(len(namespaced_repo.requests), 1)
  2197. self.assertEqual(namespaced_repo.requests[0].id, 5)
  2198. self.assertEqual(
  2199. namespaced_repo.requests[0].uid,
  2200. 'd4182a2ac2d541d884742d3037c26e58'
  2201. )
  2202. self.assertEqual(
  2203. namespaced_repo.requests[0].title,
  2204. 'test request to namespaced repo'
  2205. )
  2206. def test_read_git_lines(self):
  2207. """ Test the read_git_lines method of pagure.lib.git. """
  2208. self.test_update_git()
  2209. gitrepo = os.path.join(self.path, 'repos', 'tickets', 'test_ticket_repo.git')
  2210. output = pagure.lib.git.read_git_lines(
  2211. ['log', '-1', "--pretty='%s'"], gitrepo)
  2212. self.assertEqual(len(output), 1)
  2213. self.assertTrue(
  2214. output[0].startswith("'Updated issue ")
  2215. )
  2216. self.assertTrue(
  2217. output[0].endswith(": Test issue'")
  2218. )
  2219. # Keeping the new line symbol
  2220. output = pagure.lib.git.read_git_lines(
  2221. ['log', '-1', "--pretty='%s'"], gitrepo, keepends=True)
  2222. self.assertEqual(len(output), 1)
  2223. self.assertTrue(
  2224. output[0].endswith(": Test issue'\n")
  2225. )
  2226. def test_get_revs_between(self):
  2227. """ Test the get_revs_between method of pagure.lib.git. """
  2228. self.test_update_git()
  2229. gitrepo = os.path.join(self.path, 'repos', 'tickets', 'test_ticket_repo.git')
  2230. output = pagure.lib.git.read_git_lines(
  2231. ['log', '-3', "--pretty='%H'"], gitrepo)
  2232. self.assertEqual(len(output), 2)
  2233. from_hash = output[1].replace("'", '')
  2234. # Case 1, repo BASE is null and HEAD is equal to from_hash
  2235. to_hash = '0'
  2236. output1 = pagure.lib.git.get_revs_between(
  2237. to_hash, from_hash, gitrepo, 'refs/heads/master')
  2238. self.assertEqual(output1, [from_hash])
  2239. # Case 2, get revs between two commits (to_hash, from_hash)
  2240. to_hash = output[0].replace("'", '')
  2241. output2 = pagure.lib.git.get_revs_between(
  2242. to_hash, from_hash, gitrepo, 'refs/heads/master')
  2243. self.assertEqual(output2, [to_hash])
  2244. # Case 3, get revs between two commits (from_hash, to_hash)
  2245. output3 = pagure.lib.git.get_revs_between(
  2246. from_hash, to_hash, gitrepo, 'refs/heads/master')
  2247. self.assertEqual(output3, [to_hash])
  2248. # Case 4, get revs between two commits on two different branches
  2249. newgitrepo = tempfile.mkdtemp(prefix='pagure-')
  2250. newrepo = pygit2.clone_repository(gitrepo, newgitrepo)
  2251. newrepo.create_branch('feature', newrepo.head.get_object())
  2252. with open(os.path.join(newgitrepo, 'sources'), 'w') as stream:
  2253. stream.write('foo\n bar')
  2254. newrepo.index.add('sources')
  2255. newrepo.index.write()
  2256. # Commits the files added
  2257. tree = newrepo.index.write_tree()
  2258. author = pygit2.Signature(
  2259. 'Alice Author', 'alice@authors.tld')
  2260. committer = pygit2.Signature(
  2261. 'Cecil Committer', 'cecil@committers.tld')
  2262. newrepo.create_commit(
  2263. 'refs/heads/feature', # the name of the reference to update
  2264. author,
  2265. committer,
  2266. 'Add sources file for testing',
  2267. # binary string representing the tree object ID
  2268. tree,
  2269. # list of binary strings representing parents of the new commit
  2270. [to_hash]
  2271. )
  2272. branch_commit = newrepo.revparse_single('refs/heads/feature')
  2273. # Push to origin
  2274. ori_remote = newrepo.remotes[0]
  2275. PagureRepo.push(ori_remote, 'refs/heads/feature')
  2276. # Remove the clone
  2277. shutil.rmtree(newgitrepo)
  2278. output4 = pagure.lib.git.get_revs_between(
  2279. '0', branch_commit.oid.hex, gitrepo, 'refs/heads/feature')
  2280. self.assertEqual(output4, [branch_commit.oid.hex])
  2281. def test_get_author(self):
  2282. """ Test the get_author method of pagure.lib.git. """
  2283. self.test_update_git()
  2284. gitrepo = os.path.join(self.path, 'repos', 'tickets', 'test_ticket_repo.git')
  2285. output = pagure.lib.git.read_git_lines(
  2286. ['log', '-3', "--pretty='%H'"], gitrepo)
  2287. self.assertEqual(len(output), 2)
  2288. for githash in output:
  2289. githash = githash.replace("'", '')
  2290. output = pagure.lib.git.get_author(githash, gitrepo)
  2291. self.assertEqual(output, 'pagure')
  2292. def get_author_email(self):
  2293. """ Test the get_author_email method of pagure.lib.git. """
  2294. self.test_update_git()
  2295. gitrepo = os.path.join(self.path, 'tickets', 'test_ticket_repo.git')
  2296. output = pagure.lib.git.read_git_lines(
  2297. ['log', '-3', "--pretty='%H'"], gitrepo)
  2298. self.assertEqual(len(output), 2)
  2299. for githash in output:
  2300. githash = githash.replace("'", '')
  2301. output = pagure.lib.git.get_author_email(githash, gitrepo)
  2302. self.assertEqual(output, 'pagure')
  2303. def test_get_repo_name(self):
  2304. """ Test the get_repo_name method of pagure.lib.git. """
  2305. def runtest(reponame, *path):
  2306. gitrepo = os.path.join(self.path, 'repos', *path)
  2307. os.makedirs(gitrepo)
  2308. repo_name = pagure.lib.git.get_repo_name(gitrepo)
  2309. self.assertEqual(repo_name, reponame)
  2310. runtest('test_ticket_repo', 'tickets', 'test_ticket_repo.git')
  2311. runtest('test', 'test.git')
  2312. runtest('foo.test', 'foo.test.git')
  2313. def test_get_username(self):
  2314. """ Test the get_username method of pagure.lib.git. """
  2315. def runtest(username, *path):
  2316. gitrepo = os.path.join(self.path, 'repos', *path)
  2317. os.makedirs(gitrepo)
  2318. repo_username = pagure.lib.git.get_username(gitrepo)
  2319. self.assertEqual(repo_username, username)
  2320. runtest(None, 'tickets', 'test_ticket_repo.git')
  2321. runtest(None, 'test.git')
  2322. runtest(None, 'foo.test.git')
  2323. runtest('pingou', 'forks', 'pingou', 'foo.test.git')
  2324. runtest('pingou', 'forks', 'pingou', 'bar/foo.test.git')
  2325. def test_get_repo_namespace(self):
  2326. """ Test the get_repo_namespace method of pagure.lib.git. """
  2327. def runtest(namespace, *path):
  2328. gitrepo = os.path.join(self.path, 'repos', *path)
  2329. if not os.path.exists(gitrepo):
  2330. os.makedirs(gitrepo)
  2331. repo_namespace = pagure.lib.git.get_repo_namespace(gitrepo)
  2332. self.assertEqual(repo_namespace, namespace)
  2333. runtest(None, 'test_ticket_repo.git')
  2334. runtest('foo/bar/baz', 'foo', 'bar', 'baz', 'test.git')
  2335. runtest(None, 'foo.test.git')
  2336. runtest(None, 'forks', 'user', 'foo.test.git')
  2337. runtest('bar', 'forks', 'user', 'bar', 'foo.test.git')
  2338. runtest('ns/bar', 'forks', 'user', 'ns', 'bar', 'foo.test.git')
  2339. runtest('bar', 'forks', 'user', 'bar', 'foo.test.git')
  2340. def test_update_custom_fields_from_json(self):
  2341. """ Test the update_custom_fields_from_json method of lib.git """
  2342. tests.create_projects(self.session)
  2343. repo = pagure.lib.query._get_project(self.session, 'test')
  2344. # Create issues to play with
  2345. pagure.lib.query.new_issue(
  2346. session=self.session,
  2347. repo=repo,
  2348. title='Test issue',
  2349. content='We should work on this',
  2350. user='pingou',
  2351. issue_uid='someuid'
  2352. )
  2353. self.session.commit()
  2354. issue = pagure.lib.query.get_issue_by_uid(self.session, 'someuid')
  2355. # Fake json data, currently without custom_fields
  2356. # This should bring no new custom_fields to the issue
  2357. json_data = {
  2358. "status": "Open",
  2359. "title": "Test issue",
  2360. "private": False,
  2361. "content": "We should work on this",
  2362. "user": {
  2363. "fullname": "PY C",
  2364. "name": "pingou",
  2365. "default_email": "bar@pingou.com",
  2366. "emails": ["bar@pingou.com"]
  2367. },
  2368. "id": 1,
  2369. "blocks": [],
  2370. "depends": [],
  2371. "date_created": "1234567",
  2372. "comments": [],
  2373. }
  2374. pagure.lib.git.update_custom_field_from_json(
  2375. self.session, repo, issue, json_data)
  2376. updated_issue = pagure.lib.query.get_issue_by_uid(self.session, 'someuid')
  2377. self.assertEqual(updated_issue.to_json().get('custom_fields'), [])
  2378. custom_fields = [
  2379. {
  2380. "name": "custom1",
  2381. "key_type": "text",
  2382. "value": "value1",
  2383. "key_data": None,
  2384. },
  2385. {
  2386. "name": "custom2",
  2387. "key_type": "text",
  2388. "value": "value2",
  2389. "key_data": None,
  2390. }
  2391. ]
  2392. # Again, Fake the json data but, with custom_fields in it
  2393. # The updated issue should have the custom_fields as
  2394. # was in the json_data
  2395. json_data = {
  2396. "status": "Open",
  2397. "title": "Test issue",
  2398. "private": False,
  2399. "content": "We should work on this",
  2400. "user": {
  2401. "fullname": "PY C",
  2402. "name": "pingou",
  2403. "default_email": "bar@pingou.com",
  2404. "emails": ["bar@pingou.com"]
  2405. },
  2406. "id": 1,
  2407. "blocks": [],
  2408. "depends": [],
  2409. "date_created": "1234567",
  2410. "comments": [],
  2411. "custom_fields": custom_fields,
  2412. }
  2413. pagure.lib.git.update_custom_field_from_json(
  2414. self.session, repo, issue, json_data)
  2415. updated_issue = pagure.lib.query.get_issue_by_uid(self.session, 'someuid')
  2416. custom_fields_of_issue = updated_issue.to_json().get('custom_fields')
  2417. self.assertEqual(custom_fields_of_issue, custom_fields)
  2418. @patch('pagure.lib.notify.send_email')
  2419. @patch('pagure.lib.git.update_git')
  2420. def test_merge_pull_request_no_master(self, email_f, up_git):
  2421. """ Test the merge_pull_request function when there are no master
  2422. branch in the repo. """
  2423. email_f.return_value = True
  2424. up_git.return_value = True
  2425. gitfolder = os.path.join(self.path, 'repos')
  2426. docfolder = os.path.join(self.path, 'docs')
  2427. ticketfolder = os.path.join(self.path, 'tickets')
  2428. requestfolder = os.path.join(self.path, 'requests')
  2429. # Create project
  2430. item = pagure.lib.model.Project(
  2431. user_id=1, # pingou
  2432. name='test',
  2433. description='test project',
  2434. hook_token='aaabbbwww',
  2435. )
  2436. self.session.add(item)
  2437. self.session.commit()
  2438. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  2439. gitrepo = os.path.join(gitfolder, repo.path)
  2440. docrepo = os.path.join(docfolder, repo.path)
  2441. ticketrepo = os.path.join(ticketfolder, repo.path)
  2442. requestrepo = os.path.join(requestfolder, repo.path)
  2443. os.makedirs(os.path.join(self.path, 'repos', 'forks', 'foo'))
  2444. self.gitrepo = os.path.join(self.path, 'repos', 'test.git')
  2445. os.makedirs(self.gitrepo)
  2446. repo_obj = pygit2.init_repository(self.gitrepo, bare=True)
  2447. # Fork the project
  2448. task = pagure.lib.query.fork_project(
  2449. session=self.session,
  2450. user='foo',
  2451. repo=repo,
  2452. )
  2453. self.session.commit()
  2454. self.assertEqual(task.get(),
  2455. {'endpoint': 'ui_ns.view_repo',
  2456. 'repo': 'test',
  2457. 'username': 'foo',
  2458. 'namespace': None})
  2459. # Create repo, with some content
  2460. self.gitrepo = os.path.join(
  2461. self.path, 'repos', 'forks', 'foo', 'test.git')
  2462. tests.add_content_git_repo(self.gitrepo, branch='feature')
  2463. fork_repo = pagure.lib.query.get_authorized_project(self.session, 'test', user='foo')
  2464. # Create a PR to play with
  2465. req = pagure.lib.query.new_pull_request(
  2466. session=self.session,
  2467. repo_from=fork_repo,
  2468. branch_from='feature',
  2469. repo_to=repo,
  2470. branch_to='master',
  2471. title='test PR',
  2472. user='pingou',
  2473. requestuid='foobar',
  2474. requestid=None,
  2475. status='Open',
  2476. notify=True
  2477. )
  2478. self.assertEqual(req.id, 1)
  2479. self.assertEqual(req.title, 'test PR')
  2480. # `master` branch not found
  2481. msg = pagure.lib.git.merge_pull_request(
  2482. self.session,
  2483. request=req,
  2484. username='pingou',
  2485. domerge=False
  2486. )
  2487. self.assertEqual(msg, 'FFORWARD')
  2488. @patch('pagure.lib.notify.send_email')
  2489. @patch('pagure.lib.git.update_git')
  2490. def test_merge_pull_request_closed(self, email_f, up_git):
  2491. """ Test the merge_pull_request function when the PR was already
  2492. closed/merged. """
  2493. email_f.return_value = True
  2494. up_git.return_value = True
  2495. gitfolder = os.path.join(self.path, 'repos')
  2496. docfolder = os.path.join(self.path, 'docs')
  2497. ticketfolder = os.path.join(self.path, 'tickets')
  2498. requestfolder = os.path.join(self.path, 'requests')
  2499. # Create project
  2500. item = pagure.lib.model.Project(
  2501. user_id=1, # pingou
  2502. name='test',
  2503. description='test project',
  2504. hook_token='aaabbbwww',
  2505. )
  2506. self.session.add(item)
  2507. self.session.commit()
  2508. repo = pagure.lib.query.get_authorized_project(self.session, 'test')
  2509. os.makedirs(os.path.join(self.path, 'repos', 'forks', 'foo'))
  2510. self.gitrepo = os.path.join(self.path, 'repos', 'test.git')
  2511. os.makedirs(self.gitrepo)
  2512. repo_obj = pygit2.init_repository(self.gitrepo, bare=True)
  2513. tests.add_content_git_repo(self.gitrepo, branch='master')
  2514. # Fork the project
  2515. task = pagure.lib.query.fork_project(
  2516. session=self.session,
  2517. user='foo',
  2518. repo=repo,
  2519. )
  2520. self.session.commit()
  2521. self.assertEqual(task.get(),
  2522. {'endpoint': 'ui_ns.view_repo',
  2523. 'repo': 'test',
  2524. 'username': 'foo',
  2525. 'namespace': None})
  2526. # Create repo, with some content
  2527. self.gitrepo = os.path.join(
  2528. self.path, 'repos', 'forks', 'foo', 'test.git')
  2529. tests.add_content_git_repo(self.gitrepo, branch='feature')
  2530. fork_repo = pagure.lib.query.get_authorized_project(self.session, 'test', user='foo')
  2531. # Create a PR to play with
  2532. req = pagure.lib.query.new_pull_request(
  2533. session=self.session,
  2534. repo_from=fork_repo,
  2535. branch_from='feature',
  2536. repo_to=repo,
  2537. branch_to='master',
  2538. title='test PR',
  2539. user='pingou',
  2540. requestuid='foobar',
  2541. requestid=None,
  2542. status='Open',
  2543. notify=True
  2544. )
  2545. self.assertEqual(req.id, 1)
  2546. self.assertEqual(req.title, 'test PR')
  2547. # Close the PR before we ask to merge it
  2548. req.status = 'Closed'
  2549. req.closed_by_id = 2 # id:2 == foo
  2550. req.closed_at = datetime.datetime(2017, 10, 20, 12, 32, 10)
  2551. self.session.add(req)
  2552. self.session.commit()
  2553. # PR already closed
  2554. six.assertRaisesRegex(
  2555. self,
  2556. pagure.exceptions.PagureException,
  2557. 'This pull-request was merged or closed by foo',
  2558. pagure.lib.git.merge_pull_request,
  2559. self.session,
  2560. request=req,
  2561. username='pingou',
  2562. domerge=False
  2563. )
  2564. @patch('subprocess.Popen')
  2565. def test_generate_gitolite_acls(self, popen):
  2566. """ Test calling generate_gitolite_acls. """
  2567. pagure.SESSION = self.session
  2568. pagure.lib.git.SESSION = self.session
  2569. pagure.config.config['GITOLITE_HOME'] = '/tmp'
  2570. proc = MagicMock()
  2571. proc.communicate.return_value = (1, 2)
  2572. proc.returncode = 0
  2573. popen.return_value = proc
  2574. helper = pagure.lib.git_auth.get_git_auth_helper('gitolite3')
  2575. helper.generate_acls(project=None)
  2576. popen.assert_called_with(
  2577. 'HOME=/tmp gitolite compile && '
  2578. 'HOME=/tmp gitolite trigger POST_COMPILE',
  2579. cwd='/tmp', shell=True, stderr=-1, stdout=-1
  2580. )
  2581. def test_is_forced_push_new_branch(self):
  2582. self.assertFalse(
  2583. pagure.lib.git.is_forced_push(
  2584. '0000000000000000000000000000000000000000',
  2585. '^0e6e0b6c931d65ee22f67205a53933d841c6eeff',
  2586. 'path/is/not/important'
  2587. )
  2588. )
  2589. @patch("pagure.utils.get_repo_path")
  2590. def test_update_pull_ref(self, get_repo_path):
  2591. fake_pr = MagicMock()
  2592. fake_pr.uid = "1234567"
  2593. fake_pr.branch_from = "master"
  2594. fake_pr.id = 6
  2595. fake_pr.user = MagicMock()
  2596. fake_pr.user.user = "pingou"
  2597. fake_pr.project = "doesnt_matter_mocked_out"
  2598. projects = tests.create_projects_git(
  2599. os.path.join(self.path, "repos"),
  2600. bare=True
  2601. )
  2602. tests.add_content_git_repo(projects[0])
  2603. tests.add_content_git_repo(projects[1])
  2604. orig = pygit2.Repository(projects[0])
  2605. fork = pygit2.Repository(projects[1])
  2606. get_repo_path.return_value = projects[0]
  2607. # make sure that creating works the first time
  2608. pagure.lib.git.update_pull_ref(fake_pr, fork)
  2609. oldhex = fork.references["refs/heads/master"].get_object().hex
  2610. self.assertEqual(
  2611. orig.references["refs/pull/6/head"].get_object().hex,
  2612. oldhex,
  2613. )
  2614. # make sure that updating works correctly
  2615. tests.add_content_git_repo(projects[1], append="foobar")
  2616. newhex = fork.references["refs/heads/master"].get_object().hex
  2617. self.assertNotEqual(oldhex, newhex)
  2618. pagure.lib.git.update_pull_ref(fake_pr, fork)
  2619. self.assertEqual(
  2620. orig.references["refs/pull/6/head"].get_object().hex,
  2621. newhex,
  2622. )
  2623. # make sure the function works fine even if there's a leftover
  2624. # ref from previous failed run of the function
  2625. with patch("pygit2.remote.RemoteCollection.delete"):
  2626. pagure.lib.git.update_pull_ref(fake_pr, fork)
  2627. self.assertIsNotNone(fork.remotes["pingou_1234567"])
  2628. tests.add_content_git_repo(projects[1], append="foobarbaz")
  2629. newesthex = fork.references["refs/heads/master"].get_object().hex
  2630. self.assertNotEqual(newhex, newesthex)
  2631. pagure.lib.git.update_pull_ref(fake_pr, fork)
  2632. self.assertEqual(
  2633. orig.references["refs/pull/6/head"].get_object().hex,
  2634. newesthex,
  2635. )
  2636. class PagureLibGitCommitToPatchtests(tests.Modeltests):
  2637. """ Tests for pagure.lib.git """
  2638. maxDiff = None
  2639. def setUp(self):
  2640. """ Set up the environment for the tests. """
  2641. super(PagureLibGitCommitToPatchtests, self).setUp()
  2642. # Create a git repo to play with
  2643. self.gitrepo = os.path.join(self.path, 'repos', 'test_repo.git')
  2644. os.makedirs(self.gitrepo)
  2645. repo = pygit2.init_repository(self.gitrepo)
  2646. # Create a file in that git repo
  2647. with open(os.path.join(self.gitrepo, 'sources'), 'w') as stream:
  2648. stream.write('foo\n bar')
  2649. repo.index.add('sources')
  2650. repo.index.write()
  2651. # Commits the files added
  2652. tree = repo.index.write_tree()
  2653. author = pygit2.Signature(
  2654. 'Alice Author', 'alice@authors.tld')
  2655. committer = pygit2.Signature(
  2656. 'Cecil Committer', 'cecil@committers.tld')
  2657. repo.create_commit(
  2658. 'refs/heads/master', # the name of the reference to update
  2659. author,
  2660. committer,
  2661. 'Add sources file for testing',
  2662. # binary string representing the tree object ID
  2663. tree,
  2664. # list of binary strings representing parents of the new commit
  2665. []
  2666. )
  2667. self.first_commit = repo.revparse_single('HEAD')
  2668. # Edit the sources file again
  2669. with open(os.path.join(self.gitrepo, 'sources'), 'w') as stream:
  2670. stream.write('foo\n bar\nbaz\n boose')
  2671. repo.index.add('sources')
  2672. repo.index.write()
  2673. # Commits the files added
  2674. tree = repo.index.write_tree()
  2675. author = pygit2.Signature(
  2676. 'Alice Author', 'alice@authors.tld')
  2677. committer = pygit2.Signature(
  2678. 'Cecil Committer', 'cecil@committers.tld')
  2679. repo.create_commit(
  2680. 'refs/heads/master', # the name of the reference to update
  2681. author,
  2682. committer,
  2683. 'Add baz and boose to the sources\n\n There are more objects to '
  2684. 'consider',
  2685. # binary string representing the tree object ID
  2686. tree,
  2687. # list of binary strings representing parents of the new commit
  2688. [self.first_commit.oid.hex]
  2689. )
  2690. self.second_commit = repo.revparse_single('HEAD')
  2691. def test_commit_to_patch_first_commit(self):
  2692. """ Test the commit_to_patch function of pagure.lib.git. """
  2693. repo = pygit2.init_repository(self.gitrepo)
  2694. patch = pagure.lib.git.commit_to_patch(repo, self.first_commit)
  2695. exp = r"""Mon Sep 17 00:00:00 2001
  2696. From: Alice Author <alice@authors.tld>
  2697. Subject: Add sources file for testing
  2698. ---
  2699. diff --git a/sources b/sources
  2700. new file mode 100644
  2701. index 0000000..9f44358
  2702. --- /dev/null
  2703. +++ b/sources
  2704. @@ -0,0 +1,2 @@
  2705. +foo
  2706. + bar
  2707. \ No newline at end of file
  2708. """
  2709. npatch = []
  2710. for row in patch.split('\n'):
  2711. if row.startswith('Date:'):
  2712. continue
  2713. if row.startswith('From '):
  2714. row = row.split(' ', 2)[2]
  2715. npatch.append(row)
  2716. patch = '\n'.join(npatch)
  2717. self.assertEqual(patch, exp)
  2718. def test_commit_to_patch_single_commit(self):
  2719. """ Test the commit_to_patch function of pagure.lib.git. """
  2720. repo = pygit2.init_repository(self.gitrepo)
  2721. patch = pagure.lib.git.commit_to_patch(repo, self.second_commit)
  2722. exp = r"""Mon Sep 17 00:00:00 2001
  2723. From: Alice Author <alice@authors.tld>
  2724. Subject: Add baz and boose to the sources
  2725. There are more objects to consider
  2726. ---
  2727. diff --git a/sources b/sources
  2728. index 9f44358..2a552bb 100644
  2729. --- a/sources
  2730. +++ b/sources
  2731. @@ -1,2 +1,4 @@
  2732. foo
  2733. - bar
  2734. \ No newline at end of file
  2735. + bar
  2736. +baz
  2737. + boose
  2738. \ No newline at end of file
  2739. """
  2740. npatch = []
  2741. for row in patch.split('\n'):
  2742. if row.startswith('Date:'):
  2743. continue
  2744. if row.startswith('From '):
  2745. row = row.split(' ', 2)[2]
  2746. npatch.append(row)
  2747. patch = '\n'.join(npatch)
  2748. self.assertEqual(patch, exp)
  2749. def test_commit_to_patch_2_commits(self):
  2750. """ Test the commit_to_patch function of pagure.lib.git. """
  2751. repo = pygit2.init_repository(self.gitrepo)
  2752. patch = pagure.lib.git.commit_to_patch(
  2753. repo, [self.first_commit, self.second_commit])
  2754. exp = r"""Mon Sep 17 00:00:00 2001
  2755. From: Alice Author <alice@authors.tld>
  2756. Subject: [PATCH 1/2] Add sources file for testing
  2757. ---
  2758. diff --git a/sources b/sources
  2759. new file mode 100644
  2760. index 0000000..9f44358
  2761. --- /dev/null
  2762. +++ b/sources
  2763. @@ -0,0 +1,2 @@
  2764. +foo
  2765. + bar
  2766. \ No newline at end of file
  2767. Mon Sep 17 00:00:00 2001
  2768. From: Alice Author <alice@authors.tld>
  2769. Subject: [PATCH 2/2] Add baz and boose to the sources
  2770. There are more objects to consider
  2771. ---
  2772. diff --git a/sources b/sources
  2773. index 9f44358..2a552bb 100644
  2774. --- a/sources
  2775. +++ b/sources
  2776. @@ -1,2 +1,4 @@
  2777. foo
  2778. - bar
  2779. \ No newline at end of file
  2780. + bar
  2781. +baz
  2782. + boose
  2783. \ No newline at end of file
  2784. """
  2785. npatch = []
  2786. for row in patch.split('\n'):
  2787. if row.startswith('Date:'):
  2788. continue
  2789. if row.startswith('From '):
  2790. row = row.split(' ', 2)[2]
  2791. npatch.append(row)
  2792. patch = '\n'.join(npatch)
  2793. self.assertEqual(patch, exp)
  2794. def test_commit_to_patch_first_commit_diff(self):
  2795. """ Test the commit_to_patch function of pagure.lib.git. """
  2796. repo = pygit2.init_repository(self.gitrepo)
  2797. patch = pagure.lib.git.commit_to_patch(
  2798. repo, self.first_commit, diff_view=True)
  2799. exp = r"""diff --git a/sources b/sources
  2800. new file mode 100644
  2801. index 0000000..9f44358
  2802. --- /dev/null
  2803. +++ b/sources
  2804. @@ -0,0 +1,2 @@
  2805. +foo
  2806. + bar
  2807. \ No newline at end of file
  2808. """
  2809. npatch = []
  2810. for row in patch.split('\n'):
  2811. if row.startswith('Date:'):
  2812. continue
  2813. if row.startswith('From '):
  2814. row = row.split(' ', 2)[2]
  2815. npatch.append(row)
  2816. patch = '\n'.join(npatch)
  2817. self.assertEqual(patch, exp)
  2818. def test_commit_to_patch_single_commit_diff(self):
  2819. """ Test the commit_to_patch function of pagure.lib.git. """
  2820. repo = pygit2.init_repository(self.gitrepo)
  2821. patch = pagure.lib.git.commit_to_patch(
  2822. repo, self.second_commit, diff_view=True)
  2823. exp = r"""diff --git a/sources b/sources
  2824. index 9f44358..2a552bb 100644
  2825. --- a/sources
  2826. +++ b/sources
  2827. @@ -1,2 +1,4 @@
  2828. foo
  2829. - bar
  2830. \ No newline at end of file
  2831. + bar
  2832. +baz
  2833. + boose
  2834. \ No newline at end of file
  2835. """
  2836. npatch = []
  2837. for row in patch.split('\n'):
  2838. if row.startswith('Date:'):
  2839. continue
  2840. if row.startswith('From '):
  2841. row = row.split(' ', 2)[2]
  2842. npatch.append(row)
  2843. patch = '\n'.join(npatch)
  2844. self.assertEqual(patch, exp)
  2845. def test_commit_to_patch_two_commits_diff(self):
  2846. """ Test the commit_to_patch function of pagure.lib.git. """
  2847. repo = pygit2.init_repository(self.gitrepo)
  2848. patch = pagure.lib.git.commit_to_patch(
  2849. repo, [self.first_commit, self.second_commit], diff_view=True)
  2850. exp = r"""diff --git a/sources b/sources
  2851. new file mode 100644
  2852. index 0000000..9f44358
  2853. --- /dev/null
  2854. +++ b/sources
  2855. @@ -0,0 +1,2 @@
  2856. +foo
  2857. + bar
  2858. \ No newline at end of file
  2859. diff --git a/sources b/sources
  2860. index 9f44358..2a552bb 100644
  2861. --- a/sources
  2862. +++ b/sources
  2863. @@ -1,2 +1,4 @@
  2864. foo
  2865. - bar
  2866. \ No newline at end of file
  2867. + bar
  2868. +baz
  2869. + boose
  2870. \ No newline at end of file
  2871. """
  2872. npatch = []
  2873. for row in patch.split('\n'):
  2874. if row.startswith('Date:'):
  2875. continue
  2876. if row.startswith('From '):
  2877. row = row.split(' ', 2)[2]
  2878. npatch.append(row)
  2879. patch = '\n'.join(npatch)
  2880. self.assertEqual(patch, exp)
  2881. def test_commit_to_patch_first_commit_diff_separated(self):
  2882. """ Test the commit_to_patch function of pagure.lib.git. """
  2883. repo = pygit2.init_repository(self.gitrepo)
  2884. patches = pagure.lib.git.commit_to_patch(
  2885. repo, self.first_commit, diff_view=True, separated=True)
  2886. exp = r"""diff --git a/sources b/sources
  2887. new file mode 100644
  2888. index 0000000..9f44358
  2889. --- /dev/null
  2890. +++ b/sources
  2891. @@ -0,0 +1,2 @@
  2892. +foo
  2893. + bar
  2894. \ No newline at end of file
  2895. """
  2896. output = []
  2897. for patch in patches:
  2898. npatch = []
  2899. for row in patch.split('\n'):
  2900. if row.startswith('Date:'):
  2901. continue
  2902. if row.startswith('From '):
  2903. row = row.split(' ', 2)[2]
  2904. npatch.append(row)
  2905. patch = '\n'.join(npatch)
  2906. output.append(patch)
  2907. self.assertEqual(output, [exp])
  2908. def test_commit_to_patch_single_commit_diff_separated(self):
  2909. """ Test the commit_to_patch function of pagure.lib.git. """
  2910. repo = pygit2.init_repository(self.gitrepo)
  2911. patches = pagure.lib.git.commit_to_patch(
  2912. repo, self.second_commit, diff_view=True, separated=True)
  2913. exp = r"""diff --git a/sources b/sources
  2914. index 9f44358..2a552bb 100644
  2915. --- a/sources
  2916. +++ b/sources
  2917. @@ -1,2 +1,4 @@
  2918. foo
  2919. - bar
  2920. \ No newline at end of file
  2921. + bar
  2922. +baz
  2923. + boose
  2924. \ No newline at end of file
  2925. """
  2926. output = []
  2927. for patch in patches:
  2928. npatch = []
  2929. for row in patch.split('\n'):
  2930. if row.startswith('Date:'):
  2931. continue
  2932. if row.startswith('From '):
  2933. row = row.split(' ', 2)[2]
  2934. npatch.append(row)
  2935. patch = '\n'.join(npatch)
  2936. output.append(patch)
  2937. self.assertEqual(output, [exp])
  2938. def test_commit_to_patch_two_commits_diff_separated(self):
  2939. """ Test the commit_to_patch function of pagure.lib.git. """
  2940. repo = pygit2.init_repository(self.gitrepo)
  2941. patches = pagure.lib.git.commit_to_patch(
  2942. repo, [self.first_commit, self.second_commit], diff_view=True,
  2943. separated=True)
  2944. exp = [r"""diff --git a/sources b/sources
  2945. new file mode 100644
  2946. index 0000000..9f44358
  2947. --- /dev/null
  2948. +++ b/sources
  2949. @@ -0,0 +1,2 @@
  2950. +foo
  2951. + bar
  2952. \ No newline at end of file
  2953. """,
  2954. r"""diff --git a/sources b/sources
  2955. index 9f44358..2a552bb 100644
  2956. --- a/sources
  2957. +++ b/sources
  2958. @@ -1,2 +1,4 @@
  2959. foo
  2960. - bar
  2961. \ No newline at end of file
  2962. + bar
  2963. +baz
  2964. + boose
  2965. \ No newline at end of file
  2966. """]
  2967. output = []
  2968. for patch in patches:
  2969. npatch = []
  2970. for row in patch.split('\n'):
  2971. if row.startswith('Date:'):
  2972. continue
  2973. if row.startswith('From '):
  2974. row = row.split(' ', 2)[2]
  2975. npatch.append(row)
  2976. patch = '\n'.join(npatch)
  2977. output.append(patch)
  2978. self.assertEqual(output, exp)
  2979. if __name__ == '__main__':
  2980. unittest.main(verbosity=2)