test_pagure_flask_ui_app.py 111 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2018 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. from __future__ import unicode_literals, absolute_import
  8. import datetime
  9. import unittest
  10. import shutil
  11. import sys
  12. import tempfile
  13. import os
  14. import six
  15. import json
  16. import pygit2
  17. from mock import patch, MagicMock
  18. sys.path.insert(
  19. 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
  20. )
  21. import pagure.lib.query
  22. import tests
  23. class PagureFlaskApptests(tests.Modeltests):
  24. """ Tests for flask app controller of pagure """
  25. def test_watch_list(self):
  26. """ Test for watch list of a user """
  27. user = tests.FakeUser(username="pingou")
  28. with tests.user_set(self.app.application, user):
  29. output = self.app.get("/", follow_redirects=True)
  30. output_text = output.get_data(as_text=True)
  31. self.assertIn(
  32. '<div class="text-center">You have no Projects</div>',
  33. output_text,
  34. )
  35. tests.create_projects(self.session)
  36. output = self.app.get("/", follow_redirects=True)
  37. output_text = output.get_data(as_text=True)
  38. self.assertIn(
  39. '<h4 class="font-weight-bold mb-0">My Projects</h4>',
  40. output_text,
  41. )
  42. def test_view_users(self):
  43. """ Test the view_users endpoint. """
  44. output = self.app.get("/users/?page=abc")
  45. self.assertEqual(output.status_code, 200)
  46. output_text = output.get_data(as_text=True)
  47. self.assertIn(
  48. '<h3 class="mb-3 font-weight-bold">\n Users '
  49. '<span class="badge badge-secondary">2</span>',
  50. output_text,
  51. )
  52. self.assertIn(
  53. '<a href="/user/pingou">\n '
  54. '<div class="nowrap"><strong>pingou</strong>',
  55. output_text,
  56. )
  57. self.assertIn(
  58. '<a href="/user/foo">\n '
  59. '<div class="nowrap"><strong>foo</strong>',
  60. output_text,
  61. )
  62. @patch.dict("pagure.config.config", {"ITEM_PER_PAGE": 2})
  63. def test_view_user_repo_cnt(self):
  64. """ Test the repo counts on the view_user endpoint. """
  65. tests.create_projects(self.session)
  66. self.gitrepos = tests.create_projects_git(
  67. pagure.config.config["GIT_FOLDER"]
  68. )
  69. output = self.app.get("/user/pingou")
  70. self.assertEqual(output.status_code, 200)
  71. output_text = output.get_data(as_text=True)
  72. self.assertIn(
  73. """<span>
  74. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  75. <span class="d-none d-md-inline">Projects&nbsp;</span>
  76. </span>
  77. <div class="ml-auto">
  78. <span class="badge badge-secondary">
  79. 3
  80. </span>
  81. </div>""",
  82. output_text,
  83. )
  84. self.assertIn(
  85. """<span>
  86. <i class="fa fa-fw text-muted fa-code-fork"></i>
  87. <span class="d-none d-md-inline">Forks&nbsp;</span>
  88. </span>
  89. <div class="ml-auto">
  90. <span class="badge badge-secondary">
  91. 0
  92. </span>
  93. </div>""",
  94. output_text,
  95. )
  96. def test_view_user(self):
  97. """ Test the view_user endpoint. """
  98. output = self.app.get("/user/pingou?repopage=abc&forkpage=def")
  99. self.assertEqual(output.status_code, 200)
  100. output_text = output.get_data(as_text=True)
  101. self.assertIn(
  102. """<span>
  103. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  104. <span class="d-none d-md-inline">Projects&nbsp;</span>
  105. </span>
  106. <div class="ml-auto">
  107. <span class="badge badge-secondary">
  108. 0
  109. </span>
  110. </div>""",
  111. output_text,
  112. )
  113. self.assertIn(
  114. """<span>
  115. <i class="fa fa-fw text-muted fa-code-fork"></i>
  116. <span class="d-none d-md-inline">Forks&nbsp;</span>
  117. </span>
  118. <div class="ml-auto">
  119. <span class="badge badge-secondary">
  120. 0
  121. </span>
  122. </div>""",
  123. output_text,
  124. )
  125. tests.create_projects(self.session)
  126. self.gitrepos = tests.create_projects_git(
  127. pagure.config.config["GIT_FOLDER"]
  128. )
  129. output = self.app.get("/user/pingou?repopage=abc&forkpage=def")
  130. self.assertEqual(output.status_code, 200)
  131. output_text = output.get_data(as_text=True)
  132. self.assertIn(
  133. """<span>
  134. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  135. <span class="d-none d-md-inline">Projects&nbsp;</span>
  136. </span>
  137. <div class="ml-auto">
  138. <span class="badge badge-secondary">
  139. 3
  140. </span>
  141. </div>""",
  142. output_text,
  143. )
  144. self.assertIn(
  145. """<span>
  146. <i class="fa fa-fw text-muted fa-code-fork"></i>
  147. <span class="d-none d-md-inline">Forks&nbsp;</span>
  148. </span>
  149. <div class="ml-auto">
  150. <span class="badge badge-secondary">
  151. 0
  152. </span>
  153. </div>""",
  154. output_text,
  155. )
  156. self.assertNotIn(
  157. '<a class="page-link" href="#" tabindex="-1">page 1 of 2</a>',
  158. output_text,
  159. )
  160. @patch.dict(
  161. "pagure.config.config",
  162. {
  163. "PAGURE_ADMIN_USERS": ["pingou"],
  164. "ALLOW_ADMIN_IGNORE_EXISTING_REPOS": True,
  165. },
  166. )
  167. def test_adopt_repos(self):
  168. """ Test the new_project endpoint with existing git repo. """
  169. # Before
  170. projects = pagure.lib.query.search_projects(self.session)
  171. self.assertEqual(len(projects), 0)
  172. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  173. tests.add_content_git_repo(
  174. os.path.join(self.path, "repos", "test.git")
  175. )
  176. user = tests.FakeUser(username="pingou")
  177. with tests.user_set(self.app.application, user):
  178. data = {
  179. "csrf_token": self.get_csrf(),
  180. "name": "test",
  181. "description": "Project #1",
  182. }
  183. output = self.app.post("/new/", data=data, follow_redirects=True)
  184. self.assertEqual(output.status_code, 200)
  185. output_text = output.get_data(as_text=True)
  186. self.assertIn("The main repo test.git already exists", output_text)
  187. data["ignore_existing_repos"] = "y"
  188. output = self.app.post("/new/", data=data, follow_redirects=True)
  189. self.assertEqual(output.status_code, 200)
  190. output_text = output.get_data(as_text=True)
  191. self.assertIn("Alice Author", output_text)
  192. @patch.dict(
  193. "pagure.config.config",
  194. {"PAGURE_ADMIN_USERS": [], "USERS_IGNORE_EXISTING_REPOS": ["pingou"]},
  195. )
  196. def test_adopt_repos_non_admin(self):
  197. """ Test the new_project endpoint with existing git repo for non-admins. """
  198. # Before
  199. projects = pagure.lib.query.search_projects(self.session)
  200. self.assertEqual(len(projects), 0)
  201. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  202. tests.add_content_git_repo(
  203. os.path.join(self.path, "repos", "test.git")
  204. )
  205. user = tests.FakeUser(username="pingou")
  206. with tests.user_set(self.app.application, user):
  207. data = {
  208. "csrf_token": self.get_csrf(),
  209. "name": "test",
  210. "description": "Project #1",
  211. }
  212. output = self.app.post("/new/", data=data, follow_redirects=True)
  213. self.assertEqual(output.status_code, 200)
  214. output_text = output.get_data(as_text=True)
  215. self.assertIn("The main repo test.git already exists", output_text)
  216. data["ignore_existing_repos"] = "y"
  217. output = self.app.post("/new/", data=data, follow_redirects=True)
  218. self.assertEqual(output.status_code, 200)
  219. output_text = output.get_data(as_text=True)
  220. self.assertIn("Alice Author", output_text)
  221. @patch.dict(
  222. "pagure.config.config",
  223. {"PAGURE_ADMIN_USERS": [], "USERS_IGNORE_EXISTING_REPOS": []},
  224. )
  225. def test_adopt_repos_not_allowed(self):
  226. """ Test the new_project endpoint with existing git repo for no access. """
  227. # Before
  228. projects = pagure.lib.query.search_projects(self.session)
  229. self.assertEqual(len(projects), 0)
  230. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  231. tests.add_content_git_repo(
  232. os.path.join(self.path, "repos", "test.git")
  233. )
  234. user = tests.FakeUser(username="pingou")
  235. with tests.user_set(self.app.application, user):
  236. data = {
  237. "csrf_token": self.get_csrf(),
  238. "name": "test",
  239. "description": "Project #1",
  240. }
  241. output = self.app.post("/new/", data=data, follow_redirects=True)
  242. self.assertEqual(output.status_code, 200)
  243. output_text = output.get_data(as_text=True)
  244. self.assertIn("The main repo test.git already exists", output_text)
  245. data["ignore_existing_repos"] = "y"
  246. output = self.app.post("/new/", data=data, follow_redirects=True)
  247. self.assertEqual(output.status_code, 200)
  248. output_text = output.get_data(as_text=True)
  249. self.assertIn("The main repo test.git already exists", output_text)
  250. @patch.dict("pagure.config.config", {"PROJECT_NAME_REGEX": "^1[a-z]*$"})
  251. def test_new_project_diff_regex(self):
  252. """ Test the new_project endpoint with a different regex. """
  253. # Before
  254. projects = pagure.lib.query.search_projects(self.session)
  255. self.assertEqual(len(projects), 0)
  256. user = tests.FakeUser(username="foo")
  257. with tests.user_set(self.app.application, user):
  258. output = self.app.get("/new/")
  259. self.assertEqual(output.status_code, 200)
  260. output_text = output.get_data(as_text=True)
  261. self.assertIn("<strong>Create new Project</strong>", output_text)
  262. csrf_token = self.get_csrf(output=output)
  263. data = {
  264. "description": "Project #1",
  265. "name": "project-1",
  266. "csrf_token": csrf_token,
  267. }
  268. output = self.app.post("/new/", data=data, follow_redirects=True)
  269. self.assertEqual(output.status_code, 200)
  270. output_text = output.get_data(as_text=True)
  271. self.assertIn("<title>New project - Pagure</title>", output_text)
  272. self.assertIn("<strong>Create new Project</strong>", output_text)
  273. self.assertIn(
  274. "<small>\n Invalid input.&nbsp;\n"
  275. " </small>",
  276. output_text,
  277. )
  278. @patch.dict("pagure.config.config", {"PRIVATE_PROJECTS": True})
  279. def test_new_project_private(self):
  280. """ Test the new_project endpoint for a private project. """
  281. # Before
  282. projects = pagure.lib.query.search_projects(self.session)
  283. self.assertEqual(len(projects), 0)
  284. self.assertFalse(
  285. os.path.exists(
  286. os.path.join(self.path, "repos", "foo", "project#1.git")
  287. )
  288. )
  289. self.assertFalse(
  290. os.path.exists(
  291. os.path.join(
  292. self.path, "repos", "tickets", "foo", "project#1.git"
  293. )
  294. )
  295. )
  296. self.assertFalse(
  297. os.path.exists(
  298. os.path.join(
  299. self.path, "repos", "docs", "foo", "project#1.git"
  300. )
  301. )
  302. )
  303. self.assertFalse(
  304. os.path.exists(
  305. os.path.join(
  306. self.path, "repos", "requests", "foo", "project#1.git"
  307. )
  308. )
  309. )
  310. user = tests.FakeUser()
  311. with tests.user_set(self.app.application, user):
  312. output = self.app.get("/new/")
  313. self.assertEqual(output.status_code, 200)
  314. self.assertIn(
  315. "<strong>Create new Project</strong>",
  316. output.get_data(as_text=True),
  317. )
  318. csrf_token = self.get_csrf(output=output)
  319. data = {"description": "Project #1", "private": True}
  320. output = self.app.post("/new/", data=data)
  321. self.assertEqual(output.status_code, 200)
  322. output_text = output.get_data(as_text=True)
  323. self.assertIn("<strong>Create new Project</strong>", output_text)
  324. self.assertIn(
  325. "<small>\n This field is required.&nbsp;\n"
  326. " </small>",
  327. output_text,
  328. )
  329. data["name"] = "project-1"
  330. output = self.app.post("/new/", data=data)
  331. self.assertEqual(output.status_code, 200)
  332. output_text = output.get_data(as_text=True)
  333. self.assertIn("<strong>Create new Project</strong>", output_text)
  334. self.assertNotIn(
  335. "<small>\n This field is required.&nbsp;\n"
  336. " </small>",
  337. output_text,
  338. )
  339. data["csrf_token"] = csrf_token
  340. output = self.app.post("/new/", data=data)
  341. self.assertEqual(output.status_code, 200)
  342. output_text = output.get_data(as_text=True)
  343. self.assertIn("<strong>Create new Project</strong>", output_text)
  344. self.assertIn("No user " "&#34;username&#34; found", output_text)
  345. user.username = "foo"
  346. with tests.user_set(self.app.application, user):
  347. data["csrf_token"] = csrf_token
  348. output = self.app.post("/new/", data=data, follow_redirects=True)
  349. self.assertEqual(output.status_code, 200)
  350. output_text = output.get_data(as_text=True)
  351. self.assertIn(
  352. '<div class="projectinfo my-3">\nProject #1', output_text
  353. )
  354. self.assertIn("<p>This repo is brand new!</p>", output_text)
  355. self.assertIn(
  356. "<title>Overview - foo/project-1 - Pagure</title>", output_text
  357. )
  358. # After
  359. projects = pagure.lib.query.search_projects(self.session)
  360. self.assertEqual(len(projects), 0)
  361. projects = pagure.lib.query.search_projects(self.session, private=True)
  362. self.assertEqual(len(projects), 1)
  363. self.assertTrue(
  364. os.path.exists(
  365. os.path.join(self.path, "repos", "foo", "project-1.git")
  366. )
  367. )
  368. self.assertTrue(
  369. os.path.exists(
  370. os.path.join(
  371. self.path, "repos", "tickets", "foo", "project-1.git"
  372. )
  373. )
  374. )
  375. self.assertTrue(
  376. os.path.exists(
  377. os.path.join(
  378. self.path, "repos", "docs", "foo", "project-1.git"
  379. )
  380. )
  381. )
  382. self.assertTrue(
  383. os.path.exists(
  384. os.path.join(
  385. self.path, "repos", "requests", "foo", "project-1.git"
  386. )
  387. )
  388. )
  389. def test_non_ascii_new_project(self):
  390. """ Test the new_project endpoint with a non-ascii project. """
  391. # Before
  392. projects = pagure.lib.query.search_projects(self.session)
  393. self.assertEqual(len(projects), 0)
  394. self.assertFalse(
  395. os.path.exists(os.path.join(self.path, "repos", "project-1.git"))
  396. )
  397. self.assertFalse(
  398. os.path.exists(
  399. os.path.join(self.path, "repos", "tickets", "project-1.git")
  400. )
  401. )
  402. self.assertFalse(
  403. os.path.exists(
  404. os.path.join(self.path, "repos", "docs", "project-1.git")
  405. )
  406. )
  407. self.assertFalse(
  408. os.path.exists(
  409. os.path.join(self.path, "repos", "requests", "project-1.git")
  410. )
  411. )
  412. user = tests.FakeUser()
  413. user.username = "foo"
  414. with tests.user_set(self.app.application, user):
  415. output = self.app.get("/new/")
  416. self.assertEqual(output.status_code, 200)
  417. output_text = output.get_data(as_text=True)
  418. self.assertIn("<strong>Create new Project</strong>", output_text)
  419. csrf_token = output_text.split(
  420. 'name="csrf_token" type="hidden" value="'
  421. )[1].split('">')[0]
  422. data = {
  423. "description": "Prõjéctö #1",
  424. "name": "project-1",
  425. "csrf_token": csrf_token,
  426. "create_readme": True,
  427. }
  428. output = self.app.post("/new/", data=data, follow_redirects=True)
  429. self.assertEqual(output.status_code, 200)
  430. output_text = output.get_data(as_text=True)
  431. self.assertIn(
  432. '<div class="projectinfo my-3">\nPrõjéctö #1', output_text
  433. )
  434. self.assertIn(
  435. """<section class="readme">
  436. <div class="markdown"><h1>project-1</h1>
  437. <p>Prõjéctö #1</p></div>
  438. </section>""",
  439. output_text,
  440. )
  441. data = {
  442. "description": "Мой первый суперский репозиторий",
  443. "name": "project-2",
  444. "csrf_token": csrf_token,
  445. "create_readme": True,
  446. }
  447. output = self.app.post("/new/", data=data, follow_redirects=True)
  448. self.assertEqual(output.status_code, 200)
  449. output_text = output.get_data(as_text=True)
  450. self.assertIn(
  451. '<div class="projectinfo my-3">\nМой первый суперский репозиторий',
  452. output_text,
  453. )
  454. self.assertIn(
  455. """<section class="readme">
  456. <div class="markdown"><h1>project-2</h1>
  457. <p>Мой первый суперский репозиторий</p></div>
  458. </section>""",
  459. output_text,
  460. )
  461. # After
  462. projects = pagure.lib.query.search_projects(self.session)
  463. self.assertEqual(len(projects), 2)
  464. for project in ["project-1", "project-2"]:
  465. self.assertTrue(
  466. os.path.exists(
  467. os.path.join(self.path, "repos", "%s.git" % project)
  468. )
  469. )
  470. self.assertTrue(
  471. os.path.exists(
  472. os.path.join(
  473. self.path, "repos", "tickets", "%s.git" % project
  474. )
  475. )
  476. )
  477. self.assertTrue(
  478. os.path.exists(
  479. os.path.join(
  480. self.path, "repos", "docs", "%s.git" % project
  481. )
  482. )
  483. )
  484. self.assertTrue(
  485. os.path.exists(
  486. os.path.join(
  487. self.path, "repos", "requests", "%s.git" % project
  488. )
  489. )
  490. )
  491. @patch("pygit2.init_repository", wraps=pygit2.init_repository)
  492. def test_new_project_with_template(self, pygit2init):
  493. """Test the new_project endpoint for a new project with a template set."""
  494. # Before
  495. projects = pagure.lib.query.search_projects(self.session)
  496. self.assertEqual(len(projects), 0)
  497. self.assertFalse(
  498. os.path.exists(os.path.join(self.path, "repos", "project-1.git"))
  499. )
  500. self.assertFalse(
  501. os.path.exists(
  502. os.path.join(self.path, "repos", "tickets", "project-1.git")
  503. )
  504. )
  505. self.assertFalse(
  506. os.path.exists(
  507. os.path.join(self.path, "repos", "docs", "project-1.git")
  508. )
  509. )
  510. self.assertFalse(
  511. os.path.exists(
  512. os.path.join(self.path, "repos", "requests", "project-1.git")
  513. )
  514. )
  515. user = tests.FakeUser()
  516. user.username = "foo"
  517. with tests.user_set(self.app.application, user):
  518. output = self.app.get("/new/")
  519. self.assertEqual(output.status_code, 200)
  520. self.assertIn(
  521. "<strong>Create new Project</strong>",
  522. output.get_data(as_text=True),
  523. )
  524. csrf_token = self.get_csrf(output=output)
  525. data = {
  526. "description": "test",
  527. "name": "project-1",
  528. "csrf_token": csrf_token,
  529. "create_readme": True,
  530. }
  531. output = self.app.post("/new/", data=data, follow_redirects=True)
  532. self.assertEqual(output.status_code, 200)
  533. self.assertIn(
  534. '<div class="projectinfo my-3">\ntest',
  535. output.get_data(as_text=True),
  536. )
  537. self.assertEqual(pygit2init.call_count, 4)
  538. pygit2init.assert_any_call(
  539. "%s/repos/project-1.git" % self.path,
  540. bare=True,
  541. template_path=None,
  542. )
  543. path = os.path.join(self.path, "repos", "project-1.git")
  544. with patch.dict(
  545. "pagure.config.config", {"PROJECT_TEMPLATE_PATH": path}
  546. ):
  547. data = {
  548. "description": "test2",
  549. "name": "project-2",
  550. "csrf_token": csrf_token,
  551. "create_readme": True,
  552. }
  553. output = self.app.post(
  554. "/new/", data=data, follow_redirects=True
  555. )
  556. self.assertEqual(output.status_code, 200)
  557. self.assertIn(
  558. '<div class="projectinfo my-3">\ntest2',
  559. output.get_data(as_text=True),
  560. )
  561. self.assertEqual(pygit2init.call_count, 8)
  562. pygit2init.assert_any_call(
  563. "%s/repos/project-2.git" % self.path,
  564. bare=True,
  565. template_path="%s/repos/project-1.git" % self.path,
  566. )
  567. # After
  568. projects = pagure.lib.query.search_projects(self.session)
  569. self.assertEqual(len(projects), 2)
  570. for project in ["project-1", "project-2"]:
  571. self.assertTrue(
  572. os.path.exists(
  573. os.path.join(self.path, "repos", "%s.git" % project)
  574. )
  575. )
  576. self.assertTrue(
  577. os.path.exists(
  578. os.path.join(
  579. self.path, "repos", "tickets", "%s.git" % project
  580. )
  581. )
  582. )
  583. self.assertTrue(
  584. os.path.exists(
  585. os.path.join(
  586. self.path, "repos", "docs", "%s.git" % project
  587. )
  588. )
  589. )
  590. self.assertTrue(
  591. os.path.exists(
  592. os.path.join(
  593. self.path, "repos", "requests", "%s.git" % project
  594. )
  595. )
  596. )
  597. @patch("pagure.ui.app.admin_session_timedout")
  598. def test_user_settings(self, ast):
  599. """ Test the user_settings endpoint. """
  600. ast.return_value = False
  601. user = tests.FakeUser()
  602. with tests.user_set(self.app.application, user):
  603. output = self.app.get("/settings/")
  604. self.assertEqual(output.status_code, 404)
  605. self.assertIn(
  606. "<h2>Page not found (404)</h2>", output.get_data(as_text=True)
  607. )
  608. user.username = "foo"
  609. with tests.user_set(self.app.application, user):
  610. output = self.app.get("/settings/")
  611. self.assertEqual(output.status_code, 200)
  612. output_text = output.get_data(as_text=True)
  613. self.assertIn(
  614. "<title>foo's settings - Pagure</title>", output_text
  615. )
  616. ast.return_value = True
  617. output = self.app.get("/settings/")
  618. self.assertEqual(output.status_code, 302)
  619. @patch("pagure.decorators.admin_session_timedout")
  620. def test_add_user_sshkey(self, ast):
  621. """ Test the add_user_sshkey endpoint. """
  622. ast.return_value = False
  623. # User not logged in
  624. output = self.app.get("/settings/")
  625. self.assertEqual(output.status_code, 302)
  626. ast.return_value = False
  627. user = tests.FakeUser(username="pingou")
  628. with tests.user_set(self.app.application, user):
  629. output = self.app.get("/settings", follow_redirects=True)
  630. self.assertEqual(output.status_code, 200)
  631. output_text = output.get_data(as_text=True)
  632. self.assertIn("<strong>Add SSH key", output_text)
  633. csrf_token = self.get_csrf(output=output)
  634. data = {"ssh_key": "asdf"}
  635. # No CSRF token
  636. output = self.app.post(
  637. "/settings/usersettings/addkey",
  638. data=data,
  639. follow_redirects=True,
  640. )
  641. self.assertEqual(output.status_code, 200)
  642. output_text = output.get_data(as_text=True)
  643. self.assertIn("<strong>Add SSH key", output_text)
  644. data["csrf_token"] = csrf_token
  645. # First, invalid SSH key
  646. output = self.app.post(
  647. "/settings/usersettings/addkey",
  648. data=data,
  649. follow_redirects=True,
  650. )
  651. self.assertEqual(output.status_code, 200)
  652. output_text = output.get_data(as_text=True)
  653. self.assertIn("<strong>Add SSH key", output_text)
  654. self.assertIn("SSH key invalid", output_text)
  655. # Next up, multiple SSH keys
  656. data[
  657. "ssh_key"
  658. ] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q==\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q=="
  659. output = self.app.post(
  660. "/settings/usersettings/addkey",
  661. data=data,
  662. follow_redirects=True,
  663. )
  664. self.assertEqual(output.status_code, 200)
  665. output_text = output.get_data(as_text=True)
  666. self.assertIn("Please add single SSH keys.", output_text)
  667. # Now, a valid SSH key
  668. data[
  669. "ssh_key"
  670. ] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q=="
  671. output = self.app.post(
  672. "/settings/usersettings/addkey",
  673. data=data,
  674. follow_redirects=True,
  675. )
  676. self.assertEqual(output.status_code, 200)
  677. output_text = output.get_data(as_text=True)
  678. self.assertIn(
  679. "<title>pingou's settings - Pagure</title>", output_text
  680. )
  681. self.assertIn("SSH key added", output_text)
  682. self.assertNotIn("Push Access", output_text)
  683. # And now, adding the same key
  684. output = self.app.post(
  685. "/settings/usersettings/addkey",
  686. data=data,
  687. follow_redirects=True,
  688. )
  689. self.assertEqual(output.status_code, 200)
  690. output_text = output.get_data(as_text=True)
  691. self.assertIn("SSH key already exists", output_text)
  692. # And next, a key with push access
  693. data[
  694. "ssh_key"
  695. ] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9Xwc2RDzPBhlEDARfHldGjudIVoa04tqT1JVKGQmyllTFz7Rb8CngQL3e7zyNzotnhwYKHdoiLlPkVEiDee4dWMUe48ilqId+FJZQGhyv8fu4BoFdE1AJUVylzmltbLg14VqG5gjTpXgtlrEva9arKwBMHJjRYc8ScaSn3OgyQw=="
  696. output = self.app.post(
  697. "/settings/usersettings/addkey",
  698. data=data,
  699. follow_redirects=True,
  700. )
  701. self.assertEqual(output.status_code, 200)
  702. output_text = output.get_data(as_text=True)
  703. self.assertIn(
  704. "<title>pingou's settings - Pagure</title>", output_text
  705. )
  706. self.assertIn("SSH key added", output_text)
  707. @patch("pagure.decorators.admin_session_timedout")
  708. def test_remove_user_sshkey(self, ast):
  709. """ Test the remove_sshkey endpoint. """
  710. ast.return_value = False
  711. user = tests.FakeUser()
  712. # User not logged in
  713. output = self.app.post("/settings/usersettings/removekey/1")
  714. self.assertEqual(output.status_code, 302)
  715. user.username = "pingou"
  716. with tests.user_set(self.app.application, user):
  717. data = {"csrf_token": self.get_csrf()}
  718. output = self.app.post(
  719. "/settings/usersettings/removekey/1",
  720. data=data,
  721. follow_redirects=True,
  722. )
  723. self.assertEqual(output.status_code, 200)
  724. output_text = output.get_data(as_text=True)
  725. self.assertIn(
  726. "<title>pingou's settings - Pagure</title>", output_text
  727. )
  728. self.assertIn("SSH key does not exist", output_text)
  729. # Add a deploy key to a project
  730. pingou = pagure.lib.query.get_user(self.session, "pingou")
  731. msg = pagure.lib.query.add_sshkey_to_project_or_user(
  732. session=self.session,
  733. ssh_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q==",
  734. user=pingou,
  735. pushaccess=True,
  736. creator=pingou,
  737. )
  738. self.session.commit()
  739. self.assertEqual(msg, "SSH key added")
  740. with tests.user_set(self.app.application, user):
  741. output = self.app.post(
  742. "/settings/usersettings/removekey/1", follow_redirects=True
  743. )
  744. self.assertEqual(output.status_code, 200)
  745. output_text = output.get_data(as_text=True)
  746. self.assertIn(
  747. "<title>pingou's settings - Pagure</title>", output_text
  748. )
  749. self.assertNotIn("SSH key removed", output_text)
  750. data = {"csrf_token": self.get_csrf()}
  751. output = self.app.post(
  752. "/settings/usersettings/removekey/1",
  753. data=data,
  754. follow_redirects=True,
  755. )
  756. self.assertEqual(output.status_code, 200)
  757. output_text = output.get_data(as_text=True)
  758. self.assertIn(
  759. "<title>pingou's settings - Pagure</title>", output_text
  760. )
  761. self.assertIn("SSH key removed", output_text)
  762. def patched_commit_exists(user, namespace, repo, githash):
  763. """Patched version of pagure.pfmarkdown._commit_exists to enforce
  764. returning true on some given hash without having us actually check
  765. the git repos.
  766. """
  767. if githash in [
  768. "9364354",
  769. "9364354a",
  770. "9364354a4555ba17aa60f0dc844d70b74eb1aecd",
  771. ]:
  772. return True
  773. else:
  774. return False
  775. @patch(
  776. "pagure.pfmarkdown._commit_exists",
  777. MagicMock(side_effect=patched_commit_exists),
  778. )
  779. def test_patched_markdown_preview(self):
  780. """ Test the markdown_preview endpoint. """
  781. data = {"content": "test\n----\n\n * 1\n * item 2"}
  782. # CSRF missing
  783. output = self.app.post("/markdown/", data=data)
  784. self.assertEqual(output.status_code, 400)
  785. user = tests.FakeUser()
  786. user.username = "foo"
  787. with tests.user_set(self.app.application, user):
  788. output = self.app.get("/settings/")
  789. self.assertEqual(output.status_code, 200)
  790. output_text = output.get_data(as_text=True)
  791. self.assertIn(
  792. "<title>foo's settings - Pagure</title>", output_text
  793. )
  794. csrf_token = self.get_csrf(output=output)
  795. # With CSRF
  796. data["csrf_token"] = csrf_token
  797. output = self.app.post("/markdown/", data=data)
  798. self.assertEqual(output.status_code, 200)
  799. exp = """<div class="markdown"><h2>test</h2>
  800. <ul>
  801. <li>1</li>
  802. <li>item 2</li>
  803. </ul></div>"""
  804. self.assertEqual(output.get_data(as_text=True), exp)
  805. tests.create_projects(self.session)
  806. texts = [
  807. "pingou committed on test#9364354a4555ba17aa60f0dc844d70b74eb1aecd",
  808. "Cf commit 936435", # 6 chars - not long enough
  809. "Cf commit 9364354", # 7 chars - long enough
  810. "Cf commit 9364354a", # 8 chars - still long enough
  811. "Cf commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd", # 40 chars
  812. ]
  813. expected = [
  814. # 'pingou committed on test#9364354a4555ba17aa60f0dc844d70b74eb1aecd',
  815. '<div class="markdown"><p>pingou committed on <a href="/test/c/9364354a4555ba17aa60f0dc844d70b74eb1aecd" '
  816. 'title="Commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd"'
  817. ">test#9364354a4555ba17aa60f0dc844d70b74eb1aecd</a></p></div>",
  818. # 'Cf commit 936435',
  819. '<div class="markdown"><p>Cf commit 936435</p></div>',
  820. # 'Cf commit 9364354',
  821. #'<p>Cf commit 9364354</p>',
  822. '<div class="markdown"><p>Cf commit <a href="/test/c/9364354" '
  823. 'title="Commit 9364354">9364354</a></p></div>',
  824. # 'Cf commit 9364354a',
  825. '<div class="markdown"><p>Cf commit <a href="/test/c/9364354a" '
  826. 'title="Commit 9364354a">9364354</a></p></div>',
  827. # 'Cf commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd',
  828. '<div class="markdown"><p>Cf commit <a href="/test/c/9364354a4555ba17aa60f0dc844d70b74eb1aecd" '
  829. 'title="Commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd"'
  830. ">9364354</a></p></div>",
  831. ]
  832. with self.app.application.app_context():
  833. for idx, text in enumerate(texts):
  834. data = {"content": text, "csrf_token": csrf_token}
  835. output = self.app.post("/markdown/?repo=test", data=data)
  836. self.assertEqual(output.status_code, 200)
  837. self.assertEqual(expected[idx], output.get_data(as_text=True))
  838. def test_markdown_preview(self):
  839. """Test the markdown_preview endpoint with a non-existing commit."""
  840. user = tests.FakeUser()
  841. user.username = "foo"
  842. with tests.user_set(self.app.application, user):
  843. output = self.app.get("/settings/")
  844. self.assertEqual(output.status_code, 200)
  845. output_text = output.get_data(as_text=True)
  846. self.assertIn(
  847. "<title>foo's settings - Pagure</title>", output_text
  848. )
  849. csrf_token = self.get_csrf(output=output)
  850. tests.create_projects(self.session)
  851. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  852. text = "Cf commit 9364354a4555ba17aa60f0d"
  853. exp = '<div class="markdown"><p>Cf commit 9364354a4555ba17aa60f0d</p></div>'
  854. with self.app.application.app_context():
  855. data = {"content": text, "csrf_token": csrf_token}
  856. output = self.app.post("/markdown/?repo=test", data=data)
  857. self.assertEqual(output.status_code, 200)
  858. self.assertEqual(exp, output.get_data(as_text=True))
  859. def test_markdown_preview_valid_commit(self):
  860. """ Test the markdown_preview endpoint with an existing commit. """
  861. user = tests.FakeUser()
  862. user.username = "foo"
  863. with tests.user_set(self.app.application, user):
  864. output = self.app.get("/settings/")
  865. self.assertEqual(output.status_code, 200)
  866. output_text = output.get_data(as_text=True)
  867. self.assertIn(
  868. "<title>foo's settings - Pagure</title>", output_text
  869. )
  870. csrf_token = self.get_csrf(output=output)
  871. tests.create_projects(self.session)
  872. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  873. repopath = os.path.join(self.path, "repos", "test.git")
  874. tests.add_content_git_repo(repopath)
  875. repo = pygit2.Repository(repopath)
  876. first_commit = repo.revparse_single("HEAD")
  877. text = "Cf commit %s" % first_commit.oid.hex
  878. exp = (
  879. '<div class="markdown"><p>Cf commit <a href="/test/c/{0}" title="Commit {0}">{1}'
  880. "</a></p></div>".format(
  881. first_commit.oid.hex, first_commit.oid.hex[:7]
  882. )
  883. )
  884. with self.app.application.app_context():
  885. data = {"content": text, "csrf_token": csrf_token}
  886. output = self.app.post("/markdown/?repo=test", data=data)
  887. self.assertEqual(output.status_code, 200)
  888. self.assertEqual(exp, output.get_data(as_text=True))
  889. @patch("pagure.ui.app.admin_session_timedout")
  890. def test_remove_user_email(self, ast):
  891. """ Test the remove_user_email endpoint. """
  892. ast.return_value = False
  893. user = tests.FakeUser()
  894. with tests.user_set(self.app.application, user):
  895. output = self.app.post("/settings/email/drop")
  896. self.assertEqual(output.status_code, 404)
  897. self.assertIn(
  898. "<h2>Page not found (404)</h2>", output.get_data(as_text=True)
  899. )
  900. user.username = "foo"
  901. with tests.user_set(self.app.application, user):
  902. output = self.app.get("/settings/")
  903. self.assertEqual(output.status_code, 200)
  904. output_text = output.get_data(as_text=True)
  905. self.assertIn(
  906. "<title>foo's settings - Pagure</title>", output_text
  907. )
  908. csrf_token = self.get_csrf(output=output)
  909. data = {"email": "foo@pingou.com"}
  910. output = self.app.post(
  911. "/settings/email/drop", data=data, follow_redirects=True
  912. )
  913. self.assertEqual(output.status_code, 200)
  914. output_text = output.get_data(as_text=True)
  915. self.assertIn(
  916. "<title>foo's settings - Pagure</title>", output_text
  917. )
  918. self.assertIn(
  919. "You must always have at " "least one email", output_text
  920. )
  921. user.username = "pingou"
  922. with tests.user_set(self.app.application, user):
  923. output = self.app.get("/settings/")
  924. self.assertEqual(output.status_code, 200)
  925. output_text = output.get_data(as_text=True)
  926. self.assertIn(
  927. "<title>pingou's settings - Pagure</title>", output_text
  928. )
  929. csrf_token = self.get_csrf(output=output)
  930. data = {"email": "foo@pingou.com"}
  931. output = self.app.post(
  932. "/settings/email/drop", data=data, follow_redirects=True
  933. )
  934. self.assertEqual(output.status_code, 200)
  935. output_text = output.get_data(as_text=True)
  936. self.assertIn(
  937. "<title>pingou's settings - Pagure</title>", output_text
  938. )
  939. self.assertEqual(output_text.count("foo@pingou.com"), 4)
  940. data = {"csrf_token": csrf_token, "email": "foobar@pingou.com"}
  941. output = self.app.post(
  942. "/settings/email/drop", data=data, follow_redirects=True
  943. )
  944. self.assertEqual(output.status_code, 200)
  945. output_text = output.get_data(as_text=True)
  946. self.assertIn(
  947. "<title>pingou's settings - Pagure</title>", output_text
  948. )
  949. self.assertIn(
  950. "You do not have the "
  951. "email: foobar@pingou.com, nothing to remove",
  952. output_text,
  953. )
  954. data = {"csrf_token": csrf_token, "email": "foo@pingou.com"}
  955. output = self.app.post(
  956. "/settings/email/drop", data=data, follow_redirects=True
  957. )
  958. self.assertEqual(output.status_code, 200)
  959. output_text = output.get_data(as_text=True)
  960. self.assertEqual(output_text.count("foo@pingou.com"), 0)
  961. self.assertEqual(output_text.count("bar@pingou.com"), 3)
  962. output = self.app.post(
  963. "/settings/email/drop", data=data, follow_redirects=True
  964. )
  965. self.assertEqual(output.status_code, 200)
  966. output_text = output.get_data(as_text=True)
  967. self.assertEqual(output_text.count("foo@pingou.com"), 0)
  968. self.assertEqual(output_text.count("bar@pingou.com"), 3)
  969. ast.return_value = True
  970. output = self.app.post("/settings/email/drop", data=data)
  971. self.assertEqual(output.status_code, 302)
  972. @patch("pagure.lib.notify.send_email")
  973. @patch("pagure.ui.app.admin_session_timedout")
  974. def test_add_api_user_email(self, ast, send_email):
  975. """ Test the add_api_user_email endpoint. """
  976. send_email.return_value = True
  977. ast.return_value = False
  978. user = tests.FakeUser()
  979. with tests.user_set(self.app.application, user):
  980. output = self.app.post("/settings/email/add")
  981. self.assertEqual(output.status_code, 404)
  982. self.assertIn(
  983. "<h2>Page not found (404)</h2>", output.get_data(as_text=True)
  984. )
  985. user.username = "foo"
  986. with tests.user_set(self.app.application, user):
  987. output = self.app.post("/settings/email/add")
  988. self.assertEqual(output.status_code, 200)
  989. output_text = output.get_data(as_text=True)
  990. self.assertIn("<strong>Add new email</strong>", output_text)
  991. if self.get_wtforms_version() >= (2, 2):
  992. self.assertIn(
  993. '<input class="form-control form-control-error" id="email" '
  994. 'name="email" required type="text" value="">',
  995. output_text,
  996. )
  997. else:
  998. self.assertIn(
  999. '<input class="form-control form-control-error" id="email" '
  1000. 'name="email" type="text" value="">',
  1001. output_text,
  1002. )
  1003. user.username = "pingou"
  1004. with tests.user_set(self.app.application, user):
  1005. output = self.app.post("/settings/email/add")
  1006. self.assertEqual(output.status_code, 200)
  1007. output_text = output.get_data(as_text=True)
  1008. self.assertIn("<strong>Add new email</strong>", output_text)
  1009. if self.get_wtforms_version() >= (2, 2):
  1010. self.assertIn(
  1011. '<input class="form-control form-control-error" id="email" '
  1012. 'name="email" required type="text" value="">',
  1013. output_text,
  1014. )
  1015. else:
  1016. self.assertIn(
  1017. '<input class="form-control form-control-error" id="email" '
  1018. 'name="email" type="text" value="">',
  1019. output_text,
  1020. )
  1021. csrf_token = output_text.split(
  1022. 'name="csrf_token" type="hidden" value="'
  1023. )[1].split('">')[0]
  1024. data = {"email": "foo2@pingou.com"}
  1025. output = self.app.post(
  1026. "/settings/email/add", data=data, follow_redirects=True
  1027. )
  1028. self.assertEqual(output.status_code, 200)
  1029. output_text = output.get_data(as_text=True)
  1030. self.assertIn("<strong>Add new email</strong>", output_text)
  1031. self.assertEqual(output_text.count("foo2@pingou.com"), 1)
  1032. # New email
  1033. data = {"csrf_token": csrf_token, "email": "foðbar@pingou.com"}
  1034. output = self.app.post(
  1035. "/settings/email/add", data=data, follow_redirects=True
  1036. )
  1037. self.assertEqual(output.status_code, 200)
  1038. output_text = output.get_data(as_text=True)
  1039. self.assertIn(
  1040. "<title>pingou's settings - Pagure</title>", output_text
  1041. )
  1042. self.assertIn("Email pending validation", output_text)
  1043. self.assertEqual(output_text.count("foo@pingou.com"), 4)
  1044. self.assertEqual(output_text.count("bar@pingou.com"), 5)
  1045. self.assertEqual(output_text.count("foðbar@pingou.com"), 2)
  1046. # Email already pending
  1047. output = self.app.post(
  1048. "/settings/email/add", data=data, follow_redirects=True
  1049. )
  1050. self.assertEqual(output.status_code, 200)
  1051. output_text = output.get_data(as_text=True)
  1052. self.assertIn(
  1053. '<div class="card-header">\n '
  1054. "<strong>Add new email</strong>",
  1055. output_text,
  1056. )
  1057. self.assertIn(
  1058. "This email is already " "pending confirmation", output_text
  1059. )
  1060. # User already has this email
  1061. data = {"csrf_token": csrf_token, "email": "foo@pingou.com"}
  1062. output = self.app.post(
  1063. "/settings/email/add", data=data, follow_redirects=True
  1064. )
  1065. self.assertEqual(output.status_code, 200)
  1066. output_text = output.get_data(as_text=True)
  1067. self.assertTrue("<strong>Add new email</strong>" in output_text)
  1068. self.assertTrue(
  1069. "Invalid value, can&#39;t be any of: bar@pingou.com, "
  1070. "foo@pingou.com.&nbsp;" in output_text
  1071. or "Invalid value, can&#39;t be any of: foo@pingou.com, "
  1072. "bar@pingou.com.&nbsp;" in output_text
  1073. )
  1074. self.assertEqual(output_text.count("foo@pingou.com"), 6)
  1075. self.assertEqual(output_text.count("bar@pingou.com"), 5)
  1076. self.assertEqual(output_text.count("foðbar@pingou.com"), 0)
  1077. # Email registered by someone else
  1078. data = {"csrf_token": csrf_token, "email": "foo@bar.com"}
  1079. output = self.app.post(
  1080. "/settings/email/add", data=data, follow_redirects=True
  1081. )
  1082. self.assertEqual(output.status_code, 200)
  1083. output_text = output.get_data(as_text=True)
  1084. self.assertTrue("<strong>Add new email</strong>" in output_text)
  1085. self.assertIn(
  1086. "Invalid value, can&#39;t be any of: foo@bar.com.&nbsp;",
  1087. output_text,
  1088. )
  1089. ast.return_value = True
  1090. output = self.app.post("/settings/email/add", data=data)
  1091. self.assertEqual(output.status_code, 302)
  1092. @patch("pagure.lib.notify.send_email")
  1093. @patch("pagure.ui.app.admin_session_timedout")
  1094. def test_set_default_email(self, ast, send_email):
  1095. """ Test the set_default_email endpoint. """
  1096. send_email.return_value = True
  1097. ast.return_value = False
  1098. user = tests.FakeUser()
  1099. with tests.user_set(self.app.application, user):
  1100. output = self.app.post("/settings/email/default")
  1101. self.assertEqual(output.status_code, 404)
  1102. self.assertTrue(
  1103. "<h2>Page not found (404)</h2>"
  1104. in output.get_data(as_text=True)
  1105. )
  1106. user.username = "pingou"
  1107. with tests.user_set(self.app.application, user):
  1108. output = self.app.get("/settings/")
  1109. self.assertEqual(output.status_code, 200)
  1110. output_text = output.get_data(as_text=True)
  1111. self.assertIn(
  1112. "<title>pingou's settings - Pagure</title>", output_text
  1113. )
  1114. csrf_token = self.get_csrf(output=output)
  1115. data = {"email": "foo@pingou.com"}
  1116. output = self.app.post(
  1117. "/settings/email/default", data=data, follow_redirects=True
  1118. )
  1119. self.assertEqual(output.status_code, 200)
  1120. output_text = output.get_data(as_text=True)
  1121. self.assertIn(
  1122. "<title>pingou's settings - Pagure</title>", output_text
  1123. )
  1124. self.assertEqual(output_text.count("foo@pingou.com"), 4)
  1125. # Set invalid default email
  1126. data = {"csrf_token": csrf_token, "email": "foobar@pingou.com"}
  1127. output = self.app.post(
  1128. "/settings/email/default", data=data, follow_redirects=True
  1129. )
  1130. self.assertEqual(output.status_code, 200)
  1131. output_text = output.get_data(as_text=True)
  1132. self.assertIn(
  1133. "<title>pingou's settings - Pagure</title>", output_text
  1134. )
  1135. self.assertEqual(output_text.count("foo@pingou.com"), 4)
  1136. self.assertIn(
  1137. "You do not have the "
  1138. "email: foobar@pingou.com, nothing to set",
  1139. output_text,
  1140. )
  1141. # Set default email
  1142. data = {"csrf_token": csrf_token, "email": "foo@pingou.com"}
  1143. output = self.app.post(
  1144. "/settings/email/default", data=data, follow_redirects=True
  1145. )
  1146. self.assertEqual(output.status_code, 200)
  1147. output_text = output.get_data(as_text=True)
  1148. self.assertIn(
  1149. "<title>pingou's settings - Pagure</title>", output_text
  1150. )
  1151. self.assertEqual(output_text.count("foo@pingou.com"), 4)
  1152. self.assertIn(
  1153. "Default email set to: " "foo@pingou.com", output_text
  1154. )
  1155. ast.return_value = True
  1156. output = self.app.post("/settings/email/default", data=data)
  1157. self.assertEqual(output.status_code, 302)
  1158. @patch("pagure.lib.notify.send_email")
  1159. @patch("pagure.ui.app.admin_session_timedout")
  1160. def test_reconfirm_email(self, ast, send_email):
  1161. """ Test the reconfirm_email endpoint. """
  1162. send_email.return_value = True
  1163. ast.return_value = False
  1164. # Add a pending email to pingou
  1165. userobj = pagure.lib.query.search_user(self.session, username="pingou")
  1166. self.assertEqual(len(userobj.emails), 2)
  1167. email_pend = pagure.lib.model.UserEmailPending(
  1168. user_id=userobj.id, email="foo@fp.o", token="abcdef"
  1169. )
  1170. self.session.add(email_pend)
  1171. self.session.commit()
  1172. user = tests.FakeUser()
  1173. with tests.user_set(self.app.application, user):
  1174. output = self.app.post("/settings/email/resend")
  1175. self.assertEqual(output.status_code, 404)
  1176. self.assertTrue(
  1177. "<h2>Page not found (404)</h2>"
  1178. in output.get_data(as_text=True)
  1179. )
  1180. user.username = "pingou"
  1181. with tests.user_set(self.app.application, user):
  1182. output = self.app.get("/settings/")
  1183. self.assertEqual(output.status_code, 200)
  1184. output_text = output.get_data(as_text=True)
  1185. self.assertIn(
  1186. "<title>pingou's settings - Pagure</title>", output_text
  1187. )
  1188. csrf_token = self.get_csrf(output=output)
  1189. data = {"email": "foo@pingou.com"}
  1190. output = self.app.post(
  1191. "/settings/email/resend", data=data, follow_redirects=True
  1192. )
  1193. self.assertEqual(output.status_code, 200)
  1194. output_text = output.get_data(as_text=True)
  1195. self.assertIn(
  1196. "<title>pingou's settings - Pagure</title>", output_text
  1197. )
  1198. self.assertEqual(output_text.count("foo@pingou.com"), 4)
  1199. # Set invalid default email
  1200. data = {"csrf_token": csrf_token, "email": "foobar@pingou.com"}
  1201. output = self.app.post(
  1202. "/settings/email/resend", data=data, follow_redirects=True
  1203. )
  1204. self.assertEqual(output.status_code, 200)
  1205. output_text = output.get_data(as_text=True)
  1206. self.assertIn(
  1207. "<title>pingou's settings - Pagure</title>", output_text
  1208. )
  1209. self.assertEqual(output_text.count("foo@pingou.com"), 4)
  1210. self.assertIn(
  1211. "This email address has " "already been confirmed", output_text
  1212. )
  1213. # Validate a non-validated email
  1214. data = {"csrf_token": csrf_token, "email": "foo@fp.o"}
  1215. output = self.app.post(
  1216. "/settings/email/resend", data=data, follow_redirects=True
  1217. )
  1218. self.assertEqual(output.status_code, 200)
  1219. output_text = output.get_data(as_text=True)
  1220. self.assertIn(
  1221. "<title>pingou's settings - Pagure</title>", output_text
  1222. )
  1223. self.assertEqual(output_text.count("foo@pingou.com"), 4)
  1224. self.assertIn("Confirmation email re-sent", output_text)
  1225. ast.return_value = True
  1226. output = self.app.post("/settings/email/resend", data=data)
  1227. self.assertEqual(output.status_code, 302)
  1228. @patch("pagure.ui.app.admin_session_timedout")
  1229. def test_confirm_email(self, ast):
  1230. """ Test the confirm_email endpoint. """
  1231. output = self.app.get("/settings/email/confirm/foobar")
  1232. self.assertEqual(output.status_code, 302)
  1233. ast.return_value = False
  1234. # Add a pending email to pingou
  1235. userobj = pagure.lib.query.search_user(self.session, username="pingou")
  1236. self.assertEqual(len(userobj.emails), 2)
  1237. email_pend = pagure.lib.model.UserEmailPending(
  1238. user_id=userobj.id, email="foo@fp.o", token="abcdef"
  1239. )
  1240. self.session.add(email_pend)
  1241. self.session.commit()
  1242. user = tests.FakeUser()
  1243. user.username = "pingou"
  1244. with tests.user_set(self.app.application, user):
  1245. # Wrong token
  1246. output = self.app.get(
  1247. "/settings/email/confirm/foobar", follow_redirects=True
  1248. )
  1249. self.assertEqual(output.status_code, 200)
  1250. output_text = output.get_data(as_text=True)
  1251. self.assertIn(
  1252. "<title>pingou's settings - Pagure</title>", output_text
  1253. )
  1254. self.assertIn("No email associated with this token.", output_text)
  1255. # Confirm email
  1256. output = self.app.get(
  1257. "/settings/email/confirm/abcdef", follow_redirects=True
  1258. )
  1259. self.assertEqual(output.status_code, 200)
  1260. output_text = output.get_data(as_text=True)
  1261. self.assertIn(
  1262. "<title>pingou's settings - Pagure</title>", output_text
  1263. )
  1264. self.assertIn("Email validated", output_text)
  1265. userobj = pagure.lib.query.search_user(self.session, username="pingou")
  1266. self.assertEqual(len(userobj.emails), 3)
  1267. ast.return_value = True
  1268. output = self.app.get("/settings/email/confirm/foobar")
  1269. self.assertEqual(output.status_code, 302)
  1270. def test_view_my_requests_no_user(self):
  1271. """Test the view_user_requests endpoint."""
  1272. output = self.app.get("/user/somenonexistentuser/requests")
  1273. self.assertEqual(output.status_code, 404)
  1274. @patch("pagure.lib.git.update_git", MagicMock(return_value=True))
  1275. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  1276. def test_view_my_requests(self):
  1277. """Test the view_user_requests endpoint. """
  1278. # Create the PR
  1279. tests.create_projects(self.session)
  1280. repo = pagure.lib.query._get_project(self.session, "test")
  1281. req = pagure.lib.query.new_pull_request(
  1282. session=self.session,
  1283. repo_from=repo,
  1284. branch_from="dev",
  1285. repo_to=repo,
  1286. branch_to="master",
  1287. title="test pull-request #1",
  1288. user="pingou",
  1289. )
  1290. self.session.commit()
  1291. self.assertEqual(req.id, 1)
  1292. self.assertEqual(req.title, "test pull-request #1")
  1293. output = self.app.get("/user/pingou/requests")
  1294. self.assertEqual(output.status_code, 200)
  1295. output_text = output.get_data(as_text=True)
  1296. self.assertIn("test pull-request #1", output_text)
  1297. self.assertEqual(output_text.count('pr-status pr-status-open"'), 1)
  1298. # Add a PR in a fork
  1299. item = pagure.lib.model.Project(
  1300. user_id=1, # pingou
  1301. name="test_fork",
  1302. description="test project #1",
  1303. is_fork=True,
  1304. parent_id=1,
  1305. hook_token="aaabbbttt",
  1306. )
  1307. self.session.add(item)
  1308. repo = pagure.lib.query._get_project(
  1309. self.session, "test_fork", user="pingou"
  1310. )
  1311. req = pagure.lib.query.new_pull_request(
  1312. session=self.session,
  1313. repo_from=repo,
  1314. branch_from="dev",
  1315. repo_to=repo,
  1316. branch_to="master",
  1317. title="tést pull-request #2",
  1318. user="pingou",
  1319. )
  1320. self.session.commit()
  1321. self.assertEqual(req.id, 1)
  1322. self.assertEqual(req.title, "tést pull-request #2")
  1323. output = self.app.get("/user/pingou/requests")
  1324. self.assertEqual(output.status_code, 200)
  1325. output_text = output.get_data(as_text=True)
  1326. self.assertIn("test pull-request #1", output_text)
  1327. self.assertIn("tést pull-request #2", output_text)
  1328. self.assertEqual(output_text.count('pr-status pr-status-open"'), 2)
  1329. @patch("pagure.lib.git.update_git", MagicMock(return_value=True))
  1330. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  1331. def test_view_my_requests_pr_in_another_project(self):
  1332. """Test the view_user_requests endpoint when the user opened a PR
  1333. in another project."""
  1334. # Pingou creates the PR on test
  1335. tests.create_projects(self.session)
  1336. repo = pagure.lib.query._get_project(self.session, "test")
  1337. req = pagure.lib.query.new_pull_request(
  1338. session=self.session,
  1339. repo_from=repo,
  1340. branch_from="dev",
  1341. repo_to=repo,
  1342. branch_to="master",
  1343. title="test pull-request #1",
  1344. user="pingou",
  1345. )
  1346. self.session.commit()
  1347. self.assertEqual(req.id, 1)
  1348. self.assertEqual(req.title, "test pull-request #1")
  1349. # foo creates the PR on test
  1350. repo = pagure.lib.query._get_project(self.session, "test")
  1351. req = pagure.lib.query.new_pull_request(
  1352. session=self.session,
  1353. repo_from=repo,
  1354. branch_from="dev",
  1355. repo_to=repo,
  1356. branch_to="master",
  1357. title="test pull-request #2",
  1358. user="foo",
  1359. )
  1360. self.session.commit()
  1361. self.assertEqual(req.id, 2)
  1362. self.assertEqual(req.title, "test pull-request #2")
  1363. # Check pingou's PR list
  1364. output = self.app.get("/user/pingou/requests?type=filed")
  1365. self.assertEqual(output.status_code, 200)
  1366. output_text = output.get_data(as_text=True)
  1367. self.assertIn("test pull-request #1", output_text)
  1368. self.assertNotIn("test pull-request #2", output_text)
  1369. self.assertEqual(output_text.count('pr-status pr-status-open"'), 1)
  1370. output = self.app.get("/user/pingou/requests?type=actionable")
  1371. self.assertEqual(output.status_code, 200)
  1372. output_text = output.get_data(as_text=True)
  1373. self.assertNotIn("test pull-request #1", output_text)
  1374. self.assertIn("test pull-request #2", output_text)
  1375. self.assertEqual(output_text.count('pr-status pr-status-open"'), 1)
  1376. # Check foo's PR list
  1377. output = self.app.get("/user/foo/requests")
  1378. self.assertEqual(output.status_code, 200)
  1379. output_text = output.get_data(as_text=True)
  1380. self.assertNotIn("test pull-request #1", output_text)
  1381. self.assertIn("test pull-request #2", output_text)
  1382. self.assertEqual(output_text.count('pr-status pr-status-open"'), 1)
  1383. @patch("pagure.lib.git.update_git", MagicMock(return_value=True))
  1384. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  1385. def test_view_my_requests_against_another_project(self):
  1386. """Test the view_user_requests endpoint when there is a PR opened
  1387. by me against a project I do not have rights on."""
  1388. # Create the PR
  1389. tests.create_projects(self.session)
  1390. repo = pagure.lib.query._get_project(self.session, "test")
  1391. req = pagure.lib.query.new_pull_request(
  1392. session=self.session,
  1393. repo_from=repo,
  1394. branch_from="dev",
  1395. repo_to=repo,
  1396. branch_to="master",
  1397. title="test pull-request #1",
  1398. user="foo",
  1399. )
  1400. self.session.commit()
  1401. self.assertEqual(req.id, 1)
  1402. self.assertEqual(req.title, "test pull-request #1")
  1403. output = self.app.get("/user/foo/requests")
  1404. self.assertEqual(output.status_code, 200)
  1405. output_text = output.get_data(as_text=True)
  1406. self.assertIn("test pull-request #1", output_text)
  1407. self.assertEqual(output_text.count('pr-status pr-status-open"'), 1)
  1408. def test_view_my_issues_no_user(self):
  1409. """Test the view_user_issues endpoint with a missing user."""
  1410. output = self.app.get("/user/somenonexistentuser/issues")
  1411. self.assertEqual(output.status_code, 404)
  1412. @patch("pagure.lib.git.update_git", MagicMock(return_value=True))
  1413. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  1414. def test_view_my_issues(self):
  1415. """Test the view_user_issues endpoint when the user exists."""
  1416. # Create the issue
  1417. tests.create_projects(self.session)
  1418. repo = pagure.lib.query._get_project(self.session, "test")
  1419. msg = pagure.lib.query.new_issue(
  1420. session=self.session,
  1421. repo=repo,
  1422. title="Test issue #1",
  1423. content="We should work on this for the second time",
  1424. user="pingou",
  1425. status="Open",
  1426. )
  1427. self.session.commit()
  1428. self.assertEqual(msg.title, "Test issue #1")
  1429. output = self.app.get("/user/pingou/issues")
  1430. self.assertEqual(output.status_code, 200)
  1431. output_text = output.get_data(as_text=True)
  1432. self.assertIn("Test issue #1", output_text)
  1433. self.assertEqual(
  1434. output_text.count("issue-status issue-status-open"), 1
  1435. )
  1436. # Add an issue in a fork
  1437. item = pagure.lib.model.Project(
  1438. user_id=2, # foo
  1439. name="test_fork",
  1440. description="test project #1",
  1441. is_fork=True,
  1442. parent_id=1,
  1443. hook_token="aaabbbttt",
  1444. )
  1445. self.session.add(item)
  1446. repo = pagure.lib.query._get_project(
  1447. self.session, "test_fork", user="foo"
  1448. )
  1449. msg = pagure.lib.query.new_issue(
  1450. session=self.session,
  1451. repo=repo,
  1452. title="Test issue #2",
  1453. content="We should work on this for the second time",
  1454. user="pingou",
  1455. status="Open",
  1456. )
  1457. self.session.commit()
  1458. self.assertEqual(msg.title, "Test issue #2")
  1459. # Test the assigned issue table. Create issue then set the assignee
  1460. msg = pagure.lib.query.new_issue(
  1461. session=self.session,
  1462. repo=repo,
  1463. title="Test issue #3",
  1464. content="This issue created by foo, but assigned to pingou",
  1465. user="foo",
  1466. status="Open",
  1467. )
  1468. self.session.commit()
  1469. self.assertEqual(msg.title, "Test issue #3")
  1470. msg = pagure.lib.query.add_issue_assignee(
  1471. session=self.session, issue=msg, assignee="pingou", user="foo"
  1472. )
  1473. self.session.commit()
  1474. self.assertEqual(msg, "Issue assigned to pingou")
  1475. output = self.app.get("/user/pingou/issues")
  1476. self.assertEqual(output.status_code, 200)
  1477. output_text = output.get_data(as_text=True)
  1478. self.assertIn("Test issue #1", output_text)
  1479. self.assertIn("Test issue #2", output_text)
  1480. self.assertIn("Test issue #3", output_text)
  1481. self.assertEqual(
  1482. output_text.count("issue-status issue-status-open"), 3
  1483. )
  1484. @patch("pagure.lib.git.update_git", MagicMock(return_value=True))
  1485. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  1486. def test_view_my_issues_disabled(self):
  1487. """Test the view_user_issues endpoint when the project disabled issue
  1488. tracking."""
  1489. # Create the issue
  1490. tests.create_projects(self.session)
  1491. repo = pagure.lib.query._get_project(self.session, "test")
  1492. msg = pagure.lib.query.new_issue(
  1493. session=self.session,
  1494. repo=repo,
  1495. title="Test issue #1",
  1496. content="We should work on this for the second time",
  1497. user="pingou",
  1498. status="Open",
  1499. )
  1500. self.session.commit()
  1501. self.assertEqual(msg.title, "Test issue #1")
  1502. # Before
  1503. output = self.app.get("/user/pingou/issues")
  1504. self.assertEqual(output.status_code, 200)
  1505. output_text = output.get_data(as_text=True)
  1506. self.assertIn("Test issue #1", output_text)
  1507. self.assertEqual(
  1508. output_text.count("issue-status issue-status-open"), 1
  1509. )
  1510. # Disable issue tracking
  1511. repo = pagure.lib.query._get_project(self.session, "test")
  1512. settings = repo.settings
  1513. settings["issue_tracker"] = False
  1514. repo.settings = settings
  1515. self.session.add(repo)
  1516. self.session.commit()
  1517. # After
  1518. output = self.app.get("/user/pingou/issues")
  1519. self.assertEqual(output.status_code, 200)
  1520. output_text = output.get_data(as_text=True)
  1521. self.assertNotIn("Test issue #1", output_text)
  1522. self.assertEqual(
  1523. output_text.count("issue-status issue-status-open"), 0
  1524. )
  1525. def test_view_my_issues_tickets_turned_off(self):
  1526. """Test the view_user_issues endpoint when the user exists and
  1527. and ENABLE_TICKETS is False"""
  1528. # Turn off the tickets instance wide
  1529. pagure.config.config["ENABLE_TICKETS"] = False
  1530. output = self.app.get("/user/pingou/issues")
  1531. self.assertEqual(output.status_code, 404)
  1532. pagure.config.config["ENABLE_TICKETS"] = True
  1533. @patch("pagure.ui.app.admin_session_timedout")
  1534. def test_add_user_token(self, ast):
  1535. """ Test the add_user_token endpoint. """
  1536. ast.return_value = False
  1537. user = tests.FakeUser()
  1538. with tests.user_set(self.app.application, user):
  1539. output = self.app.get("/settings/token/new/")
  1540. self.assertEqual(output.status_code, 404)
  1541. self.assertIn(
  1542. "<h2>Page not found (404)</h2>", output.get_data(as_text=True)
  1543. )
  1544. user.username = "foo"
  1545. with tests.user_set(self.app.application, user):
  1546. output = self.app.get("/settings/token/new")
  1547. self.assertEqual(output.status_code, 200)
  1548. output_text = output.get_data(as_text=True)
  1549. self.assertIn(
  1550. '<div class="card-header">\n <strong>'
  1551. "Create a new token</strong>\n",
  1552. output_text,
  1553. )
  1554. self.assertIn(
  1555. '<input type="checkbox" name="acls" value="create_project">',
  1556. output_text,
  1557. )
  1558. csrf_token = output_text.split(
  1559. 'name="csrf_token" type="hidden" value="'
  1560. )[1].split('">')[0]
  1561. data = {"acls": ["create_project", "fork_project"]}
  1562. # missing CSRF
  1563. output = self.app.post("/settings/token/new", data=data)
  1564. self.assertEqual(output.status_code, 200)
  1565. output_text = output.get_data(as_text=True)
  1566. self.assertIn("<title>Create token - Pagure</title>", output_text)
  1567. self.assertIn(
  1568. '<div class="card-header">\n <strong>'
  1569. "Create a new token</strong>\n",
  1570. output_text,
  1571. )
  1572. self.assertIn(
  1573. '<input type="checkbox" name="acls" value="create_project">',
  1574. output_text,
  1575. )
  1576. data = {"acls": ["new_project"], "csrf_token": csrf_token}
  1577. # Invalid ACLs
  1578. output = self.app.post("/settings/token/new", data=data)
  1579. self.assertEqual(output.status_code, 200)
  1580. output_text = output.get_data(as_text=True)
  1581. self.assertIn("<title>Create token - Pagure</title>", output_text)
  1582. self.assertIn(
  1583. '<div class="card-header">\n <strong>'
  1584. "Create a new token</strong>\n",
  1585. output_text,
  1586. )
  1587. self.assertIn(
  1588. '<input type="checkbox" name="acls" value="create_project">',
  1589. output_text,
  1590. )
  1591. data = {
  1592. "acls": ["create_project", "fork_project"],
  1593. "csrf_token": csrf_token,
  1594. }
  1595. # All good
  1596. output = self.app.post(
  1597. "/settings/token/new", data=data, follow_redirects=True
  1598. )
  1599. self.assertEqual(output.status_code, 200)
  1600. output_text = output.get_data(as_text=True)
  1601. self.assertIn(
  1602. "<title>foo's settings - Pagure</title>", output_text
  1603. )
  1604. self.assertIn("Token created", output_text)
  1605. self.assertEqual(
  1606. output_text.count(
  1607. '<small class="font-weight-bold">Active until'
  1608. ),
  1609. 1,
  1610. )
  1611. ast.return_value = True
  1612. output = self.app.get("/settings/token/new")
  1613. self.assertEqual(output.status_code, 302)
  1614. @patch("pagure.ui.app.admin_session_timedout")
  1615. def test_revoke_api_user_token(self, ast):
  1616. """ Test the revoke_api_user_token endpoint. """
  1617. ast.return_value = False
  1618. user = tests.FakeUser()
  1619. with tests.user_set(self.app.application, user):
  1620. # Token doesn't exist
  1621. output = self.app.post("/settings/token/revoke/foobar")
  1622. self.assertEqual(output.status_code, 404)
  1623. self.assertTrue(
  1624. "<h2>Page not found (404)</h2>"
  1625. in output.get_data(as_text=True)
  1626. )
  1627. # Create the foobar API token but associated w/ the user 'foo'
  1628. item = pagure.lib.model.Token(
  1629. id="foobar",
  1630. user_id=2, # foo
  1631. expiration=datetime.datetime.utcnow()
  1632. + datetime.timedelta(days=30),
  1633. )
  1634. self.session.add(item)
  1635. self.session.commit()
  1636. # Token not associated w/ this user
  1637. output = self.app.post("/settings/token/revoke/foobar")
  1638. self.assertEqual(output.status_code, 404)
  1639. self.assertTrue(
  1640. "<h2>Page not found (404)</h2>"
  1641. in output.get_data(as_text=True)
  1642. )
  1643. user.username = "foo"
  1644. with tests.user_set(self.app.application, user):
  1645. # Missing CSRF token
  1646. output = self.app.post(
  1647. "/settings/token/revoke/foobar", follow_redirects=True
  1648. )
  1649. self.assertEqual(output.status_code, 200)
  1650. output_text = output.get_data(as_text=True)
  1651. self.assertIn(
  1652. "<title>foo's settings - Pagure</title>", output_text
  1653. )
  1654. self.assertEqual(
  1655. output_text.count(
  1656. '<small class="font-weight-bold">Active until'
  1657. ),
  1658. 1,
  1659. )
  1660. csrf_token = output_text.split(
  1661. 'name="csrf_token" type="hidden" value="'
  1662. )[1].split('">')[0]
  1663. data = {"csrf_token": csrf_token}
  1664. # All good - token is deleted
  1665. output = self.app.post(
  1666. "/settings/token/revoke/foobar",
  1667. data=data,
  1668. follow_redirects=True,
  1669. )
  1670. self.assertEqual(output.status_code, 200)
  1671. output_text = output.get_data(as_text=True)
  1672. self.assertIn(
  1673. "<title>foo's settings - Pagure</title>", output_text
  1674. )
  1675. self.assertEqual(
  1676. output_text.count(
  1677. '<small class="font-weight-bold">Active until'
  1678. ),
  1679. 0,
  1680. )
  1681. user = pagure.lib.query.get_user(self.session, key="foo")
  1682. self.assertEqual(len(user.tokens), 1)
  1683. expiration_dt = user.tokens[0].expiration
  1684. # Token was already deleted - no changes
  1685. output = self.app.post(
  1686. "/settings/token/revoke/foobar",
  1687. data=data,
  1688. follow_redirects=True,
  1689. )
  1690. self.assertEqual(output.status_code, 200)
  1691. output_text = output.get_data(as_text=True)
  1692. self.assertIn(
  1693. "<title>foo's settings - Pagure</title>", output_text
  1694. )
  1695. self.assertEqual(
  1696. output_text.count(
  1697. '<small class="font-weight-bold">Active until'
  1698. ),
  1699. 0,
  1700. )
  1701. # Ensure the expiration date did not change
  1702. user = pagure.lib.query.get_user(self.session, key="foo")
  1703. self.assertEqual(len(user.tokens), 1)
  1704. self.assertEqual(expiration_dt, user.tokens[0].expiration)
  1705. ast.return_value = True
  1706. output = self.app.get("/settings/token/new")
  1707. self.assertEqual(output.status_code, 302)
  1708. @patch.dict("pagure.config.config", {"PAGURE_AUTH": "fas"})
  1709. @patch.dict("pagure.utils.pagure_config", {"PAGURE_AUTH": "fas"})
  1710. def test_create_project_auth_FAS_no_FPCA(self):
  1711. """Test creating a project when auth is FAS and the user did not
  1712. sign the FPCA."""
  1713. user = tests.FakeUser(username="foo", cla_done=False)
  1714. with tests.user_set(self.app.application, user):
  1715. output = self.app.get("/new/", follow_redirects=True)
  1716. self.assertEqual(output.status_code, 200)
  1717. output_text = output.get_data(as_text=True)
  1718. self.assertIn("<title>Home - Pagure</title>", output_text)
  1719. self.assertIn(
  1720. '</i> You must <a href="https://admin.fedoraproject.org/accounts/'
  1721. '">sign the FPCA</a> (Fedora Project Contributor Agreement) '
  1722. "to use pagure</div>",
  1723. output_text,
  1724. )
  1725. class PagureFlaskAppAboutPagetests(tests.Modeltests):
  1726. """ Unit-tests for the about page. """
  1727. def test_about_page(self):
  1728. """ Test the about page when an admin_email is set. """
  1729. output = self.app.get("/about/")
  1730. self.assertEqual(output.status_code, 200)
  1731. output_text = output.get_data(as_text=True)
  1732. self.assertIn("<title>About - Pagure</title>", output_text)
  1733. self.assertIn(
  1734. "by emailing:\n "
  1735. '<a href="mailto:root@localhost.localdomain">',
  1736. output_text,
  1737. )
  1738. self.assertIn(
  1739. 'href="https://pagure.io/pagure/issues">open a ticket</a>',
  1740. output_text,
  1741. )
  1742. @patch.dict("pagure.config.config", {"ADMIN_EMAIL": "admin@fp.o"})
  1743. def test_about_page_admin_email(self):
  1744. """ Test the about page when an admin_email is set. """
  1745. output = self.app.get("/about/")
  1746. self.assertEqual(output.status_code, 200)
  1747. output_text = output.get_data(as_text=True)
  1748. self.assertIn("<title>About - Pagure</title>", output_text)
  1749. self.assertIn(
  1750. 'by emailing:\n <a href="mailto:admin@fp.o">', output_text
  1751. )
  1752. self.assertIn(
  1753. 'href="https://pagure.io/pagure/issues">open a ticket</a>',
  1754. output_text,
  1755. )
  1756. class PagureFlaskAppNoDocstests(tests.Modeltests):
  1757. """ Tests for flask app controller of pagure """
  1758. config_values = {"enable_docs": False, "docs_folder": None}
  1759. def test_new_project_no_docs_folder(self):
  1760. """ Test the new_project endpoint with DOCS_FOLDER is None. """
  1761. # Before
  1762. projects = pagure.lib.query.search_projects(self.session)
  1763. self.assertEqual(len(projects), 0)
  1764. self.assertFalse(
  1765. os.path.exists(os.path.join(self.path, "repos", "project#1.git"))
  1766. )
  1767. self.assertFalse(
  1768. os.path.exists(
  1769. os.path.join(self.path, "repos", "tickets", "project#1.git")
  1770. )
  1771. )
  1772. self.assertFalse(
  1773. os.path.exists(
  1774. os.path.join(self.path, "repos", "docs", "project#1.git")
  1775. )
  1776. )
  1777. self.assertFalse(
  1778. os.path.exists(
  1779. os.path.join(self.path, "repos", "requests", "project#1.git")
  1780. )
  1781. )
  1782. user = tests.FakeUser(username="foo")
  1783. with tests.user_set(self.app.application, user):
  1784. csrf_token = self.get_csrf()
  1785. data = {
  1786. "description": "Project #1",
  1787. "name": "project-1",
  1788. "csrf_token": csrf_token,
  1789. }
  1790. output = self.app.post("/new/", data=data, follow_redirects=True)
  1791. self.assertEqual(output.status_code, 200)
  1792. output_text = output.get_data(as_text=True)
  1793. self.assertIn(
  1794. '<div class="projectinfo my-3">\nProject #1', output_text
  1795. )
  1796. self.assertIn("<p>This repo is brand new!</p>", output_text)
  1797. self.assertIn(
  1798. "<title>Overview - project-1 - Pagure</title>", output_text
  1799. )
  1800. # After
  1801. projects = pagure.lib.query.search_projects(self.session)
  1802. self.assertEqual(len(projects), 1)
  1803. self.assertTrue(
  1804. os.path.exists(os.path.join(self.path, "repos", "project-1.git"))
  1805. )
  1806. self.assertTrue(
  1807. os.path.exists(
  1808. os.path.join(self.path, "repos", "tickets", "project-1.git")
  1809. )
  1810. )
  1811. self.assertFalse(
  1812. os.path.exists(
  1813. os.path.join(self.path, "repos", "docs", "project-1.git")
  1814. )
  1815. )
  1816. self.assertTrue(
  1817. os.path.exists(
  1818. os.path.join(self.path, "repos", "requests", "project-1.git")
  1819. )
  1820. )
  1821. class PagureFlaskAppNoTicketstests(tests.Modeltests):
  1822. """ Tests for flask app controller of pagure """
  1823. config_values = {"enable_tickets": False, "tickets_folder": None}
  1824. def test_new_project_no_tickets_folder(self):
  1825. """ Test the new_project endpoint with TICKETS_FOLDER is None. """
  1826. # Before
  1827. projects = pagure.lib.query.search_projects(self.session)
  1828. self.assertEqual(len(projects), 0)
  1829. self.assertFalse(
  1830. os.path.exists(os.path.join(self.path, "repos", "project#1.git"))
  1831. )
  1832. self.assertFalse(
  1833. os.path.exists(
  1834. os.path.join(self.path, "repos", "tickets", "project#1.git")
  1835. )
  1836. )
  1837. self.assertFalse(
  1838. os.path.exists(
  1839. os.path.join(self.path, "repos", "docs", "project#1.git")
  1840. )
  1841. )
  1842. self.assertFalse(
  1843. os.path.exists(
  1844. os.path.join(self.path, "repos", "requests", "project#1.git")
  1845. )
  1846. )
  1847. user = tests.FakeUser(username="foo")
  1848. with tests.user_set(self.app.application, user):
  1849. csrf_token = self.get_csrf()
  1850. data = {
  1851. "description": "Project #1",
  1852. "name": "project-1",
  1853. "csrf_token": csrf_token,
  1854. }
  1855. output = self.app.post("/new/", data=data, follow_redirects=True)
  1856. self.assertEqual(output.status_code, 200)
  1857. output_text = output.get_data(as_text=True)
  1858. self.assertIn(
  1859. '<div class="projectinfo my-3">\nProject #1', output_text
  1860. )
  1861. self.assertIn("<p>This repo is brand new!</p>", output_text)
  1862. self.assertIn(
  1863. "<title>Overview - project-1 - Pagure</title>", output_text
  1864. )
  1865. # After
  1866. projects = pagure.lib.query.search_projects(self.session)
  1867. self.assertEqual(len(projects), 1)
  1868. self.assertTrue(
  1869. os.path.exists(os.path.join(self.path, "repos", "project-1.git"))
  1870. )
  1871. self.assertFalse(
  1872. os.path.exists(
  1873. os.path.join(self.path, "repos", "tickets", "project-1.git")
  1874. )
  1875. )
  1876. self.assertTrue(
  1877. os.path.exists(
  1878. os.path.join(self.path, "repos", "docs", "project-1.git")
  1879. )
  1880. )
  1881. self.assertTrue(
  1882. os.path.exists(
  1883. os.path.join(self.path, "repos", "requests", "project-1.git")
  1884. )
  1885. )
  1886. class PagureFlaskAppRenewUserApiTokentests(tests.Modeltests):
  1887. @patch("pagure.decorators.admin_session_timedout")
  1888. def setUp(self, ast):
  1889. """ Constructor """
  1890. super(PagureFlaskAppRenewUserApiTokentests, self).setUp()
  1891. self.ast = ast
  1892. self.ast.return_value = False
  1893. user = tests.FakeUser(username="pingou")
  1894. with tests.user_set(self.app.application, user):
  1895. output = self.app.get("/settings/token/new")
  1896. self.assertEqual(output.status_code, 200)
  1897. output_text = output.get_data(as_text=True)
  1898. self.assertIn("<strong>Create a new token</strong>", output_text)
  1899. self.csrf_token = self.get_csrf(output=output)
  1900. # Create a token to renew
  1901. data = {"csrf_token": self.csrf_token, "acls": ["modify_project"]}
  1902. output = self.app.post(
  1903. "/settings/token/new/", data=data, follow_redirects=True
  1904. )
  1905. self.assertEqual(output.status_code, 200)
  1906. output_text = output.get_data(as_text=True)
  1907. self.assertIn("Token created", output_text)
  1908. # 1 token associated with the user, expires in 60 days
  1909. userobj = pagure.lib.query.search_user(self.session, username="pingou")
  1910. self.assertEqual(len(userobj.tokens), 1)
  1911. self.assertEqual(
  1912. userobj.tokens[0].expiration.date(),
  1913. datetime.datetime.utcnow().date()
  1914. + datetime.timedelta(days=(30 * 6)),
  1915. )
  1916. self.token = userobj.tokens[0].id
  1917. def test_renew_api_token_not_in(self):
  1918. """ Test the renew_api_token endpoint. """
  1919. # User not logged in
  1920. output = self.app.post("/settings/token/renew/123")
  1921. self.assertEqual(output.status_code, 302)
  1922. @patch("pagure.ui.app.admin_session_timedout")
  1923. def test_renew_api_token_session_old(self, ast):
  1924. """ Test the renew_api_token endpoint. """
  1925. ast.return_value = True
  1926. user = tests.FakeUser(username="pingou")
  1927. with tests.user_set(self.app.application, user):
  1928. data = {"csrf_token": self.csrf_token}
  1929. # Test when the session timed-out
  1930. output = self.app.post("/settings/token/renew/123", data=data)
  1931. self.assertEqual(output.status_code, 302)
  1932. output = self.app.get("/", follow_redirects=True)
  1933. self.assertEqual(output.status_code, 200)
  1934. output_text = output.get_data(as_text=True)
  1935. self.assertIn("Action canceled, try it again", output_text)
  1936. def test_renew_api_token_invalid_token(self):
  1937. """ Test the renew_api_token endpoint. """
  1938. user = tests.FakeUser(username="pingou")
  1939. with tests.user_set(self.app.application, user):
  1940. output = self.app.post(
  1941. "/settings/token/renew/123",
  1942. data={"csrf_token": self.csrf_token},
  1943. )
  1944. self.assertEqual(output.status_code, 404)
  1945. output_text = output.get_data(as_text=True)
  1946. self.assertIn("<p>Token not found</p>", output_text)
  1947. def test_renew_api_token(self):
  1948. """ Test the renew_api_token endpoint. """
  1949. user = tests.FakeUser(username="pingou")
  1950. with tests.user_set(self.app.application, user):
  1951. output = self.app.post(
  1952. "/settings/token/renew/%s" % self.token,
  1953. data={"csrf_token": self.csrf_token},
  1954. follow_redirects=True,
  1955. )
  1956. output_text = output.get_data(as_text=True)
  1957. self.assertIn(
  1958. "<title>pingou's settings - Pagure</title>", output_text
  1959. )
  1960. self.assertIn("Token created", output_text)
  1961. self.assertEqual(output_text.count('title="Revoke token">'), 2)
  1962. self.assertEqual(output_text.count('title="Renew token">'), 2)
  1963. self.session.commit()
  1964. # Existing token has been renewed
  1965. userobj = pagure.lib.query.search_user(
  1966. self.session, username="pingou"
  1967. )
  1968. self.assertEqual(len(userobj.tokens), 2)
  1969. self.assertEqual(
  1970. userobj.tokens[0].expiration.date(),
  1971. userobj.tokens[1].expiration.date(),
  1972. )
  1973. self.assertEqual(
  1974. userobj.tokens[0].created.date(),
  1975. userobj.tokens[1].created.date(),
  1976. )
  1977. self.assertEqual(userobj.tokens[0].acls, userobj.tokens[1].acls)
  1978. self.assertEqual(
  1979. userobj.tokens[0].description, userobj.tokens[1].description
  1980. )
  1981. class PagureFlaskAppNewProjecttests(tests.Modeltests):
  1982. """ Tests creating new project via the flask app controller of pagure """
  1983. def setUp(self):
  1984. """ Setup the environment. """
  1985. super(PagureFlaskAppNewProjecttests, self).setUp()
  1986. # Before
  1987. projects = pagure.lib.query.search_projects(self.session)
  1988. self.assertEqual(len(projects), 0)
  1989. self.assertFalse(
  1990. os.path.exists(os.path.join(self.path, "repos", "project#1.git"))
  1991. )
  1992. self.assertFalse(
  1993. os.path.exists(
  1994. os.path.join(self.path, "repos", "tickets", "project#1.git")
  1995. )
  1996. )
  1997. self.assertFalse(
  1998. os.path.exists(
  1999. os.path.join(self.path, "repos", "docs", "project#1.git")
  2000. )
  2001. )
  2002. self.assertFalse(
  2003. os.path.exists(
  2004. os.path.join(self.path, "repos", "requests", "project#1.git")
  2005. )
  2006. )
  2007. @patch.dict("pagure.config.config", {"CASE_SENSITIVE": True})
  2008. def test_new_project_case_sensitive(self):
  2009. tests.create_projects(self.session)
  2010. tests.create_projects_git(os.path.join(self.path, "repos"), bare=True)
  2011. output = self.app.get("/test")
  2012. self.assertEqual(output.status_code, 200)
  2013. output = self.app.get("/TEST")
  2014. self.assertEqual(output.status_code, 404)
  2015. user = tests.FakeUser()
  2016. user.username = "foo"
  2017. with tests.user_set(self.app.application, user):
  2018. output = self.app.get("/new/")
  2019. self.assertEqual(output.status_code, 200)
  2020. csrf_token = self.get_csrf(output=output)
  2021. data = {
  2022. "description": "TEST",
  2023. "name": "TEST",
  2024. "csrf_token": csrf_token,
  2025. "create_readme": True,
  2026. }
  2027. self.app.post("/new/", data=data, follow_redirects=True)
  2028. self.assertEqual(output.status_code, 200)
  2029. output = self.app.get("/TEST")
  2030. self.assertEqual(output.status_code, 200)
  2031. def test_new_project_readme(self):
  2032. # Before
  2033. projects = pagure.lib.query.search_projects(self.session)
  2034. self.assertEqual(len(projects), 0)
  2035. user = tests.FakeUser(username="foo")
  2036. with tests.user_set(self.app.application, user):
  2037. csrf_token = self.get_csrf()
  2038. data = {
  2039. "description": "testproject",
  2040. "name": "testproject",
  2041. "csrf_token": csrf_token,
  2042. "create_readme": True,
  2043. }
  2044. output = self.app.post("/new/", data=data, follow_redirects=True)
  2045. self.assertEqual(output.status_code, 200)
  2046. output_text = output.get_data(as_text=True)
  2047. self.assertIn(
  2048. "<title>Overview - testproject - Pagure</title>", output_text
  2049. )
  2050. self.assertIn(
  2051. '<a href="/testproject"><strong>testproject</strong></a>',
  2052. output_text,
  2053. )
  2054. self.assertIn(
  2055. '<code class="py-1 px-2 font-weight-bold '
  2056. 'commit_branch">master</code>',
  2057. output_text,
  2058. )
  2059. # After
  2060. projects = pagure.lib.query.search_projects(self.session)
  2061. self.assertEqual(len(projects), 1)
  2062. project = pagure.lib.query._get_project(self.session, "testproject")
  2063. repo = pygit2.Repository(project.repopath("main"))
  2064. self.assertEqual(repo.listall_branches(), ["master"])
  2065. @patch.dict("pagure.config.config", {"ENABLE_UI_NEW_PROJECTS": False})
  2066. def test_new_project_when_turned_off_in_the_ui(self):
  2067. """Test the new_project endpoint when new project creation is
  2068. not allowed in the UI of this pagure instance."""
  2069. user = tests.FakeUser(username="foo")
  2070. with tests.user_set(self.app.application, user):
  2071. output = self.app.get("/new/")
  2072. self.assertEqual(output.status_code, 404)
  2073. data = {"description": "Project #1", "name": "project-1"}
  2074. output = self.app.post("/new/", data=data, follow_redirects=True)
  2075. self.assertEqual(output.status_code, 404)
  2076. @patch.dict("pagure.config.config", {"ENABLE_UI_NEW_PROJECTS": False})
  2077. def test_new_project_button_when_turned_off_in_the_ui_no_project(self):
  2078. """Test the index endpoint when new project creation is
  2079. not allowed in the UI of this pagure instance."""
  2080. user = tests.FakeUser(username="foo")
  2081. with tests.user_set(self.app.application, user):
  2082. output = self.app.get("/", follow_redirects=True)
  2083. self.assertEqual(output.status_code, 200)
  2084. output_text = output.get_data(as_text=True)
  2085. self.assertIn(
  2086. '<h4 class="font-weight-bold mb-0">My Projects</h4>',
  2087. output_text,
  2088. )
  2089. # master template
  2090. self.assertNotIn(
  2091. '<span class="oi" data-glyph="plus" title="Create New"',
  2092. output_text,
  2093. )
  2094. # index_auth template
  2095. self.assertNotIn(
  2096. 'title="Create New Project" aria-hidden="true">', output_text
  2097. )
  2098. @patch.dict("pagure.config.config", {"ENABLE_UI_NEW_PROJECTS": False})
  2099. def test_new_project_button_when_turned_off_in_the_ui_w_project(self):
  2100. """Test the index endpoint when new project creation is
  2101. not allowed in the UI of this pagure instance."""
  2102. tests.create_projects(self.session)
  2103. user = tests.FakeUser(username="pingou")
  2104. with tests.user_set(self.app.application, user):
  2105. output = self.app.get("/", follow_redirects=True)
  2106. self.assertEqual(output.status_code, 200)
  2107. output_text = output.get_data(as_text=True)
  2108. self.assertIn(
  2109. '<h4 class="font-weight-bold mb-0">My Projects</h4>',
  2110. output_text,
  2111. )
  2112. # master template
  2113. self.assertNotIn(
  2114. '<span class="oi" data-glyph="plus" title="Create New"',
  2115. output_text,
  2116. )
  2117. # index_auth template
  2118. self.assertNotIn(
  2119. 'title="Create New Project" aria-hidden="true">', output_text
  2120. )
  2121. def test_new_project_with_dot(self):
  2122. """Test the new_project endpoint when new project contains a dot."""
  2123. # Before
  2124. projects = pagure.lib.query.search_projects(self.session)
  2125. self.assertEqual(len(projects), 0)
  2126. user = tests.FakeUser(username="foo")
  2127. with tests.user_set(self.app.application, user):
  2128. csrf_token = self.get_csrf()
  2129. data = {
  2130. "description": "Project #1.",
  2131. "name": "project.1",
  2132. "csrf_token": csrf_token,
  2133. }
  2134. output = self.app.post("/new/", data=data, follow_redirects=True)
  2135. self.assertEqual(output.status_code, 200)
  2136. output_text = output.get_data(as_text=True)
  2137. self.assertIn(
  2138. "<title>Overview - project.1 - Pagure</title>", output_text
  2139. )
  2140. self.assertIn(
  2141. '<a href="/project.1"><strong>project.1</strong></a>',
  2142. output_text,
  2143. )
  2144. # After
  2145. projects = pagure.lib.query.search_projects(self.session)
  2146. self.assertEqual(len(projects), 1)
  2147. def test_new_project_with_plus(self):
  2148. """Test the new_project endpoint when new project contains a plus sign."""
  2149. # Before
  2150. projects = pagure.lib.query.search_projects(self.session)
  2151. self.assertEqual(len(projects), 0)
  2152. user = tests.FakeUser(username="foo")
  2153. with tests.user_set(self.app.application, user):
  2154. csrf_token = self.get_csrf()
  2155. data = {
  2156. "description": "Project #1.",
  2157. "name": "project+1",
  2158. "csrf_token": csrf_token,
  2159. }
  2160. output = self.app.post("/new/", data=data, follow_redirects=True)
  2161. self.assertEqual(output.status_code, 200)
  2162. output_text = output.get_data(as_text=True)
  2163. self.assertIn(
  2164. "<title>Overview - project+1 - Pagure</title>", output_text
  2165. )
  2166. self.assertTrue(
  2167. '<a href="/project+1"><strong>project+1</strong></a>'
  2168. in output_text
  2169. or '<a href="/project%2B1"><strong>project+1</strong></a>'
  2170. in output_text
  2171. )
  2172. # After
  2173. projects = pagure.lib.query.search_projects(self.session)
  2174. self.assertEqual(len(projects), 1)
  2175. repo = pygit2.Repository(projects[0].repopath("main"))
  2176. self.assertEqual(repo.listall_branches(), [])
  2177. def test_new_project_with_default_branch(self):
  2178. """Test the new_project endpoint when new project contains a plus sign."""
  2179. # Before
  2180. projects = pagure.lib.query.search_projects(self.session)
  2181. self.assertEqual(len(projects), 0)
  2182. user = tests.FakeUser(username="foo")
  2183. with tests.user_set(self.app.application, user):
  2184. csrf_token = self.get_csrf()
  2185. data = {
  2186. "description": "Project #1.",
  2187. "name": "project_main",
  2188. "csrf_token": csrf_token,
  2189. "default_branch": "main",
  2190. "create_readme": True,
  2191. }
  2192. output = self.app.post("/new/", data=data, follow_redirects=True)
  2193. self.assertEqual(output.status_code, 200)
  2194. output_text = output.get_data(as_text=True)
  2195. self.assertIn(
  2196. "<title>Overview - project_main - Pagure</title>", output_text
  2197. )
  2198. self.assertIn(
  2199. '<a href="/project_main"><strong>project_main</strong></a>',
  2200. output_text,
  2201. )
  2202. self.assertIn(
  2203. '<code class="py-1 px-2 font-weight-bold '
  2204. 'commit_branch">main</code>',
  2205. output_text,
  2206. )
  2207. # After
  2208. projects = pagure.lib.query.search_projects(self.session)
  2209. self.assertEqual(len(projects), 1)
  2210. repo = pygit2.Repository(projects[0].repopath("main"))
  2211. self.assertEqual(repo.listall_branches(), ["main"])
  2212. @patch.dict("pagure.config.config", {"GIT_DEFAULT_BRANCH": "main"})
  2213. def test_new_project_with_default_branch_instance_wide(self):
  2214. """Test the new_project endpoint when new project contains a plus sign."""
  2215. # Before
  2216. projects = pagure.lib.query.search_projects(self.session)
  2217. self.assertEqual(len(projects), 0)
  2218. user = tests.FakeUser(username="foo")
  2219. with tests.user_set(self.app.application, user):
  2220. csrf_token = self.get_csrf()
  2221. data = {
  2222. "description": "Project #1.",
  2223. "name": "project_main",
  2224. "csrf_token": csrf_token,
  2225. "create_readme": True,
  2226. }
  2227. output = self.app.post("/new/", data=data, follow_redirects=True)
  2228. self.assertEqual(output.status_code, 200)
  2229. output_text = output.get_data(as_text=True)
  2230. self.assertIn(
  2231. "<title>Overview - project_main - Pagure</title>", output_text
  2232. )
  2233. self.assertIn(
  2234. '<a href="/project_main"><strong>project_main</strong></a>',
  2235. output_text,
  2236. )
  2237. self.assertIn(
  2238. '<code class="py-1 px-2 font-weight-bold '
  2239. 'commit_branch">main</code>',
  2240. output_text,
  2241. )
  2242. # After
  2243. projects = pagure.lib.query.search_projects(self.session)
  2244. self.assertEqual(len(projects), 1)
  2245. repo = pygit2.Repository(projects[0].repopath("main"))
  2246. self.assertEqual(repo.listall_branches(), ["main"])
  2247. @patch.dict("pagure.config.config", {"GIT_DEFAULT_BRANCH": "main"})
  2248. def test_new_project_with_default_branch_instance_wide_overriden(self):
  2249. """Test the new_project endpoint when new project contains a plus sign."""
  2250. # Before
  2251. projects = pagure.lib.query.search_projects(self.session)
  2252. self.assertEqual(len(projects), 0)
  2253. user = tests.FakeUser(username="foo")
  2254. with tests.user_set(self.app.application, user):
  2255. csrf_token = self.get_csrf()
  2256. data = {
  2257. "description": "Project #1.",
  2258. "name": "project_main",
  2259. "csrf_token": csrf_token,
  2260. "default_branch": "rawhide",
  2261. "create_readme": True,
  2262. }
  2263. output = self.app.post("/new/", data=data, follow_redirects=True)
  2264. self.assertEqual(output.status_code, 200)
  2265. output_text = output.get_data(as_text=True)
  2266. self.assertIn(
  2267. "<title>Overview - project_main - Pagure</title>", output_text
  2268. )
  2269. self.assertIn(
  2270. '<a href="/project_main"><strong>project_main</strong></a>',
  2271. output_text,
  2272. )
  2273. self.assertIn(
  2274. '<code class="py-1 px-2 font-weight-bold '
  2275. 'commit_branch">rawhide</code>',
  2276. output_text,
  2277. )
  2278. # After
  2279. projects = pagure.lib.query.search_projects(self.session)
  2280. self.assertEqual(len(projects), 1)
  2281. repo = pygit2.Repository(projects[0].repopath("main"))
  2282. self.assertEqual(repo.listall_branches(), ["rawhide"])
  2283. def test_new_project_when_turned_off(self):
  2284. """Test the new_project endpoint when new project creation is
  2285. not allowed in the pagure instance."""
  2286. # turn the project creation off
  2287. pagure.config.config["ENABLE_NEW_PROJECTS"] = False
  2288. # Before
  2289. projects = pagure.lib.query.search_projects(self.session)
  2290. self.assertEqual(len(projects), 0)
  2291. self.assertFalse(
  2292. os.path.exists(os.path.join(self.path, "repos", "project-1.git"))
  2293. )
  2294. self.assertFalse(
  2295. os.path.exists(
  2296. os.path.join(self.path, "repos", "tickets", "project-1.git")
  2297. )
  2298. )
  2299. self.assertFalse(
  2300. os.path.exists(
  2301. os.path.join(self.path, "repos", "docs", "project-1.git")
  2302. )
  2303. )
  2304. self.assertFalse(
  2305. os.path.exists(
  2306. os.path.join(self.path, "repos", "requests", "project-1.git")
  2307. )
  2308. )
  2309. user = tests.FakeUser()
  2310. with tests.user_set(self.app.application, user):
  2311. output = self.app.get("/new/")
  2312. self.assertEqual(output.status_code, 404)
  2313. # just get the csrf token
  2314. pagure.config.config["ENABLE_NEW_PROJECTS"] = True
  2315. output = self.app.get("/new/")
  2316. pagure.config.config["ENABLE_NEW_PROJECTS"] = False
  2317. csrf_token = (
  2318. output.get_data(as_text=True)
  2319. .split('name="csrf_token" type="hidden" value="')[1]
  2320. .split('">')[0]
  2321. )
  2322. data = {"description": "Project #1", "name": "project-1"}
  2323. user.username = "foo"
  2324. with tests.user_set(self.app.application, user):
  2325. data["csrf_token"] = csrf_token
  2326. output = self.app.post("/new/", data=data, follow_redirects=True)
  2327. self.assertEqual(output.status_code, 404)
  2328. # After
  2329. projects = pagure.lib.query.search_projects(self.session)
  2330. self.assertEqual(len(projects), 0)
  2331. self.assertFalse(
  2332. os.path.exists(os.path.join(self.path, "repos", "project-1.git"))
  2333. )
  2334. self.assertFalse(
  2335. os.path.exists(
  2336. os.path.join(self.path, "repos", "tickets", "project-1.git")
  2337. )
  2338. )
  2339. self.assertFalse(
  2340. os.path.exists(
  2341. os.path.join(self.path, "repos", "docs", "project-1.git")
  2342. )
  2343. )
  2344. self.assertFalse(
  2345. os.path.exists(
  2346. os.path.join(self.path, "repos", "requests", "project-1.git")
  2347. )
  2348. )
  2349. pagure.config.config["ENABLE_NEW_PROJECTS"] = True
  2350. def test_new_project_mirrored_invalid_url(self):
  2351. """ Test the new_project with a mirrored repo but an invalid URL. """
  2352. user = tests.FakeUser(username="foo")
  2353. with tests.user_set(self.app.application, user):
  2354. output = self.app.get("/new/")
  2355. self.assertEqual(output.status_code, 200)
  2356. csrf_token = self.get_csrf(output=output)
  2357. data = {
  2358. "description": "Project #1",
  2359. "name": "project-1",
  2360. "mirrored_from": "abcd",
  2361. "csrf_token": csrf_token,
  2362. }
  2363. output = self.app.post("/new/", data=data, follow_redirects=True)
  2364. self.assertEqual(output.status_code, 200)
  2365. output_text = output.get_data(as_text=True)
  2366. self.assertIn("<title>New project - Pagure</title>", output_text)
  2367. self.assertIn("Invalid input.&nbsp;", output_text)
  2368. def test_new_project_mirrored_invalid_sshurl(self):
  2369. """Test the new_project with a mirrored repo but an invalid
  2370. SSH-like url.
  2371. """
  2372. user = tests.FakeUser(username="foo")
  2373. with tests.user_set(self.app.application, user):
  2374. output = self.app.get("/new/")
  2375. self.assertEqual(output.status_code, 200)
  2376. csrf_token = self.get_csrf(output=output)
  2377. data = {
  2378. "description": "Project #1",
  2379. "name": "project-1",
  2380. "mirrored_from": "ssh://git@server.org/foo/bar.git",
  2381. "csrf_token": csrf_token,
  2382. }
  2383. output = self.app.post("/new/", data=data, follow_redirects=True)
  2384. self.assertEqual(output.status_code, 200)
  2385. output_text = output.get_data(as_text=True)
  2386. self.assertIn("<title>New project - Pagure</title>", output_text)
  2387. self.assertIn("Invalid input.&nbsp;", output_text)
  2388. def test_new_project_mirrored_valid_url(self):
  2389. """ Test the new_project with a mirrored repo with a valid url. """
  2390. user = tests.FakeUser(username="foo")
  2391. with tests.user_set(self.app.application, user):
  2392. output = self.app.get("/new/")
  2393. self.assertEqual(output.status_code, 200)
  2394. output_text = output.get_data(as_text=True)
  2395. self.assertIn(
  2396. '<strong><label for="mirrored_from">Mirror from URL'
  2397. "</label> </strong>",
  2398. output_text,
  2399. )
  2400. csrf_token = self.get_csrf(output=output)
  2401. data = {
  2402. "description": "Project #1",
  2403. "name": "project-1",
  2404. "mirrored_from": "https://example.com/foo/bar.git",
  2405. "csrf_token": csrf_token,
  2406. }
  2407. output = self.app.post("/new/", data=data, follow_redirects=True)
  2408. self.assertEqual(output.status_code, 200)
  2409. output_text = output.get_data(as_text=True)
  2410. self.assertIn(
  2411. "<title>Overview - project-1 - Pagure</title>", output_text
  2412. )
  2413. self.assertIn(
  2414. "<p>This repo is brand new and meant to be mirrored from "
  2415. "https://example.com/foo/bar.git !</p>",
  2416. output_text,
  2417. )
  2418. @patch.dict("pagure.config.config", {"DISABLE_MIRROR_IN": True})
  2419. def test_new_project_mirrored_mirror_disabled(self):
  2420. """Test the new_project with a mirrored repo when that feature is
  2421. disabled.
  2422. """
  2423. user = tests.FakeUser(username="foo")
  2424. with tests.user_set(self.app.application, user):
  2425. output = self.app.get("/new/")
  2426. self.assertEqual(output.status_code, 200)
  2427. output_text = output.get_data(as_text=True)
  2428. self.assertNotIn(
  2429. '<strong><label for="mirrored_from">Mirror from URL'
  2430. "</label> </strong>",
  2431. output_text,
  2432. )
  2433. csrf_token = self.get_csrf(output=output)
  2434. data = {
  2435. "description": "Project #1",
  2436. "name": "project-1",
  2437. "mirrored_from": "https://example.com/foo/bar.git",
  2438. "csrf_token": csrf_token,
  2439. }
  2440. output = self.app.post("/new/", data=data, follow_redirects=True)
  2441. self.assertEqual(output.status_code, 200)
  2442. output_text = output.get_data(as_text=True)
  2443. self.assertIn("<title>New project - Pagure</title>", output_text)
  2444. self.assertIn(
  2445. "</i> Mirroring in projects has been disabled in "
  2446. "this instance</div>",
  2447. output_text,
  2448. )
  2449. def test_new_project(self):
  2450. """ Test the new_project endpoint. """
  2451. user = tests.FakeUser()
  2452. with tests.user_set(self.app.application, user):
  2453. output = self.app.get("/new/")
  2454. self.assertEqual(output.status_code, 200)
  2455. output_text = output.get_data(as_text=True)
  2456. self.assertIn("<strong>Create new Project</strong>", output_text)
  2457. csrf_token = output_text.split(
  2458. 'name="csrf_token" type="hidden" value="'
  2459. )[1].split('">')[0]
  2460. data = {"description": "Project #1"}
  2461. output = self.app.post("/new/", data=data)
  2462. self.assertEqual(output.status_code, 200)
  2463. output_text = output.get_data(as_text=True)
  2464. self.assertIn("<strong>Create new Project</strong>", output_text)
  2465. self.assertIn(
  2466. "<small>\n This field is required.&nbsp;\n"
  2467. " </small>",
  2468. output_text,
  2469. )
  2470. data["name"] = "project-1"
  2471. output = self.app.post("/new/", data=data)
  2472. self.assertEqual(output.status_code, 200)
  2473. output_text = output.get_data(as_text=True)
  2474. self.assertIn("<strong>Create new Project</strong>", output_text)
  2475. self.assertNotIn(
  2476. "<small>\n This field is required.&nbsp;\n"
  2477. " </small>",
  2478. output_text,
  2479. )
  2480. data["csrf_token"] = csrf_token
  2481. output = self.app.post("/new/", data=data)
  2482. self.assertEqual(output.status_code, 200)
  2483. output_text = output.get_data(as_text=True)
  2484. self.assertIn("<strong>Create new Project</strong>", output_text)
  2485. self.assertIn("No user " "&#34;username&#34; found", output_text)
  2486. user.username = "foo"
  2487. with tests.user_set(self.app.application, user):
  2488. data["csrf_token"] = csrf_token
  2489. output = self.app.post("/new/", data=data, follow_redirects=True)
  2490. self.assertEqual(output.status_code, 200)
  2491. output_text = output.get_data(as_text=True)
  2492. self.assertIn(
  2493. '<div class="projectinfo my-3">\nProject #1', output_text
  2494. )
  2495. self.assertIn("<p>This repo is brand new!</p>", output_text)
  2496. self.assertIn(
  2497. "<title>Overview - project-1 - Pagure</title>", output_text
  2498. )
  2499. # After
  2500. projects = pagure.lib.query.search_projects(self.session)
  2501. self.assertEqual(len(projects), 1)
  2502. self.assertTrue(
  2503. os.path.exists(os.path.join(self.path, "repos", "project-1.git"))
  2504. )
  2505. self.assertTrue(
  2506. os.path.exists(
  2507. os.path.join(self.path, "repos", "tickets", "project-1.git")
  2508. )
  2509. )
  2510. self.assertTrue(
  2511. os.path.exists(
  2512. os.path.join(self.path, "repos", "docs", "project-1.git")
  2513. )
  2514. )
  2515. self.assertTrue(
  2516. os.path.exists(
  2517. os.path.join(self.path, "repos", "requests", "project-1.git")
  2518. )
  2519. )
  2520. @patch.dict("pagure.config.config", {"USER_NAMESPACE": True})
  2521. def test_new_project_user_namespaced(self):
  2522. """Test the new_project with a user namespaced enabled."""
  2523. user = tests.FakeUser(username="foo")
  2524. with tests.user_set(self.app.application, user):
  2525. output = self.app.get("/new/")
  2526. self.assertEqual(output.status_code, 200)
  2527. output_text = output.get_data(as_text=True)
  2528. csrf_token = self.get_csrf(output=output)
  2529. data = {
  2530. "description": "Project #1",
  2531. "name": "project-1",
  2532. "csrf_token": csrf_token,
  2533. }
  2534. output = self.app.post("/new/", data=data, follow_redirects=True)
  2535. self.assertEqual(output.status_code, 200)
  2536. output_text = output.get_data(as_text=True)
  2537. self.assertIn(
  2538. "<title>Overview - foo/project-1 - Pagure</title>", output_text
  2539. )
  2540. self.assertIn(
  2541. '<div class="projectinfo my-3">\nProject #1', output_text
  2542. )
  2543. self.assertIn("<p>This repo is brand new!</p>", output_text)
  2544. # After
  2545. projects = pagure.lib.query.search_projects(self.session)
  2546. self.assertEqual(len(projects), 1)
  2547. self.assertTrue(
  2548. os.path.exists(
  2549. os.path.join(self.path, "repos", "foo", "project-1.git")
  2550. )
  2551. )
  2552. self.assertTrue(
  2553. os.path.exists(
  2554. os.path.join(
  2555. self.path, "repos", "tickets", "foo", "project-1.git"
  2556. )
  2557. )
  2558. )
  2559. self.assertTrue(
  2560. os.path.exists(
  2561. os.path.join(
  2562. self.path, "repos", "docs", "foo", "project-1.git"
  2563. )
  2564. )
  2565. )
  2566. self.assertTrue(
  2567. os.path.exists(
  2568. os.path.join(
  2569. self.path, "repos", "requests", "foo", "project-1.git"
  2570. )
  2571. )
  2572. )
  2573. @patch.dict("pagure.config.config", {"USER_NAMESPACE": True})
  2574. def test_new_project_user_namespaced_invalid_user(self):
  2575. """Test the new_project with a user namespaced enabled."""
  2576. tests.create_user(self.session, "docs", "evil docs", ["docs@bar.com"])
  2577. user = tests.FakeUser(username="docs")
  2578. with tests.user_set(self.app.application, user):
  2579. output = self.app.get("/new/")
  2580. self.assertEqual(output.status_code, 200)
  2581. output_text = output.get_data(as_text=True)
  2582. csrf_token = self.get_csrf(output=output)
  2583. data = {
  2584. "description": "Project #1",
  2585. "name": "project-1",
  2586. "csrf_token": csrf_token,
  2587. }
  2588. output = self.app.post("/new/", data=data, follow_redirects=True)
  2589. self.assertEqual(output.status_code, 200)
  2590. output_text = output.get_data(as_text=True)
  2591. self.assertIn("<title>New project - Pagure</title>", output_text)
  2592. self.assertIn(
  2593. "</i> No project &#34;docs/project-1&#34; are allowed to be "
  2594. "created due to potential conflicts in URLs with pagure "
  2595. "itself</div>",
  2596. output_text,
  2597. )
  2598. # After
  2599. projects = pagure.lib.query.search_projects(self.session)
  2600. self.assertEqual(len(projects), 0)
  2601. if __name__ == "__main__":
  2602. unittest.main(verbosity=2)