test_pagure_flask_api_fork.py 136 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. from __future__ import unicode_literals, absolute_import
  8. import datetime
  9. import unittest
  10. import shutil
  11. import sys
  12. import os
  13. import json
  14. from mock import patch, MagicMock
  15. sys.path.insert(
  16. 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
  17. )
  18. import pagure.lib.query
  19. import pagure.default_config
  20. import tests
  21. class PagureFlaskApiForktests(tests.Modeltests):
  22. """ Tests for the flask API of pagure for issue """
  23. maxDiff = None
  24. def setUp(self):
  25. """ Set up the environnment, ran before every tests. """
  26. super(PagureFlaskApiForktests, self).setUp()
  27. pagure.config.config["REQUESTS_FOLDER"] = None
  28. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  29. def test_api_pull_request_views_pr_disabled(self):
  30. """ Test the api_pull_request_views method of the flask api when PR
  31. are disabled. """
  32. tests.create_projects(self.session)
  33. tests.create_tokens(self.session)
  34. tests.create_tokens_acl(self.session)
  35. # Create a pull-request
  36. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  37. forked_repo = pagure.lib.query.get_authorized_project(
  38. self.session, "test"
  39. )
  40. req = pagure.lib.query.new_pull_request(
  41. session=self.session,
  42. repo_from=forked_repo,
  43. branch_from="master",
  44. repo_to=repo,
  45. branch_to="master",
  46. title="test pull-request",
  47. user="pingou",
  48. )
  49. self.session.commit()
  50. self.assertEqual(req.id, 1)
  51. self.assertEqual(req.title, "test pull-request")
  52. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  53. settings = repo.settings
  54. settings["pull_requests"] = False
  55. repo.settings = settings
  56. self.session.add(repo)
  57. self.session.commit()
  58. output = self.app.get("/api/0/test/pull-requests")
  59. self.assertEqual(output.status_code, 404)
  60. data = json.loads(output.get_data(as_text=True))
  61. self.assertDictEqual(
  62. data,
  63. {
  64. "error": "Pull-Request have been deactivated for this project",
  65. "error_code": "EPULLREQUESTSDISABLED",
  66. },
  67. )
  68. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  69. def test_api_pull_request_views_pr_closed(self):
  70. """ Test the api_pull_request_views method of the flask api to list
  71. the closed PRs. """
  72. tests.create_projects(self.session)
  73. tests.create_tokens(self.session)
  74. tests.create_tokens_acl(self.session)
  75. # Create a pull-request
  76. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  77. forked_repo = pagure.lib.query.get_authorized_project(
  78. self.session, "test"
  79. )
  80. req = pagure.lib.query.new_pull_request(
  81. session=self.session,
  82. repo_from=forked_repo,
  83. branch_from="master",
  84. repo_to=repo,
  85. branch_to="master",
  86. title="test pull-request",
  87. user="pingou",
  88. )
  89. self.session.commit()
  90. self.assertEqual(req.id, 1)
  91. self.assertEqual(req.title, "test pull-request")
  92. output = self.app.get("/api/0/test/pull-requests?status=closed")
  93. self.assertEqual(output.status_code, 200)
  94. data = json.loads(output.get_data(as_text=True))
  95. for k in ["first", "last"]:
  96. self.assertIsNotNone(data["pagination"][k])
  97. data["pagination"][k] = "http://localhost..."
  98. self.assertDictEqual(
  99. data,
  100. {
  101. "args": {
  102. "assignee": None,
  103. "author": None,
  104. "tags": [],
  105. "page": 1,
  106. "per_page": 20,
  107. "status": "closed",
  108. },
  109. "pagination": {
  110. "first": "http://localhost...",
  111. "last": "http://localhost...",
  112. "next": None,
  113. "page": 1,
  114. "pages": 0,
  115. "per_page": 20,
  116. "prev": None,
  117. },
  118. "requests": [],
  119. "total_requests": 0,
  120. },
  121. )
  122. # Close the PR and try again
  123. pagure.lib.query.close_pull_request(
  124. self.session, request=req, user="pingou", merged=False
  125. )
  126. output = self.app.get("/api/0/test/pull-requests?status=closed")
  127. self.assertEqual(output.status_code, 200)
  128. data = json.loads(output.get_data(as_text=True))
  129. self.assertEqual(
  130. sorted(data.keys()),
  131. ["args", "pagination", "requests", "total_requests"],
  132. )
  133. self.assertDictEqual(
  134. data["args"],
  135. {
  136. "assignee": None,
  137. "author": None,
  138. "tags": [],
  139. "page": 1,
  140. "per_page": 20,
  141. "status": "closed",
  142. },
  143. )
  144. self.assertEqual(data["total_requests"], 1)
  145. # Create two closed pull-requests
  146. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  147. forked_repo = pagure.lib.query.get_authorized_project(
  148. self.session, "test"
  149. )
  150. pagure.lib.query.new_pull_request(
  151. session=self.session,
  152. repo_from=forked_repo,
  153. branch_from="master",
  154. repo_to=repo,
  155. branch_to="master",
  156. title="closed pullrequest by user foo on repo test",
  157. user="foo",
  158. status="Closed",
  159. )
  160. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  161. forked_repo = pagure.lib.query.get_authorized_project(
  162. self.session, "test"
  163. )
  164. pagure.lib.query.new_pull_request(
  165. session=self.session,
  166. repo_from=forked_repo,
  167. branch_from="master",
  168. repo_to=repo,
  169. branch_to="master",
  170. title="closed pullrequest by user pingou on repo test",
  171. user="pingou",
  172. status="Closed",
  173. )
  174. self.session.commit()
  175. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  176. forked_repo = pagure.lib.query.get_authorized_project(
  177. self.session, "test"
  178. )
  179. pagure.lib.query.new_pull_request(
  180. session=self.session,
  181. repo_from=forked_repo,
  182. branch_from="master",
  183. repo_to=repo,
  184. branch_to="master",
  185. title="merged pullrequest by user pingou on repo test",
  186. user="pingou",
  187. status="Merged",
  188. )
  189. self.session.commit()
  190. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  191. forked_repo = pagure.lib.query.get_authorized_project(
  192. self.session, "test"
  193. )
  194. pagure.lib.query.new_pull_request(
  195. session=self.session,
  196. repo_from=forked_repo,
  197. branch_from="master",
  198. repo_to=repo,
  199. branch_to="master",
  200. title="merged pullrequest by user foo on repo test",
  201. user="foo",
  202. status="Merged",
  203. )
  204. self.session.commit()
  205. # Test the API view of closed pull-requests
  206. output = self.app.get("/api/0/test/pull-requests?status=closed")
  207. self.assertEqual(output.status_code, 200)
  208. data = json.loads(output.get_data(as_text=True))
  209. self.assertEqual(len(data["requests"]), 3)
  210. self.assertEqual(
  211. sorted(data.keys()),
  212. ["args", "pagination", "requests", "total_requests"],
  213. )
  214. for req in data["requests"]:
  215. self.assertEqual(req["status"], "Closed")
  216. self.assertEqual(data["args"]["status"], "closed")
  217. self.assertEqual(data["args"]["page"], 1)
  218. self.assertEqual(data["total_requests"], 3)
  219. # Test the API view of merged pull-requests
  220. output = self.app.get("/api/0/test/pull-requests?status=merged")
  221. self.assertEqual(output.status_code, 200)
  222. data = json.loads(output.get_data(as_text=True))
  223. self.assertEqual(len(data["requests"]), 2)
  224. self.assertEqual(
  225. sorted(data.keys()),
  226. ["args", "pagination", "requests", "total_requests"],
  227. )
  228. for req in data["requests"]:
  229. self.assertEqual(req["status"], "Merged")
  230. self.assertEqual(data["args"]["status"], "merged")
  231. self.assertEqual(data["args"]["page"], 1)
  232. self.assertEqual(data["total_requests"], 2)
  233. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  234. def test_api_pull_request_views_all_pr(self):
  235. """ Test the api_pull_request_views method of the flask api to list
  236. all PRs. """
  237. tests.create_projects(self.session)
  238. tests.create_tokens(self.session)
  239. tests.create_tokens_acl(self.session)
  240. # Create a pull-request
  241. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  242. forked_repo = pagure.lib.query.get_authorized_project(
  243. self.session, "test"
  244. )
  245. req = pagure.lib.query.new_pull_request(
  246. session=self.session,
  247. repo_from=forked_repo,
  248. branch_from="master",
  249. repo_to=repo,
  250. branch_to="master",
  251. title="test pull-request",
  252. user="pingou",
  253. )
  254. self.session.commit()
  255. self.assertEqual(req.id, 1)
  256. self.assertEqual(req.title, "test pull-request")
  257. output = self.app.get("/api/0/test/pull-requests?status=all")
  258. self.assertEqual(output.status_code, 200)
  259. data = json.loads(output.get_data(as_text=True))
  260. self.assertEqual(
  261. sorted(data.keys()),
  262. ["args", "pagination", "requests", "total_requests"],
  263. )
  264. self.assertDictEqual(
  265. data["args"],
  266. {
  267. "assignee": None,
  268. "author": None,
  269. "tags": [],
  270. "page": 1,
  271. "per_page": 20,
  272. "status": "all",
  273. },
  274. )
  275. self.assertEqual(data["total_requests"], 1)
  276. # Close the PR and try again
  277. pagure.lib.query.close_pull_request(
  278. self.session, request=req, user="pingou", merged=False
  279. )
  280. output = self.app.get("/api/0/test/pull-requests?status=all")
  281. self.assertEqual(output.status_code, 200)
  282. data = json.loads(output.get_data(as_text=True))
  283. self.assertEqual(
  284. sorted(data.keys()),
  285. ["args", "pagination", "requests", "total_requests"],
  286. )
  287. self.assertDictEqual(
  288. data["args"],
  289. {
  290. "assignee": None,
  291. "author": None,
  292. "tags": [],
  293. "page": 1,
  294. "per_page": 20,
  295. "status": "all",
  296. },
  297. )
  298. self.assertEqual(data["total_requests"], 1)
  299. @patch("pagure.lib.notify.send_email")
  300. def test_api_pull_request_views(self, send_email):
  301. """ Test the api_pull_request_views method of the flask api. """
  302. send_email.return_value = True
  303. tests.create_projects(self.session)
  304. tests.create_tokens(self.session)
  305. tests.create_tokens_acl(self.session)
  306. # Create a pull-request
  307. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  308. forked_repo = pagure.lib.query.get_authorized_project(
  309. self.session, "test"
  310. )
  311. req = pagure.lib.query.new_pull_request(
  312. session=self.session,
  313. repo_from=forked_repo,
  314. branch_from="master",
  315. repo_to=repo,
  316. branch_to="master",
  317. title="test pull-request",
  318. user="pingou",
  319. )
  320. self.session.commit()
  321. self.assertEqual(req.id, 1)
  322. self.assertEqual(req.title, "test pull-request")
  323. # Invalid repo
  324. output = self.app.get("/api/0/foo/pull-requests")
  325. self.assertEqual(output.status_code, 404)
  326. data = json.loads(output.get_data(as_text=True))
  327. self.assertDictEqual(
  328. data, {"error": "Project not found", "error_code": "ENOPROJECT"}
  329. )
  330. # List pull-requests
  331. output = self.app.get("/api/0/test/pull-requests")
  332. self.assertEqual(output.status_code, 200)
  333. data = json.loads(output.get_data(as_text=True))
  334. data["requests"][0]["date_created"] = "1431414800"
  335. data["requests"][0]["updated_on"] = "1431414800"
  336. data["requests"][0]["project"]["date_created"] = "1431414800"
  337. data["requests"][0]["project"]["date_modified"] = "1431414800"
  338. data["requests"][0]["repo_from"]["date_created"] = "1431414800"
  339. data["requests"][0]["repo_from"]["date_modified"] = "1431414800"
  340. data["requests"][0]["uid"] = "1431414800"
  341. data["requests"][0]["last_updated"] = "1431414800"
  342. for k in ["first", "last"]:
  343. self.assertIsNotNone(data["pagination"][k])
  344. data["pagination"][k] = "http://localhost..."
  345. expected_data = {
  346. "args": {
  347. "assignee": None,
  348. "author": None,
  349. "tags": [],
  350. "page": 1,
  351. "per_page": 20,
  352. "status": True,
  353. },
  354. "pagination": {
  355. "first": "http://localhost...",
  356. "last": "http://localhost...",
  357. "next": None,
  358. "page": 1,
  359. "pages": 1,
  360. "per_page": 20,
  361. "prev": None,
  362. },
  363. "requests": [
  364. {
  365. "assignee": None,
  366. "branch": "master",
  367. "branch_from": "master",
  368. "cached_merge_status": "unknown",
  369. "closed_at": None,
  370. "closed_by": None,
  371. "comments": [],
  372. "commit_start": None,
  373. "commit_stop": None,
  374. "date_created": "1431414800",
  375. "id": 1,
  376. "initial_comment": None,
  377. "last_updated": "1431414800",
  378. "project": {
  379. "access_groups": {
  380. "admin": [],
  381. "commit": [],
  382. "ticket": [],
  383. },
  384. "access_users": {
  385. "admin": [],
  386. "commit": [],
  387. "owner": ["pingou"],
  388. "ticket": [],
  389. },
  390. "close_status": [
  391. "Invalid",
  392. "Insufficient data",
  393. "Fixed",
  394. "Duplicate",
  395. ],
  396. "custom_keys": [],
  397. "date_created": "1431414800",
  398. "date_modified": "1431414800",
  399. "description": "test project #1",
  400. "fullname": "test",
  401. "url_path": "test",
  402. "id": 1,
  403. "milestones": {},
  404. "name": "test",
  405. "namespace": None,
  406. "parent": None,
  407. "priorities": {},
  408. "tags": [],
  409. "user": {"fullname": "PY C", "name": "pingou"},
  410. },
  411. "remote_git": None,
  412. "repo_from": {
  413. "access_groups": {
  414. "admin": [],
  415. "commit": [],
  416. "ticket": [],
  417. },
  418. "access_users": {
  419. "admin": [],
  420. "commit": [],
  421. "owner": ["pingou"],
  422. "ticket": [],
  423. },
  424. "close_status": [
  425. "Invalid",
  426. "Insufficient data",
  427. "Fixed",
  428. "Duplicate",
  429. ],
  430. "custom_keys": [],
  431. "date_created": "1431414800",
  432. "date_modified": "1431414800",
  433. "description": "test project #1",
  434. "fullname": "test",
  435. "url_path": "test",
  436. "id": 1,
  437. "milestones": {},
  438. "name": "test",
  439. "namespace": None,
  440. "parent": None,
  441. "priorities": {},
  442. "tags": [],
  443. "user": {"fullname": "PY C", "name": "pingou"},
  444. },
  445. "status": "Open",
  446. "tags": [],
  447. "threshold_reached": None,
  448. "title": "test pull-request",
  449. "uid": "1431414800",
  450. "updated_on": "1431414800",
  451. "user": {"fullname": "PY C", "name": "pingou"},
  452. }
  453. ],
  454. "total_requests": 1,
  455. }
  456. self.assertDictEqual(data, expected_data)
  457. headers = {"Authorization": "token aaabbbcccddd"}
  458. # Access Pull-Request authenticated
  459. output = self.app.get("/api/0/test/pull-requests", headers=headers)
  460. self.assertEqual(output.status_code, 200)
  461. data2 = json.loads(output.get_data(as_text=True))
  462. data2["requests"][0]["date_created"] = "1431414800"
  463. data2["requests"][0]["updated_on"] = "1431414800"
  464. data2["requests"][0]["project"]["date_created"] = "1431414800"
  465. data2["requests"][0]["project"]["date_modified"] = "1431414800"
  466. data2["requests"][0]["repo_from"]["date_created"] = "1431414800"
  467. data2["requests"][0]["repo_from"]["date_modified"] = "1431414800"
  468. data2["requests"][0]["uid"] = "1431414800"
  469. data2["requests"][0]["last_updated"] = "1431414800"
  470. for k in ["first", "last"]:
  471. self.assertIsNotNone(data["pagination"][k])
  472. data2["pagination"][k] = "http://localhost..."
  473. self.assertDictEqual(data, data2)
  474. @patch("pagure.lib.notify.send_email")
  475. def test_api_pull_request_view_tag_filtered(self, send_email):
  476. """ Test the api_pull_request_view method of the flask api to list
  477. tag filtered open PRs. """
  478. send_email.return_value = True
  479. tests.create_projects(self.session)
  480. tests.create_tokens(self.session)
  481. tests.create_tokens_acl(self.session)
  482. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  483. # Add a tag
  484. pagure.lib.query.new_tag(
  485. self.session, "tag-1", "tag-1 description", "#ff0000", repo.id
  486. )
  487. # Create a pull-request
  488. forked_repo = pagure.lib.query.get_authorized_project(
  489. self.session, "test"
  490. )
  491. req = pagure.lib.query.new_pull_request(
  492. session=self.session,
  493. repo_from=forked_repo,
  494. branch_from="master",
  495. repo_to=repo,
  496. branch_to="master",
  497. title="test pull-request",
  498. user="pingou",
  499. )
  500. self.session.commit()
  501. self.assertEqual(req.id, 1)
  502. self.assertEqual(req.title, "test pull-request")
  503. output = self.app.get("/api/0/test/pull-requests?tags=tag-1")
  504. self.assertEqual(output.status_code, 200)
  505. data = json.loads(output.get_data(as_text=True))
  506. for k in ["first", "last"]:
  507. self.assertIsNotNone(data["pagination"][k])
  508. data["pagination"][k] = "http://localhost..."
  509. self.assertDictEqual(
  510. data,
  511. {
  512. "args": {
  513. "assignee": None,
  514. "author": None,
  515. "tags": ["tag-1"],
  516. "page": 1,
  517. "per_page": 20,
  518. "status": True,
  519. },
  520. "pagination": {
  521. "first": "http://localhost...",
  522. "last": "http://localhost...",
  523. "next": None,
  524. "page": 1,
  525. "pages": 0,
  526. "per_page": 20,
  527. "prev": None,
  528. },
  529. "requests": [],
  530. "total_requests": 0,
  531. },
  532. )
  533. # Tag the PR and try again
  534. pagure.lib.query.update_tags(
  535. self.session, obj=req, tags=["tag-1"], username="pingou"
  536. )
  537. self.session.commit()
  538. output = self.app.get("/api/0/test/pull-requests?tags=tag-1")
  539. self.assertEqual(output.status_code, 200)
  540. data = json.loads(output.get_data(as_text=True))
  541. self.assertEqual(
  542. sorted(data.keys()),
  543. ["args", "pagination", "requests", "total_requests"],
  544. )
  545. self.assertDictEqual(
  546. data["args"],
  547. {
  548. "assignee": None,
  549. "author": None,
  550. "tags": ["tag-1"],
  551. "page": 1,
  552. "per_page": 20,
  553. "status": True,
  554. },
  555. )
  556. self.assertEqual(data["total_requests"], 1)
  557. # Try negative filtering
  558. output = self.app.get("/api/0/test/pull-requests?tags=!tag-1")
  559. self.assertEqual(output.status_code, 200)
  560. data = json.loads(output.get_data(as_text=True))
  561. for k in ["first", "last"]:
  562. self.assertIsNotNone(data["pagination"][k])
  563. data["pagination"][k] = "http://localhost..."
  564. self.assertDictEqual(
  565. data,
  566. {
  567. "args": {
  568. "assignee": None,
  569. "author": None,
  570. "tags": ["!tag-1"],
  571. "page": 1,
  572. "per_page": 20,
  573. "status": True,
  574. },
  575. "pagination": {
  576. "first": "http://localhost...",
  577. "last": "http://localhost...",
  578. "next": None,
  579. "page": 1,
  580. "pages": 0,
  581. "per_page": 20,
  582. "prev": None,
  583. },
  584. "requests": [],
  585. "total_requests": 0,
  586. },
  587. )
  588. @patch("pagure.lib.notify.send_email")
  589. def test_api_pull_request_view_pr_disabled(self, send_email):
  590. """ Test the api_pull_request_view method of the flask api. """
  591. send_email.return_value = True
  592. tests.create_projects(self.session)
  593. tests.create_tokens(self.session)
  594. tests.create_tokens_acl(self.session)
  595. # Create a pull-request
  596. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  597. forked_repo = pagure.lib.query.get_authorized_project(
  598. self.session, "test"
  599. )
  600. req = pagure.lib.query.new_pull_request(
  601. session=self.session,
  602. repo_from=forked_repo,
  603. branch_from="master",
  604. repo_to=repo,
  605. branch_to="master",
  606. title="test pull-request",
  607. user="pingou",
  608. )
  609. self.session.commit()
  610. self.assertEqual(req.id, 1)
  611. self.assertEqual(req.title, "test pull-request")
  612. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  613. settings = repo.settings
  614. settings["pull_requests"] = False
  615. repo.settings = settings
  616. self.session.add(repo)
  617. self.session.commit()
  618. output = self.app.get("/api/0/test/pull-request/1")
  619. self.assertEqual(output.status_code, 404)
  620. data = json.loads(output.get_data(as_text=True))
  621. self.assertDictEqual(
  622. data,
  623. {
  624. "error": "Pull-Request have been deactivated for this project",
  625. "error_code": "EPULLREQUESTSDISABLED",
  626. },
  627. )
  628. @patch("pagure.lib.notify.send_email")
  629. def test_api_pull_request_view(self, send_email):
  630. """ Test the api_pull_request_view method of the flask api. """
  631. send_email.return_value = True
  632. tests.create_projects(self.session)
  633. tests.create_tokens(self.session)
  634. tests.create_tokens_acl(self.session)
  635. # Create a pull-request
  636. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  637. forked_repo = pagure.lib.query.get_authorized_project(
  638. self.session, "test"
  639. )
  640. req = pagure.lib.query.new_pull_request(
  641. session=self.session,
  642. repo_from=forked_repo,
  643. branch_from="master",
  644. repo_to=repo,
  645. branch_to="master",
  646. title="test pull-request",
  647. user="pingou",
  648. )
  649. self.session.commit()
  650. self.assertEqual(req.id, 1)
  651. self.assertEqual(req.title, "test pull-request")
  652. # Invalid repo
  653. output = self.app.get("/api/0/foo/pull-request/1")
  654. self.assertEqual(output.status_code, 404)
  655. data = json.loads(output.get_data(as_text=True))
  656. self.assertDictEqual(
  657. data, {"error": "Project not found", "error_code": "ENOPROJECT"}
  658. )
  659. # Invalid issue for this repo
  660. output = self.app.get("/api/0/test2/pull-request/1")
  661. self.assertEqual(output.status_code, 404)
  662. data = json.loads(output.get_data(as_text=True))
  663. self.assertDictEqual(
  664. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  665. )
  666. # Valid issue
  667. output = self.app.get("/api/0/test/pull-request/1")
  668. self.assertEqual(output.status_code, 200)
  669. data = json.loads(output.get_data(as_text=True))
  670. data["date_created"] = "1431414800"
  671. data["updated_on"] = "1431414800"
  672. data["project"]["date_created"] = "1431414800"
  673. data["project"]["date_modified"] = "1431414800"
  674. data["repo_from"]["date_created"] = "1431414800"
  675. data["repo_from"]["date_modified"] = "1431414800"
  676. data["uid"] = "1431414800"
  677. data["last_updated"] = "1431414800"
  678. expected_data = {
  679. "assignee": None,
  680. "branch": "master",
  681. "branch_from": "master",
  682. "cached_merge_status": "unknown",
  683. "closed_at": None,
  684. "closed_by": None,
  685. "comments": [],
  686. "commit_start": None,
  687. "commit_stop": None,
  688. "date_created": "1431414800",
  689. "id": 1,
  690. "initial_comment": None,
  691. "last_updated": "1431414800",
  692. "project": {
  693. "access_groups": {"admin": [], "commit": [], "ticket": []},
  694. "access_users": {
  695. "admin": [],
  696. "commit": [],
  697. "owner": ["pingou"],
  698. "ticket": [],
  699. },
  700. "close_status": [
  701. "Invalid",
  702. "Insufficient data",
  703. "Fixed",
  704. "Duplicate",
  705. ],
  706. "custom_keys": [],
  707. "date_created": "1431414800",
  708. "date_modified": "1431414800",
  709. "description": "test project #1",
  710. "fullname": "test",
  711. "url_path": "test",
  712. "id": 1,
  713. "milestones": {},
  714. "name": "test",
  715. "namespace": None,
  716. "parent": None,
  717. "priorities": {},
  718. "tags": [],
  719. "user": {"fullname": "PY C", "name": "pingou"},
  720. },
  721. "remote_git": None,
  722. "repo_from": {
  723. "access_groups": {"admin": [], "commit": [], "ticket": []},
  724. "access_users": {
  725. "admin": [],
  726. "commit": [],
  727. "owner": ["pingou"],
  728. "ticket": [],
  729. },
  730. "close_status": [
  731. "Invalid",
  732. "Insufficient data",
  733. "Fixed",
  734. "Duplicate",
  735. ],
  736. "custom_keys": [],
  737. "date_created": "1431414800",
  738. "date_modified": "1431414800",
  739. "description": "test project #1",
  740. "fullname": "test",
  741. "url_path": "test",
  742. "id": 1,
  743. "milestones": {},
  744. "name": "test",
  745. "namespace": None,
  746. "parent": None,
  747. "priorities": {},
  748. "tags": [],
  749. "user": {"fullname": "PY C", "name": "pingou"},
  750. },
  751. "status": "Open",
  752. "tags": [],
  753. "threshold_reached": None,
  754. "title": "test pull-request",
  755. "uid": "1431414800",
  756. "updated_on": "1431414800",
  757. "user": {"fullname": "PY C", "name": "pingou"},
  758. }
  759. self.assertDictEqual(data, expected_data)
  760. headers = {"Authorization": "token aaabbbcccddd"}
  761. # Access Pull-Request authenticated
  762. output = self.app.get("/api/0/test/pull-request/1", headers=headers)
  763. self.assertEqual(output.status_code, 200)
  764. data2 = json.loads(output.get_data(as_text=True))
  765. data2["date_created"] = "1431414800"
  766. data2["project"]["date_created"] = "1431414800"
  767. data2["project"]["date_modified"] = "1431414800"
  768. data2["repo_from"]["date_created"] = "1431414800"
  769. data2["repo_from"]["date_modified"] = "1431414800"
  770. data2["uid"] = "1431414800"
  771. data2["date_created"] = "1431414800"
  772. data2["updated_on"] = "1431414800"
  773. data2["last_updated"] = "1431414800"
  774. self.assertDictEqual(data, data2)
  775. @patch("pagure.lib.notify.send_email")
  776. def test_api_pull_request_by_uid_view(self, send_email):
  777. """ Test the api_pull_request_by_uid_view method of the flask api. """
  778. send_email.return_value = True
  779. tests.create_projects(self.session)
  780. tests.create_tokens(self.session)
  781. tests.create_tokens_acl(self.session)
  782. # Create a pull-request
  783. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  784. forked_repo = pagure.lib.query.get_authorized_project(
  785. self.session, "test"
  786. )
  787. req = pagure.lib.query.new_pull_request(
  788. session=self.session,
  789. repo_from=forked_repo,
  790. branch_from="master",
  791. repo_to=repo,
  792. branch_to="master",
  793. title="test pull-request",
  794. user="pingou",
  795. )
  796. self.session.commit()
  797. self.assertEqual(req.id, 1)
  798. self.assertEqual(req.title, "test pull-request")
  799. uid = req.uid
  800. # Invalid request
  801. output = self.app.get("/api/0/pull-requests/{}".format(uid + "aaa"))
  802. self.assertEqual(output.status_code, 404)
  803. data = json.loads(output.get_data(as_text=True))
  804. self.assertDictEqual(
  805. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  806. )
  807. # Valid issue
  808. output = self.app.get("/api/0/pull-requests/{}".format(uid))
  809. self.assertEqual(output.status_code, 200)
  810. data = json.loads(output.get_data(as_text=True))
  811. data["date_created"] = "1431414800"
  812. data["updated_on"] = "1431414800"
  813. data["project"]["date_created"] = "1431414800"
  814. data["project"]["date_modified"] = "1431414800"
  815. data["repo_from"]["date_created"] = "1431414800"
  816. data["repo_from"]["date_modified"] = "1431414800"
  817. data["last_updated"] = "1431414800"
  818. expected_data = {
  819. "assignee": None,
  820. "branch": "master",
  821. "branch_from": "master",
  822. "cached_merge_status": "unknown",
  823. "closed_at": None,
  824. "closed_by": None,
  825. "comments": [],
  826. "commit_start": None,
  827. "commit_stop": None,
  828. "date_created": "1431414800",
  829. "id": 1,
  830. "initial_comment": None,
  831. "last_updated": "1431414800",
  832. "project": {
  833. "access_groups": {"admin": [], "commit": [], "ticket": []},
  834. "access_users": {
  835. "admin": [],
  836. "commit": [],
  837. "owner": ["pingou"],
  838. "ticket": [],
  839. },
  840. "close_status": [
  841. "Invalid",
  842. "Insufficient data",
  843. "Fixed",
  844. "Duplicate",
  845. ],
  846. "custom_keys": [],
  847. "date_created": "1431414800",
  848. "date_modified": "1431414800",
  849. "description": "test project #1",
  850. "fullname": "test",
  851. "url_path": "test",
  852. "id": 1,
  853. "milestones": {},
  854. "name": "test",
  855. "namespace": None,
  856. "parent": None,
  857. "priorities": {},
  858. "tags": [],
  859. "user": {"fullname": "PY C", "name": "pingou"},
  860. },
  861. "remote_git": None,
  862. "repo_from": {
  863. "access_groups": {"admin": [], "commit": [], "ticket": []},
  864. "access_users": {
  865. "admin": [],
  866. "commit": [],
  867. "owner": ["pingou"],
  868. "ticket": [],
  869. },
  870. "close_status": [
  871. "Invalid",
  872. "Insufficient data",
  873. "Fixed",
  874. "Duplicate",
  875. ],
  876. "custom_keys": [],
  877. "date_created": "1431414800",
  878. "date_modified": "1431414800",
  879. "description": "test project #1",
  880. "fullname": "test",
  881. "url_path": "test",
  882. "id": 1,
  883. "milestones": {},
  884. "name": "test",
  885. "namespace": None,
  886. "parent": None,
  887. "priorities": {},
  888. "tags": [],
  889. "user": {"fullname": "PY C", "name": "pingou"},
  890. },
  891. "status": "Open",
  892. "tags": [],
  893. "threshold_reached": None,
  894. "title": "test pull-request",
  895. "uid": uid,
  896. "updated_on": "1431414800",
  897. "user": {"fullname": "PY C", "name": "pingou"},
  898. }
  899. self.assertDictEqual(data, expected_data)
  900. headers = {"Authorization": "token aaabbbcccddd"}
  901. # Access Pull-Request authenticated
  902. output = self.app.get(
  903. "/api/0/pull-requests/{}".format(uid), headers=headers
  904. )
  905. self.assertEqual(output.status_code, 200)
  906. data2 = json.loads(output.get_data(as_text=True))
  907. data2["date_created"] = "1431414800"
  908. data2["project"]["date_created"] = "1431414800"
  909. data2["project"]["date_modified"] = "1431414800"
  910. data2["repo_from"]["date_created"] = "1431414800"
  911. data2["repo_from"]["date_modified"] = "1431414800"
  912. data2["date_created"] = "1431414800"
  913. data2["updated_on"] = "1431414800"
  914. data2["last_updated"] = "1431414800"
  915. self.assertDictEqual(data, data2)
  916. @patch("pagure.lib.notify.send_email")
  917. def test_api_pull_request_close_pr_disabled(self, send_email):
  918. """ Test the api_pull_request_close method of the flask api. """
  919. send_email.return_value = True
  920. tests.create_projects(self.session)
  921. tests.create_tokens(self.session)
  922. tests.create_tokens_acl(self.session)
  923. # Create the pull-request to close
  924. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  925. forked_repo = pagure.lib.query.get_authorized_project(
  926. self.session, "test"
  927. )
  928. req = pagure.lib.query.new_pull_request(
  929. session=self.session,
  930. repo_from=forked_repo,
  931. branch_from="master",
  932. repo_to=repo,
  933. branch_to="master",
  934. title="test pull-request",
  935. user="pingou",
  936. )
  937. self.session.commit()
  938. self.assertEqual(req.id, 1)
  939. self.assertEqual(req.title, "test pull-request")
  940. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  941. settings = repo.settings
  942. settings["pull_requests"] = False
  943. repo.settings = settings
  944. self.session.add(repo)
  945. self.session.commit()
  946. headers = {"Authorization": "token aaabbbcccddd"}
  947. output = self.app.post(
  948. "/api/0/test/pull-request/1/close", headers=headers
  949. )
  950. self.assertEqual(output.status_code, 404)
  951. data = json.loads(output.get_data(as_text=True))
  952. self.assertDictEqual(
  953. data,
  954. {
  955. "error": "Pull-Request have been deactivated for this project",
  956. "error_code": "EPULLREQUESTSDISABLED",
  957. },
  958. )
  959. @patch("pagure.lib.notify.send_email")
  960. def test_api_pull_request_close(self, send_email):
  961. """ Test the api_pull_request_close method of the flask api. """
  962. send_email.return_value = True
  963. tests.create_projects(self.session)
  964. tests.create_tokens(self.session)
  965. tests.create_tokens_acl(self.session)
  966. # Create the pull-request to close
  967. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  968. forked_repo = pagure.lib.query.get_authorized_project(
  969. self.session, "test"
  970. )
  971. req = pagure.lib.query.new_pull_request(
  972. session=self.session,
  973. repo_from=forked_repo,
  974. branch_from="master",
  975. repo_to=repo,
  976. branch_to="master",
  977. title="test pull-request",
  978. user="pingou",
  979. )
  980. self.session.commit()
  981. self.assertEqual(req.id, 1)
  982. self.assertEqual(req.title, "test pull-request")
  983. headers = {"Authorization": "token aaabbbcccddd"}
  984. # Invalid project
  985. output = self.app.post(
  986. "/api/0/foo/pull-request/1/close", headers=headers
  987. )
  988. self.assertEqual(output.status_code, 404)
  989. data = json.loads(output.get_data(as_text=True))
  990. self.assertDictEqual(
  991. data, {"error": "Project not found", "error_code": "ENOPROJECT"}
  992. )
  993. # Valid token, wrong project
  994. output = self.app.post(
  995. "/api/0/test2/pull-request/1/close", headers=headers
  996. )
  997. self.assertEqual(output.status_code, 401)
  998. data = json.loads(output.get_data(as_text=True))
  999. self.assertEqual(
  1000. pagure.api.APIERROR.EINVALIDTOK.name, data["error_code"]
  1001. )
  1002. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data["error"])
  1003. # Invalid PR
  1004. output = self.app.post(
  1005. "/api/0/test/pull-request/2/close", headers=headers
  1006. )
  1007. self.assertEqual(output.status_code, 404)
  1008. data = json.loads(output.get_data(as_text=True))
  1009. self.assertDictEqual(
  1010. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  1011. )
  1012. # Create a token for foo for this project
  1013. item = pagure.lib.model.Token(
  1014. id="foobar_token",
  1015. user_id=2,
  1016. project_id=1,
  1017. expiration=datetime.datetime.utcnow()
  1018. + datetime.timedelta(days=30),
  1019. )
  1020. self.session.add(item)
  1021. self.session.commit()
  1022. # Allow the token to close PR
  1023. acls = pagure.lib.query.get_acls(self.session)
  1024. for acl in acls:
  1025. if acl.name == "pull_request_close":
  1026. break
  1027. item = pagure.lib.model.TokenAcl(
  1028. token_id="foobar_token", acl_id=acl.id
  1029. )
  1030. self.session.add(item)
  1031. self.session.commit()
  1032. headers = {"Authorization": "token foobar_token"}
  1033. # User not admin
  1034. output = self.app.post(
  1035. "/api/0/test/pull-request/1/close", headers=headers
  1036. )
  1037. self.assertEqual(output.status_code, 403)
  1038. data = json.loads(output.get_data(as_text=True))
  1039. self.assertDictEqual(
  1040. data,
  1041. {
  1042. "error": "You are not allowed to merge/close pull-request "
  1043. "for this project",
  1044. "error_code": "ENOPRCLOSE",
  1045. },
  1046. )
  1047. headers = {"Authorization": "token aaabbbcccddd"}
  1048. # Close PR
  1049. output = self.app.post(
  1050. "/api/0/test/pull-request/1/close", headers=headers
  1051. )
  1052. self.assertEqual(output.status_code, 200)
  1053. data = json.loads(output.get_data(as_text=True))
  1054. self.assertDictEqual(data, {"message": "Pull-request closed!"})
  1055. @patch("pagure.lib.notify.send_email")
  1056. def test_api_pull_request_merge_pr_disabled(self, send_email):
  1057. """ Test the api_pull_request_merge method of the flask api when PR
  1058. are disabled. """
  1059. send_email.return_value = True
  1060. tests.create_projects(self.session)
  1061. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1062. tests.create_projects_git(
  1063. os.path.join(self.path, "requests"), bare=True
  1064. )
  1065. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1066. tests.add_commit_git_repo(
  1067. os.path.join(self.path, "repos", "test.git"), branch="test"
  1068. )
  1069. tests.create_tokens(self.session)
  1070. tests.create_tokens_acl(self.session)
  1071. # Create the pull-request to close
  1072. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1073. forked_repo = pagure.lib.query.get_authorized_project(
  1074. self.session, "test"
  1075. )
  1076. req = pagure.lib.query.new_pull_request(
  1077. session=self.session,
  1078. repo_from=forked_repo,
  1079. branch_from="test",
  1080. repo_to=repo,
  1081. branch_to="master",
  1082. title="test pull-request",
  1083. user="pingou",
  1084. )
  1085. self.session.commit()
  1086. self.assertEqual(req.id, 1)
  1087. self.assertEqual(req.title, "test pull-request")
  1088. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1089. settings = repo.settings
  1090. settings["pull_requests"] = False
  1091. repo.settings = settings
  1092. self.session.add(repo)
  1093. self.session.commit()
  1094. headers = {"Authorization": "token aaabbbcccddd"}
  1095. output = self.app.post(
  1096. "/api/0/test/pull-request/1/merge", headers=headers
  1097. )
  1098. self.assertEqual(output.status_code, 404)
  1099. data = json.loads(output.get_data(as_text=True))
  1100. self.assertDictEqual(
  1101. data,
  1102. {
  1103. "error": "Pull-Request have been deactivated for this project",
  1104. "error_code": "EPULLREQUESTSDISABLED",
  1105. },
  1106. )
  1107. @patch("pagure.lib.notify.send_email")
  1108. def test_api_pull_request_merge_only_assigned(self, send_email):
  1109. """ Test the api_pull_request_merge method of the flask api when
  1110. only assignee can merge the PR and the PR isn't assigned. """
  1111. send_email.return_value = True
  1112. tests.create_projects(self.session)
  1113. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1114. tests.create_projects_git(
  1115. os.path.join(self.path, "requests"), bare=True
  1116. )
  1117. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1118. tests.add_commit_git_repo(
  1119. os.path.join(self.path, "repos", "test.git"), branch="test"
  1120. )
  1121. tests.create_tokens(self.session)
  1122. tests.create_tokens_acl(self.session)
  1123. # Create the pull-request to close
  1124. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1125. forked_repo = pagure.lib.query.get_authorized_project(
  1126. self.session, "test"
  1127. )
  1128. req = pagure.lib.query.new_pull_request(
  1129. session=self.session,
  1130. repo_from=forked_repo,
  1131. branch_from="test",
  1132. repo_to=repo,
  1133. branch_to="master",
  1134. title="test pull-request",
  1135. user="pingou",
  1136. )
  1137. self.session.commit()
  1138. self.assertEqual(req.id, 1)
  1139. self.assertEqual(req.title, "test pull-request")
  1140. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1141. settings = repo.settings
  1142. settings["Only_assignee_can_merge_pull-request"] = True
  1143. repo.settings = settings
  1144. self.session.add(repo)
  1145. self.session.commit()
  1146. headers = {"Authorization": "token aaabbbcccddd"}
  1147. output = self.app.post(
  1148. "/api/0/test/pull-request/1/merge", headers=headers
  1149. )
  1150. self.assertEqual(output.status_code, 403)
  1151. data = json.loads(output.get_data(as_text=True))
  1152. self.assertDictEqual(
  1153. data,
  1154. {
  1155. "error": "This request must be assigned to be merged",
  1156. "error_code": "ENOTASSIGNED",
  1157. },
  1158. )
  1159. @patch("pagure.lib.notify.send_email")
  1160. def test_api_pull_request_merge_only_assigned_not_assignee(
  1161. self, send_email
  1162. ):
  1163. """ Test the api_pull_request_merge method of the flask api when
  1164. only assignee can merge the PR and the PR isn't assigned to the
  1165. user asking to merge. """
  1166. send_email.return_value = True
  1167. tests.create_projects(self.session)
  1168. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1169. tests.create_projects_git(
  1170. os.path.join(self.path, "requests"), bare=True
  1171. )
  1172. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1173. tests.add_commit_git_repo(
  1174. os.path.join(self.path, "repos", "test.git"), branch="test"
  1175. )
  1176. tests.create_tokens(self.session)
  1177. tests.create_tokens_acl(self.session)
  1178. # Create the pull-request to close
  1179. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1180. forked_repo = pagure.lib.query.get_authorized_project(
  1181. self.session, "test"
  1182. )
  1183. req = pagure.lib.query.new_pull_request(
  1184. session=self.session,
  1185. repo_from=forked_repo,
  1186. branch_from="test",
  1187. repo_to=repo,
  1188. branch_to="master",
  1189. title="test pull-request",
  1190. user="pingou",
  1191. )
  1192. self.session.commit()
  1193. self.assertEqual(req.id, 1)
  1194. self.assertEqual(req.title, "test pull-request")
  1195. req.assignee = pagure.lib.query.search_user(self.session, "foo")
  1196. self.session.add(req)
  1197. self.session.commit()
  1198. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1199. settings = repo.settings
  1200. settings["Only_assignee_can_merge_pull-request"] = True
  1201. repo.settings = settings
  1202. self.session.add(repo)
  1203. self.session.commit()
  1204. headers = {"Authorization": "token aaabbbcccddd"}
  1205. output = self.app.post(
  1206. "/api/0/test/pull-request/1/merge", headers=headers
  1207. )
  1208. self.assertEqual(output.status_code, 403)
  1209. data = json.loads(output.get_data(as_text=True))
  1210. self.assertDictEqual(
  1211. data,
  1212. {
  1213. "error": "Only the assignee can merge this request",
  1214. "error_code": "ENOTASSIGNEE",
  1215. },
  1216. )
  1217. @patch("pagure.lib.notify.send_email")
  1218. def test_api_pull_request_merge_minimal_score(self, send_email):
  1219. """ Test the api_pull_request_merge method of the flask api when
  1220. a PR requires a certain minimal score to be merged. """
  1221. send_email.return_value = True
  1222. tests.create_projects(self.session)
  1223. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1224. tests.create_projects_git(
  1225. os.path.join(self.path, "requests"), bare=True
  1226. )
  1227. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1228. tests.add_commit_git_repo(
  1229. os.path.join(self.path, "repos", "test.git"), branch="test"
  1230. )
  1231. tests.create_tokens(self.session)
  1232. tests.create_tokens_acl(self.session)
  1233. # Create the pull-request to close
  1234. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1235. forked_repo = pagure.lib.query.get_authorized_project(
  1236. self.session, "test"
  1237. )
  1238. req = pagure.lib.query.new_pull_request(
  1239. session=self.session,
  1240. repo_from=forked_repo,
  1241. branch_from="test",
  1242. repo_to=repo,
  1243. branch_to="master",
  1244. title="test pull-request",
  1245. user="pingou",
  1246. )
  1247. self.session.commit()
  1248. self.assertEqual(req.id, 1)
  1249. self.assertEqual(req.title, "test pull-request")
  1250. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1251. settings = repo.settings
  1252. settings["Minimum_score_to_merge_pull-request"] = 2
  1253. repo.settings = settings
  1254. self.session.add(repo)
  1255. self.session.commit()
  1256. headers = {"Authorization": "token aaabbbcccddd"}
  1257. output = self.app.post(
  1258. "/api/0/test/pull-request/1/merge", headers=headers
  1259. )
  1260. self.assertEqual(output.status_code, 403)
  1261. data = json.loads(output.get_data(as_text=True))
  1262. self.assertDictEqual(
  1263. data,
  1264. {
  1265. "error": "This request does not have the minimum review "
  1266. "score necessary to be merged",
  1267. "error_code": "EPRSCORE",
  1268. },
  1269. )
  1270. @patch("pagure.lib.notify.send_email")
  1271. def test_api_pull_request_merge(self, send_email):
  1272. """ Test the api_pull_request_merge method of the flask api. """
  1273. send_email.return_value = True
  1274. tests.create_projects(self.session)
  1275. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1276. tests.create_projects_git(
  1277. os.path.join(self.path, "requests"), bare=True
  1278. )
  1279. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1280. tests.add_commit_git_repo(
  1281. os.path.join(self.path, "repos", "test.git"), branch="test"
  1282. )
  1283. tests.create_tokens(self.session)
  1284. tests.create_tokens_acl(self.session)
  1285. # Create the pull-request to close
  1286. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1287. forked_repo = pagure.lib.query.get_authorized_project(
  1288. self.session, "test"
  1289. )
  1290. req = pagure.lib.query.new_pull_request(
  1291. session=self.session,
  1292. repo_from=forked_repo,
  1293. branch_from="test",
  1294. repo_to=repo,
  1295. branch_to="master",
  1296. title="test pull-request",
  1297. user="pingou",
  1298. )
  1299. self.session.commit()
  1300. self.assertEqual(req.id, 1)
  1301. self.assertEqual(req.title, "test pull-request")
  1302. headers = {"Authorization": "token aaabbbcccddd"}
  1303. # Invalid project
  1304. output = self.app.post(
  1305. "/api/0/foo/pull-request/1/merge", headers=headers
  1306. )
  1307. self.assertEqual(output.status_code, 404)
  1308. data = json.loads(output.get_data(as_text=True))
  1309. self.assertDictEqual(
  1310. data, {"error": "Project not found", "error_code": "ENOPROJECT"}
  1311. )
  1312. # Valid token, wrong project
  1313. output = self.app.post(
  1314. "/api/0/test2/pull-request/1/merge", headers=headers
  1315. )
  1316. self.assertEqual(output.status_code, 401)
  1317. data = json.loads(output.get_data(as_text=True))
  1318. self.assertEqual(
  1319. pagure.api.APIERROR.EINVALIDTOK.name, data["error_code"]
  1320. )
  1321. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data["error"])
  1322. # Invalid PR
  1323. output = self.app.post(
  1324. "/api/0/test/pull-request/2/merge", headers=headers
  1325. )
  1326. self.assertEqual(output.status_code, 404)
  1327. data = json.loads(output.get_data(as_text=True))
  1328. self.assertDictEqual(
  1329. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  1330. )
  1331. # Create a token for foo for this project
  1332. item = pagure.lib.model.Token(
  1333. id="foobar_token",
  1334. user_id=2,
  1335. project_id=1,
  1336. expiration=datetime.datetime.utcnow()
  1337. + datetime.timedelta(days=30),
  1338. )
  1339. self.session.add(item)
  1340. self.session.commit()
  1341. # Allow the token to merge PR
  1342. acls = pagure.lib.query.get_acls(self.session)
  1343. for acl in acls:
  1344. if acl.name == "pull_request_merge":
  1345. break
  1346. item = pagure.lib.model.TokenAcl(
  1347. token_id="foobar_token", acl_id=acl.id
  1348. )
  1349. self.session.add(item)
  1350. self.session.commit()
  1351. headers = {"Authorization": "token foobar_token"}
  1352. # User not admin
  1353. output = self.app.post(
  1354. "/api/0/test/pull-request/1/merge", headers=headers
  1355. )
  1356. self.assertEqual(output.status_code, 403)
  1357. data = json.loads(output.get_data(as_text=True))
  1358. self.assertDictEqual(
  1359. data,
  1360. {
  1361. "error": "You are not allowed to merge/close pull-request "
  1362. "for this project",
  1363. "error_code": "ENOPRCLOSE",
  1364. },
  1365. )
  1366. headers = {"Authorization": "token aaabbbcccddd"}
  1367. # Merge PR
  1368. output = self.app.post(
  1369. "/api/0/test/pull-request/1/merge", headers=headers
  1370. )
  1371. self.assertEqual(output.status_code, 200)
  1372. data = json.loads(output.get_data(as_text=True))
  1373. self.assertDictEqual(data, {"message": "Changes merged!"})
  1374. @patch("pagure.lib.notify.send_email")
  1375. def test_api_pull_request_merge_conflicting(self, send_email):
  1376. """ Test the api_pull_request_merge method of the flask api. """
  1377. send_email.return_value = True
  1378. tests.create_projects(self.session)
  1379. tests.add_content_git_repo(
  1380. os.path.join(self.path, "repos", "test.git")
  1381. )
  1382. # Fork
  1383. project = pagure.lib.query.get_authorized_project(self.session, "test")
  1384. task = pagure.lib.query.fork_project(
  1385. session=self.session, user="pingou", repo=project
  1386. )
  1387. self.session.commit()
  1388. self.assertEqual(
  1389. task.get(),
  1390. {
  1391. "endpoint": "ui_ns.view_repo",
  1392. "repo": "test",
  1393. "namespace": None,
  1394. "username": "pingou",
  1395. },
  1396. )
  1397. # Add content to the fork
  1398. tests.add_content_to_git(
  1399. os.path.join(self.path, "repos", "forks", "pingou", "test.git"),
  1400. filename="foobar",
  1401. content="content from the fork",
  1402. )
  1403. # Add content to the main repo, so they conflict
  1404. tests.add_content_to_git(
  1405. os.path.join(self.path, "repos", "test.git"),
  1406. filename="foobar",
  1407. content="content from the main repo",
  1408. )
  1409. project = pagure.lib.query.get_authorized_project(self.session, "test")
  1410. fork = pagure.lib.query.get_authorized_project(
  1411. self.session, "test", user="pingou"
  1412. )
  1413. tests.create_tokens(self.session)
  1414. tests.create_tokens_acl(self.session)
  1415. # Create the pull-request to close
  1416. req = pagure.lib.query.new_pull_request(
  1417. session=self.session,
  1418. repo_from=fork,
  1419. branch_from="master",
  1420. repo_to=project,
  1421. branch_to="master",
  1422. title="test pull-request",
  1423. user="pingou",
  1424. )
  1425. self.session.commit()
  1426. self.assertEqual(req.id, 1)
  1427. self.assertEqual(req.title, "test pull-request")
  1428. headers = {"Authorization": "token aaabbbcccddd"}
  1429. # Merge PR
  1430. output = self.app.post(
  1431. "/api/0/test/pull-request/1/merge", headers=headers
  1432. )
  1433. self.assertEqual(output.status_code, 409)
  1434. data = json.loads(output.get_data(as_text=True))
  1435. self.assertDictEqual(
  1436. data,
  1437. {
  1438. "error": "This pull-request conflicts and thus cannot be merged",
  1439. "error_code": "EPRCONFLICTS",
  1440. },
  1441. )
  1442. @patch("pagure.lib.notify.send_email")
  1443. def test_api_pull_request_merge_user_token(self, send_email):
  1444. """ Test the api_pull_request_merge method of the flask api. """
  1445. send_email.return_value = True
  1446. tests.create_projects(self.session)
  1447. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  1448. tests.create_projects_git(
  1449. os.path.join(self.path, "requests"), bare=True
  1450. )
  1451. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  1452. tests.add_commit_git_repo(
  1453. os.path.join(self.path, "repos", "test.git"), branch="test"
  1454. )
  1455. tests.create_tokens(self.session, project_id=None)
  1456. tests.create_tokens_acl(self.session)
  1457. # Create the pull-request to close
  1458. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1459. forked_repo = pagure.lib.query.get_authorized_project(
  1460. self.session, "test"
  1461. )
  1462. req = pagure.lib.query.new_pull_request(
  1463. session=self.session,
  1464. repo_from=forked_repo,
  1465. branch_from="test",
  1466. repo_to=repo,
  1467. branch_to="master",
  1468. title="test pull-request",
  1469. user="pingou",
  1470. )
  1471. self.session.commit()
  1472. self.assertEqual(req.id, 1)
  1473. self.assertEqual(req.title, "test pull-request")
  1474. headers = {"Authorization": "token aaabbbcccddd"}
  1475. # Invalid project
  1476. output = self.app.post(
  1477. "/api/0/foo/pull-request/1/merge", headers=headers
  1478. )
  1479. self.assertEqual(output.status_code, 404)
  1480. data = json.loads(output.get_data(as_text=True))
  1481. self.assertDictEqual(
  1482. data, {"error": "Project not found", "error_code": "ENOPROJECT"}
  1483. )
  1484. # Valid token, invalid PR
  1485. output = self.app.post(
  1486. "/api/0/test2/pull-request/1/merge", headers=headers
  1487. )
  1488. self.assertEqual(output.status_code, 404)
  1489. data = json.loads(output.get_data(as_text=True))
  1490. self.assertDictEqual(
  1491. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  1492. )
  1493. # Valid token, invalid PR - other project
  1494. output = self.app.post(
  1495. "/api/0/test/pull-request/2/merge", headers=headers
  1496. )
  1497. self.assertEqual(output.status_code, 404)
  1498. data = json.loads(output.get_data(as_text=True))
  1499. self.assertDictEqual(
  1500. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  1501. )
  1502. # Create a token for foo for this project
  1503. item = pagure.lib.model.Token(
  1504. id="foobar_token",
  1505. user_id=2,
  1506. project_id=1,
  1507. expiration=datetime.datetime.utcnow()
  1508. + datetime.timedelta(days=30),
  1509. )
  1510. self.session.add(item)
  1511. self.session.commit()
  1512. # Allow the token to merge PR
  1513. acls = pagure.lib.query.get_acls(self.session)
  1514. acl = None
  1515. for acl in acls:
  1516. if acl.name == "pull_request_merge":
  1517. break
  1518. item = pagure.lib.model.TokenAcl(
  1519. token_id="foobar_token", acl_id=acl.id
  1520. )
  1521. self.session.add(item)
  1522. self.session.commit()
  1523. headers = {"Authorization": "token foobar_token"}
  1524. # User not admin
  1525. output = self.app.post(
  1526. "/api/0/test/pull-request/1/merge", headers=headers
  1527. )
  1528. self.assertEqual(output.status_code, 403)
  1529. data = json.loads(output.get_data(as_text=True))
  1530. self.assertDictEqual(
  1531. data,
  1532. {
  1533. "error": "You are not allowed to merge/close pull-request "
  1534. "for this project",
  1535. "error_code": "ENOPRCLOSE",
  1536. },
  1537. )
  1538. headers = {"Authorization": "token aaabbbcccddd"}
  1539. # Merge PR
  1540. output = self.app.post(
  1541. "/api/0/test/pull-request/1/merge", headers=headers
  1542. )
  1543. self.assertEqual(output.status_code, 200)
  1544. data = json.loads(output.get_data(as_text=True))
  1545. self.assertDictEqual(data, {"message": "Changes merged!"})
  1546. @patch("pagure.lib.notify.send_email")
  1547. def test_api_pull_request_add_comment(self, mockemail):
  1548. """ Test the api_pull_request_add_comment method of the flask api. """
  1549. mockemail.return_value = True
  1550. tests.create_projects(self.session)
  1551. tests.create_tokens(self.session)
  1552. tests.create_tokens_acl(self.session)
  1553. headers = {"Authorization": "token aaabbbcccddd"}
  1554. # Invalid project
  1555. output = self.app.post(
  1556. "/api/0/foo/pull-request/1/comment", headers=headers
  1557. )
  1558. self.assertEqual(output.status_code, 404)
  1559. data = json.loads(output.get_data(as_text=True))
  1560. self.assertDictEqual(
  1561. data, {"error": "Project not found", "error_code": "ENOPROJECT"}
  1562. )
  1563. # Valid token, wrong project
  1564. output = self.app.post(
  1565. "/api/0/test2/pull-request/1/comment", headers=headers
  1566. )
  1567. self.assertEqual(output.status_code, 401)
  1568. data = json.loads(output.get_data(as_text=True))
  1569. self.assertEqual(
  1570. pagure.api.APIERROR.EINVALIDTOK.name, data["error_code"]
  1571. )
  1572. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data["error"])
  1573. # No input
  1574. output = self.app.post(
  1575. "/api/0/test/pull-request/1/comment", headers=headers
  1576. )
  1577. self.assertEqual(output.status_code, 404)
  1578. data = json.loads(output.get_data(as_text=True))
  1579. self.assertDictEqual(
  1580. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  1581. )
  1582. # Create a pull-request
  1583. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1584. forked_repo = pagure.lib.query.get_authorized_project(
  1585. self.session, "test"
  1586. )
  1587. req = pagure.lib.query.new_pull_request(
  1588. session=self.session,
  1589. repo_from=forked_repo,
  1590. branch_from="master",
  1591. repo_to=repo,
  1592. branch_to="master",
  1593. title="test pull-request",
  1594. user="pingou",
  1595. )
  1596. self.session.commit()
  1597. self.assertEqual(req.id, 1)
  1598. self.assertEqual(req.title, "test pull-request")
  1599. # Check comments before
  1600. self.session.commit()
  1601. request = pagure.lib.query.search_pull_requests(
  1602. self.session, project_id=1, requestid=1
  1603. )
  1604. self.assertEqual(len(request.comments), 0)
  1605. data = {"title": "test issue"}
  1606. # Incomplete request
  1607. output = self.app.post(
  1608. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  1609. )
  1610. self.assertEqual(output.status_code, 400)
  1611. data = json.loads(output.get_data(as_text=True))
  1612. self.assertDictEqual(
  1613. data,
  1614. {
  1615. "error": "Invalid or incomplete input submitted",
  1616. "error_code": "EINVALIDREQ",
  1617. "errors": {"comment": ["This field is required."]},
  1618. },
  1619. )
  1620. # No change
  1621. self.session.commit()
  1622. request = pagure.lib.query.search_pull_requests(
  1623. self.session, project_id=1, requestid=1
  1624. )
  1625. self.assertEqual(len(request.comments), 0)
  1626. data = {"comment": "This is a very interesting question"}
  1627. # Valid request
  1628. output = self.app.post(
  1629. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  1630. )
  1631. self.assertEqual(output.status_code, 200)
  1632. data = json.loads(output.get_data(as_text=True))
  1633. self.assertDictEqual(data, {"message": "Comment added"})
  1634. # One comment added
  1635. self.session.commit()
  1636. request = pagure.lib.query.search_pull_requests(
  1637. self.session, project_id=1, requestid=1
  1638. )
  1639. self.assertEqual(len(request.comments), 1)
  1640. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  1641. def test_api_pull_request_add_comment_wrong_user(self):
  1642. """ Test the api_pull_request_add_comment method of the flask api
  1643. when the user is not found in the DB. """
  1644. tests.create_projects(self.session)
  1645. tests.create_tokens(self.session, project_id=None)
  1646. tests.create_tokens_acl(self.session)
  1647. headers = {"Authorization": "token aaabbbcccddd"}
  1648. # Create a pull-request
  1649. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1650. forked_repo = pagure.lib.query.get_authorized_project(
  1651. self.session, "test"
  1652. )
  1653. req = pagure.lib.query.new_pull_request(
  1654. session=self.session,
  1655. repo_from=forked_repo,
  1656. branch_from="master",
  1657. repo_to=repo,
  1658. branch_to="master",
  1659. title="test pull-request",
  1660. user="pingou",
  1661. )
  1662. self.session.commit()
  1663. self.assertEqual(req.id, 1)
  1664. self.assertEqual(req.title, "test pull-request")
  1665. data = {"comment": "This is a very interesting question"}
  1666. # Valid request
  1667. with patch(
  1668. "pagure.lib.query.add_pull_request_comment",
  1669. side_effect=pagure.exceptions.PagureException("error"),
  1670. ):
  1671. output = self.app.post(
  1672. "/api/0/test/pull-request/1/comment",
  1673. data=data,
  1674. headers=headers,
  1675. )
  1676. self.assertEqual(output.status_code, 400)
  1677. data = json.loads(output.get_data(as_text=True))
  1678. self.assertDictEqual(
  1679. data, {"error": "error", "error_code": "ENOCODE"}
  1680. )
  1681. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  1682. def test_api_pull_request_add_comment_pr_disabled(self):
  1683. """ Test the api_pull_request_add_comment method of the flask api
  1684. when PRs are disabled. """
  1685. tests.create_projects(self.session)
  1686. tests.create_tokens(self.session, project_id=None)
  1687. tests.create_tokens_acl(self.session)
  1688. headers = {"Authorization": "token aaabbbcccddd"}
  1689. # Create a pull-request
  1690. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1691. forked_repo = pagure.lib.query.get_authorized_project(
  1692. self.session, "test"
  1693. )
  1694. req = pagure.lib.query.new_pull_request(
  1695. session=self.session,
  1696. repo_from=forked_repo,
  1697. branch_from="master",
  1698. repo_to=repo,
  1699. branch_to="master",
  1700. title="test pull-request",
  1701. user="pingou",
  1702. )
  1703. self.session.commit()
  1704. self.assertEqual(req.id, 1)
  1705. self.assertEqual(req.title, "test pull-request")
  1706. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1707. settings = repo.settings
  1708. settings["pull_requests"] = False
  1709. repo.settings = settings
  1710. self.session.add(repo)
  1711. self.session.commit()
  1712. data = {"comment": "This is a very interesting question"}
  1713. # Valid request
  1714. output = self.app.post(
  1715. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  1716. )
  1717. self.assertEqual(output.status_code, 404)
  1718. data = json.loads(output.get_data(as_text=True))
  1719. self.assertDictEqual(
  1720. data,
  1721. {
  1722. "error": "Pull-Request have been deactivated for this project",
  1723. "error_code": "EPULLREQUESTSDISABLED",
  1724. },
  1725. )
  1726. # no comment added
  1727. self.session.commit()
  1728. request = pagure.lib.query.search_pull_requests(
  1729. self.session, project_id=1, requestid=1
  1730. )
  1731. self.assertEqual(len(request.comments), 0)
  1732. @patch("pagure.lib.notify.send_email")
  1733. def test_api_pull_request_add_comment_user_token(self, mockemail):
  1734. """ Test the api_pull_request_add_comment method of the flask api. """
  1735. mockemail.return_value = True
  1736. tests.create_projects(self.session)
  1737. tests.create_tokens(self.session, project_id=None)
  1738. tests.create_tokens_acl(self.session)
  1739. headers = {"Authorization": "token aaabbbcccddd"}
  1740. # Invalid project
  1741. output = self.app.post(
  1742. "/api/0/foo/pull-request/1/comment", headers=headers
  1743. )
  1744. self.assertEqual(output.status_code, 404)
  1745. data = json.loads(output.get_data(as_text=True))
  1746. self.assertDictEqual(
  1747. data, {"error": "Project not found", "error_code": "ENOPROJECT"}
  1748. )
  1749. # Valid token, invalid request
  1750. output = self.app.post(
  1751. "/api/0/test2/pull-request/1/comment", headers=headers
  1752. )
  1753. self.assertEqual(output.status_code, 404)
  1754. data = json.loads(output.get_data(as_text=True))
  1755. self.assertDictEqual(
  1756. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  1757. )
  1758. # Valid token, invalid request in another project
  1759. output = self.app.post(
  1760. "/api/0/test/pull-request/1/comment", headers=headers
  1761. )
  1762. self.assertEqual(output.status_code, 404)
  1763. data = json.loads(output.get_data(as_text=True))
  1764. self.assertDictEqual(
  1765. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  1766. )
  1767. # Create a pull-request
  1768. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1769. forked_repo = pagure.lib.query.get_authorized_project(
  1770. self.session, "test"
  1771. )
  1772. req = pagure.lib.query.new_pull_request(
  1773. session=self.session,
  1774. repo_from=forked_repo,
  1775. branch_from="master",
  1776. repo_to=repo,
  1777. branch_to="master",
  1778. title="test pull-request",
  1779. user="pingou",
  1780. )
  1781. self.session.commit()
  1782. self.assertEqual(req.id, 1)
  1783. self.assertEqual(req.title, "test pull-request")
  1784. # Check comments before
  1785. self.session.commit()
  1786. request = pagure.lib.query.search_pull_requests(
  1787. self.session, project_id=1, requestid=1
  1788. )
  1789. self.assertEqual(len(request.comments), 0)
  1790. data = {"title": "test issue"}
  1791. # Incomplete request
  1792. output = self.app.post(
  1793. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  1794. )
  1795. self.assertEqual(output.status_code, 400)
  1796. data = json.loads(output.get_data(as_text=True))
  1797. self.assertDictEqual(
  1798. data,
  1799. {
  1800. "error": "Invalid or incomplete input submitted",
  1801. "error_code": "EINVALIDREQ",
  1802. "errors": {"comment": ["This field is required."]},
  1803. },
  1804. )
  1805. # No change
  1806. self.session.commit()
  1807. request = pagure.lib.query.search_pull_requests(
  1808. self.session, project_id=1, requestid=1
  1809. )
  1810. self.assertEqual(len(request.comments), 0)
  1811. data = {"comment": "This is a very interesting question"}
  1812. # Valid request
  1813. output = self.app.post(
  1814. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  1815. )
  1816. self.assertEqual(output.status_code, 200)
  1817. data = json.loads(output.get_data(as_text=True))
  1818. self.assertDictEqual(data, {"message": "Comment added"})
  1819. # One comment added
  1820. self.session.commit()
  1821. request = pagure.lib.query.search_pull_requests(
  1822. self.session, project_id=1, requestid=1
  1823. )
  1824. self.assertEqual(len(request.comments), 1)
  1825. @patch("pagure.lib.notify.send_email")
  1826. def test_api_subscribe_pull_request_pr_disabled(self, p_send_email):
  1827. """ Test the api_subscribe_pull_request method of the flask api. """
  1828. p_send_email.return_value = True
  1829. tests.create_projects(self.session)
  1830. tests.create_tokens(self.session)
  1831. tests.create_tokens_acl(self.session)
  1832. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1833. settings = repo.settings
  1834. settings["pull_requests"] = False
  1835. repo.settings = settings
  1836. self.session.add(repo)
  1837. self.session.commit()
  1838. headers = {"Authorization": "token aaabbbcccddd"}
  1839. # Invalid project
  1840. output = self.app.post(
  1841. "/api/0/test/pull-request/1/subscribe", headers=headers
  1842. )
  1843. self.assertEqual(output.status_code, 404)
  1844. data = json.loads(output.get_data(as_text=True))
  1845. self.assertDictEqual(
  1846. data,
  1847. {
  1848. "error": "Pull-Request have been deactivated for this project",
  1849. "error_code": "EPULLREQUESTSDISABLED",
  1850. },
  1851. )
  1852. @patch("pagure.lib.git.update_git")
  1853. @patch("pagure.lib.notify.send_email")
  1854. def test_api_subscribe_pull_request_invalid_token(
  1855. self, p_send_email, p_ugt
  1856. ):
  1857. """ Test the api_subscribe_pull_request method of the flask api. """
  1858. p_send_email.return_value = True
  1859. p_ugt.return_value = True
  1860. item = pagure.lib.model.User(
  1861. user="bar",
  1862. fullname="bar foo",
  1863. password="foo",
  1864. default_email="bar@bar.com",
  1865. )
  1866. self.session.add(item)
  1867. item = pagure.lib.model.UserEmail(user_id=3, email="bar@bar.com")
  1868. self.session.add(item)
  1869. self.session.commit()
  1870. tests.create_projects(self.session)
  1871. tests.create_tokens(self.session, user_id=3, project_id=2)
  1872. tests.create_tokens_acl(self.session)
  1873. headers = {"Authorization": "token aaabbbcccddd"}
  1874. # Create pull-request
  1875. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1876. req = pagure.lib.query.new_pull_request(
  1877. session=self.session,
  1878. repo_from=repo,
  1879. branch_from="feature",
  1880. repo_to=repo,
  1881. branch_to="master",
  1882. title="test pull-request",
  1883. user="pingou",
  1884. )
  1885. self.session.commit()
  1886. self.assertEqual(req.id, 1)
  1887. self.assertEqual(req.title, "test pull-request")
  1888. # Check subscribtion before
  1889. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1890. request = pagure.lib.query.search_pull_requests(
  1891. self.session, project_id=1, requestid=1
  1892. )
  1893. self.assertEqual(
  1894. pagure.lib.query.get_watch_list(self.session, request),
  1895. set(["pingou"]),
  1896. )
  1897. data = {}
  1898. output = self.app.post(
  1899. "/api/0/test/pull-request/1/subscribe", data=data, headers=headers
  1900. )
  1901. self.assertEqual(output.status_code, 401)
  1902. data = json.loads(output.get_data(as_text=True))
  1903. self.assertDictEqual(
  1904. data,
  1905. {
  1906. "error": "Invalid or expired token. Please visit "
  1907. "http://localhost.localdomain/settings#nav-api-tab to get or "
  1908. "renew your API token.",
  1909. "error_code": "EINVALIDTOK",
  1910. },
  1911. )
  1912. @patch("pagure.lib.git.update_git")
  1913. @patch("pagure.lib.notify.send_email")
  1914. def test_api_subscribe_pull_request(self, p_send_email, p_ugt):
  1915. """ Test the api_subscribe_pull_request method of the flask api. """
  1916. p_send_email.return_value = True
  1917. p_ugt.return_value = True
  1918. item = pagure.lib.model.User(
  1919. user="bar",
  1920. fullname="bar foo",
  1921. password="foo",
  1922. default_email="bar@bar.com",
  1923. )
  1924. self.session.add(item)
  1925. item = pagure.lib.model.UserEmail(user_id=3, email="bar@bar.com")
  1926. self.session.add(item)
  1927. self.session.commit()
  1928. tests.create_projects(self.session)
  1929. tests.create_tokens(self.session, user_id=3)
  1930. tests.create_tokens_acl(self.session)
  1931. headers = {"Authorization": "token aaabbbcccddd"}
  1932. # Invalid project
  1933. output = self.app.post(
  1934. "/api/0/foo/pull-request/1/subscribe", headers=headers
  1935. )
  1936. self.assertEqual(output.status_code, 404)
  1937. data = json.loads(output.get_data(as_text=True))
  1938. self.assertDictEqual(
  1939. data, {"error": "Project not found", "error_code": "ENOPROJECT"}
  1940. )
  1941. # Valid token, wrong project
  1942. output = self.app.post(
  1943. "/api/0/test2/pull-request/1/subscribe", headers=headers
  1944. )
  1945. self.assertEqual(output.status_code, 401)
  1946. data = json.loads(output.get_data(as_text=True))
  1947. self.assertEqual(
  1948. pagure.api.APIERROR.EINVALIDTOK.name, data["error_code"]
  1949. )
  1950. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data["error"])
  1951. # No input
  1952. output = self.app.post(
  1953. "/api/0/test/pull-request/1/subscribe", headers=headers
  1954. )
  1955. self.assertEqual(output.status_code, 404)
  1956. data = json.loads(output.get_data(as_text=True))
  1957. self.assertDictEqual(
  1958. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  1959. )
  1960. # Create pull-request
  1961. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1962. req = pagure.lib.query.new_pull_request(
  1963. session=self.session,
  1964. repo_from=repo,
  1965. branch_from="feature",
  1966. repo_to=repo,
  1967. branch_to="master",
  1968. title="test pull-request",
  1969. user="pingou",
  1970. )
  1971. self.session.commit()
  1972. self.assertEqual(req.id, 1)
  1973. self.assertEqual(req.title, "test pull-request")
  1974. # Check subscribtion before
  1975. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  1976. request = pagure.lib.query.search_pull_requests(
  1977. self.session, project_id=1, requestid=1
  1978. )
  1979. self.assertEqual(
  1980. pagure.lib.query.get_watch_list(self.session, request),
  1981. set(["pingou"]),
  1982. )
  1983. # Unsubscribe - no changes
  1984. data = {}
  1985. output = self.app.post(
  1986. "/api/0/test/pull-request/1/subscribe", data=data, headers=headers
  1987. )
  1988. self.assertEqual(output.status_code, 200)
  1989. data = json.loads(output.get_data(as_text=True))
  1990. data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
  1991. self.assertDictEqual(
  1992. data,
  1993. {
  1994. "message": "You are no longer watching this pull-request",
  1995. "avatar_url": "https://seccdn.libravatar.org/avatar/...",
  1996. "user": "bar",
  1997. },
  1998. )
  1999. data = {}
  2000. output = self.app.post(
  2001. "/api/0/test/pull-request/1/subscribe", data=data, headers=headers
  2002. )
  2003. self.assertEqual(output.status_code, 200)
  2004. data = json.loads(output.get_data(as_text=True))
  2005. data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
  2006. self.assertDictEqual(
  2007. data,
  2008. {
  2009. "message": "You are no longer watching this pull-request",
  2010. "avatar_url": "https://seccdn.libravatar.org/avatar/...",
  2011. "user": "bar",
  2012. },
  2013. )
  2014. # No change
  2015. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2016. request = pagure.lib.query.search_pull_requests(
  2017. self.session, project_id=1, requestid=1
  2018. )
  2019. self.assertEqual(
  2020. pagure.lib.query.get_watch_list(self.session, request),
  2021. set(["pingou"]),
  2022. )
  2023. # Subscribe
  2024. data = {"status": True}
  2025. output = self.app.post(
  2026. "/api/0/test/pull-request/1/subscribe", data=data, headers=headers
  2027. )
  2028. self.assertEqual(output.status_code, 200)
  2029. data = json.loads(output.get_data(as_text=True))
  2030. data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
  2031. self.assertDictEqual(
  2032. data,
  2033. {
  2034. "message": "You are now watching this pull-request",
  2035. "avatar_url": "https://seccdn.libravatar.org/avatar/...",
  2036. "user": "bar",
  2037. },
  2038. )
  2039. # Subscribe - no changes
  2040. data = {"status": True}
  2041. output = self.app.post(
  2042. "/api/0/test/pull-request/1/subscribe", data=data, headers=headers
  2043. )
  2044. self.assertEqual(output.status_code, 200)
  2045. data = json.loads(output.get_data(as_text=True))
  2046. data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
  2047. self.assertDictEqual(
  2048. data,
  2049. {
  2050. "message": "You are now watching this pull-request",
  2051. "avatar_url": "https://seccdn.libravatar.org/avatar/...",
  2052. "user": "bar",
  2053. },
  2054. )
  2055. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2056. request = pagure.lib.query.search_pull_requests(
  2057. self.session, project_id=1, requestid=1
  2058. )
  2059. self.assertEqual(
  2060. pagure.lib.query.get_watch_list(self.session, request),
  2061. set(["pingou", "bar"]),
  2062. )
  2063. # Unsubscribe
  2064. data = {}
  2065. output = self.app.post(
  2066. "/api/0/test/pull-request/1/subscribe", data=data, headers=headers
  2067. )
  2068. self.assertEqual(output.status_code, 200)
  2069. data = json.loads(output.get_data(as_text=True))
  2070. data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
  2071. self.assertDictEqual(
  2072. data,
  2073. {
  2074. "message": "You are no longer watching this pull-request",
  2075. "avatar_url": "https://seccdn.libravatar.org/avatar/...",
  2076. "user": "bar",
  2077. },
  2078. )
  2079. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2080. request = pagure.lib.query.search_pull_requests(
  2081. self.session, project_id=1, requestid=1
  2082. )
  2083. self.assertEqual(
  2084. pagure.lib.query.get_watch_list(self.session, request),
  2085. set(["pingou"]),
  2086. )
  2087. @patch("pagure.lib.git.update_git")
  2088. @patch("pagure.lib.notify.send_email")
  2089. def test_api_subscribe_pull_request_logged_in(self, p_send_email, p_ugt):
  2090. """ Test the api_subscribe_pull_request method of the flask api
  2091. when the user is logged in via the UI. """
  2092. p_send_email.return_value = True
  2093. p_ugt.return_value = True
  2094. item = pagure.lib.model.User(
  2095. user="bar",
  2096. fullname="bar foo",
  2097. password="foo",
  2098. default_email="bar@bar.com",
  2099. )
  2100. self.session.add(item)
  2101. item = pagure.lib.model.UserEmail(user_id=3, email="bar@bar.com")
  2102. self.session.add(item)
  2103. self.session.commit()
  2104. tests.create_projects(self.session)
  2105. tests.create_tokens(self.session, user_id=3)
  2106. tests.create_tokens_acl(self.session)
  2107. # Create pull-request
  2108. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2109. req = pagure.lib.query.new_pull_request(
  2110. session=self.session,
  2111. repo_from=repo,
  2112. branch_from="feature",
  2113. repo_to=repo,
  2114. branch_to="master",
  2115. title="test pull-request",
  2116. user="pingou",
  2117. )
  2118. self.session.commit()
  2119. self.assertEqual(req.id, 1)
  2120. self.assertEqual(req.title, "test pull-request")
  2121. # Check subscribtion before
  2122. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2123. request = pagure.lib.query.search_pull_requests(
  2124. self.session, project_id=1, requestid=1
  2125. )
  2126. self.assertEqual(
  2127. pagure.lib.query.get_watch_list(self.session, request),
  2128. set(["pingou"]),
  2129. )
  2130. # Subscribe
  2131. user = tests.FakeUser(username="foo")
  2132. with tests.user_set(self.app.application, user):
  2133. data = {"status": True}
  2134. output = self.app.post(
  2135. "/api/0/test/pull-request/1/subscribe", data=data
  2136. )
  2137. self.assertEqual(output.status_code, 200)
  2138. data = json.loads(output.get_data(as_text=True))
  2139. data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
  2140. self.assertDictEqual(
  2141. data,
  2142. {
  2143. "message": "You are now watching this pull-request",
  2144. "avatar_url": "https://seccdn.libravatar.org/avatar/...",
  2145. "user": "foo",
  2146. },
  2147. )
  2148. # Check subscribtions after
  2149. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2150. request = pagure.lib.query.search_pull_requests(
  2151. self.session, project_id=1, requestid=1
  2152. )
  2153. self.assertEqual(
  2154. pagure.lib.query.get_watch_list(self.session, request),
  2155. set(["pingou", "foo"]),
  2156. )
  2157. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2158. def test_api_pull_request_open_invalid_project(self):
  2159. """ Test the api_pull_request_create method of the flask api when
  2160. not the project doesn't exist.
  2161. """
  2162. tests.create_projects(self.session)
  2163. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2164. tests.create_projects_git(
  2165. os.path.join(self.path, "requests"), bare=True
  2166. )
  2167. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2168. tests.add_commit_git_repo(
  2169. os.path.join(self.path, "repos", "test.git"), branch="test"
  2170. )
  2171. tests.create_tokens(self.session)
  2172. tests.create_tokens_acl(self.session)
  2173. headers = {"Authorization": "token aaabbbcccddd"}
  2174. data = {
  2175. "initial_comment": "Nothing much, the changes speak for themselves",
  2176. "branch_to": "master",
  2177. "branch_from": "test",
  2178. }
  2179. output = self.app.post(
  2180. "/api/0/foobar/pull-request/new", headers=headers, data=data
  2181. )
  2182. self.assertEqual(output.status_code, 404)
  2183. data = json.loads(output.get_data(as_text=True))
  2184. self.assertDictEqual(
  2185. data, {"error": "Project not found", "error_code": "ENOPROJECT"}
  2186. )
  2187. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2188. def test_api_pull_request_open_missing_title(self):
  2189. """ Test the api_pull_request_create method of the flask api when
  2190. not title is submitted.
  2191. """
  2192. tests.create_projects(self.session)
  2193. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2194. tests.create_projects_git(
  2195. os.path.join(self.path, "requests"), bare=True
  2196. )
  2197. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2198. tests.add_commit_git_repo(
  2199. os.path.join(self.path, "repos", "test.git"), branch="test"
  2200. )
  2201. tests.create_tokens(self.session)
  2202. tests.create_tokens_acl(self.session)
  2203. headers = {"Authorization": "token aaabbbcccddd"}
  2204. data = {
  2205. "initial_comment": "Nothing much, the changes speak for themselves",
  2206. "branch_to": "master",
  2207. "branch_from": "test",
  2208. }
  2209. output = self.app.post(
  2210. "/api/0/test/pull-request/new", headers=headers, data=data
  2211. )
  2212. self.assertEqual(output.status_code, 400)
  2213. data = json.loads(output.get_data(as_text=True))
  2214. self.assertDictEqual(
  2215. data,
  2216. {
  2217. "error": "Invalid or incomplete input submitted",
  2218. "error_code": "EINVALIDREQ",
  2219. "errors": {"title": ["This field is required."]},
  2220. },
  2221. )
  2222. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2223. def test_api_pull_request_open_missing_branch_to(self):
  2224. """ Test the api_pull_request_create method of the flask api when
  2225. not branch to is submitted.
  2226. """
  2227. tests.create_projects(self.session)
  2228. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2229. tests.create_projects_git(
  2230. os.path.join(self.path, "requests"), bare=True
  2231. )
  2232. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2233. tests.add_commit_git_repo(
  2234. os.path.join(self.path, "repos", "test.git"), branch="test"
  2235. )
  2236. tests.create_tokens(self.session)
  2237. tests.create_tokens_acl(self.session)
  2238. headers = {"Authorization": "token aaabbbcccddd"}
  2239. data = {
  2240. "title": "Test PR",
  2241. "initial_comment": "Nothing much, the changes speak for themselves",
  2242. "branch_from": "test",
  2243. }
  2244. output = self.app.post(
  2245. "/api/0/test/pull-request/new", headers=headers, data=data
  2246. )
  2247. self.assertEqual(output.status_code, 400)
  2248. data = json.loads(output.get_data(as_text=True))
  2249. self.assertDictEqual(
  2250. data,
  2251. {
  2252. "error": "Invalid or incomplete input submitted",
  2253. "error_code": "EINVALIDREQ",
  2254. "errors": {"branch_to": ["This field is required."]},
  2255. },
  2256. )
  2257. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2258. def test_api_pull_request_open_missing_branch_from(self):
  2259. """ Test the api_pull_request_create method of the flask api when
  2260. not branch from is submitted.
  2261. """
  2262. tests.create_projects(self.session)
  2263. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2264. tests.create_projects_git(
  2265. os.path.join(self.path, "requests"), bare=True
  2266. )
  2267. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2268. tests.add_commit_git_repo(
  2269. os.path.join(self.path, "repos", "test.git"), branch="test"
  2270. )
  2271. tests.create_tokens(self.session)
  2272. tests.create_tokens_acl(self.session)
  2273. headers = {"Authorization": "token aaabbbcccddd"}
  2274. data = {
  2275. "title": "Test PR",
  2276. "initial_comment": "Nothing much, the changes speak for themselves",
  2277. "branch_to": "master",
  2278. }
  2279. output = self.app.post(
  2280. "/api/0/test/pull-request/new", headers=headers, data=data
  2281. )
  2282. self.assertEqual(output.status_code, 400)
  2283. data = json.loads(output.get_data(as_text=True))
  2284. self.assertDictEqual(
  2285. data,
  2286. {
  2287. "error": "Invalid or incomplete input submitted",
  2288. "error_code": "EINVALIDREQ",
  2289. "errors": {"branch_from": ["This field is required."]},
  2290. },
  2291. )
  2292. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2293. def test_api_pull_request_open_pr_disabled(self):
  2294. """ Test the api_pull_request_create method of the flask api when
  2295. the parent repo disabled pull-requests.
  2296. """
  2297. tests.create_projects(self.session)
  2298. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2299. tests.create_projects_git(
  2300. os.path.join(self.path, "requests"), bare=True
  2301. )
  2302. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2303. tests.add_commit_git_repo(
  2304. os.path.join(self.path, "repos", "test.git"), branch="test"
  2305. )
  2306. tests.create_tokens(self.session)
  2307. tests.create_tokens_acl(self.session)
  2308. # Check the behavior if the project disabled the issue tracker
  2309. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2310. settings = repo.settings
  2311. settings["pull_requests"] = False
  2312. repo.settings = settings
  2313. self.session.add(repo)
  2314. self.session.commit()
  2315. headers = {"Authorization": "token aaabbbcccddd"}
  2316. data = {
  2317. "title": "Test PR",
  2318. "initial_comment": "Nothing much, the changes speak for themselves",
  2319. "branch_to": "master",
  2320. "branch_from": "test",
  2321. }
  2322. output = self.app.post(
  2323. "/api/0/test/pull-request/new", headers=headers, data=data
  2324. )
  2325. self.assertEqual(output.status_code, 404)
  2326. data = json.loads(output.get_data(as_text=True))
  2327. self.assertDictEqual(
  2328. data,
  2329. {
  2330. "error": "Pull-Request have been deactivated for this project",
  2331. "error_code": "EPULLREQUESTSDISABLED",
  2332. },
  2333. )
  2334. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2335. def test_api_pull_request_open_signed_pr(self):
  2336. """ Test the api_pull_request_create method of the flask api when
  2337. the parent repo enforces signed-off pull-requests.
  2338. """
  2339. tests.create_projects(self.session)
  2340. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2341. tests.create_projects_git(
  2342. os.path.join(self.path, "requests"), bare=True
  2343. )
  2344. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2345. tests.add_commit_git_repo(
  2346. os.path.join(self.path, "repos", "test.git"), branch="test"
  2347. )
  2348. tests.create_tokens(self.session)
  2349. tests.create_tokens_acl(self.session)
  2350. # Check the behavior if the project disabled the issue tracker
  2351. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2352. settings = repo.settings
  2353. settings["Enforce_signed-off_commits_in_pull-request"] = True
  2354. repo.settings = settings
  2355. self.session.add(repo)
  2356. self.session.commit()
  2357. headers = {"Authorization": "token aaabbbcccddd"}
  2358. data = {
  2359. "title": "Test PR",
  2360. "initial_comment": "Nothing much, the changes speak for themselves",
  2361. "branch_to": "master",
  2362. "branch_from": "test",
  2363. }
  2364. output = self.app.post(
  2365. "/api/0/test/pull-request/new", headers=headers, data=data
  2366. )
  2367. self.assertEqual(output.status_code, 400)
  2368. data = json.loads(output.get_data(as_text=True))
  2369. self.assertDictEqual(
  2370. data,
  2371. {
  2372. "error": "This repo enforces that all commits are signed "
  2373. "off by their author.",
  2374. "error_code": "ENOSIGNEDOFF",
  2375. },
  2376. )
  2377. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2378. def test_api_pull_request_open_invalid_branch_from(self):
  2379. """ Test the api_pull_request_create method of the flask api when
  2380. the branch from does not exist.
  2381. """
  2382. tests.create_projects(self.session)
  2383. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2384. tests.create_projects_git(
  2385. os.path.join(self.path, "requests"), bare=True
  2386. )
  2387. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2388. tests.add_commit_git_repo(
  2389. os.path.join(self.path, "repos", "test.git"), branch="test"
  2390. )
  2391. tests.create_tokens(self.session)
  2392. tests.create_tokens_acl(self.session)
  2393. # Check the behavior if the project disabled the issue tracker
  2394. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2395. settings = repo.settings
  2396. settings["Enforce_signed-off_commits_in_pull-request"] = True
  2397. repo.settings = settings
  2398. self.session.add(repo)
  2399. self.session.commit()
  2400. headers = {"Authorization": "token aaabbbcccddd"}
  2401. data = {
  2402. "title": "Test PR",
  2403. "initial_comment": "Nothing much, the changes speak for themselves",
  2404. "branch_to": "master",
  2405. "branch_from": "foobarbaz",
  2406. }
  2407. output = self.app.post(
  2408. "/api/0/test/pull-request/new", headers=headers, data=data
  2409. )
  2410. self.assertEqual(output.status_code, 400)
  2411. data = json.loads(output.get_data(as_text=True))
  2412. self.assertDictEqual(
  2413. data,
  2414. {
  2415. "error": "Invalid or incomplete input submitted",
  2416. "error_code": "EINVALIDREQ",
  2417. "errors": "Branch foobarbaz does not exist",
  2418. },
  2419. )
  2420. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2421. def test_api_pull_request_open_invalid_token(self):
  2422. """ Test the api_pull_request_create method of the flask api when
  2423. queried with an invalid token.
  2424. """
  2425. tests.create_projects(self.session)
  2426. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2427. tests.create_projects_git(
  2428. os.path.join(self.path, "requests"), bare=True
  2429. )
  2430. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2431. tests.add_commit_git_repo(
  2432. os.path.join(self.path, "repos", "test.git"), branch="test"
  2433. )
  2434. tests.create_tokens(self.session)
  2435. tests.create_tokens_acl(self.session)
  2436. headers = {"Authorization": "token aaabbbcccddd"}
  2437. data = {
  2438. "title": "Test PR",
  2439. "initial_comment": "Nothing much, the changes speak for themselves",
  2440. "branch_to": "master",
  2441. "branch_from": "foobarbaz",
  2442. }
  2443. output = self.app.post(
  2444. "/api/0/test2/pull-request/new", headers=headers, data=data
  2445. )
  2446. self.assertEqual(output.status_code, 401)
  2447. data = json.loads(output.get_data(as_text=True))
  2448. self.assertDictEqual(
  2449. data,
  2450. {
  2451. "error": "Invalid or expired token. Please visit "
  2452. "http://localhost.localdomain/settings#nav-api-tab to get or "
  2453. "renew your API token.",
  2454. "error_code": "EINVALIDTOK",
  2455. },
  2456. )
  2457. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2458. def test_api_pull_request_open_invalid_access(self):
  2459. """ Test the api_pull_request_create method of the flask api when
  2460. the user opening the PR doesn't have commit access.
  2461. """
  2462. tests.create_projects(self.session)
  2463. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2464. tests.create_projects_git(
  2465. os.path.join(self.path, "requests"), bare=True
  2466. )
  2467. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2468. tests.add_commit_git_repo(
  2469. os.path.join(self.path, "repos", "test.git"), branch="test"
  2470. )
  2471. tests.create_tokens(self.session, user_id=2)
  2472. tests.create_tokens_acl(self.session)
  2473. headers = {"Authorization": "token aaabbbcccddd"}
  2474. data = {
  2475. "title": "Test PR",
  2476. "initial_comment": "Nothing much, the changes speak for themselves",
  2477. "branch_to": "master",
  2478. "branch_from": "foobarbaz",
  2479. }
  2480. output = self.app.post(
  2481. "/api/0/test/pull-request/new", headers=headers, data=data
  2482. )
  2483. self.assertEqual(output.status_code, 401)
  2484. data = json.loads(output.get_data(as_text=True))
  2485. self.assertDictEqual(
  2486. data,
  2487. {
  2488. "error": "You do not have sufficient permissions to "
  2489. "perform this action",
  2490. "error_code": "ENOTHIGHENOUGH",
  2491. },
  2492. )
  2493. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2494. def test_api_pull_request_open_invalid_branch_to(self):
  2495. """ Test the api_pull_request_create method of the flask api when
  2496. the branch to does not exist.
  2497. """
  2498. tests.create_projects(self.session)
  2499. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2500. tests.create_projects_git(
  2501. os.path.join(self.path, "requests"), bare=True
  2502. )
  2503. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2504. tests.add_commit_git_repo(
  2505. os.path.join(self.path, "repos", "test.git"), branch="test"
  2506. )
  2507. tests.create_tokens(self.session)
  2508. tests.create_tokens_acl(self.session)
  2509. # Check the behavior if the project disabled the issue tracker
  2510. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2511. settings = repo.settings
  2512. settings["Enforce_signed-off_commits_in_pull-request"] = True
  2513. repo.settings = settings
  2514. self.session.add(repo)
  2515. self.session.commit()
  2516. headers = {"Authorization": "token aaabbbcccddd"}
  2517. data = {
  2518. "title": "Test PR",
  2519. "initial_comment": "Nothing much, the changes speak for themselves",
  2520. "branch_to": "foobarbaz",
  2521. "branch_from": "test",
  2522. }
  2523. output = self.app.post(
  2524. "/api/0/test/pull-request/new", headers=headers, data=data
  2525. )
  2526. self.assertEqual(output.status_code, 400)
  2527. data = json.loads(output.get_data(as_text=True))
  2528. self.assertDictEqual(
  2529. data,
  2530. {
  2531. "error": "Invalid or incomplete input submitted",
  2532. "error_code": "EINVALIDREQ",
  2533. "errors": "Branch foobarbaz could not be found in the "
  2534. "target repo",
  2535. },
  2536. )
  2537. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2538. def test_api_pull_request_open_project_token_different_project(self):
  2539. """Test the api_pull_request_create method with the project token
  2540. of a different project - fails"""
  2541. tests.create_projects(self.session)
  2542. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2543. tests.create_projects_git(
  2544. os.path.join(self.path, "requests"), bare=True
  2545. )
  2546. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2547. tests.add_commit_git_repo(
  2548. os.path.join(self.path, "repos", "test.git"), branch="test"
  2549. )
  2550. tests.create_tokens(self.session, project_id=2)
  2551. tests.create_tokens_acl(self.session)
  2552. headers = {"Authorization": "token foo_token"}
  2553. data = {
  2554. "title": "Test of PR",
  2555. "inicial comment": "Some readme adjustment",
  2556. "branch_to": "master",
  2557. "branch_from": "test",
  2558. }
  2559. output = self.app.post(
  2560. "/api/0/test/pull-request/new", headers=headers, data=data
  2561. )
  2562. self.assertEqual(output.status_code, 401)
  2563. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2564. def test_api_pull_request_open_user_token_invalid_acls(self):
  2565. """Test the api_pull_request_create method with the user token, but with
  2566. no acls for opening pull request - fails"""
  2567. tests.create_projects(self.session)
  2568. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2569. tests.create_projects_git(
  2570. os.path.join(self.path, "requests"), bare=True
  2571. )
  2572. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2573. tests.add_commit_git_repo(
  2574. os.path.join(self.path, "repos", "test.git"), branch="test"
  2575. )
  2576. tests.create_tokens(self.session, project_id=None)
  2577. for acl in (
  2578. "create_project",
  2579. "fork_project",
  2580. "modify_project",
  2581. "update_watch_status",
  2582. ):
  2583. tests.create_tokens_acl(self.session, acl_name=acl)
  2584. headers = {"Authorization": "token aaabbbcccddd"}
  2585. data = {
  2586. "title": "Test of PR",
  2587. "initial_comment": "Some readme adjustment",
  2588. "branch_to": "master",
  2589. "branch_from": "test",
  2590. }
  2591. output = self.app.post(
  2592. "/api/0/test/pull-request/new", headers=headers, data=data
  2593. )
  2594. self.assertEqual(output.status_code, 401)
  2595. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2596. def test_api_pull_request_open_from_branch_to_origin(self):
  2597. """Test the api_pull_request_create method from a fork to a master,
  2598. with project token of a origin with all the acls"""
  2599. tests.create_projects(self.session)
  2600. tests.create_projects(
  2601. self.session, is_fork=True, hook_token_suffix="foo"
  2602. )
  2603. project_query = self.session.query(pagure.lib.model.Project)
  2604. for project in project_query.filter_by(name="test").all():
  2605. if project.parent_id == None:
  2606. parent = project
  2607. else:
  2608. child = project
  2609. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2610. tests.create_projects_git(
  2611. os.path.join(self.path, "requests"), bare=True
  2612. )
  2613. tests.add_readme_git_repo(
  2614. os.path.join(self.path, "repos", "forks", "pingou", "test.git"),
  2615. branch="branch",
  2616. )
  2617. tests.add_commit_git_repo(
  2618. os.path.join(self.path, "repos", "forks", "pingou", "test.git"),
  2619. branch="branch",
  2620. )
  2621. # Create tokens
  2622. parent_token = pagure.lib.model.Token(
  2623. id="iamparenttoken",
  2624. user_id=parent.user_id,
  2625. project_id=parent.id,
  2626. expiration=datetime.datetime.utcnow()
  2627. + datetime.timedelta(days=30),
  2628. )
  2629. self.session.add(parent_token)
  2630. fork_token = pagure.lib.model.Token(
  2631. id="iamforktoken",
  2632. user_id=child.user_id,
  2633. project_id=child.id,
  2634. expiration=datetime.datetime.utcnow()
  2635. + datetime.timedelta(days=30),
  2636. )
  2637. self.session.add(fork_token)
  2638. self.session.commit()
  2639. tests.create_tokens_acl(self.session, token_id="iamparenttoken")
  2640. for acl in pagure.default_config.CROSS_PROJECT_ACLS:
  2641. tests.create_tokens_acl(
  2642. self.session, token_id="iamforktoken", acl_name=acl
  2643. )
  2644. headers = {"Authorization": "token iamforktoken"}
  2645. data = {
  2646. "title": "war of tomatoes",
  2647. "initial_comment": "the manifest",
  2648. "branch_to": "master",
  2649. "branch_from": "branch",
  2650. "repo_from": "test",
  2651. "repo_from_username": "pingou",
  2652. }
  2653. output = self.app.post(
  2654. "/api/0/test/pull-request/new", headers=headers, data=data
  2655. )
  2656. self.assertEqual(output.status_code, 200)
  2657. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2658. def test_api_pull_request_open(self):
  2659. """ Test the api_pull_request_create method of the flask api. """
  2660. tests.create_projects(self.session)
  2661. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2662. tests.create_projects_git(
  2663. os.path.join(self.path, "requests"), bare=True
  2664. )
  2665. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2666. tests.add_commit_git_repo(
  2667. os.path.join(self.path, "repos", "test.git"), branch="test"
  2668. )
  2669. tests.create_tokens(self.session)
  2670. tests.create_tokens_acl(self.session)
  2671. headers = {"Authorization": "token aaabbbcccddd"}
  2672. data = {
  2673. "title": "Test PR",
  2674. "initial_comment": "Nothing much, the changes speak for themselves",
  2675. "branch_to": "master",
  2676. "branch_from": "test",
  2677. }
  2678. output = self.app.post(
  2679. "/api/0/test/pull-request/new", headers=headers, data=data
  2680. )
  2681. self.assertEqual(output.status_code, 200)
  2682. data = json.loads(output.get_data(as_text=True))
  2683. data["project"]["date_created"] = "1516348115"
  2684. data["project"]["date_modified"] = "1516348115"
  2685. data["repo_from"]["date_created"] = "1516348115"
  2686. data["repo_from"]["date_modified"] = "1516348115"
  2687. data["uid"] = "e8b68df8711648deac67c3afed15a798"
  2688. data["commit_start"] = "114f1b468a5f05e635fcb6394273f3f907386eab"
  2689. data["commit_stop"] = "114f1b468a5f05e635fcb6394273f3f907386eab"
  2690. data["date_created"] = "1516348115"
  2691. data["last_updated"] = "1516348115"
  2692. data["updated_on"] = "1516348115"
  2693. self.assertDictEqual(
  2694. data,
  2695. {
  2696. "assignee": None,
  2697. "branch": "master",
  2698. "branch_from": "test",
  2699. "cached_merge_status": "unknown",
  2700. "closed_at": None,
  2701. "closed_by": None,
  2702. "comments": [],
  2703. "commit_start": "114f1b468a5f05e635fcb6394273f3f907386eab",
  2704. "commit_stop": "114f1b468a5f05e635fcb6394273f3f907386eab",
  2705. "date_created": "1516348115",
  2706. "id": 1,
  2707. "initial_comment": "Nothing much, the changes speak for themselves",
  2708. "last_updated": "1516348115",
  2709. "project": {
  2710. "access_groups": {"admin": [], "commit": [], "ticket": []},
  2711. "access_users": {
  2712. "admin": [],
  2713. "commit": [],
  2714. "owner": ["pingou"],
  2715. "ticket": [],
  2716. },
  2717. "close_status": [
  2718. "Invalid",
  2719. "Insufficient data",
  2720. "Fixed",
  2721. "Duplicate",
  2722. ],
  2723. "custom_keys": [],
  2724. "date_created": "1516348115",
  2725. "date_modified": "1516348115",
  2726. "description": "test project #1",
  2727. "fullname": "test",
  2728. "id": 1,
  2729. "milestones": {},
  2730. "name": "test",
  2731. "namespace": None,
  2732. "parent": None,
  2733. "priorities": {},
  2734. "tags": [],
  2735. "url_path": "test",
  2736. "user": {"fullname": "PY C", "name": "pingou"},
  2737. },
  2738. "remote_git": None,
  2739. "repo_from": {
  2740. "access_groups": {"admin": [], "commit": [], "ticket": []},
  2741. "access_users": {
  2742. "admin": [],
  2743. "commit": [],
  2744. "owner": ["pingou"],
  2745. "ticket": [],
  2746. },
  2747. "close_status": [
  2748. "Invalid",
  2749. "Insufficient data",
  2750. "Fixed",
  2751. "Duplicate",
  2752. ],
  2753. "custom_keys": [],
  2754. "date_created": "1516348115",
  2755. "date_modified": "1516348115",
  2756. "description": "test project #1",
  2757. "fullname": "test",
  2758. "id": 1,
  2759. "milestones": {},
  2760. "name": "test",
  2761. "namespace": None,
  2762. "parent": None,
  2763. "priorities": {},
  2764. "tags": [],
  2765. "url_path": "test",
  2766. "user": {"fullname": "PY C", "name": "pingou"},
  2767. },
  2768. "status": "Open",
  2769. "tags": [],
  2770. "threshold_reached": None,
  2771. "title": "Test PR",
  2772. "uid": "e8b68df8711648deac67c3afed15a798",
  2773. "updated_on": "1516348115",
  2774. "user": {"fullname": "PY C", "name": "pingou"},
  2775. },
  2776. )
  2777. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2778. def test_api_pull_request_open_missing_initial_comment(self):
  2779. """ Test the api_pull_request_create method of the flask api when
  2780. not initial comment is submitted.
  2781. """
  2782. tests.create_projects(self.session)
  2783. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2784. tests.create_projects_git(
  2785. os.path.join(self.path, "requests"), bare=True
  2786. )
  2787. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2788. tests.add_commit_git_repo(
  2789. os.path.join(self.path, "repos", "test.git"), branch="test"
  2790. )
  2791. tests.create_tokens(self.session)
  2792. tests.create_tokens_acl(self.session)
  2793. headers = {"Authorization": "token aaabbbcccddd"}
  2794. data = {
  2795. "title": "Test PR",
  2796. "branch_to": "master",
  2797. "branch_from": "test",
  2798. }
  2799. output = self.app.post(
  2800. "/api/0/test/pull-request/new", headers=headers, data=data
  2801. )
  2802. self.assertEqual(output.status_code, 200)
  2803. data = json.loads(output.get_data(as_text=True))
  2804. data["project"]["date_created"] = "1516348115"
  2805. data["project"]["date_modified"] = "1516348115"
  2806. data["repo_from"]["date_created"] = "1516348115"
  2807. data["repo_from"]["date_modified"] = "1516348115"
  2808. data["uid"] = "e8b68df8711648deac67c3afed15a798"
  2809. data["commit_start"] = "114f1b468a5f05e635fcb6394273f3f907386eab"
  2810. data["commit_stop"] = "114f1b468a5f05e635fcb6394273f3f907386eab"
  2811. data["date_created"] = "1516348115"
  2812. data["last_updated"] = "1516348115"
  2813. data["updated_on"] = "1516348115"
  2814. self.assertDictEqual(
  2815. data,
  2816. {
  2817. "assignee": None,
  2818. "branch": "master",
  2819. "branch_from": "test",
  2820. "cached_merge_status": "unknown",
  2821. "closed_at": None,
  2822. "closed_by": None,
  2823. "comments": [],
  2824. "commit_start": "114f1b468a5f05e635fcb6394273f3f907386eab",
  2825. "commit_stop": "114f1b468a5f05e635fcb6394273f3f907386eab",
  2826. "date_created": "1516348115",
  2827. "id": 1,
  2828. "initial_comment": None,
  2829. "last_updated": "1516348115",
  2830. "project": {
  2831. "access_groups": {"admin": [], "commit": [], "ticket": []},
  2832. "access_users": {
  2833. "admin": [],
  2834. "commit": [],
  2835. "owner": ["pingou"],
  2836. "ticket": [],
  2837. },
  2838. "close_status": [
  2839. "Invalid",
  2840. "Insufficient data",
  2841. "Fixed",
  2842. "Duplicate",
  2843. ],
  2844. "custom_keys": [],
  2845. "date_created": "1516348115",
  2846. "date_modified": "1516348115",
  2847. "description": "test project #1",
  2848. "fullname": "test",
  2849. "id": 1,
  2850. "milestones": {},
  2851. "name": "test",
  2852. "namespace": None,
  2853. "parent": None,
  2854. "priorities": {},
  2855. "tags": [],
  2856. "url_path": "test",
  2857. "user": {"fullname": "PY C", "name": "pingou"},
  2858. },
  2859. "remote_git": None,
  2860. "repo_from": {
  2861. "access_groups": {"admin": [], "commit": [], "ticket": []},
  2862. "access_users": {
  2863. "admin": [],
  2864. "commit": [],
  2865. "owner": ["pingou"],
  2866. "ticket": [],
  2867. },
  2868. "close_status": [
  2869. "Invalid",
  2870. "Insufficient data",
  2871. "Fixed",
  2872. "Duplicate",
  2873. ],
  2874. "custom_keys": [],
  2875. "date_created": "1516348115",
  2876. "date_modified": "1516348115",
  2877. "description": "test project #1",
  2878. "fullname": "test",
  2879. "id": 1,
  2880. "milestones": {},
  2881. "name": "test",
  2882. "namespace": None,
  2883. "parent": None,
  2884. "priorities": {},
  2885. "tags": [],
  2886. "url_path": "test",
  2887. "user": {"fullname": "PY C", "name": "pingou"},
  2888. },
  2889. "status": "Open",
  2890. "tags": [],
  2891. "threshold_reached": None,
  2892. "title": "Test PR",
  2893. "uid": "e8b68df8711648deac67c3afed15a798",
  2894. "updated_on": "1516348115",
  2895. "user": {"fullname": "PY C", "name": "pingou"},
  2896. },
  2897. )
  2898. class PagureFlaskApiForkPRDiffStatstests(tests.Modeltests):
  2899. """ Tests for the flask API of pagure for the diff stats endpoint of PRs
  2900. """
  2901. maxDiff = None
  2902. def setUp(self):
  2903. """ Set up the environnment, ran before every tests. """
  2904. super(PagureFlaskApiForkPRDiffStatstests, self).setUp()
  2905. pagure.config.config["REQUESTS_FOLDER"] = None
  2906. tests.create_projects(self.session)
  2907. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2908. tests.create_projects_git(
  2909. os.path.join(self.path, "requests"), bare=True
  2910. )
  2911. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  2912. tests.add_commit_git_repo(
  2913. os.path.join(self.path, "repos", "test.git"), ncommits=5
  2914. )
  2915. tests.add_commit_git_repo(
  2916. os.path.join(self.path, "repos", "test.git"), branch="test"
  2917. )
  2918. # Create the pull-request to close
  2919. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2920. req = pagure.lib.query.new_pull_request(
  2921. session=self.session,
  2922. repo_from=repo,
  2923. branch_from="test",
  2924. repo_to=repo,
  2925. branch_to="master",
  2926. title="test pull-request",
  2927. user="pingou",
  2928. )
  2929. self.session.commit()
  2930. self.assertEqual(req.id, 1)
  2931. self.assertEqual(req.title, "test pull-request")
  2932. @patch("pagure.lib.git.update_git", MagicMock(return_value=True))
  2933. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2934. def test_api_pull_request_diffstats_no_repo(self):
  2935. """ Test the api_pull_request_merge method of the flask api. """
  2936. output = self.app.get("/api/0/invalid/pull-request/404/diffstats")
  2937. self.assertEqual(output.status_code, 404)
  2938. data = json.loads(output.get_data(as_text=True))
  2939. self.assertEqual(
  2940. data, {"error": "Project not found", "error_code": "ENOPROJECT"}
  2941. )
  2942. @patch("pagure.lib.git.update_git", MagicMock(return_value=True))
  2943. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2944. def test_api_pull_request_diffstats_no_pr(self):
  2945. """ Test the api_pull_request_merge method of the flask api. """
  2946. output = self.app.get("/api/0/test/pull-request/404/diffstats")
  2947. self.assertEqual(output.status_code, 404)
  2948. data = json.loads(output.get_data(as_text=True))
  2949. self.assertEqual(
  2950. data, {"error": "Pull-Request not found", "error_code": "ENOREQ"}
  2951. )
  2952. @patch("pagure.lib.git.update_git", MagicMock(return_value=True))
  2953. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2954. def test_api_pull_request_diffstats_file_modified(self):
  2955. """ Test the api_pull_request_merge method of the flask api. """
  2956. output = self.app.get("/api/0/test/pull-request/1/diffstats")
  2957. self.assertEqual(output.status_code, 200)
  2958. data = json.loads(output.get_data(as_text=True))
  2959. self.assertEqual(
  2960. data,
  2961. {
  2962. "sources": {
  2963. "lines_added": 10,
  2964. "lines_removed": 0,
  2965. "new_id": "540916fbd3d825d14cc0c0b2397606fda69379ce",
  2966. "old_id": "265f133a7c94ede4cb183dd808219c5bf9e08f87",
  2967. "old_path": "sources",
  2968. "status": "M",
  2969. }
  2970. },
  2971. )
  2972. @patch("pagure.lib.git.update_git", MagicMock(return_value=True))
  2973. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  2974. def test_api_pull_request_diffstats_file_added_mofidied(self):
  2975. """ Test the api_pull_request_merge method of the flask api. """
  2976. tests.add_commit_git_repo(
  2977. os.path.join(self.path, "repos", "test.git"), ncommits=5
  2978. )
  2979. tests.add_readme_git_repo(
  2980. os.path.join(self.path, "repos", "test.git"),
  2981. readme_name="README.md",
  2982. branch="test",
  2983. )
  2984. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  2985. self.assertEqual(len(repo.requests), 1)
  2986. output = self.app.get("/api/0/test/pull-request/1/diffstats")
  2987. self.assertEqual(output.status_code, 200)
  2988. data = json.loads(output.get_data(as_text=True))
  2989. self.assertTrue(
  2990. data
  2991. in [
  2992. {
  2993. "README.md": {
  2994. "lines_added": 5,
  2995. "lines_removed": 0,
  2996. "new_id": "bd913ea153650b94f33f53e5164c36a28b761bf4",
  2997. "old_id": "0000000000000000000000000000000000000000",
  2998. "old_path": "README.md",
  2999. "status": "A",
  3000. },
  3001. "sources": {
  3002. "lines_added": 5,
  3003. "lines_removed": 0,
  3004. "new_id": "540916fbd3d825d14cc0c0b2397606fda69379ce",
  3005. "old_id": "293500070b9dfc6ab66e31383f8f7fccf6a95fe2",
  3006. "old_path": "sources",
  3007. "status": "M",
  3008. },
  3009. },
  3010. {
  3011. "README.md": {
  3012. "lines_added": 5,
  3013. "lines_removed": 0,
  3014. "new_id": "bd913ea153650b94f33f53e5164c36a28b761bf4",
  3015. "old_id": "0000000000000000000000000000000000000000",
  3016. "old_path": "README.md",
  3017. "status": "A",
  3018. },
  3019. "sources": {
  3020. "lines_added": 10,
  3021. "lines_removed": 0,
  3022. "new_id": "540916fbd3d825d14cc0c0b2397606fda69379ce",
  3023. "old_id": "265f133a7c94ede4cb183dd808219c5bf9e08f87",
  3024. "old_path": "sources",
  3025. "status": "M",
  3026. },
  3027. },
  3028. ]
  3029. )
  3030. @patch("pagure.lib.git.update_git", MagicMock(return_value=True))
  3031. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  3032. def test_api_pull_request_diffstats_file_modified_deleted(self):
  3033. """ Test the api_pull_request_merge method of the flask api. """
  3034. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  3035. self.assertEqual(len(repo.requests), 1)
  3036. pagure.lib.tasks.update_pull_request(repo.requests[0].uid)
  3037. tests.add_readme_git_repo(
  3038. os.path.join(self.path, "repos", "test.git"),
  3039. readme_name="README.md",
  3040. branch="test",
  3041. )
  3042. tests.remove_file_git_repo(
  3043. os.path.join(self.path, "repos", "test.git"),
  3044. filename="sources",
  3045. branch="test",
  3046. )
  3047. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  3048. self.assertEqual(len(repo.requests), 1)
  3049. pagure.lib.tasks.update_pull_request(repo.requests[0].uid)
  3050. output = self.app.get("/api/0/test/pull-request/1/diffstats")
  3051. self.assertEqual(output.status_code, 200)
  3052. data = json.loads(output.get_data(as_text=True))
  3053. self.assertEqual(
  3054. data,
  3055. {
  3056. "README.md": {
  3057. "lines_added": 5,
  3058. "lines_removed": 0,
  3059. "new_id": "bd913ea153650b94f33f53e5164c36a28b761bf4",
  3060. "old_id": "0000000000000000000000000000000000000000",
  3061. "old_path": "README.md",
  3062. "status": "A",
  3063. },
  3064. "sources": {
  3065. "lines_added": 0,
  3066. "lines_removed": 5,
  3067. "new_id": "0000000000000000000000000000000000000000",
  3068. "old_id": "265f133a7c94ede4cb183dd808219c5bf9e08f87",
  3069. "old_path": "sources",
  3070. "status": "D",
  3071. },
  3072. },
  3073. )
  3074. class PagureApiThresholdReachedTests(tests.Modeltests):
  3075. """ Test the behavior of the threshold_reached value returned by the API.
  3076. """
  3077. maxDiff = None
  3078. def _clean_data(self, data):
  3079. data["project"]["date_created"] = "1516348115"
  3080. data["project"]["date_modified"] = "1516348115"
  3081. data["repo_from"]["date_created"] = "1516348115"
  3082. data["repo_from"]["date_modified"] = "1516348115"
  3083. data["uid"] = "e8b68df8711648deac67c3afed15a798"
  3084. data["commit_start"] = "114f1b468a5f05e635fcb6394273f3f907386eab"
  3085. data["commit_stop"] = "114f1b468a5f05e635fcb6394273f3f907386eab"
  3086. data["date_created"] = "1516348115"
  3087. data["last_updated"] = "1516348115"
  3088. data["updated_on"] = "1516348115"
  3089. data["comments"] = [] # Let's not check the comments
  3090. return data
  3091. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  3092. def setUp(self):
  3093. """ Set up the environment for the tests. """
  3094. super(PagureApiThresholdReachedTests, self).setUp()
  3095. tests.create_projects(self.session)
  3096. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  3097. tests.create_projects_git(
  3098. os.path.join(self.path, "requests"), bare=True
  3099. )
  3100. tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git"))
  3101. tests.add_commit_git_repo(
  3102. os.path.join(self.path, "repos", "test.git"), branch="test"
  3103. )
  3104. tests.create_tokens(self.session)
  3105. tests.create_tokens_acl(self.session)
  3106. # Add a token for user `foo`
  3107. item = pagure.lib.model.Token(
  3108. id="aaabbbcccddd_foo",
  3109. user_id=2,
  3110. project_id=1,
  3111. expiration=datetime.datetime.utcnow()
  3112. + datetime.timedelta(days=30),
  3113. )
  3114. self.session.add(item)
  3115. self.session.commit()
  3116. tests.create_tokens_acl(self.session, token_id="aaabbbcccddd_foo")
  3117. # Add a minimal required score:
  3118. repo = pagure.lib.query._get_project(self.session, "test")
  3119. settings = repo.settings
  3120. settings["Minimum_score_to_merge_pull-request"] = 2
  3121. repo.settings = settings
  3122. self.session.add(repo)
  3123. self.session.commit()
  3124. headers = {"Authorization": "token aaabbbcccddd"}
  3125. data = {
  3126. "title": "Test PR",
  3127. "initial_comment": "Nothing much, the changes speak for themselves",
  3128. "branch_to": "master",
  3129. "branch_from": "test",
  3130. }
  3131. output = self.app.post(
  3132. "/api/0/test/pull-request/new", headers=headers, data=data
  3133. )
  3134. self.assertEqual(output.status_code, 200)
  3135. self.expected_data = {
  3136. "assignee": None,
  3137. "branch": "master",
  3138. "branch_from": "test",
  3139. "cached_merge_status": "unknown",
  3140. "closed_at": None,
  3141. "closed_by": None,
  3142. "comments": [],
  3143. "commit_start": "114f1b468a5f05e635fcb6394273f3f907386eab",
  3144. "commit_stop": "114f1b468a5f05e635fcb6394273f3f907386eab",
  3145. "date_created": "1516348115",
  3146. "id": 1,
  3147. "initial_comment": "Nothing much, the changes speak for themselves",
  3148. "last_updated": "1516348115",
  3149. "project": {
  3150. "access_groups": {"admin": [], "commit": [], "ticket": []},
  3151. "access_users": {
  3152. "admin": [],
  3153. "commit": [],
  3154. "owner": ["pingou"],
  3155. "ticket": [],
  3156. },
  3157. "close_status": [
  3158. "Invalid",
  3159. "Insufficient data",
  3160. "Fixed",
  3161. "Duplicate",
  3162. ],
  3163. "custom_keys": [],
  3164. "date_created": "1516348115",
  3165. "date_modified": "1516348115",
  3166. "description": "test project #1",
  3167. "fullname": "test",
  3168. "id": 1,
  3169. "milestones": {},
  3170. "name": "test",
  3171. "namespace": None,
  3172. "parent": None,
  3173. "priorities": {},
  3174. "tags": [],
  3175. "url_path": "test",
  3176. "user": {"fullname": "PY C", "name": "pingou"},
  3177. },
  3178. "remote_git": None,
  3179. "repo_from": {
  3180. "access_groups": {"admin": [], "commit": [], "ticket": []},
  3181. "access_users": {
  3182. "admin": [],
  3183. "commit": [],
  3184. "owner": ["pingou"],
  3185. "ticket": [],
  3186. },
  3187. "close_status": [
  3188. "Invalid",
  3189. "Insufficient data",
  3190. "Fixed",
  3191. "Duplicate",
  3192. ],
  3193. "custom_keys": [],
  3194. "date_created": "1516348115",
  3195. "date_modified": "1516348115",
  3196. "description": "test project #1",
  3197. "fullname": "test",
  3198. "id": 1,
  3199. "milestones": {},
  3200. "name": "test",
  3201. "namespace": None,
  3202. "parent": None,
  3203. "priorities": {},
  3204. "tags": [],
  3205. "url_path": "test",
  3206. "user": {"fullname": "PY C", "name": "pingou"},
  3207. },
  3208. "status": "Open",
  3209. "tags": [],
  3210. "threshold_reached": None,
  3211. "title": "Test PR",
  3212. "uid": "e8b68df8711648deac67c3afed15a798",
  3213. "updated_on": "1516348115",
  3214. "user": {"fullname": "PY C", "name": "pingou"},
  3215. }
  3216. def test_api_pull_request_no_comments(self):
  3217. """ Check the value of threshold_reach when the PR has no comments.
  3218. """
  3219. # Check the PR with 0 comment:
  3220. output = self.app.get("/api/0/test/pull-request/1")
  3221. self.assertEqual(output.status_code, 200)
  3222. data = json.loads(output.get_data(as_text=True))
  3223. data = self._clean_data(data)
  3224. self.expected_data["threshold_reached"] = False
  3225. self.assertDictEqual(data, self.expected_data)
  3226. def test_api_pull_request_one_comments(self):
  3227. """ Check the value of threshold_reach when the PR has one comment.
  3228. """
  3229. # Check the PR with 1 comment:
  3230. headers = {"Authorization": "token aaabbbcccddd"}
  3231. data = {"comment": "This is a very interesting solution :thumbsup:"}
  3232. output = self.app.post(
  3233. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3234. )
  3235. self.assertEqual(output.status_code, 200)
  3236. data = json.loads(output.get_data(as_text=True))
  3237. self.assertDictEqual(data, {"message": "Comment added"})
  3238. output = self.app.get("/api/0/test/pull-request/1")
  3239. self.assertEqual(output.status_code, 200)
  3240. data = json.loads(output.get_data(as_text=True))
  3241. data = self._clean_data(data)
  3242. self.expected_data["threshold_reached"] = False
  3243. self.assertDictEqual(data, self.expected_data)
  3244. def test_api_pull_request_two_comments_one_person(self):
  3245. """ Check the value of threshold_reach when the PR has two comments
  3246. but from the same person.
  3247. """
  3248. # Add two comments from the same user:
  3249. headers = {"Authorization": "token aaabbbcccddd"}
  3250. data = {"comment": "This is a very interesting solution :thumbsup:"}
  3251. output = self.app.post(
  3252. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3253. )
  3254. self.assertEqual(output.status_code, 200)
  3255. data = json.loads(output.get_data(as_text=True))
  3256. self.assertDictEqual(data, {"message": "Comment added"})
  3257. headers = {"Authorization": "token aaabbbcccddd"}
  3258. data = {"comment": "Indeed it is :thumbsup:"}
  3259. output = self.app.post(
  3260. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3261. )
  3262. self.assertEqual(output.status_code, 200)
  3263. data = json.loads(output.get_data(as_text=True))
  3264. self.assertDictEqual(data, {"message": "Comment added"})
  3265. output = self.app.get("/api/0/test/pull-request/1")
  3266. self.assertEqual(output.status_code, 200)
  3267. data = json.loads(output.get_data(as_text=True))
  3268. data = self._clean_data(data)
  3269. self.expected_data["threshold_reached"] = False
  3270. self.assertDictEqual(data, self.expected_data)
  3271. def test_api_pull_request_two_comments_two_persons(self):
  3272. """ Check the value of threshold_reach when the PR has two comments
  3273. from two different persons.
  3274. """
  3275. # Add two comments from two users:
  3276. headers = {"Authorization": "token aaabbbcccddd"}
  3277. data = {"comment": "This is a very interesting solution :thumbsup:"}
  3278. output = self.app.post(
  3279. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3280. )
  3281. self.assertEqual(output.status_code, 200)
  3282. data = json.loads(output.get_data(as_text=True))
  3283. self.assertDictEqual(data, {"message": "Comment added"})
  3284. headers = {"Authorization": "token aaabbbcccddd_foo"}
  3285. data = {"comment": "Indeed it is :thumbsup:"}
  3286. output = self.app.post(
  3287. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3288. )
  3289. self.assertEqual(output.status_code, 200)
  3290. data = json.loads(output.get_data(as_text=True))
  3291. self.assertDictEqual(data, {"message": "Comment added"})
  3292. output = self.app.get("/api/0/test/pull-request/1")
  3293. self.assertEqual(output.status_code, 200)
  3294. data = json.loads(output.get_data(as_text=True))
  3295. data = self._clean_data(data)
  3296. data["comments"] = [] # Let's not check the comments
  3297. self.expected_data["threshold_reached"] = True
  3298. self.assertDictEqual(data, self.expected_data)
  3299. def test_api_pull_request_three_comments_two_persons_changed_to_no(self):
  3300. """ Check the value of threshold_reach when the PR has three
  3301. comments from two person among which one changed their mind from
  3302. +1 to -1.
  3303. """
  3304. # Add three comments from two users:
  3305. headers = {"Authorization": "token aaabbbcccddd"}
  3306. data = {"comment": "This is a very interesting solution :thumbsup:"}
  3307. output = self.app.post(
  3308. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3309. )
  3310. self.assertEqual(output.status_code, 200)
  3311. data = json.loads(output.get_data(as_text=True))
  3312. self.assertDictEqual(data, {"message": "Comment added"})
  3313. headers = {"Authorization": "token aaabbbcccddd_foo"}
  3314. data = {"comment": "Indeed it is :thumbsup:"}
  3315. output = self.app.post(
  3316. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3317. )
  3318. self.assertEqual(output.status_code, 200)
  3319. data = json.loads(output.get_data(as_text=True))
  3320. self.assertDictEqual(data, {"message": "Comment added"})
  3321. data = {
  3322. "comment": "Nevermind the bug is elsewhere in fact :thumbsdown:"
  3323. }
  3324. output = self.app.post(
  3325. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3326. )
  3327. self.assertEqual(output.status_code, 200)
  3328. data = json.loads(output.get_data(as_text=True))
  3329. self.assertDictEqual(data, {"message": "Comment added"})
  3330. output = self.app.get("/api/0/test/pull-request/1")
  3331. self.assertEqual(output.status_code, 200)
  3332. data = json.loads(output.get_data(as_text=True))
  3333. data = self._clean_data(data)
  3334. data["comments"] = [] # Let's not check the comments
  3335. self.expected_data["threshold_reached"] = False
  3336. self.assertDictEqual(data, self.expected_data)
  3337. def test_api_pull_request_three_comments_two_persons_changed_to_yes(self):
  3338. """ Check the value of threshold_reach when the PR has three
  3339. comments from two person among which one changed their mind from
  3340. -1 to +1
  3341. """
  3342. # Add three comments from two users:
  3343. headers = {"Authorization": "token aaabbbcccddd"}
  3344. data = {"comment": "This is a very interesting solution :thumbsup:"}
  3345. output = self.app.post(
  3346. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3347. )
  3348. self.assertEqual(output.status_code, 200)
  3349. data = json.loads(output.get_data(as_text=True))
  3350. self.assertDictEqual(data, {"message": "Comment added"})
  3351. headers = {"Authorization": "token aaabbbcccddd_foo"}
  3352. data = {"comment": "I think the bug is elsewhere :thumbsdown:"}
  3353. output = self.app.post(
  3354. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3355. )
  3356. self.assertEqual(output.status_code, 200)
  3357. data = json.loads(output.get_data(as_text=True))
  3358. self.assertDictEqual(data, {"message": "Comment added"})
  3359. data = {"comment": "Nevermind it is here :thumbsup:"}
  3360. output = self.app.post(
  3361. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  3362. )
  3363. self.assertEqual(output.status_code, 200)
  3364. data = json.loads(output.get_data(as_text=True))
  3365. self.assertDictEqual(data, {"message": "Comment added"})
  3366. output = self.app.get("/api/0/test/pull-request/1")
  3367. self.assertEqual(output.status_code, 200)
  3368. data = json.loads(output.get_data(as_text=True))
  3369. data = self._clean_data(data)
  3370. data["comments"] = [] # Let's not check the comments
  3371. self.expected_data["threshold_reached"] = True
  3372. self.assertDictEqual(data, self.expected_data)
  3373. if __name__ == "__main__":
  3374. unittest.main(verbosity=2)