test_pagure_flask_api_ui_private_repo.py 102 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905
  1. # -*- coding: utf-8 -*-
  2. __requires__ = ['SQLAlchemy >= 0.8']
  3. import pkg_resources
  4. import datetime
  5. import unittest
  6. import shutil
  7. import sys
  8. import tempfile
  9. import os
  10. import json
  11. import pygit2
  12. from mock import patch
  13. sys.path.insert(0, os.path.join(os.path.dirname(
  14. os.path.abspath(__file__)), '..'))
  15. import pagure.lib
  16. import tests
  17. from pagure.lib.repo import PagureRepo
  18. FULL_ISSUE_LIST = [
  19. {
  20. "assignee": None,
  21. "blocks": [],
  22. "close_status": None,
  23. "closed_at": None,
  24. "comments": [],
  25. "content": "We should work on this",
  26. "custom_fields": [],
  27. "date_created": "1431414800",
  28. "depends": [],
  29. "id": 8,
  30. "last_updated": "1431414800",
  31. "milestone": "",
  32. "priority": None,
  33. "private": True,
  34. "status": "Open",
  35. "tags": [],
  36. "title": "Test issue",
  37. "user": {
  38. "fullname": "PY C",
  39. "name": "pingou"
  40. }
  41. },
  42. {
  43. "assignee": None,
  44. "blocks": [],
  45. "close_status": None,
  46. "closed_at": None,
  47. "comments": [],
  48. "content": "This issue needs attention",
  49. "custom_fields": [],
  50. "date_created": "1431414800",
  51. "depends": [],
  52. "id": 7,
  53. "last_updated": "1431414800",
  54. "milestone": "",
  55. "priority": None,
  56. "private": True,
  57. "status": "Open",
  58. "tags": [],
  59. "title": "test issue",
  60. "user": {
  61. "fullname": "PY C",
  62. "name": "pingou"
  63. }
  64. },
  65. {
  66. "assignee": None,
  67. "blocks": [],
  68. "close_status": None,
  69. "closed_at": None,
  70. "comments": [],
  71. "content": "This issue needs attention",
  72. "custom_fields": [],
  73. "date_created": "1431414800",
  74. "depends": [],
  75. "id": 6,
  76. "last_updated": "1431414800",
  77. "milestone": "",
  78. "priority": None,
  79. "private": True,
  80. "status": "Open",
  81. "tags": [],
  82. "title": "test issue",
  83. "user": {
  84. "fullname": "PY C",
  85. "name": "pingou"
  86. }
  87. },
  88. {
  89. "assignee": None,
  90. "blocks": [],
  91. "close_status": None,
  92. "closed_at": None,
  93. "comments": [],
  94. "content": "This issue needs attention",
  95. "custom_fields": [],
  96. "date_created": "1431414800",
  97. "depends": [],
  98. "id": 5,
  99. "last_updated": "1431414800",
  100. "milestone": "",
  101. "priority": None,
  102. "private": False,
  103. "status": "Open",
  104. "tags": [],
  105. "title": "test issue",
  106. "user": {
  107. "fullname": "PY C",
  108. "name": "pingou"
  109. }
  110. },
  111. {
  112. "assignee": None,
  113. "blocks": [],
  114. "close_status": None,
  115. "closed_at": None,
  116. "comments": [],
  117. "content": "This issue needs attention",
  118. "custom_fields": [],
  119. "date_created": "1431414800",
  120. "depends": [],
  121. "id": 4,
  122. "last_updated": "1431414800",
  123. "milestone": "",
  124. "priority": None,
  125. "private": False,
  126. "status": "Open",
  127. "tags": [],
  128. "title": "test issue",
  129. "user": {
  130. "fullname": "PY C",
  131. "name": "pingou"
  132. }
  133. },
  134. {
  135. "assignee": None,
  136. "blocks": [],
  137. "close_status": None,
  138. "closed_at": None,
  139. "comments": [],
  140. "content": "This issue needs attention",
  141. "custom_fields": [],
  142. "date_created": "1431414800",
  143. "depends": [],
  144. "id": 3,
  145. "last_updated": "1431414800",
  146. "milestone": "",
  147. "priority": None,
  148. "private": False,
  149. "status": "Open",
  150. "tags": [],
  151. "title": "test issue",
  152. "user": {
  153. "fullname": "PY C",
  154. "name": "pingou"
  155. }
  156. },
  157. {
  158. "assignee": None,
  159. "blocks": [],
  160. "close_status": None,
  161. "closed_at": None,
  162. "comments": [],
  163. "content": "This issue needs attention",
  164. "custom_fields": [],
  165. "date_created": "1431414800",
  166. "depends": [],
  167. "id": 2,
  168. "last_updated": "1431414800",
  169. "milestone": "",
  170. "priority": None,
  171. "private": False,
  172. "status": "Open",
  173. "tags": [],
  174. "title": "test issue",
  175. "user": {
  176. "fullname": "PY C",
  177. "name": "pingou"
  178. }
  179. },
  180. {
  181. "assignee": None,
  182. "blocks": [],
  183. "close_status": None,
  184. "closed_at": None,
  185. "comments": [],
  186. "content": "This issue needs attention",
  187. "custom_fields": [],
  188. "date_created": "1431414800",
  189. "depends": [],
  190. "id": 1,
  191. "last_updated": "1431414800",
  192. "milestone": "",
  193. "priority": None,
  194. "private": False,
  195. "status": "Open",
  196. "tags": [],
  197. "title": "test issue",
  198. "user": {
  199. "fullname": "PY C",
  200. "name": "pingou"
  201. }
  202. }
  203. ]
  204. class PagurePrivateRepotest(tests.Modeltests):
  205. """ Tests for private repo in pagure """
  206. def setUp(self):
  207. """ Set up the environnment, ran before every tests. """
  208. super(PagurePrivateRepotest, self).setUp()
  209. pagure.APP.config['TESTING'] = True
  210. pagure.APP.config['DATAGREPPER_URL'] = None
  211. pagure.APP.config['PRIVATE_PROJECTS'] = True
  212. pagure.SESSION = self.session
  213. pagure.lib.SESSION = self.session
  214. pagure.ui.SESSION = self.session
  215. pagure.ui.app.SESSION = self.session
  216. pagure.ui.filters.SESSION = self.session
  217. pagure.ui.fork.SESSION = self.session
  218. pagure.ui.repo.SESSION = self.session
  219. pagure.ui.issues.SESSION = self.session
  220. pagure.api.SESSION = self.session
  221. pagure.api.project.SESSION = self.session
  222. pagure.api.fork.SESSION = self.session
  223. pagure.api.issue.SESSION = self.session
  224. pagure.APP.config['VIRUS_SCAN_ATTACHMENTS'] = False
  225. self.app = pagure.APP.test_client()
  226. def set_up_git_repo(
  227. self, new_project=None, branch_from='feature', mtype='FF'):
  228. """ Set up the git repo and create the corresponding PullRequest
  229. object.
  230. """
  231. # Create a git repo to play with
  232. gitrepo = os.path.join(self.path, 'repos', 'pmc.git')
  233. repo = pygit2.init_repository(gitrepo, bare=True)
  234. newpath = tempfile.mkdtemp(prefix='pagure-private-test')
  235. repopath = os.path.join(newpath, 'test')
  236. clone_repo = pygit2.clone_repository(gitrepo, repopath)
  237. # Create a file in that git repo
  238. with open(os.path.join(repopath, 'sources'), 'w') as stream:
  239. stream.write('foo\n bar')
  240. clone_repo.index.add('sources')
  241. clone_repo.index.write()
  242. # Commits the files added
  243. tree = clone_repo.index.write_tree()
  244. author = pygit2.Signature(
  245. 'Alice Author', 'alice@authors.tld')
  246. committer = pygit2.Signature(
  247. 'Cecil Committer', 'cecil@committers.tld')
  248. clone_repo.create_commit(
  249. 'refs/heads/master', # the name of the reference to update
  250. author,
  251. committer,
  252. 'Add sources file for testing',
  253. # binary string representing the tree object ID
  254. tree,
  255. # list of binary strings representing parents of the new commit
  256. []
  257. )
  258. refname = 'refs/heads/master:refs/heads/master'
  259. ori_remote = clone_repo.remotes[0]
  260. PagureRepo.push(ori_remote, refname)
  261. first_commit = repo.revparse_single('HEAD')
  262. if mtype == 'merge':
  263. with open(os.path.join(repopath, '.gitignore'), 'w') as stream:
  264. stream.write('*~')
  265. clone_repo.index.add('.gitignore')
  266. clone_repo.index.write()
  267. # Commits the files added
  268. tree = clone_repo.index.write_tree()
  269. author = pygit2.Signature(
  270. 'Alice Äuthòr', 'alice@äuthòrs.tld')
  271. committer = pygit2.Signature(
  272. 'Cecil Cõmmîttër', 'cecil@cõmmîttërs.tld')
  273. clone_repo.create_commit(
  274. 'refs/heads/master',
  275. author,
  276. committer,
  277. 'Add .gitignore file for testing',
  278. # binary string representing the tree object ID
  279. tree,
  280. # list of binary strings representing parents of the new commit
  281. [first_commit.oid.hex]
  282. )
  283. refname = 'refs/heads/master:refs/heads/master'
  284. ori_remote = clone_repo.remotes[0]
  285. PagureRepo.push(ori_remote, refname)
  286. if mtype == 'conflicts':
  287. with open(os.path.join(repopath, 'sources'), 'w') as stream:
  288. stream.write('foo\n bar\nbaz')
  289. clone_repo.index.add('sources')
  290. clone_repo.index.write()
  291. # Commits the files added
  292. tree = clone_repo.index.write_tree()
  293. author = pygit2.Signature(
  294. 'Alice Author', 'alice@authors.tld')
  295. committer = pygit2.Signature(
  296. 'Cecil Committer', 'cecil@committers.tld')
  297. clone_repo.create_commit(
  298. 'refs/heads/master',
  299. author,
  300. committer,
  301. 'Add sources conflicting',
  302. # binary string representing the tree object ID
  303. tree,
  304. # list of binary strings representing parents of the new commit
  305. [first_commit.oid.hex]
  306. )
  307. refname = 'refs/heads/master:refs/heads/master'
  308. ori_remote = clone_repo.remotes[0]
  309. PagureRepo.push(ori_remote, refname)
  310. # Set the second repo
  311. new_gitrepo = repopath
  312. if new_project:
  313. # Create a new git repo to play with
  314. new_gitrepo = os.path.join(newpath, new_project.fullname)
  315. if not os.path.exists(new_gitrepo):
  316. os.makedirs(new_gitrepo)
  317. new_repo = pygit2.clone_repository(gitrepo, new_gitrepo)
  318. repo = pygit2.Repository(new_gitrepo)
  319. if mtype != 'nochanges':
  320. # Edit the sources file again
  321. with open(os.path.join(new_gitrepo, 'sources'), 'w') as stream:
  322. stream.write('foo\n bar\nbaz\n boose')
  323. repo.index.add('sources')
  324. repo.index.write()
  325. # Commits the files added
  326. tree = repo.index.write_tree()
  327. author = pygit2.Signature(
  328. 'Alice Author', 'alice@authors.tld')
  329. committer = pygit2.Signature(
  330. 'Cecil Committer', 'cecil@committers.tld')
  331. repo.create_commit(
  332. 'refs/heads/%s' % branch_from,
  333. author,
  334. committer,
  335. 'A commit on branch %s' % branch_from,
  336. tree,
  337. [first_commit.oid.hex]
  338. )
  339. refname = 'refs/heads/%s' % (branch_from)
  340. ori_remote = repo.remotes[0]
  341. PagureRepo.push(ori_remote, refname)
  342. # Create a PR for these changes
  343. project = pagure.lib._get_project(self.session, 'pmc')
  344. req = pagure.lib.new_pull_request(
  345. session=self.session,
  346. repo_from=project,
  347. branch_from=branch_from,
  348. repo_to=project,
  349. branch_to='master',
  350. title='PR from the %s branch' % branch_from,
  351. user='pingou',
  352. requestfolder=None,
  353. )
  354. self.session.commit()
  355. self.assertEqual(req.id, 1)
  356. self.assertEqual(req.title, 'PR from the %s branch' % branch_from)
  357. shutil.rmtree(newpath)
  358. def test_index(self):
  359. """ Test the index endpoint. """
  360. output = self.app.get('/')
  361. self.assertEqual(output.status_code, 200)
  362. self.assertIn(
  363. '<h2 class="m-b-1">All Projects '
  364. '<span class="label label-default">0</span></h2>', output.get_data(as_text=True))
  365. # Add a private project
  366. item = pagure.lib.model.Project(
  367. user_id=2, # foo
  368. name='test3',
  369. description='test project description',
  370. hook_token='aaabbbeee',
  371. private=True,
  372. )
  373. self.session.add(item)
  374. # Add a public project
  375. item = pagure.lib.model.Project(
  376. user_id=2, # foo
  377. name='test4',
  378. description='test project description',
  379. hook_token='aaabbbeeeccceee',
  380. )
  381. self.session.add(item)
  382. self.session.commit()
  383. output = self.app.get('/?page=abc')
  384. self.assertEqual(output.status_code, 200)
  385. self.assertIn(
  386. '<h2 class="m-b-1">All Projects '
  387. '<span class="label label-default">1</span></h2>', output.get_data(as_text=True))
  388. user = tests.FakeUser(username='foo')
  389. with tests.user_set(pagure.APP, user):
  390. output = self.app.get('/')
  391. self.assertIn(
  392. 'My Projects <span class="label label-default">2</span>',
  393. output.get_data(as_text=True))
  394. self.assertIn(
  395. 'Forks <span class="label label-default">0</span>',
  396. output.get_data(as_text=True))
  397. self.assertEqual(
  398. output.get_data(as_text=True).count('<p>No group found</p>'), 1)
  399. self.assertEqual(
  400. output.get_data(as_text=True).count('<div class="card-header">'), 6)
  401. def test_view_user(self):
  402. """ Test the view_user endpoint. """
  403. output = self.app.get('/user/foo?repopage=abc&forkpage=def')
  404. self.assertEqual(output.status_code, 200)
  405. self.assertIn(
  406. 'Projects <span class="label label-default">0</span>',
  407. output.get_data(as_text=True))
  408. self.assertIn(
  409. 'Forks <span class="label label-default">0</span>',
  410. output.get_data(as_text=True))
  411. # Add a private project
  412. item = pagure.lib.model.Project(
  413. user_id=2, # foo
  414. name='test3',
  415. description='test project description',
  416. hook_token='aaabbbeee',
  417. private=True,
  418. )
  419. self.session.add(item)
  420. # Add a public project
  421. item = pagure.lib.model.Project(
  422. user_id=2, # foo
  423. name='test4',
  424. description='test project description',
  425. hook_token='aaabbbeeeccceee',
  426. )
  427. self.session.add(item)
  428. self.session.commit()
  429. self.gitrepos = tests.create_projects_git(
  430. pagure.APP.config['GIT_FOLDER'])
  431. output = self.app.get('/user/foo')
  432. self.assertEqual(output.status_code, 200)
  433. self.assertIn(
  434. 'Projects <span class="label label-default">1</span>',
  435. output.get_data(as_text=True))
  436. self.assertIn(
  437. 'Forks <span class="label label-default">0</span>', output.get_data(as_text=True))
  438. user = tests.FakeUser(username='foo')
  439. with tests.user_set(pagure.APP, user):
  440. output = self.app.get('/user/foo')
  441. self.assertIn(
  442. 'Projects <span class="label label-default">2</span>',
  443. output.get_data(as_text=True))
  444. self.assertIn(
  445. 'Forks <span class="label label-default">0</span>',
  446. output.get_data(as_text=True))
  447. self.assertEqual(
  448. output.get_data(as_text=True).count('<p>No group found</p>'), 1)
  449. self.assertEqual(
  450. output.get_data(as_text=True).count('<div class="card-header">'), 5)
  451. user.username = 'pingou'
  452. with tests.user_set(pagure.APP, user):
  453. output = self.app.get('/user/foo')
  454. self.assertIn(
  455. 'Projects <span class="label label-default">1</span>',
  456. output.get_data(as_text=True))
  457. self.assertIn(
  458. 'Forks <span class="label label-default">0</span>',
  459. output.get_data(as_text=True))
  460. self.assertEqual(
  461. output.get_data(as_text=True).count('<p>No group found</p>'), 1)
  462. self.assertEqual(
  463. output.get_data(as_text=True).count('<div class="card-header">'), 5)
  464. # Check pingou has 0 projects
  465. user.username = 'pingou'
  466. with tests.user_set(pagure.APP, user):
  467. output = self.app.get('/')
  468. self.assertIn(
  469. 'My Projects <span class="label label-default">0</span>',
  470. output.get_data(as_text=True))
  471. self.assertIn(
  472. 'Forks <span class="label label-default">0</span>',
  473. output.get_data(as_text=True))
  474. self.assertEqual(
  475. output.get_data(as_text=True).count('<p>No group found</p>'), 1)
  476. self.assertEqual(
  477. output.get_data(as_text=True).count('<div class="card-header">'), 6)
  478. repo = pagure.lib._get_project(self.session, 'test3')
  479. msg = pagure.lib.add_user_to_project(
  480. session=self.session,
  481. project=repo,
  482. new_user='pingou',
  483. user='foo',
  484. )
  485. self.assertEqual(msg, 'User added')
  486. # New user added to private projects
  487. user.username = 'pingou'
  488. with tests.user_set(pagure.APP, user):
  489. output = self.app.get('/')
  490. self.assertIn(
  491. 'My Projects <span class="label label-default">1</span>',
  492. output.get_data(as_text=True))
  493. self.assertIn(
  494. 'Forks <span class="label label-default">0</span>',
  495. output.get_data(as_text=True))
  496. self.assertEqual(
  497. output.get_data(as_text=True).count('<p>No group found</p>'), 1)
  498. self.assertEqual(
  499. output.get_data(as_text=True).count('<div class="card-header">'), 6)
  500. @patch('pagure.ui.repo.admin_session_timedout')
  501. def test_private_settings_ui(self, ast):
  502. """ Test UI for private repo"""
  503. ast.return_value = False
  504. # Add private repo
  505. item = pagure.lib.model.Project(
  506. user_id=1, # pingou
  507. name='test4',
  508. description='test project description',
  509. hook_token='aaabbbeeeceee',
  510. private=True,
  511. )
  512. self.session.add(item)
  513. self.session.commit()
  514. # Add a git repo
  515. repo_path = os.path.join(
  516. pagure.APP.config.get('GIT_FOLDER'), 'test4.git')
  517. if not os.path.exists(repo_path):
  518. os.makedirs(repo_path)
  519. pygit2.init_repository(repo_path)
  520. user = tests.FakeUser(username='pingou')
  521. with tests.user_set(pagure.APP, user):
  522. tests.create_projects(self.session)
  523. tests.create_projects_git(pagure.APP.config.get('GIT_FOLDER'))
  524. output = self.app.get('/test/settings')
  525. # Check for a public repo
  526. self.assertEqual(output.status_code, 200)
  527. self.assertNotIn(
  528. '<input type="checkbox" value="private" name="private"',
  529. output.get_data(as_text=True))
  530. output = self.app.get('/test4/settings')
  531. # Check for private repo
  532. self.assertEqual(output.status_code, 200)
  533. self.assertIn(
  534. '<input type="checkbox" value="private" name="private" checked="" />',
  535. output.get_data(as_text=True))
  536. # Check the new project form has 'private' checkbox
  537. output = self.app.get('/new')
  538. self.assertEqual(output.status_code, 200)
  539. self.assertIn(
  540. '<input id="private" name="private" type="checkbox" value="y">',
  541. output.get_data(as_text=True))
  542. @patch('pagure.ui.repo.admin_session_timedout')
  543. def test_private_settings_ui_update_privacy_false(self, ast):
  544. """ Test UI for private repo"""
  545. ast.return_value = False
  546. # Add private repo
  547. item = pagure.lib.model.Project(
  548. user_id=1, # pingou
  549. name='test4',
  550. description='test project description',
  551. hook_token='aaabbbeeeceee',
  552. private=True,
  553. )
  554. self.session.add(item)
  555. self.session.commit()
  556. # Add a git repo
  557. repo_path = os.path.join(
  558. pagure.APP.config.get('GIT_FOLDER'), 'test4.git')
  559. pygit2.init_repository(repo_path)
  560. user = tests.FakeUser(username='pingou')
  561. with tests.user_set(pagure.APP, user):
  562. # Check for private repo
  563. output = self.app.get('/test4/settings')
  564. self.assertEqual(output.status_code, 200)
  565. self.assertIn(
  566. '<input type="checkbox" value="private" name="private" checked="" />',
  567. output.get_data(as_text=True))
  568. repo = pagure.lib._get_project(self.session, 'test4')
  569. self.assertTrue(repo.private)
  570. # Make the project public
  571. data = {
  572. 'description': 'test project description',
  573. 'private': False,
  574. 'csrf_token': self.get_csrf(),
  575. }
  576. output = self.app.post(
  577. '/test4/update', data=data, follow_redirects=True)
  578. self.assertEqual(output.status_code, 200)
  579. self.assertIn(
  580. '</button>\n'\
  581. ' Project updated',
  582. output.get_data(as_text=True))
  583. self.assertNotIn(
  584. '<input type="checkbox" value="private" name="private" checked="" />',
  585. output.get_data(as_text=True))
  586. repo = pagure.lib._get_project(self.session, 'test4')
  587. self.assertFalse(repo.private)
  588. @patch('pagure.ui.repo.admin_session_timedout')
  589. def test_private_settings_ui_update_privacy_true(self, ast):
  590. """ Test UI for private repo"""
  591. ast.return_value = False
  592. # Add private repo
  593. item = pagure.lib.model.Project(
  594. user_id=1, # pingou
  595. name='test4',
  596. description='test project description',
  597. hook_token='aaabbbeeeceee',
  598. private=False,
  599. )
  600. self.session.add(item)
  601. self.session.commit()
  602. # Add a git repo
  603. repo_path = os.path.join(
  604. pagure.APP.config.get('GIT_FOLDER'), 'test4.git')
  605. pygit2.init_repository(repo_path)
  606. user = tests.FakeUser(username='pingou')
  607. with tests.user_set(pagure.APP, user):
  608. # Check for public repo
  609. output = self.app.get('/test4/settings')
  610. self.assertEqual(output.status_code, 200)
  611. self.assertNotIn(
  612. '<input type="checkbox" value="private" name="private" checked=""/>',
  613. output.get_data(as_text=True))
  614. repo = pagure.lib._get_project(self.session, 'test4')
  615. self.assertFalse(repo.private)
  616. # Make the project private
  617. data = {
  618. 'description': 'test project description',
  619. 'private': True,
  620. 'csrf_token': self.get_csrf(),
  621. }
  622. output = self.app.post(
  623. '/test4/update', data=data, follow_redirects=True)
  624. self.assertEqual(output.status_code, 200)
  625. self.assertIn(
  626. '</button>\n'\
  627. ' Project updated',
  628. output.get_data(as_text=True))
  629. self.assertNotIn(
  630. '<input type="checkbox" value="private" name="private" checked=""/>',
  631. output.get_data(as_text=True))
  632. # No change since we can't do public -> private
  633. repo = pagure.lib._get_project(self.session, 'test4')
  634. self.assertFalse(repo.private)
  635. @patch('pagure.lib.notify.send_email')
  636. def test_private_pr(self, send_email):
  637. """Test pull request made to the private repo"""
  638. send_email.return_value = True
  639. # Add a private project
  640. item = pagure.lib.model.Project(
  641. user_id=1, # pingou
  642. name='pmc',
  643. description='test project description',
  644. hook_token='aaabbbeeeceee',
  645. private=True,
  646. )
  647. self.session.add(item)
  648. self.session.commit()
  649. repo = pagure.lib._get_project(self.session, 'pmc')
  650. msg = pagure.lib.add_user_to_project(
  651. session=self.session,
  652. project=repo,
  653. new_user='foo',
  654. user='pingou',
  655. )
  656. self.session.commit()
  657. self.assertEqual(msg, 'User added')
  658. # Create all the git repos
  659. tests.create_projects_git(
  660. os.path.join(self.path, 'requests'), bare=True)
  661. # Add a git repo
  662. repo_path = os.path.join(
  663. pagure.APP.config.get('REQUESTS_FOLDER'), 'pmc.git')
  664. if not os.path.exists(repo_path):
  665. os.makedirs(repo_path)
  666. pygit2.init_repository(repo_path, bare=True)
  667. # Check repo was created
  668. user = tests.FakeUser(username='pingou')
  669. with tests.user_set(pagure.APP, user):
  670. output = self.app.get('/user/pingou/')
  671. self.assertEqual(output.status_code, 200)
  672. self.assertIn(
  673. '<div class="card-header">\n Projects <span '
  674. 'class="label label-default">1</span>', output.get_data(as_text=True))
  675. self.assertIn(
  676. 'Forks <span class="label label-default">0</span>',
  677. output.get_data(as_text=True))
  678. self.set_up_git_repo(new_project=None, branch_from='feature')
  679. project = pagure.lib._get_project(self.session, 'pmc')
  680. self.assertEqual(len(project.requests), 1)
  681. output = self.app.get('/pmc/pull-request/1')
  682. self.assertEqual(output.status_code, 200)
  683. # Check repo was created
  684. user = tests.FakeUser()
  685. with tests.user_set(pagure.APP, user):
  686. output = self.app.get('/pmc/pull-requests')
  687. self.assertEqual(output.status_code, 404)
  688. user = tests.FakeUser(username='pingou')
  689. with tests.user_set(pagure.APP, user):
  690. output = self.app.get('/pmc/pull-requests')
  691. self.assertEqual(output.status_code, 200)
  692. user = tests.FakeUser(username='foo')
  693. with tests.user_set(pagure.APP, user):
  694. output = self.app.get('/pmc/pull-requests')
  695. self.assertEqual(output.status_code, 200)
  696. @patch('pagure.lib.git.update_git')
  697. @patch('pagure.lib.notify.send_email')
  698. def test_private_repo_issues_ui(self, p_send_email, p_ugt):
  699. """ Test issues made to private repo"""
  700. p_send_email.return_value = True
  701. p_ugt.return_value = True
  702. # Add private repo
  703. item = pagure.lib.model.Project(
  704. user_id=1, # pingou
  705. name='test4',
  706. description='test project description',
  707. hook_token='aaabbbeeeceee',
  708. private=True,
  709. )
  710. self.session.add(item)
  711. self.session.commit()
  712. for repo in ['GIT_FOLDER', 'TICKETS_FOLDER']:
  713. # Add a git repo
  714. repo_path = os.path.join(
  715. pagure.APP.config.get(repo), 'test4.git')
  716. if not os.path.exists(repo_path):
  717. os.makedirs(repo_path)
  718. pygit2.init_repository(repo_path)
  719. # Check if the private repo issues are publicly not accesible
  720. output = self.app.get('/test4/issues')
  721. self.assertEqual(output.status_code, 404)
  722. # Create issues to play with
  723. repo = pagure.lib._get_project(self.session, 'test4')
  724. msg = pagure.lib.new_issue(
  725. session=self.session,
  726. repo=repo,
  727. title='Test issue',
  728. content='We should work on this',
  729. user='pingou',
  730. ticketfolder=None
  731. )
  732. self.session.commit()
  733. self.assertEqual(msg.title, 'Test issue')
  734. user = tests.FakeUser()
  735. with tests.user_set(pagure.APP, user):
  736. # Whole list
  737. output = self.app.get('/test4/issues')
  738. self.assertEqual(output.status_code, 404)
  739. # Check single issue
  740. output = self.app.get('/test4/issue/1')
  741. self.assertEqual(output.status_code, 404)
  742. user = tests.FakeUser()
  743. with tests.user_set(pagure.APP, user):
  744. # Whole list
  745. output = self.app.get('/test4/issues')
  746. self.assertEqual(output.status_code, 404)
  747. user = tests.FakeUser(username='pingou')
  748. with tests.user_set(pagure.APP, user):
  749. # Whole list
  750. output = self.app.get('/test4/issues')
  751. self.assertEqual(output.status_code, 200)
  752. self.assertIn(
  753. '<title>Issues - test4 - Pagure</title>', output.get_data(as_text=True))
  754. self.assertTrue(
  755. '<h2>\n 1 Open Issues' in output.get_data(as_text=True))
  756. # Check single issue
  757. output = self.app.get('/test4/issue/1')
  758. self.assertEqual(output.status_code, 200)
  759. repo = pagure.lib._get_project(self.session, 'test4')
  760. msg = pagure.lib.add_user_to_project(
  761. session=self.session,
  762. project=repo,
  763. new_user='foo',
  764. user='pingou',
  765. )
  766. self.session.commit()
  767. self.assertEqual(msg, 'User added')
  768. user.username = 'foo'
  769. with tests.user_set(pagure.APP, user):
  770. # Whole list
  771. output = self.app.get('/test4/issues')
  772. self.assertEqual(output.status_code, 200)
  773. self.assertIn(
  774. '<title>Issues - test4 - Pagure</title>', output.get_data(as_text=True))
  775. self.assertTrue(
  776. '<h2>\n 1 Open Issues' in output.get_data(as_text=True))
  777. # Check single issue
  778. output = self.app.get('/test4/issue/1')
  779. self.assertEqual(output.status_code, 200)
  780. # API checks
  781. def test_api_private_repo_projects(self):
  782. """ Test api points for private repo for projects"""
  783. # Add private repo
  784. item = pagure.lib.model.Project(
  785. user_id=1, # pingou
  786. name='test4',
  787. description='test project description',
  788. hook_token='aaabbbeeeceee',
  789. private=True,
  790. )
  791. self.session.add(item)
  792. self.session.commit()
  793. # Create a git repo to play with
  794. gitrepo = os.path.join(self.path, 'repos', 'test4.git')
  795. repo = pygit2.init_repository(gitrepo, bare=True)
  796. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  797. repopath = os.path.join(newpath, 'repos', 'test4')
  798. clone_repo = pygit2.clone_repository(gitrepo, repopath)
  799. # Create a file in that git repo
  800. with open(os.path.join(repopath, 'sources'), 'w') as stream:
  801. stream.write('foo\n bar')
  802. clone_repo.index.add('sources')
  803. clone_repo.index.write()
  804. # Commits the files added
  805. tree = clone_repo.index.write_tree()
  806. author = pygit2.Signature(
  807. 'Alice Author', 'alice@authors.tld')
  808. committer = pygit2.Signature(
  809. 'Cecil Committer', 'cecil@committers.tld')
  810. clone_repo.create_commit(
  811. 'refs/heads/master', # the name of the reference to update
  812. author,
  813. committer,
  814. 'Add sources file for testing',
  815. # binary string representing the tree object ID
  816. tree,
  817. # list of binary strings representing parents of the new commit
  818. []
  819. )
  820. refname = 'refs/heads/master:refs/heads/master'
  821. ori_remote = clone_repo.remotes[0]
  822. PagureRepo.push(ori_remote, refname)
  823. # Tag our first commit
  824. first_commit = repo.revparse_single('HEAD')
  825. tagger = pygit2.Signature('Alice Doe', 'adoe@example.com', 12347, 0)
  826. repo.create_tag(
  827. "0.0.1", first_commit.oid.hex, pygit2.GIT_OBJ_COMMIT, tagger,
  828. "Release 0.0.1")
  829. # Create a token for foo for this project
  830. item = pagure.lib.model.Token(
  831. id='foobar_token',
  832. user_id=1,
  833. project_id=1,
  834. expiration=datetime.datetime.utcnow() + datetime.timedelta(
  835. days=30)
  836. )
  837. self.session.add(item)
  838. self.session.commit()
  839. item = pagure.lib.model.TokenAcl(
  840. token_id='foobar_token',
  841. acl_id=1,
  842. )
  843. self.session.add(item)
  844. self.session.commit()
  845. # Check if the admin requests
  846. user = tests.FakeUser(username='pingou')
  847. with tests.user_set(pagure.APP, user):
  848. # Check tags
  849. output = self.app.get('/api/0/test4/git/tags')
  850. self.assertEqual(output.status_code, 200)
  851. data = json.loads(output.get_data(as_text=True))
  852. self.assertDictEqual(
  853. data,
  854. {'tags': ['0.0.1'], 'total_tags': 1}
  855. )
  856. output = self.app.get('/api/0/test4/git/tags')
  857. self.assertEqual(output.status_code, 404)
  858. # Chekc if user is not admin
  859. user = tests.FakeUser()
  860. with tests.user_set(pagure.APP, user):
  861. output = self.app.get('/api/0/test4/git/tags')
  862. self.assertEqual(output.status_code, 404)
  863. shutil.rmtree(newpath)
  864. # Check before adding
  865. repo = pagure.lib._get_project(self.session, 'test4')
  866. self.assertEqual(repo.tags, [])
  867. # Adding a tag
  868. output = pagure.lib.update_tags(
  869. self.session, repo, 'infra', 'pingou',
  870. ticketfolder=None)
  871. self.assertEqual(output, ['Issue tagged with: infra'])
  872. # Check after adding
  873. repo = pagure.lib._get_project(self.session, 'test4')
  874. self.assertEqual(len(repo.tags), 1)
  875. self.assertEqual(repo.tags_text, ['infra'])
  876. # Check the API
  877. output = self.app.get('/api/0/projects?tags=inf')
  878. self.assertEqual(output.status_code, 404)
  879. data = json.loads(output.get_data(as_text=True))
  880. self.assertDictEqual(
  881. data,
  882. {'error_code': 'ENOPROJECTS', 'error': 'No projects found'}
  883. )
  884. # Request by not a loggged in user
  885. output = self.app.get('/api/0/projects?tags=infra')
  886. self.assertEqual(output.status_code, 404)
  887. user = tests.FakeUser()
  888. with tests.user_set(pagure.APP, user):
  889. # Request by a non authorized user
  890. output = self.app.get('/api/0/projects?tags=infra')
  891. self.assertEqual(output.status_code, 404)
  892. user.username = 'pingou'
  893. with tests.user_set(pagure.APP, user):
  894. # Private repo username is compulsion to pass
  895. output = self.app.get('/api/0/projects?tags=infra')
  896. self.assertEqual(output.status_code, 404)
  897. output = self.app.get('/api/0/projects?username=pingou')
  898. self.assertEqual(output.status_code, 200)
  899. data = json.loads(output.get_data(as_text=True))
  900. data['projects'][0]['date_created'] = "1436527638"
  901. self.assertDictEqual(
  902. data,
  903. {
  904. "args": {
  905. "fork": None,
  906. "namespace": None,
  907. "owner": None,
  908. "pattern": None,
  909. "tags": [],
  910. "username": "pingou"
  911. },
  912. "total_projects": 1,
  913. "projects": [
  914. {
  915. "access_groups": {
  916. "admin": [],
  917. "commit": [],
  918. "ticket": []
  919. },
  920. "access_users": {
  921. "admin": [],
  922. "commit": [],
  923. "owner": [
  924. "pingou"
  925. ],
  926. "ticket": []
  927. },
  928. "close_status": [],
  929. "custom_keys": [],
  930. "date_created": "1436527638",
  931. "description": "test project description",
  932. "id": 1,
  933. "milestones": {},
  934. "name": "test4",
  935. "fullname": "test4",
  936. "namespace": None,
  937. "parent": None,
  938. "priorities": {},
  939. "tags": ["infra"],
  940. "user": {
  941. "fullname": "PY C",
  942. "name": "pingou"
  943. }
  944. },
  945. ]
  946. }
  947. )
  948. output = self.app.get('/api/0/projects?username=pingou&tags=infra')
  949. self.assertEqual(output.status_code, 200)
  950. data = json.loads(output.get_data(as_text=True))
  951. data['projects'][0]['date_created'] = "1436527638"
  952. self.assertDictEqual(
  953. data,
  954. {
  955. "args": {
  956. "fork": None,
  957. "namespace": None,
  958. "owner": None,
  959. "pattern": None,
  960. "tags": ["infra"],
  961. "username": "pingou"
  962. },
  963. "total_projects": 1,
  964. "projects": [
  965. {
  966. "access_groups": {
  967. "admin": [],
  968. "commit": [],
  969. "ticket": []
  970. },
  971. "access_users": {
  972. "admin": [],
  973. "commit": [],
  974. "owner": [
  975. "pingou"
  976. ],
  977. "ticket": []
  978. },
  979. "close_status": [],
  980. "custom_keys": [],
  981. "date_created": "1436527638",
  982. "description": "test project description",
  983. "id": 1,
  984. "milestones": {},
  985. "name": "test4",
  986. "fullname": "test4",
  987. "namespace": None,
  988. "parent": None,
  989. "priorities": {},
  990. "tags": ["infra"],
  991. "user": {
  992. "fullname": "PY C",
  993. "name": "pingou"
  994. }
  995. }
  996. ]
  997. }
  998. )
  999. # Api pull-request views
  1000. @patch('pagure.lib.notify.send_email')
  1001. def test_api_private_repo_fork(self, send_email):
  1002. """ Test api endpoints in api/fork"""
  1003. send_email.return_value = True
  1004. # Add private repo
  1005. item = pagure.lib.model.Project(
  1006. user_id=1, # pingou
  1007. name='test4',
  1008. description='test project description',
  1009. hook_token='aaabbbeeeceee',
  1010. private=True,
  1011. )
  1012. self.session.add(item)
  1013. self.session.commit()
  1014. tests.create_tokens(self.session)
  1015. tests.create_tokens_acl(self.session)
  1016. headers = {'Authorization': 'token aaabbbcccddd'}
  1017. # Create a pull-request
  1018. repo = pagure.lib._get_project(self.session, 'test4')
  1019. forked_repo = pagure.lib._get_project(self.session, 'test4')
  1020. req = pagure.lib.new_pull_request(
  1021. session=self.session,
  1022. repo_from=forked_repo,
  1023. branch_from='master',
  1024. repo_to=repo,
  1025. branch_to='master',
  1026. title='test pull-request',
  1027. user='pingou',
  1028. requestfolder=None,
  1029. )
  1030. self.session.commit()
  1031. self.assertEqual(req.id, 1)
  1032. self.assertEqual(req.title, 'test pull-request')
  1033. # Check list of PR
  1034. output = self.app.get('/api/0/test4/pull-requests')
  1035. self.assertEqual(output.status_code, 404)
  1036. # Check single PR
  1037. output = self.app.get('/api/0/test/pull-request/1')
  1038. self.assertEqual(output.status_code, 404)
  1039. user = tests.FakeUser(username='pingou')
  1040. with tests.user_set(pagure.APP, user):
  1041. # List pull-requests
  1042. output = self.app.get('/api/0/test4/pull-requests')
  1043. self.assertEqual(output.status_code, 200)
  1044. data = json.loads(output.get_data(as_text=True))
  1045. data['requests'][0]['date_created'] = '1431414800'
  1046. data['requests'][0]['updated_on'] = '1431414800'
  1047. data['requests'][0]['project']['date_created'] = '1431414800'
  1048. data['requests'][0]['repo_from']['date_created'] = '1431414800'
  1049. data['requests'][0]['uid'] = '1431414800'
  1050. data['requests'][0]['last_updated'] = '1431414800'
  1051. self.assertDictEqual(
  1052. data,
  1053. {
  1054. "args": {
  1055. "assignee": None,
  1056. "author": None,
  1057. "status": True
  1058. },
  1059. "requests": [
  1060. {
  1061. "assignee": None,
  1062. "branch": "master",
  1063. "branch_from": "master",
  1064. "closed_at": None,
  1065. "closed_by": None,
  1066. "comments": [],
  1067. "commit_start": None,
  1068. "commit_stop": None,
  1069. "date_created": "1431414800",
  1070. "last_updated": "1431414800",
  1071. "id": 1,
  1072. "initial_comment": None,
  1073. "project": {
  1074. "access_groups": {
  1075. "admin": [],
  1076. "commit": [],
  1077. "ticket": []
  1078. },
  1079. "access_users": {
  1080. "admin": [],
  1081. "commit": [],
  1082. "owner": [
  1083. "pingou"
  1084. ],
  1085. "ticket": []
  1086. },
  1087. "close_status": [],
  1088. "custom_keys": [],
  1089. "date_created": "1431414800",
  1090. "description": "test project description",
  1091. "id": 1,
  1092. "milestones": {},
  1093. "name": "test4",
  1094. "fullname": "test4",
  1095. "namespace": None,
  1096. "parent": None,
  1097. "priorities": {},
  1098. "tags": [],
  1099. "user": {
  1100. "fullname": "PY C",
  1101. "name": "pingou"
  1102. }
  1103. },
  1104. "remote_git": None,
  1105. "repo_from": {
  1106. "access_groups": {
  1107. "admin": [],
  1108. "commit": [],
  1109. "ticket": []
  1110. },
  1111. "access_users": {
  1112. "admin": [],
  1113. "commit": [],
  1114. "owner": [
  1115. "pingou"
  1116. ],
  1117. "ticket": []
  1118. },
  1119. "close_status": [],
  1120. "custom_keys": [],
  1121. "date_created": "1431414800",
  1122. "description": "test project description",
  1123. "id": 1,
  1124. "milestones": {},
  1125. "fullname": "test4",
  1126. "name": "test4",
  1127. "namespace": None,
  1128. "parent": None,
  1129. "priorities": {},
  1130. "tags": [],
  1131. "user": {
  1132. "fullname": "PY C",
  1133. "name": "pingou"
  1134. }
  1135. },
  1136. "status": "Open",
  1137. "title": "test pull-request",
  1138. "uid": "1431414800",
  1139. "updated_on": "1431414800",
  1140. "user": {
  1141. "fullname": "PY C",
  1142. "name": "pingou"
  1143. }
  1144. }
  1145. ],
  1146. "total_requests": 1
  1147. }
  1148. )
  1149. headers = {'Authorization': 'token foobar_token'}
  1150. # Access Pull-Request authenticated
  1151. output = self.app.get(
  1152. '/api/0/test4/pull-requests', headers=headers)
  1153. self.assertEqual(output.status_code, 200)
  1154. data2 = json.loads(output.get_data(as_text=True))
  1155. data2['requests'][0]['date_created'] = '1431414800'
  1156. data2['requests'][0]['updated_on'] = '1431414800'
  1157. data2['requests'][0]['project']['date_created'] = '1431414800'
  1158. data2['requests'][0]['repo_from']['date_created'] = '1431414800'
  1159. data2['requests'][0]['uid'] = '1431414800'
  1160. data2['requests'][0]['last_updated'] = '1431414800'
  1161. self.assertDictEqual(data, data2)
  1162. # For single PR
  1163. output = self.app.get('/api/0/test4/pull-request/1')
  1164. self.assertEqual(output.status_code, 200)
  1165. data = json.loads(output.get_data(as_text=True))
  1166. data['date_created'] = '1431414800'
  1167. data['updated_on'] = '1431414800'
  1168. data['project']['date_created'] = '1431414800'
  1169. data['repo_from']['date_created'] = '1431414800'
  1170. data['uid'] = '1431414800'
  1171. data['last_updated'] = '1431414800'
  1172. self.assertDictEqual(
  1173. data,
  1174. {
  1175. "assignee": None,
  1176. "branch": "master",
  1177. "branch_from": "master",
  1178. "closed_at": None,
  1179. "closed_by": None,
  1180. "comments": [],
  1181. "commit_start": None,
  1182. "commit_stop": None,
  1183. "date_created": "1431414800",
  1184. "last_updated": "1431414800",
  1185. "id": 1,
  1186. "initial_comment": None,
  1187. "project": {
  1188. "access_groups": {
  1189. "admin": [],
  1190. "commit": [],
  1191. "ticket": []
  1192. },
  1193. "access_users": {
  1194. "admin": [],
  1195. "commit": [],
  1196. "owner": [
  1197. "pingou"
  1198. ],
  1199. "ticket": []
  1200. },
  1201. "close_status": [],
  1202. "custom_keys": [],
  1203. "date_created": "1431414800",
  1204. "description": "test project description",
  1205. "id": 1,
  1206. "milestones": {},
  1207. "name": "test4",
  1208. "fullname": "test4",
  1209. "namespace": None,
  1210. "parent": None,
  1211. "priorities": {},
  1212. "tags": [],
  1213. "user": {
  1214. "fullname": "PY C",
  1215. "name": "pingou"
  1216. }
  1217. },
  1218. "remote_git": None,
  1219. "repo_from": {
  1220. "access_groups": {
  1221. "admin": [],
  1222. "commit": [],
  1223. "ticket": []
  1224. },
  1225. "access_users": {
  1226. "admin": [],
  1227. "commit": [],
  1228. "owner": [
  1229. "pingou"
  1230. ],
  1231. "ticket": []
  1232. },
  1233. "close_status": [],
  1234. "custom_keys": [],
  1235. "date_created": "1431414800",
  1236. "description": "test project description",
  1237. "id": 1,
  1238. "milestones": {},
  1239. "name": "test4",
  1240. "fullname": "test4",
  1241. "namespace": None,
  1242. "parent": None,
  1243. "priorities": {},
  1244. "tags": [],
  1245. "user": {
  1246. "fullname": "PY C",
  1247. "name": "pingou"
  1248. }
  1249. },
  1250. "status": "Open",
  1251. "title": "test pull-request",
  1252. "uid": "1431414800",
  1253. "updated_on": "1431414800",
  1254. "user": {
  1255. "fullname": "PY C",
  1256. "name": "pingou"
  1257. }
  1258. }
  1259. )
  1260. # Access Pull-Request authenticated
  1261. output = self.app.get(
  1262. '/api/0/test4/pull-request/1', headers=headers)
  1263. self.assertEqual(output.status_code, 200)
  1264. data2 = json.loads(output.get_data(as_text=True))
  1265. data2['date_created'] = '1431414800'
  1266. data2['project']['date_created'] = '1431414800'
  1267. data2['repo_from']['date_created'] = '1431414800'
  1268. data2['uid'] = '1431414800'
  1269. data2['date_created'] = '1431414800'
  1270. data2['updated_on'] = '1431414800'
  1271. data2['last_updated'] = '1431414800'
  1272. self.assertDictEqual(data, data2)
  1273. @patch('pagure.lib.notify.send_email')
  1274. def test_api_pr_private_repo_add_comment(self, mockemail):
  1275. """ Test the api_pull_request_add_comment method of the flask api. """
  1276. mockemail.return_value = True
  1277. pagure.APP.config['REQUESTS_FOLDER'] = None
  1278. # Add private repo
  1279. item = pagure.lib.model.Project(
  1280. user_id=1, # pingou
  1281. name='test4',
  1282. description='test project description',
  1283. hook_token='aaabbbeeeceee',
  1284. private=True,
  1285. )
  1286. self.session.add(item)
  1287. self.session.commit()
  1288. tests.create_tokens(self.session)
  1289. tests.create_tokens_acl(self.session)
  1290. headers = {'Authorization': 'token aaabbbcccddd'}
  1291. # Create a pull-request
  1292. repo = pagure.lib._get_project(self.session, 'test4')
  1293. forked_repo = pagure.lib._get_project(self.session, 'test4')
  1294. req = pagure.lib.new_pull_request(
  1295. session=self.session,
  1296. repo_from=forked_repo,
  1297. branch_from='master',
  1298. repo_to=repo,
  1299. branch_to='master',
  1300. title='test pull-request',
  1301. user='pingou',
  1302. requestfolder=None,
  1303. )
  1304. self.session.commit()
  1305. self.assertEqual(req.id, 1)
  1306. self.assertEqual(req.title, 'test pull-request')
  1307. # Check comments before
  1308. request = pagure.lib.search_pull_requests(
  1309. self.session, project_id=1, requestid=1)
  1310. self.assertEqual(len(request.comments), 0)
  1311. data = {
  1312. 'title': 'test issue',
  1313. }
  1314. # Incomplete request
  1315. output = self.app.post(
  1316. '/api/0/test4/pull-request/1/comment', data=data, headers=headers)
  1317. self.assertEqual(output.status_code, 400)
  1318. data = json.loads(output.get_data(as_text=True))
  1319. self.assertDictEqual(
  1320. data,
  1321. {
  1322. "error": "Invalid or incomplete input submited",
  1323. "error_code": "EINVALIDREQ",
  1324. "errors": {"comment": ["This field is required."]}
  1325. }
  1326. )
  1327. # No change
  1328. request = pagure.lib.search_pull_requests(
  1329. self.session, project_id=1, requestid=1)
  1330. self.assertEqual(len(request.comments), 0)
  1331. data = {
  1332. 'comment': 'This is a very interesting question',
  1333. }
  1334. # Valid request
  1335. output = self.app.post(
  1336. '/api/0/test4/pull-request/1/comment', data=data, headers=headers)
  1337. self.assertEqual(output.status_code, 200)
  1338. data = json.loads(output.get_data(as_text=True))
  1339. self.assertDictEqual(
  1340. data,
  1341. {'message': 'Comment added'}
  1342. )
  1343. # One comment added
  1344. request = pagure.lib.search_pull_requests(
  1345. self.session, project_id=1, requestid=1)
  1346. self.assertEqual(len(request.comments), 1)
  1347. @patch('pagure.lib.notify.send_email')
  1348. def test_api_private_repo_pr_add_flag(self, mockemail):
  1349. """ Test the api_pull_request_add_flag method of the flask api. """
  1350. mockemail.return_value = True
  1351. pagure.APP.config['REQUESTS_FOLDER'] = None
  1352. # Add private repo
  1353. item = pagure.lib.model.Project(
  1354. user_id=1, # pingou
  1355. name='test4',
  1356. description='test project description',
  1357. hook_token='aaabbbeeeceee',
  1358. private=True,
  1359. )
  1360. self.session.add(item)
  1361. self.session.commit()
  1362. # Add private repo
  1363. item = pagure.lib.model.Project(
  1364. user_id=1, # pingou
  1365. name='test2',
  1366. description='test project description',
  1367. hook_token='foo_bar',
  1368. private=True,
  1369. )
  1370. self.session.add(item)
  1371. self.session.commit()
  1372. tests.create_tokens(self.session)
  1373. tests.create_tokens_acl(self.session)
  1374. headers = {'Authorization': 'token aaabbbcccddd'}
  1375. # Invalid project
  1376. output = self.app.post(
  1377. '/api/0/foo/pull-request/1/flag', headers=headers)
  1378. self.assertEqual(output.status_code, 404)
  1379. data = json.loads(output.get_data(as_text=True))
  1380. self.assertDictEqual(
  1381. data,
  1382. {
  1383. "error": "Project not found",
  1384. "error_code": "ENOPROJECT",
  1385. }
  1386. )
  1387. # Valid token, wrong project
  1388. output = self.app.post(
  1389. '/api/0/test2/pull-request/1/flag', headers=headers)
  1390. self.assertEqual(output.status_code, 401)
  1391. data = json.loads(output.get_data(as_text=True))
  1392. self.assertDictEqual(
  1393. data,
  1394. {
  1395. "error": "Invalid or expired token. Please visit "
  1396. "https://pagure.org/ to get or renew your API token.",
  1397. "error_code": "EINVALIDTOK",
  1398. }
  1399. )
  1400. # No input
  1401. output = self.app.post(
  1402. '/api/0/test4/pull-request/1/flag', headers=headers)
  1403. self.assertEqual(output.status_code, 404)
  1404. data = json.loads(output.get_data(as_text=True))
  1405. self.assertDictEqual(
  1406. data,
  1407. {
  1408. "error": "Pull-Request not found",
  1409. "error_code": "ENOREQ",
  1410. }
  1411. )
  1412. # Create a pull-request
  1413. repo = pagure.lib._get_project(self.session, 'test4')
  1414. forked_repo = pagure.lib._get_project(self.session, 'test4')
  1415. req = pagure.lib.new_pull_request(
  1416. session=self.session,
  1417. repo_from=forked_repo,
  1418. branch_from='master',
  1419. repo_to=repo,
  1420. branch_to='master',
  1421. title='test pull-request',
  1422. user='pingou',
  1423. requestfolder=None,
  1424. )
  1425. self.session.commit()
  1426. self.assertEqual(req.id, 1)
  1427. self.assertEqual(req.title, 'test pull-request')
  1428. # Check comments before
  1429. request = pagure.lib.search_pull_requests(
  1430. self.session, project_id=1, requestid=1)
  1431. self.assertEqual(len(request.flags), 0)
  1432. data = {
  1433. 'username': 'Jenkins',
  1434. 'percent': 100,
  1435. 'url': 'http://jenkins.cloud.fedoraproject.org/',
  1436. 'uid': 'jenkins_build_pagure_100+seed',
  1437. }
  1438. # Incomplete request
  1439. output = self.app.post(
  1440. '/api/0/test4/pull-request/1/flag', data=data, headers=headers)
  1441. self.assertEqual(output.status_code, 400)
  1442. data = json.loads(output.get_data(as_text=True))
  1443. self.assertDictEqual(
  1444. data,
  1445. {
  1446. "error": "Invalid or incomplete input submited",
  1447. "error_code": "EINVALIDREQ",
  1448. "errors": {"comment": ["This field is required."]}
  1449. }
  1450. )
  1451. # No change
  1452. request = pagure.lib.search_pull_requests(
  1453. self.session, project_id=1, requestid=1)
  1454. self.assertEqual(len(request.flags), 0)
  1455. data = {
  1456. 'username': 'Jenkins',
  1457. 'percent': 0,
  1458. 'comment': 'Tests failed',
  1459. 'url': 'http://jenkins.cloud.fedoraproject.org/',
  1460. 'uid': 'jenkins_build_pagure_100+seed',
  1461. }
  1462. # Valid request
  1463. output = self.app.post(
  1464. '/api/0/test4/pull-request/1/flag', data=data, headers=headers)
  1465. self.assertEqual(output.status_code, 200)
  1466. data = json.loads(output.get_data(as_text=True))
  1467. self.assertDictEqual(
  1468. data,
  1469. {'message': 'Flag added'}
  1470. )
  1471. # One flag added
  1472. request = pagure.lib.search_pull_requests(
  1473. self.session, project_id=1, requestid=1)
  1474. self.assertEqual(len(request.flags), 1)
  1475. self.assertEqual(request.flags[0].comment, 'Tests failed')
  1476. self.assertEqual(request.flags[0].percent, 0)
  1477. # Update flag
  1478. data = {
  1479. 'username': 'Jenkins',
  1480. 'percent': 100,
  1481. 'comment': 'Tests passed',
  1482. 'url': 'http://jenkins.cloud.fedoraproject.org/',
  1483. 'uid': 'jenkins_build_pagure_100+seed',
  1484. }
  1485. output = self.app.post(
  1486. '/api/0/test4/pull-request/1/flag', data=data, headers=headers)
  1487. self.assertEqual(output.status_code, 200)
  1488. data = json.loads(output.get_data(as_text=True))
  1489. self.assertDictEqual(
  1490. data,
  1491. {'message': 'Flag updated'}
  1492. )
  1493. # One flag added
  1494. request = pagure.lib.search_pull_requests(
  1495. self.session, project_id=1, requestid=1)
  1496. self.assertEqual(len(request.flags), 1)
  1497. self.assertEqual(request.flags[0].comment, 'Tests passed')
  1498. self.assertEqual(request.flags[0].percent, 100)
  1499. @patch('pagure.lib.notify.send_email')
  1500. def test_api_private_repo_pr_close(self, send_email):
  1501. """ Test the api_pull_request_close method of the flask api. """
  1502. send_email.return_value = True
  1503. pagure.APP.config['REQUESTS_FOLDER'] = None
  1504. # Add private repo
  1505. item = pagure.lib.model.Project(
  1506. user_id=1, # pingou
  1507. name='test4',
  1508. description='test project description',
  1509. hook_token='aaabbbeeeceee',
  1510. private=True,
  1511. )
  1512. self.session.add(item)
  1513. self.session.commit()
  1514. tests.create_tokens(self.session)
  1515. tests.create_tokens_acl(self.session)
  1516. # Add private repo
  1517. item = pagure.lib.model.Project(
  1518. user_id=1, # pingou
  1519. name='test2',
  1520. description='test project description',
  1521. hook_token='foo_bar',
  1522. private=True,
  1523. )
  1524. self.session.add(item)
  1525. self.session.commit()
  1526. # Create the pull-request to close
  1527. repo = pagure.lib._get_project(self.session, 'test4')
  1528. forked_repo = pagure.lib._get_project(self.session, 'test4')
  1529. req = pagure.lib.new_pull_request(
  1530. session=self.session,
  1531. repo_from=forked_repo,
  1532. branch_from='master',
  1533. repo_to=repo,
  1534. branch_to='master',
  1535. title='test pull-request',
  1536. user='pingou',
  1537. requestfolder=None,
  1538. )
  1539. self.session.commit()
  1540. self.assertEqual(req.id, 1)
  1541. self.assertEqual(req.title, 'test pull-request')
  1542. headers = {'Authorization': 'token aaabbbcccddd'}
  1543. # Invalid project
  1544. output = self.app.post(
  1545. '/api/0/foo/pull-request/1/close', headers=headers)
  1546. self.assertEqual(output.status_code, 404)
  1547. data = json.loads(output.get_data(as_text=True))
  1548. self.assertDictEqual(
  1549. data,
  1550. {
  1551. "error": "Project not found",
  1552. "error_code": "ENOPROJECT",
  1553. }
  1554. )
  1555. # Valid token, wrong project
  1556. output = self.app.post(
  1557. '/api/0/test2/pull-request/1/close', headers=headers)
  1558. self.assertEqual(output.status_code, 401)
  1559. data = json.loads(output.get_data(as_text=True))
  1560. self.assertDictEqual(
  1561. data,
  1562. {
  1563. "error": "Invalid or expired token. Please visit "
  1564. "https://pagure.org/ to get or renew your API token.",
  1565. "error_code": "EINVALIDTOK",
  1566. }
  1567. )
  1568. # Invalid PR
  1569. output = self.app.post(
  1570. '/api/0/test4/pull-request/2/close', headers=headers)
  1571. self.assertEqual(output.status_code, 404)
  1572. data = json.loads(output.get_data(as_text=True))
  1573. self.assertDictEqual(
  1574. data,
  1575. {'error': 'Pull-Request not found', 'error_code': "ENOREQ"}
  1576. )
  1577. # Create a token for foo for this project
  1578. item = pagure.lib.model.Token(
  1579. id='foobar_token',
  1580. user_id=2,
  1581. project_id=1,
  1582. expiration=datetime.datetime.utcnow() + datetime.timedelta(
  1583. days=30)
  1584. )
  1585. self.session.add(item)
  1586. self.session.commit()
  1587. # Allow the token to close PR
  1588. acls = pagure.lib.get_acls(self.session)
  1589. acl = None
  1590. for acl in acls:
  1591. if acl.name == 'pull_request_close':
  1592. break
  1593. item = pagure.lib.model.TokenAcl(
  1594. token_id='foobar_token',
  1595. acl_id=acl.id,
  1596. )
  1597. self.session.add(item)
  1598. self.session.commit()
  1599. headers = {'Authorization': 'token foobar_token'}
  1600. # User not admin
  1601. output = self.app.post(
  1602. '/api/0/test4/pull-request/1/close', headers=headers)
  1603. self.assertEqual(output.status_code, 404)
  1604. data = json.loads(output.get_data(as_text=True))
  1605. self.assertDictEqual(
  1606. data,
  1607. {
  1608. "error": "Project not found",
  1609. "error_code": "ENOPROJECT",
  1610. }
  1611. )
  1612. headers = {'Authorization': 'token aaabbbcccddd'}
  1613. # Close PR
  1614. output = self.app.post(
  1615. '/api/0/test4/pull-request/1/close', headers=headers)
  1616. self.assertEqual(output.status_code, 200)
  1617. data = json.loads(output.get_data(as_text=True))
  1618. self.assertDictEqual(
  1619. data,
  1620. {"message": "Pull-request closed!"}
  1621. )
  1622. @patch('pagure.lib.notify.send_email')
  1623. def test_api_private_repo_pr_merge(self, send_email):
  1624. """ Test the api_pull_request_merge method of the flask api. """
  1625. send_email.return_value = True
  1626. pagure.APP.config['REQUESTS_FOLDER'] = None
  1627. # Add private repo
  1628. item = pagure.lib.model.Project(
  1629. user_id=1, # pingou
  1630. name='test4',
  1631. description='test project description',
  1632. hook_token='aaabbbeeeceee',
  1633. private=True,
  1634. )
  1635. self.session.add(item)
  1636. self.session.commit()
  1637. tests.create_projects(self.session)
  1638. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  1639. tests.create_projects_git(os.path.join(self.path, 'requests'),
  1640. bare=True)
  1641. tests.add_readme_git_repo(os.path.join(self.path, 'repos',
  1642. 'test4.git'))
  1643. tests.add_commit_git_repo(os.path.join(self.path, 'repos',
  1644. 'test4.git'),
  1645. branch='test')
  1646. tests.create_tokens(self.session)
  1647. tests.create_tokens_acl(self.session)
  1648. # Add private repo
  1649. item = pagure.lib.model.Project(
  1650. user_id=1, # pingou
  1651. name='test2',
  1652. description='test project description',
  1653. hook_token='foo_bar',
  1654. private=True,
  1655. )
  1656. self.session.add(item)
  1657. self.session.commit()
  1658. # Create the pull-request to close
  1659. repo = pagure.lib._get_project(self.session, 'test4')
  1660. forked_repo = pagure.lib._get_project(self.session, 'test4')
  1661. req = pagure.lib.new_pull_request(
  1662. session=self.session,
  1663. repo_from=forked_repo,
  1664. branch_from='test',
  1665. repo_to=repo,
  1666. branch_to='master',
  1667. title='test pull-request',
  1668. user='pingou',
  1669. requestfolder=None,
  1670. )
  1671. self.session.commit()
  1672. self.assertEqual(req.id, 1)
  1673. self.assertEqual(req.title, 'test pull-request')
  1674. headers = {'Authorization': 'token aaabbbcccddd'}
  1675. # Invalid project
  1676. output = self.app.post(
  1677. '/api/0/foo/pull-request/1/merge', headers=headers)
  1678. self.assertEqual(output.status_code, 404)
  1679. data = json.loads(output.get_data(as_text=True))
  1680. self.assertDictEqual(
  1681. data,
  1682. {
  1683. "error": "Project not found",
  1684. "error_code": "ENOPROJECT",
  1685. }
  1686. )
  1687. # Valid token, wrong project
  1688. output = self.app.post(
  1689. '/api/0/test2/pull-request/1/merge', headers=headers)
  1690. self.assertEqual(output.status_code, 401)
  1691. data = json.loads(output.get_data(as_text=True))
  1692. self.assertDictEqual(
  1693. data,
  1694. {
  1695. "error": "Invalid or expired token. Please visit "
  1696. "https://pagure.org/ to get or renew your API token.",
  1697. "error_code": "EINVALIDTOK",
  1698. }
  1699. )
  1700. # Invalid PR
  1701. output = self.app.post(
  1702. '/api/0/test4/pull-request/2/merge', headers=headers)
  1703. self.assertEqual(output.status_code, 404)
  1704. data = json.loads(output.get_data(as_text=True))
  1705. self.assertDictEqual(
  1706. data,
  1707. {'error': 'Pull-Request not found', 'error_code': "ENOREQ"}
  1708. )
  1709. # Create a token for foo for this project
  1710. item = pagure.lib.model.Token(
  1711. id='foobar_token',
  1712. user_id=2,
  1713. project_id=1,
  1714. expiration=datetime.datetime.utcnow() + datetime.timedelta(
  1715. days=30)
  1716. )
  1717. self.session.add(item)
  1718. self.session.commit()
  1719. # Allow the token to merge PR
  1720. acls = pagure.lib.get_acls(self.session)
  1721. acl = None
  1722. for acl in acls:
  1723. if acl.name == 'pull_request_merge':
  1724. break
  1725. item = pagure.lib.model.TokenAcl(
  1726. token_id='foobar_token',
  1727. acl_id=acl.id,
  1728. )
  1729. self.session.add(item)
  1730. self.session.commit()
  1731. headers = {'Authorization': 'token foobar_token'}
  1732. # User not admin
  1733. output = self.app.post(
  1734. '/api/0/test4/pull-request/1/merge', headers=headers)
  1735. self.assertEqual(output.status_code, 404)
  1736. data = json.loads(output.get_data(as_text=True))
  1737. self.assertDictEqual(
  1738. data,
  1739. {
  1740. "error": "Project not found",
  1741. "error_code": "ENOPROJECT",
  1742. }
  1743. )
  1744. headers = {'Authorization': 'token aaabbbcccddd'}
  1745. # Merge PR
  1746. output = self.app.post(
  1747. '/api/0/test4/pull-request/1/merge', headers=headers)
  1748. self.assertEqual(output.status_code, 200)
  1749. data = json.loads(output.get_data(as_text=True))
  1750. self.assertDictEqual(
  1751. data,
  1752. {"message": "Changes merged!"}
  1753. )
  1754. def test_api_private_repo_new_issue(self):
  1755. """ Test the api_new_issue method of the flask api. """
  1756. # Add private repo
  1757. item = pagure.lib.model.Project(
  1758. user_id=1, # pingou
  1759. name='test4',
  1760. description='test project description',
  1761. hook_token='aaabbbeeeceee',
  1762. private=True,
  1763. )
  1764. self.session.add(item)
  1765. self.session.commit()
  1766. for repo in ['GIT_FOLDER', 'TICKETS_FOLDER']:
  1767. # Add a git repo
  1768. repo_path = os.path.join(
  1769. pagure.APP.config.get(repo), 'test4.git')
  1770. if not os.path.exists(repo_path):
  1771. os.makedirs(repo_path)
  1772. pygit2.init_repository(repo_path, bare=True)
  1773. tests.create_tokens(self.session)
  1774. tests.create_tokens_acl(self.session)
  1775. # Add private repo
  1776. item = pagure.lib.model.Project(
  1777. user_id=1, # pingou
  1778. name='test2',
  1779. description='test project description',
  1780. hook_token='foo_bar',
  1781. private=True,
  1782. )
  1783. self.session.add(item)
  1784. self.session.commit()
  1785. headers = {'Authorization': 'token aaabbbcccddd'}
  1786. # Valid token, wrong project
  1787. output = self.app.post('/api/0/test2/new_issue', headers=headers)
  1788. self.assertEqual(output.status_code, 401)
  1789. data = json.loads(output.get_data(as_text=True))
  1790. self.assertDictEqual(
  1791. data,
  1792. {
  1793. "error": "Invalid or expired token. Please visit "
  1794. "https://pagure.org/ to get or renew your API token.",
  1795. "error_code": "EINVALIDTOK",
  1796. }
  1797. )
  1798. # No input
  1799. output = self.app.post('/api/0/test4/new_issue', headers=headers)
  1800. self.assertEqual(output.status_code, 400)
  1801. data = json.loads(output.get_data(as_text=True))
  1802. self.assertDictEqual(
  1803. data,
  1804. {
  1805. "error": "Invalid or incomplete input submited",
  1806. "error_code": "EINVALIDREQ",
  1807. "errors": {
  1808. "issue_content": ["This field is required."],
  1809. "title": ["This field is required."]
  1810. }
  1811. })
  1812. data = {
  1813. 'title': 'test issue',
  1814. }
  1815. # Invalid repo
  1816. output = self.app.post(
  1817. '/api/0/foo/new_issue', data=data, headers=headers)
  1818. self.assertEqual(output.status_code, 404)
  1819. data = json.loads(output.get_data(as_text=True))
  1820. self.assertDictEqual(
  1821. data,
  1822. {
  1823. "error": "Project not found",
  1824. "error_code": "ENOPROJECT",
  1825. }
  1826. )
  1827. # Incomplete request
  1828. output = self.app.post(
  1829. '/api/0/test4/new_issue', data=data, headers=headers)
  1830. self.assertEqual(output.status_code, 400)
  1831. data = json.loads(output.get_data(as_text=True))
  1832. self.assertDictEqual(
  1833. data,
  1834. {
  1835. "error": "Invalid or incomplete input submited",
  1836. "error_code": "EINVALIDREQ",
  1837. "errors": {
  1838. "issue_content": ["This field is required."],
  1839. "title": ["This field is required."]
  1840. }
  1841. }
  1842. )
  1843. data = {
  1844. 'title': 'test issue',
  1845. 'issue_content': 'This issue needs attention',
  1846. }
  1847. # Valid request
  1848. output = self.app.post(
  1849. '/api/0/test4/new_issue', data=data, headers=headers)
  1850. self.assertEqual(output.status_code, 200)
  1851. data = json.loads(output.get_data(as_text=True))
  1852. data['issue']['date_created'] = '1431414800'
  1853. data['issue']['last_updated'] = '1431414800'
  1854. self.assertDictEqual(
  1855. data,
  1856. {
  1857. 'issue': FULL_ISSUE_LIST[7],
  1858. 'message': 'Issue created'
  1859. }
  1860. )
  1861. def test_api_priavte_repo_view_issues(self):
  1862. """ Test the api_view_issues method of the flask api. """
  1863. self.test_api_private_repo_new_issue()
  1864. # Invalid repo
  1865. output = self.app.get('/api/0/foo/issues')
  1866. self.assertEqual(output.status_code, 404)
  1867. data = json.loads(output.get_data(as_text=True))
  1868. self.assertDictEqual(
  1869. data,
  1870. {
  1871. "error": "Project not found",
  1872. "error_code": "ENOPROJECT",
  1873. }
  1874. )
  1875. # List all opened issues
  1876. user = tests.FakeUser(username='pingou')
  1877. with tests.user_set(pagure.APP, user):
  1878. output = self.app.get('/api/0/test4/issues')
  1879. self.assertEqual(output.status_code, 200)
  1880. data = json.loads(output.get_data(as_text=True))
  1881. data['issues'][0]['date_created'] = '1431414800'
  1882. data['issues'][0]['last_updated'] = '1431414800'
  1883. self.assertDictEqual(
  1884. data,
  1885. {
  1886. "args": {
  1887. "assignee": None,
  1888. "author": None,
  1889. "milestones": [],
  1890. "no_stones": None,
  1891. "priority": None,
  1892. "since": None,
  1893. "status": None,
  1894. "tags": []
  1895. },
  1896. "total_issues": 1,
  1897. "issues": [
  1898. {
  1899. "assignee": None,
  1900. "blocks": [],
  1901. "close_status": None,
  1902. "closed_at": None,
  1903. "comments": [],
  1904. "content": "This issue needs attention",
  1905. "custom_fields": [],
  1906. "date_created": "1431414800",
  1907. "last_updated": "1431414800",
  1908. "depends": [],
  1909. "id": 1,
  1910. "milestone": "",
  1911. "priority": None,
  1912. "private": False,
  1913. "status": "Open",
  1914. "tags": [],
  1915. "title": "test issue",
  1916. "user": {
  1917. "fullname": "PY C",
  1918. "name": "pingou"
  1919. }
  1920. }
  1921. ]
  1922. }
  1923. )
  1924. # Create private issue
  1925. repo = pagure.lib._get_project(self.session, 'test4')
  1926. msg = pagure.lib.new_issue(
  1927. session=self.session,
  1928. repo=repo,
  1929. title='Test issue',
  1930. content='We should work on this',
  1931. user='pingou',
  1932. milestone='',
  1933. ticketfolder=None,
  1934. private=True,
  1935. )
  1936. self.session.commit()
  1937. self.assertEqual(msg.title, 'Test issue')
  1938. # Private issues are retrieved
  1939. user = tests.FakeUser(username='pingou')
  1940. with tests.user_set(pagure.APP, user):
  1941. output = self.app.get('/api/0/test4/issues')
  1942. self.assertEqual(output.status_code, 200)
  1943. data = json.loads(output.get_data(as_text=True))
  1944. data['issues'][0]['date_created'] = '1431414800'
  1945. data['issues'][0]['last_updated'] = '1431414800'
  1946. data['issues'][1]['date_created'] = '1431414800'
  1947. data['issues'][1]['last_updated'] = '1431414800'
  1948. self.assertDictEqual(
  1949. data,
  1950. {
  1951. "args": {
  1952. "assignee": None,
  1953. "author": None,
  1954. "milestones": [],
  1955. "no_stones": None,
  1956. "priority": None,
  1957. "status": None,
  1958. "since": None,
  1959. "tags": []
  1960. },
  1961. "issues": [
  1962. {
  1963. "assignee": None,
  1964. "blocks": [],
  1965. "close_status": None,
  1966. "closed_at": None,
  1967. "comments": [],
  1968. "content": "We should work on this",
  1969. "custom_fields": [],
  1970. "date_created": "1431414800",
  1971. "last_updated": "1431414800",
  1972. "depends": [],
  1973. "id": 2,
  1974. "milestone": "",
  1975. "priority": None,
  1976. "private": True,
  1977. "status": "Open",
  1978. "tags": [],
  1979. "title": "Test issue",
  1980. "user": {
  1981. "fullname": "PY C",
  1982. "name": "pingou"
  1983. }
  1984. },
  1985. {
  1986. "assignee": None,
  1987. "blocks": [],
  1988. "close_status": None,
  1989. "closed_at": None,
  1990. "comments": [],
  1991. "content": "This issue needs attention",
  1992. "custom_fields": [],
  1993. "date_created": "1431414800",
  1994. "last_updated": "1431414800",
  1995. "depends": [],
  1996. "id": 1,
  1997. "milestone": "",
  1998. "priority": None,
  1999. "private": False,
  2000. "status": "Open",
  2001. "tags": [],
  2002. "title": "test issue",
  2003. "user": {
  2004. "fullname": "PY C",
  2005. "name": "pingou"
  2006. }
  2007. }
  2008. ],
  2009. "total_issues": 2
  2010. }
  2011. )
  2012. # Access issues authenticated but non-existing token
  2013. headers = {'Authorization': 'token aaabbbccc'}
  2014. output = self.app.get('/api/0/test4/issues', headers=headers)
  2015. self.assertEqual(output.status_code, 401)
  2016. headers = {'Authorization': 'token aaabbbcccddd'}
  2017. # Access issues authenticated correctly
  2018. output = self.app.get('/api/0/test4/issues', headers=headers)
  2019. self.assertEqual(output.status_code, 200)
  2020. data = json.loads(output.get_data(as_text=True))
  2021. data['issues'][0]['date_created'] = '1431414800'
  2022. data['issues'][0]['last_updated'] = '1431414800'
  2023. data['issues'][1]['date_created'] = '1431414800'
  2024. data['issues'][1]['last_updated'] = '1431414800'
  2025. self.assertDictEqual(
  2026. data,
  2027. {
  2028. "args": {
  2029. "assignee": None,
  2030. "author": None,
  2031. "milestones": [],
  2032. "no_stones": None,
  2033. "priority": None,
  2034. "status": None,
  2035. "since": None,
  2036. "tags": []
  2037. },
  2038. "issues": [
  2039. {
  2040. "assignee": None,
  2041. "blocks": [],
  2042. "close_status": None,
  2043. "closed_at": None,
  2044. "comments": [],
  2045. "content": "We should work on this",
  2046. "custom_fields": [],
  2047. "date_created": "1431414800",
  2048. "last_updated": "1431414800",
  2049. "depends": [],
  2050. "id": 2,
  2051. "milestone": "",
  2052. "priority": None,
  2053. "private": True,
  2054. "status": "Open",
  2055. "tags": [],
  2056. "title": "Test issue",
  2057. "user": {
  2058. "fullname": "PY C",
  2059. "name": "pingou"
  2060. }
  2061. },
  2062. {
  2063. "assignee": None,
  2064. "blocks": [],
  2065. "close_status": None,
  2066. "closed_at": None,
  2067. "comments": [],
  2068. "content": "This issue needs attention",
  2069. "custom_fields": [],
  2070. "date_created": "1431414800",
  2071. "last_updated": "1431414800",
  2072. "depends": [],
  2073. "id": 1,
  2074. "milestone": "",
  2075. "priority": None,
  2076. "private": False,
  2077. "status": "Open",
  2078. "tags": [],
  2079. "title": "test issue",
  2080. "user": {
  2081. "fullname": "PY C",
  2082. "name": "pingou"
  2083. }
  2084. }
  2085. ],
  2086. "total_issues": 2
  2087. }
  2088. )
  2089. # List closed issue
  2090. output = self.app.get(
  2091. '/api/0/test4/issues?status=Closed', headers=headers)
  2092. self.assertEqual(output.status_code, 200)
  2093. data = json.loads(output.get_data(as_text=True))
  2094. self.assertDictEqual(
  2095. data,
  2096. {
  2097. "args": {
  2098. "assignee": None,
  2099. "author": None,
  2100. "milestones": [],
  2101. "no_stones": None,
  2102. "priority": None,
  2103. "status": "Closed",
  2104. "since": None,
  2105. "tags": []
  2106. },
  2107. "total_issues": 0,
  2108. "issues": []
  2109. }
  2110. )
  2111. # List closed issue
  2112. output = self.app.get(
  2113. '/api/0/test4/issues?status=Invalid', headers=headers)
  2114. self.assertEqual(output.status_code, 200)
  2115. data = json.loads(output.get_data(as_text=True))
  2116. self.assertDictEqual(
  2117. data,
  2118. {
  2119. "args": {
  2120. "assignee": None,
  2121. "author": None,
  2122. "milestones": [],
  2123. "no_stones": None,
  2124. "priority": None,
  2125. "status": "Invalid",
  2126. "since": None,
  2127. "tags": []
  2128. },
  2129. "total_issues": 0,
  2130. "issues": []
  2131. }
  2132. )
  2133. # List all issues
  2134. output = self.app.get(
  2135. '/api/0/test4/issues?status=All', headers=headers)
  2136. self.assertEqual(output.status_code, 200)
  2137. data = json.loads(output.get_data(as_text=True))
  2138. data['issues'][0]['date_created'] = '1431414800'
  2139. data['issues'][0]['last_updated'] = '1431414800'
  2140. data['issues'][1]['date_created'] = '1431414800'
  2141. data['issues'][1]['last_updated'] = '1431414800'
  2142. self.assertDictEqual(
  2143. data,
  2144. {
  2145. "args": {
  2146. "assignee": None,
  2147. "author": None,
  2148. "milestones": [],
  2149. "no_stones": None,
  2150. "priority": None,
  2151. "since": None,
  2152. "status": "All",
  2153. "tags": []
  2154. },
  2155. "issues": [
  2156. {
  2157. "assignee": None,
  2158. "blocks": [],
  2159. "close_status": None,
  2160. "closed_at": None,
  2161. "comments": [],
  2162. "content": "We should work on this",
  2163. "custom_fields": [],
  2164. "date_created": "1431414800",
  2165. "last_updated": "1431414800",
  2166. "depends": [],
  2167. "id": 2,
  2168. "milestone": "",
  2169. "priority": None,
  2170. "private": True,
  2171. "status": "Open",
  2172. "tags": [],
  2173. "title": "Test issue",
  2174. "user": {
  2175. "fullname": "PY C",
  2176. "name": "pingou"
  2177. }
  2178. },
  2179. {
  2180. "assignee": None,
  2181. "blocks": [],
  2182. "close_status": None,
  2183. "closed_at": None,
  2184. "comments": [],
  2185. "content": "This issue needs attention",
  2186. "custom_fields": [],
  2187. "date_created": "1431414800",
  2188. "last_updated": "1431414800",
  2189. "depends": [],
  2190. "id": 1,
  2191. "milestone": "",
  2192. "priority": None,
  2193. "private": False,
  2194. "status": "Open",
  2195. "tags": [],
  2196. "title": "test issue",
  2197. "user": {
  2198. "fullname": "PY C",
  2199. "name": "pingou"
  2200. }
  2201. }
  2202. ],
  2203. "total_issues": 2
  2204. }
  2205. )
  2206. def test_api_pivate_repo_view_issue(self):
  2207. """ Test the api_view_issue method of the flask api. """
  2208. self.test_api_private_repo_new_issue()
  2209. # Invalid repo
  2210. output = self.app.get('/api/0/foo/issue/1')
  2211. self.assertEqual(output.status_code, 404)
  2212. data = json.loads(output.get_data(as_text=True))
  2213. self.assertDictEqual(
  2214. data,
  2215. {
  2216. "error": "Project not found",
  2217. "error_code": "ENOPROJECT",
  2218. }
  2219. )
  2220. # Invalid issue for this repo
  2221. output = self.app.get('/api/0/test4/issue/1')
  2222. self.assertEqual(output.status_code, 404)
  2223. data = json.loads(output.get_data(as_text=True))
  2224. self.assertDictEqual(
  2225. data,
  2226. {
  2227. "error": "Project not found",
  2228. "error_code": "ENOPROJECT",
  2229. }
  2230. )
  2231. # Un-authorized user
  2232. user = tests.FakeUser()
  2233. with tests.user_set(pagure.APP, user):
  2234. output = self.app.get('/api/0/test4/issue/1')
  2235. self.assertEqual(output.status_code, 404)
  2236. data = json.loads(output.get_data(as_text=True))
  2237. self.assertDictEqual(
  2238. data,
  2239. {
  2240. "error": "Project not found",
  2241. "error_code": "ENOPROJECT",
  2242. }
  2243. )
  2244. # Valid issue
  2245. user = tests.FakeUser(username='pingou')
  2246. with tests.user_set(pagure.APP, user):
  2247. output = self.app.get('/api/0/test4/issue/1')
  2248. self.assertEqual(output.status_code, 200)
  2249. data = json.loads(output.get_data(as_text=True))
  2250. data['date_created'] = '1431414800'
  2251. data['last_updated'] = '1431414800'
  2252. self.assertDictEqual(
  2253. data,
  2254. {
  2255. "assignee": None,
  2256. "blocks": [],
  2257. "close_status": None,
  2258. "closed_at": None,
  2259. "comments": [],
  2260. "content": "This issue needs attention",
  2261. "custom_fields": [],
  2262. "date_created": "1431414800",
  2263. "depends": [],
  2264. "id": 1,
  2265. "last_updated": "1431414800",
  2266. "milestone": "",
  2267. "priority": None,
  2268. "private": False,
  2269. "status": "Open",
  2270. "tags": [],
  2271. "title": "test issue",
  2272. "user": {
  2273. "fullname": "PY C",
  2274. "name": "pingou"
  2275. }
  2276. }
  2277. )
  2278. headers = {'Authorization': 'token aaabbbccc'}
  2279. # Access issue authenticated but non-existing token
  2280. output = self.app.get('/api/0/test4/issue/1', headers=headers)
  2281. self.assertEqual(output.status_code, 401)
  2282. data = json.loads(output.get_data(as_text=True))
  2283. self.assertDictEqual(
  2284. data,
  2285. {
  2286. "error": "Invalid or expired token. Please visit https://pagure.org/ to get or renew your API token.",
  2287. "error_code": "EINVALIDTOK"
  2288. }
  2289. )
  2290. headers = {'Authorization': 'token aaabbbcccddd'}
  2291. # Access issue authenticated correctly
  2292. output = self.app.get('/api/0/test4/issue/1', headers=headers)
  2293. self.assertEqual(output.status_code, 200)
  2294. data = json.loads(output.get_data(as_text=True))
  2295. data['date_created'] = '1431414800'
  2296. data['last_updated'] = '1431414800'
  2297. self.assertDictEqual(
  2298. data,
  2299. {
  2300. "assignee": None,
  2301. "blocks": [],
  2302. "close_status": None,
  2303. "closed_at": None,
  2304. "comments": [],
  2305. "content": "This issue needs attention",
  2306. "custom_fields": [],
  2307. "date_created": "1431414800",
  2308. "depends": [],
  2309. "id": 1,
  2310. "last_updated": "1431414800",
  2311. "milestone": "",
  2312. "priority": None,
  2313. "private": False,
  2314. "status": "Open",
  2315. "tags": [],
  2316. "title": "test issue",
  2317. "user": {
  2318. "fullname": "PY C",
  2319. "name": "pingou"
  2320. }
  2321. }
  2322. )
  2323. def test_api_private_repo_change_status_issue(self):
  2324. """ Test the api_change_status_issue method of the flask api. """
  2325. item = pagure.lib.model.Project(
  2326. user_id=1, # pingou
  2327. name='test4',
  2328. description='test project description',
  2329. hook_token='aaabbbeeeceee',
  2330. private=True,
  2331. )
  2332. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  2333. self.session.add(item)
  2334. self.session.commit()
  2335. for repo in ['GIT_FOLDER', 'TICKETS_FOLDER']:
  2336. # Add a git repo
  2337. repo_path = os.path.join(
  2338. pagure.APP.config.get(repo), 'test4.git')
  2339. if not os.path.exists(repo_path):
  2340. os.makedirs(repo_path)
  2341. pygit2.init_repository(repo_path, bare=True)
  2342. tests.create_tokens(self.session)
  2343. tests.create_tokens_acl(self.session)
  2344. headers = {'Authorization': 'token aaabbbcccddd'}
  2345. # Invalid project
  2346. output = self.app.post('/api/0/foo/issue/1/status', headers=headers)
  2347. self.assertEqual(output.status_code, 404)
  2348. data = json.loads(output.get_data(as_text=True))
  2349. self.assertDictEqual(
  2350. data,
  2351. {
  2352. "error": "Project not found",
  2353. "error_code": "ENOPROJECT",
  2354. }
  2355. )
  2356. # Valid token, wrong project
  2357. user = tests.FakeUser(username='pingou')
  2358. with tests.user_set(pagure.APP, user):
  2359. output = self.app.post(
  2360. '/api/0/test2/issue/1/status', headers=headers)
  2361. self.assertEqual(output.status_code, 404)
  2362. data = json.loads(output.get_data(as_text=True))
  2363. self.assertDictEqual(
  2364. data,
  2365. {
  2366. "error": "Project not found",
  2367. "error_code": "ENOPROJECT",
  2368. }
  2369. )
  2370. # No input
  2371. output = self.app.post('/api/0/test4/issue/1/status', headers=headers)
  2372. self.assertEqual(output.status_code, 404)
  2373. data = json.loads(output.get_data(as_text=True))
  2374. self.assertDictEqual(
  2375. data,
  2376. {
  2377. "error": "Issue not found",
  2378. "error_code": "ENOISSUE",
  2379. }
  2380. )
  2381. # Create normal issue
  2382. repo = pagure.lib._get_project(self.session, 'test4')
  2383. msg = pagure.lib.new_issue(
  2384. session=self.session,
  2385. repo=repo,
  2386. title='Test issue #1',
  2387. content='We should work on this',
  2388. user='pingou',
  2389. ticketfolder=None,
  2390. private=False,
  2391. )
  2392. self.session.commit()
  2393. self.assertEqual(msg.title, 'Test issue #1')
  2394. # Check status before
  2395. repo = pagure.lib._get_project(self.session, 'test4')
  2396. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  2397. self.assertEqual(issue.status, 'Open')
  2398. data = {
  2399. 'title': 'test issue',
  2400. }
  2401. user = tests.FakeUser(username='pingou')
  2402. with tests.user_set(pagure.APP, user):
  2403. # Incomplete request
  2404. output = self.app.post(
  2405. '/api/0/test4/issue/1/status', data=data, headers=headers)
  2406. self.assertEqual(output.status_code, 400)
  2407. data = json.loads(output.get_data(as_text=True))
  2408. self.assertDictEqual(
  2409. data,
  2410. {
  2411. "error": "Invalid or incomplete input submited",
  2412. "error_code": "EINVALIDREQ",
  2413. "errors": {"status": ["Not a valid choice"]}
  2414. }
  2415. )
  2416. # No change
  2417. repo = pagure.lib._get_project(self.session, 'test4')
  2418. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  2419. self.assertEqual(issue.status, 'Open')
  2420. data = {
  2421. 'status': 'Open',
  2422. }
  2423. # Valid request but no change
  2424. output = self.app.post(
  2425. '/api/0/test4/issue/1/status', data=data, headers=headers)
  2426. self.assertEqual(output.status_code, 200)
  2427. data = json.loads(output.get_data(as_text=True))
  2428. self.assertDictEqual(
  2429. data,
  2430. {'message': 'No changes'}
  2431. )
  2432. # No change
  2433. repo = pagure.lib._get_project(self.session, 'test4')
  2434. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  2435. self.assertEqual(issue.status, 'Open')
  2436. data = {
  2437. 'status': 'Fixed',
  2438. }
  2439. # Valid request
  2440. output = self.app.post(
  2441. '/api/0/test4/issue/1/status', data=data, headers=headers)
  2442. self.assertEqual(output.status_code, 200)
  2443. data = json.loads(output.get_data(as_text=True))
  2444. self.assertDictEqual(
  2445. data,
  2446. {'message':[
  2447. 'Issue status updated to: Closed (was: Open)',
  2448. 'Issue close_status updated to: Fixed'
  2449. ]}
  2450. )
  2451. @patch('pagure.lib.git.update_git')
  2452. @patch('pagure.lib.notify.send_email')
  2453. def test_api_private_repo_comment_issue(self, p_send_email, p_ugt):
  2454. """ Test the api_comment_issue method of the flask api. """
  2455. p_send_email.return_value = True
  2456. p_ugt.return_value = True
  2457. item = pagure.lib.model.Project(
  2458. user_id=1, # pingou
  2459. name='test4',
  2460. description='test project description',
  2461. hook_token='aaabbbeeeceee',
  2462. private=True,
  2463. )
  2464. self.session.add(item)
  2465. self.session.commit()
  2466. tests.create_tokens(self.session)
  2467. tests.create_tokens_acl(self.session)
  2468. headers = {'Authorization': 'token aaabbbcccddd'}
  2469. # Invalid project
  2470. output = self.app.post('/api/0/foo/issue/1/comment', headers=headers)
  2471. self.assertEqual(output.status_code, 404)
  2472. data = json.loads(output.get_data(as_text=True))
  2473. self.assertDictEqual(
  2474. data,
  2475. {
  2476. "error": "Project not found",
  2477. "error_code": "ENOPROJECT",
  2478. }
  2479. )
  2480. # Invalid token, right project
  2481. headers = {'Authorization': 'token aaabbbccc'}
  2482. output = self.app.post('/api/0/test4/issue/1/comment', headers=headers)
  2483. self.assertEqual(output.status_code, 401)
  2484. data = json.loads(output.get_data(as_text=True))
  2485. self.assertDictEqual(
  2486. data,
  2487. {
  2488. "error": "Invalid or expired token. Please visit "
  2489. "https://pagure.org/ to get or renew your API token.",
  2490. "error_code": "EINVALIDTOK",
  2491. }
  2492. )
  2493. headers = {'Authorization': 'token aaabbbcccddd'}
  2494. # No input
  2495. output = self.app.post('/api/0/test4/issue/1/comment', headers=headers)
  2496. self.assertEqual(output.status_code, 404)
  2497. data = json.loads(output.get_data(as_text=True))
  2498. self.assertDictEqual(
  2499. data,
  2500. {
  2501. "error": "Issue not found",
  2502. "error_code": "ENOISSUE",
  2503. }
  2504. )
  2505. # Create normal issue
  2506. repo = pagure.lib._get_project(self.session, 'test4')
  2507. msg = pagure.lib.new_issue(
  2508. session=self.session,
  2509. repo=repo,
  2510. title='Test issue #1',
  2511. content='We should work on this',
  2512. user='pingou',
  2513. ticketfolder=None,
  2514. private=False,
  2515. issue_uid='aaabbbccc#1',
  2516. )
  2517. self.session.commit()
  2518. self.assertEqual(msg.title, 'Test issue #1')
  2519. # Check comments before
  2520. repo = pagure.lib._get_project(self.session, 'test4')
  2521. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  2522. self.assertEqual(len(issue.comments), 0)
  2523. data = {
  2524. 'title': 'test issue',
  2525. }
  2526. # Incomplete request
  2527. output = self.app.post(
  2528. '/api/0/test4/issue/1/comment', data=data, headers=headers)
  2529. self.assertEqual(output.status_code, 400)
  2530. data = json.loads(output.get_data(as_text=True))
  2531. self.assertDictEqual(
  2532. data,
  2533. {
  2534. "error": "Invalid or incomplete input submited",
  2535. "error_code": "EINVALIDREQ",
  2536. "errors": {"comment": ["This field is required."]}
  2537. }
  2538. )
  2539. # No change
  2540. repo = pagure.lib._get_project(self.session, 'test4')
  2541. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  2542. self.assertEqual(issue.status, 'Open')
  2543. data = {
  2544. 'comment': 'This is a very interesting question',
  2545. }
  2546. # Valid request
  2547. output = self.app.post(
  2548. '/api/0/test4/issue/1/comment', data=data, headers=headers)
  2549. self.assertEqual(output.status_code, 200)
  2550. data = json.loads(output.get_data(as_text=True))
  2551. self.assertDictEqual(
  2552. data,
  2553. {'message': 'Comment added'}
  2554. )
  2555. # One comment added
  2556. repo = pagure.lib._get_project(self.session, 'test4')
  2557. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  2558. self.assertEqual(len(issue.comments), 1)
  2559. @patch('pagure.lib.git.update_git')
  2560. @patch('pagure.lib.notify.send_email')
  2561. def test_api_view_issue_comment(self, p_send_email, p_ugt):
  2562. """ Test the api_view_issue_comment endpoint. """
  2563. p_send_email.return_value = True
  2564. p_ugt.return_value = True
  2565. self.test_api_private_repo_comment_issue()
  2566. # View a comment that does not exist
  2567. output = self.app.get('/api/0/foo/issue/100/comment/2')
  2568. self.assertEqual(output.status_code, 404)
  2569. # Issue exists but not the comment
  2570. output = self.app.get('/api/0/test/issue/1/comment/2')
  2571. self.assertEqual(output.status_code, 404)
  2572. # Issue and comment exists
  2573. output = self.app.get('/api/0/test/issue/1/comment/1')
  2574. self.assertEqual(output.status_code, 404)
  2575. user = tests.FakeUser(username='pingou')
  2576. with tests.user_set(pagure.APP, user):
  2577. output = self.app.get('/api/0/test4/issue/1/comment/1')
  2578. self.assertEqual(output.status_code, 200)
  2579. data = json.loads(output.get_data(as_text=True))
  2580. data['date_created'] = '1435821770'
  2581. data["comment_date"] = "2015-07-02 09:22"
  2582. data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
  2583. self.assertDictEqual(
  2584. data,
  2585. {
  2586. "avatar_url": "https://seccdn.libravatar.org/avatar/...",
  2587. "comment": "This is a very interesting question",
  2588. "comment_date": "2015-07-02 09:22",
  2589. "notification": False,
  2590. "date_created": "1435821770",
  2591. "edited_on": None,
  2592. "editor": None,
  2593. "id": 1,
  2594. "parent": None,
  2595. "user": {
  2596. "fullname": "PY C",
  2597. "name": "pingou"
  2598. }
  2599. }
  2600. )
  2601. # Issue and comment exists, using UID
  2602. output = self.app.get('/api/0/test4/issue/aaabbbccc#1/comment/1')
  2603. self.assertEqual(output.status_code, 200)
  2604. data = json.loads(output.get_data(as_text=True))
  2605. data['date_created'] = '1435821770'
  2606. data["comment_date"] = "2015-07-02 09:22"
  2607. data["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
  2608. self.assertDictEqual(
  2609. data,
  2610. {
  2611. "avatar_url": "https://seccdn.libravatar.org/avatar/...",
  2612. "comment": "This is a very interesting question",
  2613. "comment_date": "2015-07-02 09:22",
  2614. "notification": False,
  2615. "date_created": "1435821770",
  2616. "edited_on": None,
  2617. "editor": None,
  2618. "id": 1,
  2619. "parent": None,
  2620. "user": {
  2621. "fullname": "PY C",
  2622. "name": "pingou"
  2623. }
  2624. }
  2625. )
  2626. if __name__ == '__main__':
  2627. unittest.main(verbosity=2)