1
0

test_pagure_flask_api_user.py 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944
  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 os
  10. import shutil
  11. import sys
  12. import unittest
  13. import json
  14. from mock import patch
  15. sys.path.insert(
  16. 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
  17. )
  18. import pagure.api
  19. import pagure.config
  20. import pagure.lib.model as model
  21. import pagure.lib.query
  22. import tests
  23. import zoneinfo
  24. class PagureFlaskApiUSertests(tests.Modeltests):
  25. """Tests for the flask API of pagure for issue"""
  26. maxDiff = None
  27. def setUp(self):
  28. """Set up the environnment, ran before every tests."""
  29. super(PagureFlaskApiUSertests, self).setUp()
  30. pagure.config.config["REQUESTS_FOLDER"] = None
  31. def test_api_users(self):
  32. """Test the api_users function."""
  33. output = self.app.get("/api/0/users")
  34. self.assertEqual(output.status_code, 200)
  35. data = json.loads(output.get_data(as_text=True))
  36. self.assertEqual(sorted(data["users"]), ["foo", "pingou"])
  37. self.assertEqual(
  38. sorted(data.keys()), ["mention", "total_users", "users"]
  39. )
  40. self.assertEqual(data["total_users"], 2)
  41. output = self.app.get("/api/0/users?pattern=p")
  42. self.assertEqual(output.status_code, 200)
  43. data = json.loads(output.get_data(as_text=True))
  44. self.assertEqual(data["users"], ["pingou"])
  45. self.assertEqual(
  46. sorted(data.keys()), ["mention", "total_users", "users"]
  47. )
  48. self.assertEqual(data["total_users"], 1)
  49. def test_api_view_user(self):
  50. """
  51. Test the api_view_user method of the flask api
  52. The tested user has no project or forks.
  53. """
  54. output = self.app.get("/api/0/user/pingou")
  55. self.assertEqual(output.status_code, 200)
  56. exp = {
  57. "forks": [],
  58. "forks_pagination": {
  59. "first": "http://localhost...",
  60. "last": "http://localhost...",
  61. "next": None,
  62. "forkpage": 1,
  63. "pages": 0,
  64. "per_page": 20,
  65. "prev": None,
  66. },
  67. "repos": [],
  68. "repos_pagination": {
  69. "first": "http://localhost...",
  70. "last": "http://localhost...",
  71. "next": None,
  72. "repopage": 1,
  73. "pages": 0,
  74. "per_page": 20,
  75. "prev": None,
  76. },
  77. "user": {
  78. "fullname": "PY C",
  79. "name": "pingou",
  80. "url_path": "user/pingou",
  81. "full_url": "http://localhost.localdomain/user/pingou",
  82. "avatar_url": "https://seccdn.libravatar.org/avatar/...",
  83. },
  84. }
  85. data = json.loads(output.get_data(as_text=True))
  86. data["user"]["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
  87. for k in ["forks_pagination", "repos_pagination"]:
  88. for k2 in ["first", "last"]:
  89. self.assertIsNotNone(data[k][k2])
  90. data[k][k2] = "http://localhost..."
  91. self.assertEqual(data, exp)
  92. def test_api_view_user_with_project(self):
  93. """
  94. Test the api_view_user method of the flask api,
  95. this time the user has some project defined.
  96. """
  97. tests.create_projects(self.session)
  98. output = self.app.get("/api/0/user/pingou")
  99. self.assertEqual(output.status_code, 200)
  100. data = json.loads(output.get_data(as_text=True))
  101. data["repos"][0]["date_created"] = "1490272832"
  102. data["repos"][0]["date_modified"] = "1490272832"
  103. data["repos"][1]["date_created"] = "1490272832"
  104. data["repos"][1]["date_modified"] = "1490272832"
  105. data["repos"][2]["date_created"] = "1490272832"
  106. data["repos"][2]["date_modified"] = "1490272832"
  107. for k in ["forks_pagination", "repos_pagination"]:
  108. for k2 in ["first", "last"]:
  109. self.assertIsNotNone(data[k][k2])
  110. data[k][k2] = "http://localhost..."
  111. expected_data = {
  112. "forks": [],
  113. "forks_pagination": {
  114. "first": "http://localhost...",
  115. "last": "http://localhost...",
  116. "next": None,
  117. "forkpage": 1,
  118. "pages": 0,
  119. "per_page": 20,
  120. "prev": None,
  121. },
  122. "repos": [
  123. {
  124. "access_groups": {
  125. "admin": [],
  126. "collaborator": [],
  127. "commit": [],
  128. "ticket": [],
  129. },
  130. "access_users": {
  131. "admin": [],
  132. "collaborator": [],
  133. "commit": [],
  134. "owner": ["pingou"],
  135. "ticket": [],
  136. },
  137. "close_status": [
  138. "Invalid",
  139. "Insufficient data",
  140. "Fixed",
  141. "Duplicate",
  142. ],
  143. "custom_keys": [],
  144. "date_created": "1490272832",
  145. "date_modified": "1490272832",
  146. "description": "test project #1",
  147. "fullname": "test",
  148. "url_path": "test",
  149. "full_url": "http://localhost.localdomain/test",
  150. "id": 1,
  151. "milestones": {},
  152. "name": "test",
  153. "namespace": None,
  154. "parent": None,
  155. "priorities": {},
  156. "tags": [],
  157. "user": {
  158. "fullname": "PY C",
  159. "name": "pingou",
  160. "url_path": "user/pingou",
  161. "full_url": "http://localhost.localdomain/user/pingou",
  162. },
  163. },
  164. {
  165. "access_groups": {
  166. "admin": [],
  167. "collaborator": [],
  168. "commit": [],
  169. "ticket": [],
  170. },
  171. "access_users": {
  172. "admin": [],
  173. "collaborator": [],
  174. "commit": [],
  175. "owner": ["pingou"],
  176. "ticket": [],
  177. },
  178. "close_status": [
  179. "Invalid",
  180. "Insufficient data",
  181. "Fixed",
  182. "Duplicate",
  183. ],
  184. "custom_keys": [],
  185. "date_created": "1490272832",
  186. "date_modified": "1490272832",
  187. "description": "test project #2",
  188. "full_url": "http://localhost.localdomain/test2",
  189. "fullname": "test2",
  190. "url_path": "test2",
  191. "id": 2,
  192. "milestones": {},
  193. "name": "test2",
  194. "namespace": None,
  195. "parent": None,
  196. "priorities": {},
  197. "tags": [],
  198. "user": {
  199. "fullname": "PY C",
  200. "name": "pingou",
  201. "url_path": "user/pingou",
  202. "full_url": "http://localhost.localdomain/user/pingou",
  203. },
  204. },
  205. {
  206. "access_groups": {
  207. "admin": [],
  208. "collaborator": [],
  209. "commit": [],
  210. "ticket": [],
  211. },
  212. "access_users": {
  213. "admin": [],
  214. "collaborator": [],
  215. "commit": [],
  216. "owner": ["pingou"],
  217. "ticket": [],
  218. },
  219. "close_status": [
  220. "Invalid",
  221. "Insufficient data",
  222. "Fixed",
  223. "Duplicate",
  224. ],
  225. "custom_keys": [],
  226. "date_created": "1490272832",
  227. "date_modified": "1490272832",
  228. "description": "namespaced test project",
  229. "fullname": "somenamespace/test3",
  230. "url_path": "somenamespace/test3",
  231. "full_url": "http://localhost.localdomain/somenamespace/test3",
  232. "id": 3,
  233. "milestones": {},
  234. "name": "test3",
  235. "namespace": "somenamespace",
  236. "parent": None,
  237. "priorities": {},
  238. "tags": [],
  239. "user": {
  240. "fullname": "PY C",
  241. "full_url": "http://localhost.localdomain/user/pingou",
  242. "name": "pingou",
  243. "url_path": "user/pingou",
  244. },
  245. },
  246. ],
  247. "repos_pagination": {
  248. "first": "http://localhost...",
  249. "last": "http://localhost...",
  250. "next": None,
  251. "repopage": 1,
  252. "pages": 1,
  253. "per_page": 20,
  254. "prev": None,
  255. },
  256. "user": {
  257. "fullname": "PY C",
  258. "name": "pingou",
  259. "url_path": "user/pingou",
  260. "full_url": "http://localhost.localdomain/user/pingou",
  261. "avatar_url": "https://seccdn.libravatar.org/avatar/...",
  262. },
  263. }
  264. data["user"]["avatar_url"] = "https://seccdn.libravatar.org/avatar/..."
  265. self.assertEqual(data, expected_data)
  266. @patch("pagure.lib.notify.send_email")
  267. def test_api_view_user_activity_stats(self, mockemail):
  268. """Test the api_view_user_activity_stats method of the flask user
  269. api."""
  270. mockemail.return_value = True
  271. tests.create_projects(self.session)
  272. tests.create_tokens(self.session)
  273. tests.create_tokens_acl(self.session)
  274. headers = {"Authorization": "token aaabbbcccddd"}
  275. # Create a pull-request
  276. repo = pagure.lib.query._get_project(self.session, "test")
  277. forked_repo = pagure.lib.query._get_project(self.session, "test")
  278. req = pagure.lib.query.new_pull_request(
  279. session=self.session,
  280. repo_from=forked_repo,
  281. branch_from="master",
  282. repo_to=repo,
  283. branch_to="master",
  284. title="test pull-request",
  285. user="pingou",
  286. )
  287. self.session.commit()
  288. self.assertEqual(req.id, 1)
  289. self.assertEqual(req.title, "test pull-request")
  290. # Check comments before
  291. self.session.commit()
  292. request = pagure.lib.query.search_pull_requests(
  293. self.session, project_id=1, requestid=1
  294. )
  295. self.assertEqual(len(request.comments), 0)
  296. data = {"comment": "This is a very interesting question"}
  297. # Valid request
  298. output = self.app.post(
  299. "/api/0/test/pull-request/1/comment", data=data, headers=headers
  300. )
  301. self.assertEqual(output.status_code, 200)
  302. data = json.loads(output.get_data(as_text=True))
  303. self.assertDictEqual(data, {"message": "Comment added"})
  304. # One comment added
  305. self.session.commit()
  306. request = pagure.lib.query.search_pull_requests(
  307. self.session, project_id=1, requestid=1
  308. )
  309. self.assertEqual(len(request.comments), 1)
  310. # Close PR
  311. output = self.app.post(
  312. "/api/0/test/pull-request/1/close", headers=headers
  313. )
  314. self.assertEqual(output.status_code, 200)
  315. data = json.loads(output.get_data(as_text=True))
  316. self.assertDictEqual(data, {"message": "Pull-request closed!"})
  317. # PR closed
  318. self.session.commit()
  319. request = pagure.lib.query.search_pull_requests(
  320. self.session, project_id=1, requestid=1
  321. )
  322. self.assertEqual(request.status, "Closed")
  323. # Finally retrieve the user's logs
  324. output = self.app.get("/api/0/user/pingou/activity/stats")
  325. self.assertEqual(output.status_code, 200)
  326. data = json.loads(output.get_data(as_text=True))
  327. date = datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
  328. self.assertDictEqual(data, {date: 4})
  329. @patch("pagure.lib.notify.send_email")
  330. def test_api_view_user_activity_date(self, mockemail):
  331. """Test the api_view_user_activity_date method of the flask user
  332. api."""
  333. self.test_api_view_user_activity_stats()
  334. # Invalid date
  335. output = self.app.get("/api/0/user/pingou/activity/AABB")
  336. self.assertEqual(output.status_code, 400)
  337. # Invalid date, arrow >= 0.15 throws an exception,
  338. # previous versions parsed it
  339. output = self.app.get("/api/0/user/pingou/activity/2016asd")
  340. arrow_version = self.get_arrow_version()
  341. if arrow_version >= (1, 0, 0):
  342. self.assertEqual(output.status_code, 400)
  343. exp = {
  344. "error": "Could not match input '2016asd' to any of the following formats: "
  345. "YYYY-MM-DD, YYYY-M-DD, YYYY-M-D, YYYY/MM/DD, YYYY/M/DD, YYYY/M/D, "
  346. "YYYY.MM.DD, YYYY.M.DD, YYYY.M.D, YYYYMMDD, YYYY-DDDD, YYYYDDDD, "
  347. "YYYY-MM, YYYY/MM, YYYY.MM, YYYY, W.",
  348. "error_code": "ENOCODE",
  349. }
  350. self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
  351. elif arrow_version >= (0, 15):
  352. self.assertEqual(output.status_code, 400)
  353. exp = {
  354. "error": "Could not match input '2016asd' to any of the following formats: "
  355. "YYYY-MM-DD, YYYY-M-DD, YYYY-M-D, YYYY/MM/DD, YYYY/M/DD, YYYY/M/D, "
  356. "YYYY.MM.DD, YYYY.M.DD, YYYY.M.D, YYYYMMDD, YYYY-DDDD, YYYYDDDD, "
  357. "YYYY-MM, YYYY/MM, YYYY.MM, YYYY, W",
  358. "error_code": "ENOCODE",
  359. }
  360. self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
  361. else:
  362. self.assertEqual(output.status_code, 200)
  363. exp = {"activities": [], "date": "2016-01-01"}
  364. self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
  365. # Invalid date, arrow => throws an exception,
  366. # previous versions parsed it just not really as expected
  367. output = self.app.get("/api/0/user/pingou/activity/20161245")
  368. if self.get_arrow_version() >= (0, 15):
  369. self.assertEqual(output.status_code, 400)
  370. exp = {
  371. "error": "day is out of range for month",
  372. "error_code": "ENOCODE",
  373. }
  374. self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
  375. else:
  376. self.assertEqual(output.status_code, 200)
  377. exp = {"activities": [], "date": "1970-08-22"}
  378. self.assertEqual(json.loads(output.get_data(as_text=True)), exp)
  379. date = datetime.datetime.utcnow().date().strftime("%Y-%m-%d")
  380. # Retrieve the user's logs for today
  381. output = self.app.get("/api/0/user/pingou/activity/%s" % date)
  382. self.assertEqual(output.status_code, 200)
  383. data = json.loads(output.get_data(as_text=True))
  384. exp = {
  385. "activities": [
  386. {
  387. "date": date,
  388. "date_created": "1477558752",
  389. "type": "pull-request",
  390. "description_mk": '<div class="markdown"><p>pingou created PR <a href="/test/pull-request/1" title="[Closed] test pull-request">test#1</a></p></div>',
  391. "id": 1,
  392. "ref_id": "1",
  393. "type": "created",
  394. "user": {
  395. "fullname": "PY C",
  396. "full_url": "http://localhost.localdomain/user/pingou",
  397. "name": "pingou",
  398. "url_path": "user/pingou",
  399. },
  400. },
  401. {
  402. "date": date,
  403. "date_created": "1477558752",
  404. "type": "pull-request",
  405. "description_mk": '<div class="markdown"><p>pingou commented on PR <a href="/test/pull-request/1" title="[Closed] test pull-request">test#1</a></p></div>',
  406. "id": 2,
  407. "ref_id": "1",
  408. "type": "commented",
  409. "user": {
  410. "fullname": "PY C",
  411. "full_url": "http://localhost.localdomain/user/pingou",
  412. "name": "pingou",
  413. "url_path": "user/pingou",
  414. },
  415. },
  416. {
  417. "date": date,
  418. "date_created": "1477558752",
  419. "type": "pull-request",
  420. "description_mk": '<div class="markdown"><p>pingou closed PR <a href="/test/pull-request/1" title="[Closed] test pull-request">test#1</a></p></div>',
  421. "id": 3,
  422. "ref_id": "1",
  423. "type": "closed",
  424. "user": {
  425. "fullname": "PY C",
  426. "full_url": "http://localhost.localdomain/user/pingou",
  427. "name": "pingou",
  428. "url_path": "user/pingou",
  429. },
  430. },
  431. {
  432. "date": date,
  433. "date_created": "1477558752",
  434. "type": "pull-request",
  435. "description_mk": '<div class="markdown"><p>pingou commented on PR <a href="/test/pull-request/1" title="[Closed] test pull-request">test#1</a></p></div>',
  436. "id": 4,
  437. "ref_id": "1",
  438. "type": "commented",
  439. "user": {
  440. "fullname": "PY C",
  441. "full_url": "http://localhost.localdomain/user/pingou",
  442. "name": "pingou",
  443. "url_path": "user/pingou",
  444. },
  445. },
  446. ],
  447. "date": date,
  448. }
  449. for idx, act in enumerate(data["activities"]):
  450. act["date_created"] = "1477558752"
  451. data["activities"][idx] = act
  452. self.assertEqual(data, exp)
  453. @patch("pagure.lib.notify.send_email")
  454. def test_api_view_user_activity_date_1_activity(self, mockemail):
  455. """Test the api_view_user_activity_date method of the flask user
  456. api when the user only did one action."""
  457. tests.create_projects(self.session)
  458. repo = pagure.lib.query._get_project(self.session, "test")
  459. now = datetime.datetime.utcnow()
  460. date = now.date().strftime("%Y-%m-%d")
  461. # Create a single commit log
  462. log = model.PagureLog(
  463. user_id=1,
  464. user_email="foo@bar.com",
  465. project_id=1,
  466. log_type="committed",
  467. ref_id="githash",
  468. date=now.date(),
  469. date_created=now,
  470. )
  471. self.session.add(log)
  472. self.session.commit()
  473. # Retrieve the user's logs for today
  474. output = self.app.get(
  475. "/api/0/user/pingou/activity/%s?grouped=1" % date
  476. )
  477. self.assertEqual(output.status_code, 200)
  478. data = json.loads(output.get_data(as_text=True))
  479. exp = {
  480. "activities": [
  481. {
  482. "description_mk": '<div class="markdown"><p>pingou committed on test#githash</p></div>'
  483. }
  484. ],
  485. "date": date,
  486. }
  487. self.assertEqual(data, exp)
  488. @patch("pagure.lib.notify.send_email")
  489. def test_api_view_user_activity_timezone_negative(self, mockemail):
  490. """Test api_view_user_activity{_stats,_date} with the America/
  491. New York timezone, which is 5 hours behind UTC in winter and
  492. 4 hours behind UTC in summer (daylight savings). The events
  493. will occur on XXXX-02-15 in UTC, but on XXXX-02-14 local.
  494. """
  495. tests.create_projects(self.session)
  496. today = datetime.datetime.utcnow()
  497. # stats/activty returns data for now()-1year time range, so alter
  498. # year as needed to select 15th feb of current or previous year
  499. if today < datetime.datetime(today.year, 2, 15, 3, 30):
  500. year = today.year - 1
  501. else:
  502. year = today.year
  503. dateobj = datetime.datetime(year, 2, 15, 3, 30)
  504. utcdate = "%s-02-15" % year
  505. # the Unix timestamp for YYYY-02-15 12:00 UTC
  506. utcts = str(
  507. int(
  508. (
  509. datetime.datetime(
  510. year, 2, 15, 12, 0, tzinfo=datetime.timezone.utc
  511. )
  512. - datetime.datetime(
  513. 1970, 1, 1, tzinfo=datetime.timezone.utc
  514. )
  515. ).total_seconds()
  516. )
  517. )
  518. localdate = "%s-02-14" % year
  519. # the Unix timestamp for YYYY-02-15 18:00 America/New_York
  520. localts = str(
  521. int(
  522. (
  523. datetime.datetime(
  524. year,
  525. 2,
  526. 14,
  527. 17,
  528. 0,
  529. tzinfo=zoneinfo.ZoneInfo("America/New_York"),
  530. )
  531. - datetime.datetime(
  532. 1970,
  533. 1,
  534. 1,
  535. tzinfo=zoneinfo.ZoneInfo("America/New_York"),
  536. )
  537. ).total_seconds()
  538. )
  539. )
  540. # Create a single commit log
  541. log = model.PagureLog(
  542. user_id=1,
  543. user_email="foo@bar.com",
  544. project_id=1,
  545. log_type="committed",
  546. ref_id="githash",
  547. date=dateobj.date(),
  548. date_created=dateobj,
  549. )
  550. self.session.add(log)
  551. self.session.commit()
  552. # Retrieve the user's stats with no timezone specified (==UTC)
  553. output = self.app.get("/api/0/user/pingou/activity/stats")
  554. self.assertEqual(output.status_code, 200)
  555. data = json.loads(output.get_data(as_text=True))
  556. # date in output should be UTC date
  557. self.assertDictEqual(data, {utcdate: 1})
  558. # Now in timestamp format...
  559. output = self.app.get(
  560. "/api/0/user/pingou/activity/stats?format=timestamp"
  561. )
  562. self.assertEqual(output.status_code, 200)
  563. data = json.loads(output.get_data(as_text=True))
  564. # timestamp in output should be UTC ts
  565. self.assertDictEqual(data, {utcts: 1})
  566. # Retrieve the user's stats with local timezone specified
  567. output = self.app.get(
  568. "/api/0/user/pingou/activity/stats?tz=America/New_York"
  569. )
  570. self.assertEqual(output.status_code, 200)
  571. data = json.loads(output.get_data(as_text=True))
  572. # date in output should be local date
  573. self.assertDictEqual(data, {localdate: 1})
  574. # Now in timestamp format...
  575. output = self.app.get(
  576. "/api/0/user/pingou/activity/stats?format=timestamp&tz=America/New_York"
  577. )
  578. self.assertEqual(output.status_code, 200)
  579. data = json.loads(output.get_data(as_text=True))
  580. # timestamp in output should be local ts
  581. self.assertDictEqual(data, {localts: 1})
  582. # Retrieve the user's logs for 2018-02-15 with no timezone
  583. output = self.app.get(
  584. "/api/0/user/pingou/activity/%s?grouped=1" % utcdate
  585. )
  586. self.assertEqual(output.status_code, 200)
  587. data = json.loads(output.get_data(as_text=True))
  588. exp = {
  589. "activities": [
  590. {
  591. "description_mk": '<div class="markdown"><p>pingou committed on test#githash</p></div>'
  592. }
  593. ],
  594. "date": utcdate,
  595. }
  596. self.assertEqual(data, exp)
  597. # Now retrieve the user's logs for 2018-02-14 with local time
  598. output = self.app.get(
  599. "/api/0/user/pingou/activity/%s?grouped=1&tz=America/New_York"
  600. % localdate
  601. )
  602. self.assertEqual(output.status_code, 200)
  603. data = json.loads(output.get_data(as_text=True))
  604. exp["date"] = localdate
  605. self.assertEqual(data, exp)
  606. @patch("pagure.lib.notify.send_email")
  607. def test_api_view_user_activity_timezone_positive(self, mockemail):
  608. """Test api_view_user_activity{_stats,_date} with the Asia/
  609. Dubai timezone, which is 4 hours ahead of UTC. The events will
  610. occur on XXXX-02-15 in UTC, but on XXXX-02-16 in local time.
  611. """
  612. tests.create_projects(self.session)
  613. today = datetime.datetime.utcnow()
  614. # stats/activty returns data for now()-1year time range, so alter
  615. # year as needed to select 15th feb of current or previous year
  616. if today < datetime.datetime(today.year, 2, 15, 3, 30):
  617. year = today.year - 1
  618. else:
  619. year = today.year
  620. dateobj = datetime.datetime(year, 2, 15, 22, 30)
  621. utcdate = "%s-02-15" % year
  622. # the Unix timestamp for YYYY-02-15 12:00 UTC
  623. utcts = str(
  624. int(
  625. (
  626. datetime.datetime(
  627. year, 2, 15, 12, 0, tzinfo=datetime.timezone.utc
  628. )
  629. - datetime.datetime(
  630. 1970, 1, 1, tzinfo=datetime.timezone.utc
  631. )
  632. ).total_seconds()
  633. )
  634. )
  635. localdate = "%s-02-16" % year
  636. # the Unix timestamp for YYYY-02-16 9:00 Asia/Dubai
  637. localts = str(
  638. int(
  639. (
  640. datetime.datetime(
  641. year,
  642. 2,
  643. 16,
  644. 8,
  645. 0,
  646. tzinfo=zoneinfo.ZoneInfo("Asia/Dubai"),
  647. )
  648. - datetime.datetime(
  649. 1970, 1, 1, tzinfo=zoneinfo.ZoneInfo("Asia/Dubai")
  650. )
  651. ).total_seconds()
  652. )
  653. )
  654. # Create a single commit log
  655. log = model.PagureLog(
  656. user_id=1,
  657. user_email="foo@bar.com",
  658. project_id=1,
  659. log_type="committed",
  660. ref_id="githash",
  661. date=dateobj.date(),
  662. date_created=dateobj,
  663. )
  664. self.session.add(log)
  665. self.session.commit()
  666. # Retrieve the user's stats with no timezone specified (==UTC)
  667. output = self.app.get("/api/0/user/pingou/activity/stats")
  668. self.assertEqual(output.status_code, 200)
  669. data = json.loads(output.get_data(as_text=True))
  670. # date in output should be UTC date
  671. self.assertDictEqual(data, {utcdate: 1})
  672. # Now in timestamp format...
  673. output = self.app.get(
  674. "/api/0/user/pingou/activity/stats?format=timestamp"
  675. )
  676. self.assertEqual(output.status_code, 200)
  677. data = json.loads(output.get_data(as_text=True))
  678. # timestamp in output should be UTC ts
  679. self.assertDictEqual(data, {utcts: 1})
  680. # Retrieve the user's stats with local timezone specified
  681. output = self.app.get(
  682. "/api/0/user/pingou/activity/stats?tz=Asia/Dubai"
  683. )
  684. self.assertEqual(output.status_code, 200)
  685. data = json.loads(output.get_data(as_text=True))
  686. # date in output should be local date
  687. self.assertDictEqual(data, {localdate: 1})
  688. # Now in timestamp format...
  689. output = self.app.get(
  690. "/api/0/user/pingou/activity/stats?format=timestamp&tz=Asia/Dubai"
  691. )
  692. self.assertEqual(output.status_code, 200)
  693. data = json.loads(output.get_data(as_text=True))
  694. # timestamp in output should be local ts
  695. self.assertDictEqual(data, {localts: 1})
  696. # Retrieve the user's logs for 2018-02-15 with no timezone
  697. output = self.app.get(
  698. "/api/0/user/pingou/activity/%s?grouped=1" % utcdate
  699. )
  700. self.assertEqual(output.status_code, 200)
  701. data = json.loads(output.get_data(as_text=True))
  702. exp = {
  703. "activities": [
  704. {
  705. "description_mk": '<div class="markdown"><p>pingou committed on test#githash</p></div>'
  706. }
  707. ],
  708. "date": utcdate,
  709. }
  710. self.assertEqual(data, exp)
  711. # Now retrieve the user's logs for 2018-02-16 with local time
  712. output = self.app.get(
  713. "/api/0/user/pingou/activity/%s?grouped=1&tz=Asia/Dubai"
  714. % localdate
  715. )
  716. self.assertEqual(output.status_code, 200)
  717. data = json.loads(output.get_data(as_text=True))
  718. exp["date"] = localdate
  719. self.assertEqual(data, exp)
  720. class PagureFlaskApiUsertestrequests(tests.Modeltests):
  721. """Tests for the user requests endpoints"""
  722. maxDiff = None
  723. def setUp(self):
  724. """Set up the environnment, ran before every tests."""
  725. super(PagureFlaskApiUsertestrequests, self).setUp()
  726. pagure.config.config["REQUESTS_FOLDER"] = None
  727. tests.create_projects(self.session)
  728. # Create few pull-requests
  729. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  730. forked_repo = pagure.lib.query.get_authorized_project(
  731. self.session, "test"
  732. )
  733. pagure.lib.query.new_pull_request(
  734. session=self.session,
  735. repo_from=forked_repo,
  736. branch_from="master",
  737. repo_to=repo,
  738. branch_to="master",
  739. title="open pullrequest by user foo on repo test",
  740. user="foo",
  741. )
  742. repo = pagure.lib.query.get_authorized_project(self.session, "test2")
  743. forked_repo = pagure.lib.query.get_authorized_project(
  744. self.session, "test2"
  745. )
  746. pagure.lib.query.new_pull_request(
  747. session=self.session,
  748. repo_from=forked_repo,
  749. branch_from="master",
  750. repo_to=repo,
  751. branch_to="master",
  752. title="open pullrequest by user foo on repo test2",
  753. user="foo",
  754. )
  755. self.session.commit()
  756. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  757. forked_repo = pagure.lib.query.get_authorized_project(
  758. self.session, "test"
  759. )
  760. pagure.lib.query.new_pull_request(
  761. session=self.session,
  762. repo_from=forked_repo,
  763. branch_from="master",
  764. repo_to=repo,
  765. branch_to="master",
  766. title="closed pullrequest by user foo on repo test",
  767. user="foo",
  768. status="Closed",
  769. )
  770. repo = pagure.lib.query.get_authorized_project(self.session, "test2")
  771. forked_repo = pagure.lib.query.get_authorized_project(
  772. self.session, "test2"
  773. )
  774. pagure.lib.query.new_pull_request(
  775. session=self.session,
  776. repo_from=forked_repo,
  777. branch_from="master",
  778. repo_to=repo,
  779. branch_to="master",
  780. title="closed pullrequest by user foo on repo test2",
  781. user="foo",
  782. status="Closed",
  783. )
  784. self.session.commit()
  785. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  786. forked_repo = pagure.lib.query.get_authorized_project(
  787. self.session, "test"
  788. )
  789. pagure.lib.query.new_pull_request(
  790. session=self.session,
  791. repo_from=forked_repo,
  792. branch_from="master",
  793. repo_to=repo,
  794. branch_to="master",
  795. title="merged pullrequest by user foo on repo test",
  796. user="foo",
  797. status="Merged",
  798. )
  799. repo = pagure.lib.query.get_authorized_project(self.session, "test2")
  800. forked_repo = pagure.lib.query.get_authorized_project(
  801. self.session, "test2"
  802. )
  803. pagure.lib.query.new_pull_request(
  804. session=self.session,
  805. repo_from=forked_repo,
  806. branch_from="master",
  807. repo_to=repo,
  808. branch_to="master",
  809. title="merged pullrequest by user foo on repo test2",
  810. user="foo",
  811. status="Merged",
  812. )
  813. self.session.commit()
  814. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  815. forked_repo = pagure.lib.query.get_authorized_project(
  816. self.session, "test"
  817. )
  818. pagure.lib.query.new_pull_request(
  819. session=self.session,
  820. repo_from=forked_repo,
  821. branch_from="master",
  822. repo_to=repo,
  823. branch_to="master",
  824. title="open pullrequest by user pingou on repo test",
  825. user="pingou",
  826. )
  827. self.session.commit()
  828. repo = pagure.lib.query.get_authorized_project(self.session, "test2")
  829. forked_repo = pagure.lib.query.get_authorized_project(
  830. self.session, "test2"
  831. )
  832. pagure.lib.query.new_pull_request(
  833. session=self.session,
  834. repo_from=forked_repo,
  835. branch_from="master",
  836. repo_to=repo,
  837. branch_to="master",
  838. title="open pullrequest by user pingou on repo test2",
  839. user="pingou",
  840. )
  841. self.session.commit()
  842. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  843. forked_repo = pagure.lib.query.get_authorized_project(
  844. self.session, "test"
  845. )
  846. pagure.lib.query.new_pull_request(
  847. session=self.session,
  848. repo_from=forked_repo,
  849. branch_from="master",
  850. repo_to=repo,
  851. branch_to="master",
  852. title="closed pullrequest by user pingou on repo test",
  853. user="pingou",
  854. status="Closed",
  855. )
  856. self.session.commit()
  857. repo = pagure.lib.query.get_authorized_project(self.session, "test2")
  858. forked_repo = pagure.lib.query.get_authorized_project(
  859. self.session, "test2"
  860. )
  861. pagure.lib.query.new_pull_request(
  862. session=self.session,
  863. repo_from=forked_repo,
  864. branch_from="master",
  865. repo_to=repo,
  866. branch_to="master",
  867. title="closed pullrequest by user pingou on repo test2",
  868. user="pingou",
  869. status="Closed",
  870. )
  871. self.session.commit()
  872. repo = pagure.lib.query.get_authorized_project(self.session, "test")
  873. forked_repo = pagure.lib.query.get_authorized_project(
  874. self.session, "test"
  875. )
  876. pagure.lib.query.new_pull_request(
  877. session=self.session,
  878. repo_from=forked_repo,
  879. branch_from="master",
  880. repo_to=repo,
  881. branch_to="master",
  882. title="merged pullrequest by user pingou on repo test",
  883. user="pingou",
  884. status="Merged",
  885. )
  886. self.session.commit()
  887. repo = pagure.lib.query.get_authorized_project(self.session, "test2")
  888. forked_repo = pagure.lib.query.get_authorized_project(
  889. self.session, "test2"
  890. )
  891. pagure.lib.query.new_pull_request(
  892. session=self.session,
  893. repo_from=forked_repo,
  894. branch_from="master",
  895. repo_to=repo,
  896. branch_to="master",
  897. title="merged pullrequest by user pingou on repo test2",
  898. user="pingou",
  899. status="Merged",
  900. )
  901. self.session.commit()
  902. @patch("pagure.lib.notify.send_email")
  903. def test_api_view_user_requests_filed(self, mockemail):
  904. """Test the api_view_user_requests_filed method of the flask user
  905. api"""
  906. # First we test without the status parameter. It should default to `open`
  907. output = self.app.get("/api/0/user/pingou/requests/filed")
  908. self.assertEqual(output.status_code, 200)
  909. data = json.loads(output.get_data(as_text=True))
  910. self.assertEqual(len(data["requests"]), 2)
  911. self.assertEqual(
  912. sorted(data.keys()),
  913. ["args", "pagination", "requests", "total_requests"],
  914. )
  915. self.assertEqual(data["requests"][0]["user"]["name"], "pingou")
  916. self.assertEqual(data["requests"][1]["user"]["name"], "pingou")
  917. self.assertEqual(data["requests"][0]["status"], "Open")
  918. self.assertEqual(data["requests"][1]["status"], "Open")
  919. self.assertEqual(
  920. data["requests"][0]["title"],
  921. "open pullrequest by user pingou on repo test2",
  922. )
  923. self.assertEqual(
  924. data["requests"][1]["title"],
  925. "open pullrequest by user pingou on repo test",
  926. )
  927. self.assertEqual(data["args"]["status"], "open")
  928. self.assertEqual(data["args"]["page"], 1)
  929. # Next test with the status parameter set to `open`.
  930. output = self.app.get("/api/0/user/pingou/requests/filed?status=open")
  931. self.assertEqual(output.status_code, 200)
  932. data = json.loads(output.get_data(as_text=True))
  933. self.assertEqual(len(data["requests"]), 2)
  934. self.assertEqual(
  935. sorted(data.keys()),
  936. ["args", "pagination", "requests", "total_requests"],
  937. )
  938. self.assertEqual(data["requests"][0]["user"]["name"], "pingou")
  939. self.assertEqual(data["requests"][1]["user"]["name"], "pingou")
  940. self.assertEqual(data["requests"][0]["status"], "Open")
  941. self.assertEqual(data["requests"][1]["status"], "Open")
  942. self.assertEqual(
  943. data["requests"][0]["title"],
  944. "open pullrequest by user pingou on repo test2",
  945. )
  946. self.assertEqual(
  947. data["requests"][1]["title"],
  948. "open pullrequest by user pingou on repo test",
  949. )
  950. self.assertEqual(data["args"]["status"], "open")
  951. self.assertEqual(data["args"]["page"], 1)
  952. # Next test with the status parameter set to `closed`.
  953. output = self.app.get(
  954. "/api/0/user/pingou/requests/filed?status=closed"
  955. )
  956. self.assertEqual(output.status_code, 200)
  957. data = json.loads(output.get_data(as_text=True))
  958. self.assertEqual(len(data["requests"]), 2)
  959. self.assertEqual(
  960. sorted(data.keys()),
  961. ["args", "pagination", "requests", "total_requests"],
  962. )
  963. self.assertEqual(data["requests"][0]["user"]["name"], "pingou")
  964. self.assertEqual(data["requests"][1]["user"]["name"], "pingou")
  965. self.assertEqual(data["requests"][0]["status"], "Closed")
  966. self.assertEqual(data["requests"][1]["status"], "Closed")
  967. self.assertEqual(
  968. data["requests"][0]["title"],
  969. "closed pullrequest by user pingou on repo test2",
  970. )
  971. self.assertEqual(
  972. data["requests"][1]["title"],
  973. "closed pullrequest by user pingou on repo test",
  974. )
  975. self.assertEqual(data["args"]["status"], "closed")
  976. self.assertEqual(data["args"]["page"], 1)
  977. # Next test with the status parameter set to `merged`.
  978. output = self.app.get(
  979. "/api/0/user/pingou/requests/filed?status=merged"
  980. )
  981. self.assertEqual(output.status_code, 200)
  982. data = json.loads(output.get_data(as_text=True))
  983. self.assertEqual(len(data["requests"]), 2)
  984. self.assertEqual(
  985. sorted(data.keys()),
  986. ["args", "pagination", "requests", "total_requests"],
  987. )
  988. self.assertEqual(data["requests"][0]["user"]["name"], "pingou")
  989. self.assertEqual(data["requests"][1]["user"]["name"], "pingou")
  990. self.assertEqual(data["requests"][0]["status"], "Merged")
  991. self.assertEqual(data["requests"][1]["status"], "Merged")
  992. self.assertEqual(
  993. data["requests"][0]["title"],
  994. "merged pullrequest by user pingou on repo test2",
  995. )
  996. self.assertEqual(
  997. data["requests"][1]["title"],
  998. "merged pullrequest by user pingou on repo test",
  999. )
  1000. self.assertEqual(data["args"]["status"], "merged")
  1001. self.assertEqual(data["args"]["page"], 1)
  1002. # Finally, test with the status parameter set to `all`.
  1003. output = self.app.get("/api/0/user/pingou/requests/filed?status=all")
  1004. self.assertEqual(output.status_code, 200)
  1005. data = json.loads(output.get_data(as_text=True))
  1006. self.assertEqual(len(data["requests"]), 6)
  1007. self.assertEqual(
  1008. sorted(data.keys()),
  1009. ["args", "pagination", "requests", "total_requests"],
  1010. )
  1011. self.assertEqual(data["requests"][0]["user"]["name"], "pingou")
  1012. self.assertEqual(data["requests"][1]["user"]["name"], "pingou")
  1013. self.assertEqual(data["requests"][2]["user"]["name"], "pingou")
  1014. self.assertEqual(data["requests"][3]["user"]["name"], "pingou")
  1015. self.assertEqual(data["requests"][4]["user"]["name"], "pingou")
  1016. self.assertEqual(data["requests"][5]["user"]["name"], "pingou")
  1017. self.assertEqual(data["requests"][0]["status"], "Merged")
  1018. self.assertEqual(data["requests"][1]["status"], "Merged")
  1019. self.assertEqual(data["requests"][2]["status"], "Closed")
  1020. self.assertEqual(data["requests"][3]["status"], "Closed")
  1021. self.assertEqual(data["requests"][4]["status"], "Open")
  1022. self.assertEqual(data["requests"][5]["status"], "Open")
  1023. self.assertEqual(
  1024. data["requests"][0]["title"],
  1025. "merged pullrequest by user pingou on repo test2",
  1026. )
  1027. self.assertEqual(
  1028. data["requests"][1]["title"],
  1029. "merged pullrequest by user pingou on repo test",
  1030. )
  1031. self.assertEqual(
  1032. data["requests"][2]["title"],
  1033. "closed pullrequest by user pingou on repo test2",
  1034. )
  1035. self.assertEqual(
  1036. data["requests"][3]["title"],
  1037. "closed pullrequest by user pingou on repo test",
  1038. )
  1039. self.assertEqual(
  1040. data["requests"][4]["title"],
  1041. "open pullrequest by user pingou on repo test2",
  1042. )
  1043. self.assertEqual(
  1044. data["requests"][5]["title"],
  1045. "open pullrequest by user pingou on repo test",
  1046. )
  1047. self.assertEqual(data["args"]["status"], "all")
  1048. self.assertEqual(data["args"]["page"], 1)
  1049. # Test page 2 with the status parameter set to `all`.
  1050. output = self.app.get(
  1051. "/api/0/user/pingou/requests/filed?status=all&page=2"
  1052. )
  1053. self.assertEqual(output.status_code, 200)
  1054. data = json.loads(output.get_data(as_text=True))
  1055. self.assertEqual(len(data["requests"]), 0)
  1056. self.assertEqual(
  1057. sorted(data.keys()),
  1058. ["args", "pagination", "requests", "total_requests"],
  1059. )
  1060. self.assertEqual(data["args"]["page"], 2)
  1061. @patch("pagure.lib.notify.send_email")
  1062. def test_api_view_user_requests_filed_created(self, mockemail):
  1063. """Test the api_view_user_requests_filed method of the flask user
  1064. api with the created parameter"""
  1065. today = datetime.datetime.utcnow().date()
  1066. output = self.app.get(
  1067. "/api/0/user/pingou/requests/filed?status=all&created=%s"
  1068. % (today.isoformat())
  1069. )
  1070. self.assertEqual(output.status_code, 200)
  1071. data = json.loads(output.get_data(as_text=True))
  1072. self.assertEqual(len(data["requests"]), 6)
  1073. yesterday = today - datetime.timedelta(days=1)
  1074. output = self.app.get(
  1075. "/api/0/user/pingou/requests/filed?status=all&created=%s"
  1076. % (yesterday.isoformat())
  1077. )
  1078. self.assertEqual(output.status_code, 200)
  1079. data = json.loads(output.get_data(as_text=True))
  1080. self.assertEqual(len(data["requests"]), 6)
  1081. tomorrow = today + datetime.timedelta(days=1)
  1082. output = self.app.get(
  1083. "/api/0/user/pingou/requests/filed?status=all&created=%s"
  1084. % (tomorrow.isoformat())
  1085. )
  1086. self.assertEqual(output.status_code, 200)
  1087. data = json.loads(output.get_data(as_text=True))
  1088. self.assertEqual(len(data["requests"]), 0)
  1089. output = self.app.get(
  1090. "/api/0/user/pingou/requests/filed?status=all&created=..%s"
  1091. % (today.isoformat())
  1092. )
  1093. self.assertEqual(output.status_code, 200)
  1094. data = json.loads(output.get_data(as_text=True))
  1095. self.assertEqual(len(data["requests"]), 0)
  1096. output = self.app.get(
  1097. "/api/0/user/pingou/requests/filed?status=all&created=..%s"
  1098. % (yesterday.isoformat())
  1099. )
  1100. self.assertEqual(output.status_code, 200)
  1101. data = json.loads(output.get_data(as_text=True))
  1102. self.assertEqual(len(data["requests"]), 0)
  1103. thedaybefore = today - datetime.timedelta(days=1)
  1104. output = self.app.get(
  1105. "/api/0/user/pingou/requests/filed?status=all&created=..%s"
  1106. % (thedaybefore.isoformat())
  1107. )
  1108. self.assertEqual(output.status_code, 200)
  1109. data = json.loads(output.get_data(as_text=True))
  1110. self.assertEqual(len(data["requests"]), 0)
  1111. output = self.app.get(
  1112. "/api/0/user/pingou/requests/filed?status=all&created=..%s"
  1113. % (tomorrow.isoformat())
  1114. )
  1115. self.assertEqual(output.status_code, 200)
  1116. data = json.loads(output.get_data(as_text=True))
  1117. self.assertEqual(len(data["requests"]), 6)
  1118. output = self.app.get(
  1119. "/api/0/user/pingou/requests/filed?status=all&created=%s..%s"
  1120. % (thedaybefore.isoformat(), tomorrow.isoformat())
  1121. )
  1122. self.assertEqual(output.status_code, 200)
  1123. data = json.loads(output.get_data(as_text=True))
  1124. self.assertEqual(len(data["requests"]), 6)
  1125. @patch("pagure.lib.notify.send_email")
  1126. def test_api_view_user_requests_filed_updated(self, mockemail):
  1127. """Test the api_view_user_requests_filed method of the flask user
  1128. api with the created parameter"""
  1129. today = datetime.datetime.utcnow().date()
  1130. output = self.app.get(
  1131. "/api/0/user/pingou/requests/filed?status=all&updated=%s"
  1132. % (today.isoformat())
  1133. )
  1134. self.assertEqual(output.status_code, 200)
  1135. data = json.loads(output.get_data(as_text=True))
  1136. self.assertEqual(len(data["requests"]), 6)
  1137. yesterday = today - datetime.timedelta(days=1)
  1138. output = self.app.get(
  1139. "/api/0/user/pingou/requests/filed?status=all&updated=%s"
  1140. % (yesterday.isoformat())
  1141. )
  1142. self.assertEqual(output.status_code, 200)
  1143. data = json.loads(output.get_data(as_text=True))
  1144. self.assertEqual(len(data["requests"]), 6)
  1145. tomorrow = today + datetime.timedelta(days=1)
  1146. output = self.app.get(
  1147. "/api/0/user/pingou/requests/filed?status=all&updated=%s"
  1148. % (tomorrow.isoformat())
  1149. )
  1150. self.assertEqual(output.status_code, 200)
  1151. data = json.loads(output.get_data(as_text=True))
  1152. self.assertEqual(len(data["requests"]), 0)
  1153. @patch("pagure.lib.notify.send_email")
  1154. def test_api_view_user_requests_filed_closed(self, mockemail):
  1155. """Test the api_view_user_requests_filed method of the flask user
  1156. api with the created parameter"""
  1157. today = datetime.datetime.utcnow().date()
  1158. output = self.app.get(
  1159. "/api/0/user/pingou/requests/filed?status=all&closed=%s"
  1160. % (today.isoformat())
  1161. )
  1162. self.assertEqual(output.status_code, 200)
  1163. data = json.loads(output.get_data(as_text=True))
  1164. self.assertEqual(len(data["requests"]), 0)
  1165. yesterday = today - datetime.timedelta(days=1)
  1166. output = self.app.get(
  1167. "/api/0/user/pingou/requests/filed?status=all&closed=%s"
  1168. % (yesterday.isoformat())
  1169. )
  1170. self.assertEqual(output.status_code, 200)
  1171. data = json.loads(output.get_data(as_text=True))
  1172. self.assertEqual(len(data["requests"]), 0)
  1173. tomorrow = today + datetime.timedelta(days=1)
  1174. output = self.app.get(
  1175. "/api/0/user/pingou/requests/filed?status=all&closed=%s"
  1176. % (tomorrow.isoformat())
  1177. )
  1178. self.assertEqual(output.status_code, 200)
  1179. data = json.loads(output.get_data(as_text=True))
  1180. self.assertEqual(len(data["requests"]), 0)
  1181. @patch("pagure.lib.notify.send_email")
  1182. def test_api_view_user_requests_filed_foo(self, mockemail):
  1183. """Test the api_view_user_requests_filed method of the flask user
  1184. api"""
  1185. # Default data returned
  1186. output = self.app.get(
  1187. "/api/0/user/foo/requests/filed?status=all&per_page=6"
  1188. )
  1189. self.assertEqual(output.status_code, 200)
  1190. data = json.loads(output.get_data(as_text=True))
  1191. self.assertEqual(len(data["requests"]), 6)
  1192. self.assertEqual(
  1193. sorted(data.keys()),
  1194. ["args", "pagination", "requests", "total_requests"],
  1195. )
  1196. # There are 6 PRs, that's 1 page at 6 results per page
  1197. self.assertEqual(data["pagination"]["pages"], 1)
  1198. @patch("pagure.lib.notify.send_email")
  1199. def test_api_view_user_requests_filed_foo_grp_access(self, mockemail):
  1200. """Test when the user has accessed to some PRs via a group."""
  1201. # Add the user to a group
  1202. msg = pagure.lib.query.add_group(
  1203. self.session,
  1204. group_name="some_group",
  1205. display_name="Some Group",
  1206. description=None,
  1207. group_type="bar",
  1208. user="pingou",
  1209. is_admin=False,
  1210. blacklist=[],
  1211. )
  1212. self.session.commit()
  1213. # Add the group to the project `test2`
  1214. project = pagure.lib.query._get_project(self.session, "test2")
  1215. msg = pagure.lib.query.add_group_to_project(
  1216. session=self.session,
  1217. project=project,
  1218. new_group="some_group",
  1219. user="pingou",
  1220. )
  1221. self.session.commit()
  1222. self.assertEqual(msg, "Group added")
  1223. # Add foo to the group
  1224. group = pagure.lib.query.search_groups(
  1225. self.session, group_name="some_group"
  1226. )
  1227. result = pagure.lib.query.add_user_to_group(
  1228. self.session, "foo", group, "pingou", True
  1229. )
  1230. self.session.commit()
  1231. self.assertEqual(result, "User `foo` added to the group `some_group`.")
  1232. # Query the API for foo's filed PRs
  1233. output = self.app.get(
  1234. "/api/0/user/foo/requests/filed?status=all&per_page=6"
  1235. )
  1236. self.assertEqual(output.status_code, 200)
  1237. data = json.loads(output.get_data(as_text=True))
  1238. self.assertEqual(len(data["requests"]), 6)
  1239. self.assertEqual(
  1240. sorted(data.keys()),
  1241. ["args", "pagination", "requests", "total_requests"],
  1242. )
  1243. # There are 6 PRs, that's 1 page at 6 results per page
  1244. self.assertEqual(data["pagination"]["pages"], 1)
  1245. @patch("pagure.lib.notify.send_email")
  1246. def test_api_view_user_requests_actionable(self, mockemail):
  1247. """Test the api_view_user_requests_actionable method of the flask user
  1248. api"""
  1249. # First we test without the status parameter. It should default to `open`
  1250. output = self.app.get("/api/0/user/pingou/requests/actionable")
  1251. self.assertEqual(output.status_code, 200)
  1252. data = json.loads(output.get_data(as_text=True))
  1253. self.assertEqual(len(data["requests"]), 2)
  1254. self.assertEqual(
  1255. sorted(data.keys()),
  1256. ["args", "pagination", "requests", "total_requests"],
  1257. )
  1258. self.assertEqual(data["requests"][0]["user"]["name"], "foo")
  1259. self.assertEqual(data["requests"][1]["user"]["name"], "foo")
  1260. self.assertEqual(data["requests"][0]["status"], "Open")
  1261. self.assertEqual(data["requests"][1]["status"], "Open")
  1262. self.assertEqual(
  1263. data["requests"][0]["title"],
  1264. "open pullrequest by user foo on repo test2",
  1265. )
  1266. self.assertEqual(
  1267. data["requests"][1]["title"],
  1268. "open pullrequest by user foo on repo test",
  1269. )
  1270. self.assertEqual(data["args"]["status"], "open")
  1271. self.assertEqual(data["args"]["page"], 1)
  1272. # Next test with the status parameter set to `open`.
  1273. output = self.app.get(
  1274. "/api/0/user/pingou/requests/actionable?status=open"
  1275. )
  1276. self.assertEqual(output.status_code, 200)
  1277. data = json.loads(output.get_data(as_text=True))
  1278. self.assertEqual(len(data["requests"]), 2)
  1279. self.assertEqual(
  1280. sorted(data.keys()),
  1281. ["args", "pagination", "requests", "total_requests"],
  1282. )
  1283. self.assertEqual(data["requests"][0]["user"]["name"], "foo")
  1284. self.assertEqual(data["requests"][1]["user"]["name"], "foo")
  1285. self.assertEqual(data["requests"][0]["status"], "Open")
  1286. self.assertEqual(data["requests"][1]["status"], "Open")
  1287. self.assertEqual(
  1288. data["requests"][0]["title"],
  1289. "open pullrequest by user foo on repo test2",
  1290. )
  1291. self.assertEqual(
  1292. data["requests"][1]["title"],
  1293. "open pullrequest by user foo on repo test",
  1294. )
  1295. self.assertEqual(data["args"]["status"], "open")
  1296. self.assertEqual(data["args"]["page"], 1)
  1297. # Next test with the status parameter set to `closed`.
  1298. output = self.app.get(
  1299. "/api/0/user/pingou/requests/actionable?status=closed"
  1300. )
  1301. self.assertEqual(output.status_code, 200)
  1302. data = json.loads(output.get_data(as_text=True))
  1303. self.assertEqual(len(data["requests"]), 2)
  1304. self.assertEqual(
  1305. sorted(data.keys()),
  1306. ["args", "pagination", "requests", "total_requests"],
  1307. )
  1308. self.assertEqual(data["requests"][0]["user"]["name"], "foo")
  1309. self.assertEqual(data["requests"][1]["user"]["name"], "foo")
  1310. self.assertEqual(data["requests"][0]["status"], "Closed")
  1311. self.assertEqual(data["requests"][1]["status"], "Closed")
  1312. self.assertEqual(
  1313. data["requests"][0]["title"],
  1314. "closed pullrequest by user foo on repo test2",
  1315. )
  1316. self.assertEqual(
  1317. data["requests"][1]["title"],
  1318. "closed pullrequest by user foo on repo test",
  1319. )
  1320. self.assertEqual(data["args"]["status"], "closed")
  1321. self.assertEqual(data["args"]["page"], 1)
  1322. # Next test with the status parameter set to `merged`.
  1323. output = self.app.get(
  1324. "/api/0/user/pingou/requests/actionable?status=merged"
  1325. )
  1326. self.assertEqual(output.status_code, 200)
  1327. data = json.loads(output.get_data(as_text=True))
  1328. self.assertEqual(len(data["requests"]), 2)
  1329. self.assertEqual(
  1330. sorted(data.keys()),
  1331. ["args", "pagination", "requests", "total_requests"],
  1332. )
  1333. self.assertEqual(data["requests"][0]["user"]["name"], "foo")
  1334. self.assertEqual(data["requests"][1]["user"]["name"], "foo")
  1335. self.assertEqual(data["requests"][0]["status"], "Merged")
  1336. self.assertEqual(data["requests"][1]["status"], "Merged")
  1337. self.assertEqual(
  1338. data["requests"][0]["title"],
  1339. "merged pullrequest by user foo on repo test2",
  1340. )
  1341. self.assertEqual(
  1342. data["requests"][1]["title"],
  1343. "merged pullrequest by user foo on repo test",
  1344. )
  1345. self.assertEqual(data["args"]["status"], "merged")
  1346. self.assertEqual(data["args"]["page"], 1)
  1347. # Finally, test with the status parameter set to `all`.
  1348. output = self.app.get(
  1349. "/api/0/user/pingou/requests/actionable?status=all"
  1350. )
  1351. self.assertEqual(output.status_code, 200)
  1352. data = json.loads(output.get_data(as_text=True))
  1353. self.assertEqual(len(data["requests"]), 6)
  1354. self.assertEqual(
  1355. sorted(data.keys()),
  1356. ["args", "pagination", "requests", "total_requests"],
  1357. )
  1358. self.assertEqual(data["requests"][0]["user"]["name"], "foo")
  1359. self.assertEqual(data["requests"][1]["user"]["name"], "foo")
  1360. self.assertEqual(data["requests"][2]["user"]["name"], "foo")
  1361. self.assertEqual(data["requests"][3]["user"]["name"], "foo")
  1362. self.assertEqual(data["requests"][4]["user"]["name"], "foo")
  1363. self.assertEqual(data["requests"][5]["user"]["name"], "foo")
  1364. self.assertEqual(data["requests"][0]["status"], "Merged")
  1365. self.assertEqual(data["requests"][1]["status"], "Merged")
  1366. self.assertEqual(data["requests"][2]["status"], "Closed")
  1367. self.assertEqual(data["requests"][3]["status"], "Closed")
  1368. self.assertEqual(data["requests"][4]["status"], "Open")
  1369. self.assertEqual(data["requests"][5]["status"], "Open")
  1370. self.assertEqual(
  1371. data["requests"][0]["title"],
  1372. "merged pullrequest by user foo on repo test2",
  1373. )
  1374. self.assertEqual(
  1375. data["requests"][1]["title"],
  1376. "merged pullrequest by user foo on repo test",
  1377. )
  1378. self.assertEqual(
  1379. data["requests"][2]["title"],
  1380. "closed pullrequest by user foo on repo test2",
  1381. )
  1382. self.assertEqual(
  1383. data["requests"][3]["title"],
  1384. "closed pullrequest by user foo on repo test",
  1385. )
  1386. self.assertEqual(
  1387. data["requests"][4]["title"],
  1388. "open pullrequest by user foo on repo test2",
  1389. )
  1390. self.assertEqual(
  1391. data["requests"][5]["title"],
  1392. "open pullrequest by user foo on repo test",
  1393. )
  1394. self.assertEqual(data["args"]["status"], "all")
  1395. self.assertEqual(data["args"]["page"], 1)
  1396. # Test page 2 with the status parameter set to `all`.
  1397. output = self.app.get(
  1398. "/api/0/user/pingou/requests/actionable?status=all&page=2"
  1399. )
  1400. self.assertEqual(output.status_code, 200)
  1401. data = json.loads(output.get_data(as_text=True))
  1402. self.assertEqual(len(data["requests"]), 0)
  1403. self.assertEqual(
  1404. sorted(data.keys()),
  1405. ["args", "pagination", "requests", "total_requests"],
  1406. )
  1407. self.assertEqual(data["args"]["page"], 2)
  1408. @patch("pagure.lib.notify.send_email")
  1409. def test_api_view_user_requests_actionable_created(self, mockemail):
  1410. """Test the api_view_user_requests_filed method of the flask user
  1411. api with the created parameter"""
  1412. today = datetime.datetime.utcnow().date()
  1413. output = self.app.get(
  1414. "/api/0/user/pingou/requests/actionable?status=all&created=%s"
  1415. % (today.isoformat())
  1416. )
  1417. self.assertEqual(output.status_code, 200)
  1418. data = json.loads(output.get_data(as_text=True))
  1419. self.assertEqual(len(data["requests"]), 6)
  1420. yesterday = today - datetime.timedelta(days=1)
  1421. output = self.app.get(
  1422. "/api/0/user/pingou/requests/actionable?status=all&created=%s"
  1423. % (yesterday.isoformat())
  1424. )
  1425. self.assertEqual(output.status_code, 200)
  1426. data = json.loads(output.get_data(as_text=True))
  1427. self.assertEqual(len(data["requests"]), 6)
  1428. tomorrow = today + datetime.timedelta(days=1)
  1429. output = self.app.get(
  1430. "/api/0/user/pingou/requests/actionable?status=all&created=%s"
  1431. % (tomorrow.isoformat())
  1432. )
  1433. self.assertEqual(output.status_code, 200)
  1434. data = json.loads(output.get_data(as_text=True))
  1435. self.assertEqual(len(data["requests"]), 0)
  1436. output = self.app.get(
  1437. "/api/0/user/pingou/requests/actionable?status=all&created=..%s"
  1438. % (today.isoformat())
  1439. )
  1440. self.assertEqual(output.status_code, 200)
  1441. data = json.loads(output.get_data(as_text=True))
  1442. self.assertEqual(len(data["requests"]), 0)
  1443. output = self.app.get(
  1444. "/api/0/user/pingou/requests/actionable?status=all&created=..%s"
  1445. % (yesterday.isoformat())
  1446. )
  1447. self.assertEqual(output.status_code, 200)
  1448. data = json.loads(output.get_data(as_text=True))
  1449. self.assertEqual(len(data["requests"]), 0)
  1450. thedaybefore = today - datetime.timedelta(days=1)
  1451. output = self.app.get(
  1452. "/api/0/user/pingou/requests/actionable?status=all&created=..%s"
  1453. % (thedaybefore.isoformat())
  1454. )
  1455. self.assertEqual(output.status_code, 200)
  1456. data = json.loads(output.get_data(as_text=True))
  1457. self.assertEqual(len(data["requests"]), 0)
  1458. output = self.app.get(
  1459. "/api/0/user/pingou/requests/actionable?status=all&created=..%s"
  1460. % (tomorrow.isoformat())
  1461. )
  1462. self.assertEqual(output.status_code, 200)
  1463. data = json.loads(output.get_data(as_text=True))
  1464. self.assertEqual(len(data["requests"]), 6)
  1465. output = self.app.get(
  1466. "/api/0/user/pingou/requests/actionable?status=all&created=%s..%s"
  1467. % (thedaybefore.isoformat(), tomorrow.isoformat())
  1468. )
  1469. self.assertEqual(output.status_code, 200)
  1470. data = json.loads(output.get_data(as_text=True))
  1471. self.assertEqual(len(data["requests"]), 6)
  1472. @patch("pagure.lib.notify.send_email")
  1473. def test_api_view_user_requests_actionable_updated(self, mockemail):
  1474. """Test the api_view_user_requests_filed method of the flask user
  1475. api with the created parameter"""
  1476. today = datetime.datetime.utcnow().date()
  1477. output = self.app.get(
  1478. "/api/0/user/pingou/requests/actionable?status=all&updated=%s"
  1479. % (today.isoformat())
  1480. )
  1481. self.assertEqual(output.status_code, 200)
  1482. data = json.loads(output.get_data(as_text=True))
  1483. self.assertEqual(len(data["requests"]), 6)
  1484. yesterday = today - datetime.timedelta(days=1)
  1485. output = self.app.get(
  1486. "/api/0/user/pingou/requests/actionable?status=all&updated=%s"
  1487. % (yesterday.isoformat())
  1488. )
  1489. self.assertEqual(output.status_code, 200)
  1490. data = json.loads(output.get_data(as_text=True))
  1491. self.assertEqual(len(data["requests"]), 6)
  1492. tomorrow = today + datetime.timedelta(days=1)
  1493. output = self.app.get(
  1494. "/api/0/user/pingou/requests/actionable?status=all&updated=%s"
  1495. % (tomorrow.isoformat())
  1496. )
  1497. self.assertEqual(output.status_code, 200)
  1498. data = json.loads(output.get_data(as_text=True))
  1499. self.assertEqual(len(data["requests"]), 0)
  1500. @patch("pagure.lib.notify.send_email")
  1501. def test_api_view_user_requests_actionable_closed(self, mockemail):
  1502. """Test the api_view_user_requests_filed method of the flask user
  1503. api with the created parameter"""
  1504. today = datetime.datetime.utcnow().date()
  1505. output = self.app.get(
  1506. "/api/0/user/pingou/requests/actionable?status=all&closed=%s"
  1507. % (today.isoformat())
  1508. )
  1509. self.assertEqual(output.status_code, 200)
  1510. data = json.loads(output.get_data(as_text=True))
  1511. self.assertEqual(len(data["requests"]), 0)
  1512. yesterday = today - datetime.timedelta(days=1)
  1513. output = self.app.get(
  1514. "/api/0/user/pingou/requests/actionable?status=all&closed=%s"
  1515. % (yesterday.isoformat())
  1516. )
  1517. self.assertEqual(output.status_code, 200)
  1518. data = json.loads(output.get_data(as_text=True))
  1519. self.assertEqual(len(data["requests"]), 0)
  1520. tomorrow = today + datetime.timedelta(days=1)
  1521. output = self.app.get(
  1522. "/api/0/user/pingou/requests/actionable?status=all&closed=%s"
  1523. % (tomorrow.isoformat())
  1524. )
  1525. self.assertEqual(output.status_code, 200)
  1526. data = json.loads(output.get_data(as_text=True))
  1527. self.assertEqual(len(data["requests"]), 0)
  1528. class PagureFlaskApiUsertestissues(tests.Modeltests):
  1529. """Tests for the user issues endpoints"""
  1530. maxDiff = None
  1531. def setUp(self):
  1532. """Set up the environnment, ran before every tests."""
  1533. super(PagureFlaskApiUsertestissues, self).setUp()
  1534. pagure.config.config["REQUESTS_FOLDER"] = None
  1535. tests.create_projects(self.session)
  1536. repo = pagure.lib.query._get_project(self.session, "test")
  1537. # Create issues to play with
  1538. msg = pagure.lib.query.new_issue(
  1539. session=self.session,
  1540. repo=repo,
  1541. title="Test issue",
  1542. content="We should work on this",
  1543. user="pingou",
  1544. )
  1545. self.session.commit()
  1546. self.assertEqual(msg.title, "Test issue")
  1547. def test_user_issues_empty(self):
  1548. """Return the list of issues associated with the specified user."""
  1549. output = self.app.get("/api/0/user/foo/issues")
  1550. self.assertEqual(output.status_code, 200)
  1551. data = json.loads(output.get_data(as_text=True))
  1552. for k in ["pagination_issues_assigned", "pagination_issues_created"]:
  1553. for k2 in ["first", "last"]:
  1554. self.assertIsNotNone(data[k][k2])
  1555. data[k][k2] = None
  1556. self.assertEqual(
  1557. data,
  1558. {
  1559. "args": {
  1560. "assignee": True,
  1561. "author": True,
  1562. "closed": None,
  1563. "created": None,
  1564. "milestones": [],
  1565. "no_stones": None,
  1566. "order": None,
  1567. "order_key": None,
  1568. "page": 1,
  1569. "since": None,
  1570. "status": None,
  1571. "tags": [],
  1572. "updated": None,
  1573. },
  1574. "issues_assigned": [],
  1575. "issues_created": [],
  1576. "pagination_issues_assigned": {
  1577. "first": None,
  1578. "last": None,
  1579. "next": None,
  1580. "page": 1,
  1581. "pages": 0,
  1582. "per_page": 20,
  1583. "prev": None,
  1584. },
  1585. "pagination_issues_created": {
  1586. "first": None,
  1587. "last": None,
  1588. "next": None,
  1589. "page": 1,
  1590. "pages": 0,
  1591. "per_page": 20,
  1592. "prev": None,
  1593. },
  1594. "total_issues_assigned": 0,
  1595. "total_issues_assigned_pages": 1,
  1596. "total_issues_created": 0,
  1597. "total_issues_created_pages": 1,
  1598. },
  1599. )
  1600. def test_user_issues(self):
  1601. """Return the list of issues associated with the specified user."""
  1602. output = self.app.get("/api/0/user/pingou/issues")
  1603. self.assertEqual(output.status_code, 200)
  1604. data = json.loads(output.get_data(as_text=True))
  1605. issues = []
  1606. for issue in data["issues_created"]:
  1607. issue["date_created"] = "1513111778"
  1608. issue["last_updated"] = "1513111778"
  1609. issue["project"]["date_created"] = "1513111778"
  1610. issue["project"]["date_modified"] = "1513111778"
  1611. issues.append(issue)
  1612. data["issues_created"] = issues
  1613. for k in ["pagination_issues_assigned", "pagination_issues_created"]:
  1614. for k2 in ["first", "last"]:
  1615. self.assertIsNotNone(data[k][k2])
  1616. data[k][k2] = None
  1617. self.assertEqual(
  1618. data,
  1619. {
  1620. "args": {
  1621. "assignee": True,
  1622. "author": True,
  1623. "closed": None,
  1624. "created": None,
  1625. "milestones": [],
  1626. "no_stones": None,
  1627. "order": None,
  1628. "order_key": None,
  1629. "page": 1,
  1630. "since": None,
  1631. "status": None,
  1632. "tags": [],
  1633. "updated": None,
  1634. },
  1635. "issues_assigned": [],
  1636. "issues_created": [
  1637. {
  1638. "assignee": None,
  1639. "blocks": [],
  1640. "close_status": None,
  1641. "closed_at": None,
  1642. "closed_by": None,
  1643. "comments": [],
  1644. "content": "We should work on this",
  1645. "custom_fields": [],
  1646. "date_created": "1513111778",
  1647. "full_url": "http://localhost.localdomain/test/issue/1",
  1648. "depends": [],
  1649. "id": 1,
  1650. "last_updated": "1513111778",
  1651. "milestone": None,
  1652. "priority": None,
  1653. "private": False,
  1654. "project": {
  1655. "access_groups": {
  1656. "admin": [],
  1657. "collaborator": [],
  1658. "commit": [],
  1659. "ticket": [],
  1660. },
  1661. "access_users": {
  1662. "admin": [],
  1663. "collaborator": [],
  1664. "commit": [],
  1665. "owner": ["pingou"],
  1666. "ticket": [],
  1667. },
  1668. "close_status": [
  1669. "Invalid",
  1670. "Insufficient data",
  1671. "Fixed",
  1672. "Duplicate",
  1673. ],
  1674. "custom_keys": [],
  1675. "date_created": "1513111778",
  1676. "date_modified": "1513111778",
  1677. "description": "test project #1",
  1678. "full_url": "http://localhost.localdomain/test",
  1679. "fullname": "test",
  1680. "id": 1,
  1681. "milestones": {},
  1682. "name": "test",
  1683. "namespace": None,
  1684. "parent": None,
  1685. "priorities": {},
  1686. "tags": [],
  1687. "url_path": "test",
  1688. "user": {
  1689. "fullname": "PY C",
  1690. "full_url": "http://localhost.localdomain/user/pingou",
  1691. "name": "pingou",
  1692. "url_path": "user/pingou",
  1693. },
  1694. },
  1695. "related_prs": [],
  1696. "status": "Open",
  1697. "tags": [],
  1698. "title": "Test issue",
  1699. "user": {
  1700. "fullname": "PY C",
  1701. "full_url": "http://localhost.localdomain/user/pingou",
  1702. "name": "pingou",
  1703. "url_path": "user/pingou",
  1704. },
  1705. }
  1706. ],
  1707. "pagination_issues_assigned": {
  1708. "first": None,
  1709. "last": None,
  1710. "next": None,
  1711. "page": 1,
  1712. "pages": 0,
  1713. "per_page": 20,
  1714. "prev": None,
  1715. },
  1716. "pagination_issues_created": {
  1717. "first": None,
  1718. "last": None,
  1719. "next": None,
  1720. "page": 1,
  1721. "pages": 1,
  1722. "per_page": 20,
  1723. "prev": None,
  1724. },
  1725. "total_issues_assigned": 0,
  1726. "total_issues_assigned_pages": 1,
  1727. "total_issues_created": 1,
  1728. "total_issues_created_pages": 1,
  1729. },
  1730. )
  1731. def test_user_issues_created(self):
  1732. """Return the list of issues associated with the specified user
  1733. and play with the created filter."""
  1734. today = datetime.datetime.utcnow().date()
  1735. output = self.app.get(
  1736. "/api/0/user/pingou/issues?created=%s" % (today.isoformat())
  1737. )
  1738. self.assertEqual(output.status_code, 200)
  1739. data = json.loads(output.get_data(as_text=True))
  1740. self.assertEqual(data["total_issues_assigned"], 0)
  1741. self.assertEqual(data["total_issues_created"], 1)
  1742. yesterday = today - datetime.timedelta(days=1)
  1743. output = self.app.get(
  1744. "/api/0/user/pingou/issues?created=%s" % (yesterday.isoformat())
  1745. )
  1746. self.assertEqual(output.status_code, 200)
  1747. data = json.loads(output.get_data(as_text=True))
  1748. self.assertEqual(data["total_issues_assigned"], 0)
  1749. self.assertEqual(data["total_issues_created"], 1)
  1750. tomorrow = today + datetime.timedelta(days=1)
  1751. output = self.app.get(
  1752. "/api/0/user/pingou/issues?created=%s" % (tomorrow.isoformat())
  1753. )
  1754. self.assertEqual(output.status_code, 200)
  1755. data = json.loads(output.get_data(as_text=True))
  1756. self.assertEqual(data["total_issues_assigned"], 0)
  1757. self.assertEqual(data["total_issues_created"], 0)
  1758. output = self.app.get(
  1759. "/api/0/user/pingou/issues?created=..%s" % (yesterday.isoformat())
  1760. )
  1761. self.assertEqual(output.status_code, 200)
  1762. data = json.loads(output.get_data(as_text=True))
  1763. self.assertEqual(data["total_issues_assigned"], 0)
  1764. self.assertEqual(data["total_issues_created"], 0)
  1765. output = self.app.get(
  1766. "/api/0/user/pingou/issues?created=%s..%s"
  1767. % (yesterday.isoformat(), today.isoformat())
  1768. )
  1769. self.assertEqual(output.status_code, 200)
  1770. data = json.loads(output.get_data(as_text=True))
  1771. self.assertEqual(data["total_issues_assigned"], 0)
  1772. self.assertEqual(data["total_issues_created"], 0)
  1773. output = self.app.get(
  1774. "/api/0/user/pingou/issues?created=%s..%s"
  1775. % (yesterday.isoformat(), tomorrow.isoformat())
  1776. )
  1777. self.assertEqual(output.status_code, 200)
  1778. data = json.loads(output.get_data(as_text=True))
  1779. self.assertEqual(data["total_issues_assigned"], 0)
  1780. self.assertEqual(data["total_issues_created"], 1)
  1781. if __name__ == "__main__":
  1782. unittest.main(verbosity=2)