test_pagure_flask_api_fork.py 142 KB

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