1
0

test_pagure_flask_api_user.py 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2018 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. __requires__ = ['SQLAlchemy >= 0.8']
  8. import pkg_resources
  9. import datetime
  10. import unittest
  11. import shutil
  12. import sys
  13. import os
  14. import json
  15. from mock import patch
  16. sys.path.insert(0, os.path.join(os.path.dirname(
  17. os.path.abspath(__file__)), '..'))
  18. import pagure.api
  19. import pagure.config
  20. import pagure.lib
  21. import pagure.lib.model as model
  22. import tests
  23. class PagureFlaskApiUSertests(tests.Modeltests):
  24. """ Tests for the flask API of pagure for issue """
  25. maxDiff = None
  26. def setUp(self):
  27. """ Set up the environnment, ran before every tests. """
  28. super(PagureFlaskApiUSertests, self).setUp()
  29. pagure.config.config['REQUESTS_FOLDER'] = None
  30. def test_api_users(self):
  31. """ Test the api_users function. """
  32. output = self.app.get('/api/0/users')
  33. self.assertEqual(output.status_code, 200)
  34. data = json.loads(output.data)
  35. self.assertEqual(sorted(data['users']), ['foo', 'pingou'])
  36. self.assertEqual(sorted(data.keys()), ['mention', 'total_users', 'users'])
  37. self.assertEqual(data['total_users'], 2)
  38. output = self.app.get('/api/0/users?pattern=p')
  39. self.assertEqual(output.status_code, 200)
  40. data = json.loads(output.data)
  41. self.assertEqual(data['users'], ['pingou'])
  42. self.assertEqual(sorted(data.keys()), ['mention', 'total_users', 'users'])
  43. self.assertEqual(data['total_users'], 1)
  44. def test_api_view_user(self):
  45. """
  46. Test the api_view_user method of the flask api
  47. The tested user has no project or forks.
  48. """
  49. output = self.app.get('/api/0/user/pingou')
  50. self.assertEqual(output.status_code, 200)
  51. exp = {
  52. "forks": [],
  53. "repos": [],
  54. "user": { "fullname": "PY C", "name": "pingou"}}
  55. data = json.loads(output.data)
  56. self.assertEqual(data, exp)
  57. def test_api_view_user_with_project(self):
  58. """
  59. Test the api_view_user method of the flask api,
  60. this time the user has some project defined.
  61. """
  62. tests.create_projects(self.session)
  63. output = self.app.get('/api/0/user/pingou')
  64. self.assertEqual(output.status_code, 200)
  65. data = json.loads(output.data)
  66. data['repos'][0]['date_created'] = "1490272832"
  67. data['repos'][0]['date_modified'] = "1490272832"
  68. data['repos'][1]['date_created'] = "1490272832"
  69. data['repos'][1]['date_modified'] = "1490272832"
  70. data['repos'][2]['date_created'] = "1490272832"
  71. data['repos'][2]['date_modified'] = "1490272832"
  72. expected_data = {
  73. "forks": [],
  74. "repos": [
  75. {
  76. "access_groups": {
  77. "admin": [],
  78. "commit": [],
  79. "ticket": []
  80. },
  81. "access_users": {
  82. "admin": [],
  83. "commit": [],
  84. "owner": ["pingou"],
  85. "ticket": []
  86. },
  87. "close_status": [
  88. "Invalid",
  89. "Insufficient data",
  90. "Fixed",
  91. "Duplicate"
  92. ],
  93. "custom_keys": [],
  94. "date_created": "1490272832",
  95. "date_modified": "1490272832",
  96. "description": "test project #1",
  97. "fullname": "test",
  98. "url_path": "test",
  99. "id": 1,
  100. "milestones": {},
  101. "name": "test",
  102. "namespace": None,
  103. "parent": None,
  104. "priorities": {},
  105. "tags": [],
  106. "user": {
  107. "fullname": "PY C",
  108. "name": "pingou"
  109. }
  110. },
  111. {
  112. "access_groups": {
  113. "admin": [],
  114. "commit": [],
  115. "ticket": []
  116. },
  117. "access_users": {
  118. "admin": [],
  119. "commit": [],
  120. "owner": ["pingou"],
  121. "ticket": []
  122. },
  123. "close_status": [
  124. "Invalid",
  125. "Insufficient data",
  126. "Fixed",
  127. "Duplicate"
  128. ],
  129. "custom_keys": [],
  130. "date_created": "1490272832",
  131. "date_modified": "1490272832",
  132. "description": "test project #2",
  133. "fullname": "test2",
  134. "url_path": "test2",
  135. "id": 2,
  136. "milestones": {},
  137. "name": "test2",
  138. "namespace": None,
  139. "parent": None,
  140. "priorities": {},
  141. "tags": [],
  142. "user": {
  143. "fullname": "PY C",
  144. "name": "pingou"
  145. }
  146. },
  147. {
  148. "access_groups": {
  149. "admin": [],
  150. "commit": [],
  151. "ticket": []},
  152. "access_users": {
  153. "admin": [],
  154. "commit": [],
  155. "owner": ["pingou"],
  156. "ticket": []
  157. },
  158. "close_status": [
  159. "Invalid",
  160. "Insufficient data",
  161. "Fixed",
  162. "Duplicate"
  163. ],
  164. "custom_keys": [],
  165. "date_created": "1490272832",
  166. "date_modified": "1490272832",
  167. "description": "namespaced test project",
  168. "fullname": "somenamespace/test3",
  169. "url_path": "somenamespace/test3",
  170. "id": 3,
  171. "milestones": {},
  172. "name": "test3",
  173. "namespace": "somenamespace",
  174. "parent": None,
  175. "priorities": {},
  176. "tags": [],
  177. "user": {
  178. "fullname": "PY C",
  179. "name": "pingou"
  180. }
  181. }
  182. ],
  183. "user": {
  184. "fullname": "PY C",
  185. "name": "pingou"
  186. }
  187. }
  188. self.assertEqual(data, expected_data)
  189. @patch('pagure.lib.notify.send_email')
  190. def test_api_view_user_activity_stats(self, mockemail):
  191. """ Test the api_view_user_activity_stats method of the flask user
  192. api. """
  193. mockemail.return_value = True
  194. tests.create_projects(self.session)
  195. tests.create_tokens(self.session)
  196. tests.create_tokens_acl(self.session)
  197. headers = {'Authorization': 'token aaabbbcccddd'}
  198. # Create a pull-request
  199. repo = pagure.lib._get_project(self.session, 'test')
  200. forked_repo = pagure.lib._get_project(self.session, 'test')
  201. req = pagure.lib.new_pull_request(
  202. session=self.session,
  203. repo_from=forked_repo,
  204. branch_from='master',
  205. repo_to=repo,
  206. branch_to='master',
  207. title='test pull-request',
  208. user='pingou',
  209. requestfolder=None,
  210. )
  211. self.session.commit()
  212. self.assertEqual(req.id, 1)
  213. self.assertEqual(req.title, 'test pull-request')
  214. # Check comments before
  215. self.session.commit()
  216. request = pagure.lib.search_pull_requests(
  217. self.session, project_id=1, requestid=1)
  218. self.assertEqual(len(request.comments), 0)
  219. data = {
  220. 'comment': 'This is a very interesting question',
  221. }
  222. # Valid request
  223. output = self.app.post(
  224. '/api/0/test/pull-request/1/comment', data=data, headers=headers)
  225. self.assertEqual(output.status_code, 200)
  226. data = json.loads(output.data)
  227. self.assertDictEqual(
  228. data,
  229. {'message': 'Comment added'}
  230. )
  231. # One comment added
  232. self.session.commit()
  233. request = pagure.lib.search_pull_requests(
  234. self.session, project_id=1, requestid=1)
  235. self.assertEqual(len(request.comments), 1)
  236. # Close PR
  237. output = self.app.post(
  238. '/api/0/test/pull-request/1/close', headers=headers)
  239. self.assertEqual(output.status_code, 200)
  240. data = json.loads(output.data)
  241. self.assertDictEqual(
  242. data,
  243. {"message": "Pull-request closed!"}
  244. )
  245. # PR closed
  246. self.session.commit()
  247. request = pagure.lib.search_pull_requests(
  248. self.session, project_id=1, requestid=1)
  249. self.assertEqual(request.status, 'Closed')
  250. # Finally retrieve the user's logs
  251. output = self.app.get('/api/0/user/pingou/activity/stats')
  252. self.assertEqual(output.status_code, 200)
  253. data = json.loads(output.data)
  254. date = datetime.datetime.utcnow().date().strftime('%Y-%m-%d')
  255. self.assertDictEqual(data, {date: 4})
  256. @patch('pagure.lib.notify.send_email')
  257. def test_api_view_user_activity_date(self, mockemail):
  258. """ Test the api_view_user_activity_date method of the flask user
  259. api. """
  260. self.test_api_view_user_activity_stats()
  261. # Invalid date
  262. output = self.app.get('/api/0/user/pingou/activity/AABB')
  263. self.assertEqual(output.status_code, 400)
  264. # Invalid date
  265. output = self.app.get('/api/0/user/pingou/activity/2016asd')
  266. self.assertEqual(output.status_code, 200)
  267. exp = {
  268. "activities": [],
  269. "date": "2016-01-01"
  270. }
  271. self.assertEqual(json.loads(output.data), exp)
  272. # Date parsed, just not really as expected
  273. output = self.app.get('/api/0/user/pingou/activity/20161245')
  274. self.assertEqual(output.status_code, 200)
  275. exp = {
  276. "activities": [],
  277. "date": "1970-08-22"
  278. }
  279. self.assertEqual(json.loads(output.data), exp)
  280. date = datetime.datetime.utcnow().date().strftime('%Y-%m-%d')
  281. # Retrieve the user's logs for today
  282. output = self.app.get('/api/0/user/pingou/activity/%s' % date)
  283. self.assertEqual(output.status_code, 200)
  284. data = json.loads(output.data)
  285. exp = {
  286. "activities": [
  287. {
  288. "date": date,
  289. "date_created": "1477558752",
  290. "type": "pull-request",
  291. "description_mk": "<p>pingou created PR <a href=\"/test/pull-request/1\" title=\"[Closed] test pull-request\">test#1</a></p>",
  292. "id": 1,
  293. "ref_id": "1",
  294. "type": "created",
  295. "user": {
  296. "fullname": "PY C",
  297. "name": "pingou"
  298. }
  299. },
  300. {
  301. "date": date,
  302. "date_created": "1477558752",
  303. "type": "pull-request",
  304. "description_mk": "<p>pingou commented on PR <a href=\"/test/pull-request/1\" title=\"[Closed] test pull-request\">test#1</a></p>",
  305. "id": 2,
  306. "ref_id": "1",
  307. "type": "commented",
  308. "user": {
  309. "fullname": "PY C",
  310. "name": "pingou"
  311. }
  312. },
  313. {
  314. "date": date,
  315. "date_created": "1477558752",
  316. "type": "pull-request",
  317. "description_mk": "<p>pingou closed PR <a href=\"/test/pull-request/1\" title=\"[Closed] test pull-request\">test#1</a></p>",
  318. "id": 3,
  319. "ref_id": "1",
  320. "type": "closed",
  321. "user": {
  322. "fullname": "PY C",
  323. "name": "pingou"
  324. }
  325. },
  326. {
  327. "date": date,
  328. "date_created": "1477558752",
  329. "type": "pull-request",
  330. "description_mk": "<p>pingou commented on PR <a href=\"/test/pull-request/1\" title=\"[Closed] test pull-request\">test#1</a></p>",
  331. "id": 4,
  332. "ref_id": "1",
  333. "type": "commented",
  334. "user": {
  335. "fullname": "PY C",
  336. "name": "pingou"
  337. }
  338. }
  339. ],
  340. "date": date,
  341. }
  342. for idx, act in enumerate(data['activities']):
  343. act['date_created'] = '1477558752'
  344. data['activities'][idx] = act
  345. self.assertEqual(data, exp)
  346. @patch('pagure.lib.notify.send_email')
  347. def test_api_view_user_activity_date_1_activity(self, mockemail):
  348. """ Test the api_view_user_activity_date method of the flask user
  349. api when the user only did one action. """
  350. tests.create_projects(self.session)
  351. repo = pagure.lib._get_project(self.session, 'test')
  352. now = datetime.datetime.utcnow()
  353. date = now.date().strftime('%Y-%m-%d')
  354. # Create a single commit log
  355. log = model.PagureLog(
  356. user_id=1,
  357. user_email='foo@bar.com',
  358. project_id=1,
  359. log_type='committed',
  360. ref_id='githash',
  361. date=now.date(),
  362. date_created=now
  363. )
  364. self.session.add(log)
  365. self.session.commit()
  366. # Retrieve the user's logs for today
  367. output = self.app.get(
  368. '/api/0/user/pingou/activity/%s?grouped=1' % date)
  369. self.assertEqual(output.status_code, 200)
  370. data = json.loads(output.data)
  371. exp = {
  372. "activities": [
  373. {
  374. "description_mk": "<p>pingou committed on test#githash</p>"
  375. }
  376. ],
  377. "date": date,
  378. }
  379. self.assertEqual(data, exp)
  380. @patch('pagure.lib.notify.send_email')
  381. def test_api_view_user_activity_timezone_negative(self, mockemail):
  382. """Test api_view_user_activity{_stats,_date} with the America/
  383. New York timezone, which is 5 hours behind UTC in winter and
  384. 4 hours behind UTC in summer (daylight savings). The events
  385. will occur on 2018-02-15 in UTC, but on 2018-02-14 local.
  386. """
  387. tests.create_projects(self.session)
  388. repo = pagure.lib._get_project(self.session, 'test')
  389. dateobj = datetime.datetime(2018, 2, 15, 3, 30)
  390. utcdate = '2018-02-15'
  391. # the Unix timestamp for 2018-02-15 12:00 UTC
  392. utcts = '1518696000'
  393. localdate = '2018-02-14'
  394. # the Unix timestamp for 2018-02-14 12:00 America/New_York
  395. localts = '1518627600'
  396. # Create a single commit log
  397. log = model.PagureLog(
  398. user_id=1,
  399. user_email='foo@bar.com',
  400. project_id=1,
  401. log_type='committed',
  402. ref_id='githash',
  403. date=dateobj.date(),
  404. date_created=dateobj
  405. )
  406. self.session.add(log)
  407. self.session.commit()
  408. # Retrieve the user's stats with no timezone specified (==UTC)
  409. output = self.app.get('/api/0/user/pingou/activity/stats')
  410. self.assertEqual(output.status_code, 200)
  411. data = json.loads(output.data)
  412. # date in output should be UTC date
  413. self.assertDictEqual(data, {utcdate: 1})
  414. # Now in timestamp format...
  415. output = self.app.get('/api/0/user/pingou/activity/stats?format=timestamp')
  416. self.assertEqual(output.status_code, 200)
  417. data = json.loads(output.data)
  418. # timestamp in output should be UTC ts
  419. self.assertDictEqual(data, {utcts: 1})
  420. # Retrieve the user's stats with local timezone specified
  421. output = self.app.get('/api/0/user/pingou/activity/stats?tz=America/New_York')
  422. self.assertEqual(output.status_code, 200)
  423. data = json.loads(output.data)
  424. # date in output should be local date
  425. self.assertDictEqual(data, {localdate: 1})
  426. # Now in timestamp format...
  427. output = self.app.get('/api/0/user/pingou/activity/stats?format=timestamp&tz=America/New_York')
  428. self.assertEqual(output.status_code, 200)
  429. data = json.loads(output.data)
  430. # timestamp in output should be local ts
  431. self.assertDictEqual(data, {localts: 1})
  432. # Retrieve the user's logs for 2018-02-15 with no timezone
  433. output = self.app.get(
  434. '/api/0/user/pingou/activity/%s?grouped=1' % utcdate)
  435. self.assertEqual(output.status_code, 200)
  436. data = json.loads(output.data)
  437. exp = {
  438. "activities": [
  439. {
  440. "description_mk": "<p>pingou committed on test#githash</p>"
  441. }
  442. ],
  443. "date": utcdate,
  444. }
  445. self.assertEqual(data, exp)
  446. # Now retrieve the user's logs for 2018-02-14 with local time
  447. output = self.app.get(
  448. '/api/0/user/pingou/activity/%s?grouped=1&tz=America/New_York' % localdate)
  449. self.assertEqual(output.status_code, 200)
  450. data = json.loads(output.data)
  451. exp['date'] = localdate
  452. self.assertEqual(data, exp)
  453. @patch('pagure.lib.notify.send_email')
  454. def test_api_view_user_activity_timezone_positive(self, mockemail):
  455. """Test api_view_user_activity{_stats,_date} with the Asia/
  456. Dubai timezone, which is 4 hours ahead of UTC. The events will
  457. occur on 2018-02-15 in UTC, but on 2018-02-16 in local time.
  458. """
  459. tests.create_projects(self.session)
  460. repo = pagure.lib._get_project(self.session, 'test')
  461. dateobj = datetime.datetime(2018, 2, 15, 22, 30)
  462. utcdate = '2018-02-15'
  463. # the Unix timestamp for 2018-02-15 12:00 UTC
  464. utcts = '1518696000'
  465. localdate = '2018-02-16'
  466. # the Unix timestamp for 2018-02-16 12:00 Asia/Dubai
  467. localts = '1518768000'
  468. # Create a single commit log
  469. log = model.PagureLog(
  470. user_id=1,
  471. user_email='foo@bar.com',
  472. project_id=1,
  473. log_type='committed',
  474. ref_id='githash',
  475. date=dateobj.date(),
  476. date_created=dateobj
  477. )
  478. self.session.add(log)
  479. self.session.commit()
  480. # Retrieve the user's stats with no timezone specified (==UTC)
  481. output = self.app.get('/api/0/user/pingou/activity/stats')
  482. self.assertEqual(output.status_code, 200)
  483. data = json.loads(output.data)
  484. # date in output should be UTC date
  485. self.assertDictEqual(data, {utcdate: 1})
  486. # Now in timestamp format...
  487. output = self.app.get('/api/0/user/pingou/activity/stats?format=timestamp')
  488. self.assertEqual(output.status_code, 200)
  489. data = json.loads(output.data)
  490. # timestamp in output should be UTC ts
  491. self.assertDictEqual(data, {utcts: 1})
  492. # Retrieve the user's stats with local timezone specified
  493. output = self.app.get('/api/0/user/pingou/activity/stats?tz=Asia/Dubai')
  494. self.assertEqual(output.status_code, 200)
  495. data = json.loads(output.data)
  496. # date in output should be local date
  497. self.assertDictEqual(data, {localdate: 1})
  498. # Now in timestamp format...
  499. output = self.app.get('/api/0/user/pingou/activity/stats?format=timestamp&tz=Asia/Dubai')
  500. self.assertEqual(output.status_code, 200)
  501. data = json.loads(output.data)
  502. # timestamp in output should be local ts
  503. self.assertDictEqual(data, {localts: 1})
  504. # Retrieve the user's logs for 2018-02-15 with no timezone
  505. output = self.app.get(
  506. '/api/0/user/pingou/activity/%s?grouped=1' % utcdate)
  507. self.assertEqual(output.status_code, 200)
  508. data = json.loads(output.data)
  509. exp = {
  510. "activities": [
  511. {
  512. "description_mk": "<p>pingou committed on test#githash</p>"
  513. }
  514. ],
  515. "date": utcdate,
  516. }
  517. self.assertEqual(data, exp)
  518. # Now retrieve the user's logs for 2018-02-16 with local time
  519. output = self.app.get(
  520. '/api/0/user/pingou/activity/%s?grouped=1&tz=Asia/Dubai' % localdate)
  521. self.assertEqual(output.status_code, 200)
  522. data = json.loads(output.data)
  523. exp['date'] = localdate
  524. self.assertEqual(data, exp)
  525. class PagureFlaskApiUsertestrequests(tests.Modeltests):
  526. """ Tests for the user requests endpoints """
  527. maxDiff = None
  528. def setUp(self):
  529. """ Set up the environnment, ran before every tests. """
  530. super(PagureFlaskApiUsertestrequests, self).setUp()
  531. pagure.config.config['REQUESTS_FOLDER'] = None
  532. tests.create_projects(self.session)
  533. # Create few pull-requests
  534. repo = pagure.lib.get_authorized_project(self.session, 'test')
  535. forked_repo = pagure.lib.get_authorized_project(self.session, 'test')
  536. pagure.lib.new_pull_request(
  537. session=self.session,
  538. repo_from=forked_repo,
  539. branch_from='master',
  540. repo_to=repo,
  541. branch_to='master',
  542. title='open pullrequest by user foo on repo test',
  543. user='foo',
  544. requestfolder=None,
  545. )
  546. repo = pagure.lib.get_authorized_project(self.session, 'test2')
  547. forked_repo = pagure.lib.get_authorized_project(self.session, 'test2')
  548. pagure.lib.new_pull_request(
  549. session=self.session,
  550. repo_from=forked_repo,
  551. branch_from='master',
  552. repo_to=repo,
  553. branch_to='master',
  554. title='open pullrequest by user foo on repo test2',
  555. user='foo',
  556. requestfolder=None,
  557. )
  558. self.session.commit()
  559. repo = pagure.lib.get_authorized_project(self.session, 'test')
  560. forked_repo = pagure.lib.get_authorized_project(self.session, 'test')
  561. pagure.lib.new_pull_request(
  562. session=self.session,
  563. repo_from=forked_repo,
  564. branch_from='master',
  565. repo_to=repo,
  566. branch_to='master',
  567. title='closed pullrequest by user foo on repo test',
  568. user='foo',
  569. status='Closed',
  570. requestfolder=None,
  571. )
  572. repo = pagure.lib.get_authorized_project(self.session, 'test2')
  573. forked_repo = pagure.lib.get_authorized_project(self.session, 'test2')
  574. pagure.lib.new_pull_request(
  575. session=self.session,
  576. repo_from=forked_repo,
  577. branch_from='master',
  578. repo_to=repo,
  579. branch_to='master',
  580. title='closed pullrequest by user foo on repo test2',
  581. user='foo',
  582. status='Closed',
  583. requestfolder=None,
  584. )
  585. self.session.commit()
  586. repo = pagure.lib.get_authorized_project(self.session, 'test')
  587. forked_repo = pagure.lib.get_authorized_project(self.session, 'test')
  588. pagure.lib.new_pull_request(
  589. session=self.session,
  590. repo_from=forked_repo,
  591. branch_from='master',
  592. repo_to=repo,
  593. branch_to='master',
  594. title='merged pullrequest by user foo on repo test',
  595. user='foo',
  596. status='Merged',
  597. requestfolder=None,
  598. )
  599. repo = pagure.lib.get_authorized_project(self.session, 'test2')
  600. forked_repo = pagure.lib.get_authorized_project(self.session, 'test2')
  601. pagure.lib.new_pull_request(
  602. session=self.session,
  603. repo_from=forked_repo,
  604. branch_from='master',
  605. repo_to=repo,
  606. branch_to='master',
  607. title='merged pullrequest by user foo on repo test2',
  608. user='foo',
  609. status='Merged',
  610. requestfolder=None,
  611. )
  612. self.session.commit()
  613. repo = pagure.lib.get_authorized_project(self.session, 'test')
  614. forked_repo = pagure.lib.get_authorized_project(self.session, 'test')
  615. pagure.lib.new_pull_request(
  616. session=self.session,
  617. repo_from=forked_repo,
  618. branch_from='master',
  619. repo_to=repo,
  620. branch_to='master',
  621. title='open pullrequest by user pingou on repo test',
  622. user='pingou',
  623. requestfolder=None,
  624. )
  625. self.session.commit()
  626. repo = pagure.lib.get_authorized_project(self.session, 'test2')
  627. forked_repo = pagure.lib.get_authorized_project(self.session, 'test2')
  628. pagure.lib.new_pull_request(
  629. session=self.session,
  630. repo_from=forked_repo,
  631. branch_from='master',
  632. repo_to=repo,
  633. branch_to='master',
  634. title='open pullrequest by user pingou on repo test2',
  635. user='pingou',
  636. requestfolder=None,
  637. )
  638. self.session.commit()
  639. repo = pagure.lib.get_authorized_project(self.session, 'test')
  640. forked_repo = pagure.lib.get_authorized_project(self.session, 'test')
  641. pagure.lib.new_pull_request(
  642. session=self.session,
  643. repo_from=forked_repo,
  644. branch_from='master',
  645. repo_to=repo,
  646. branch_to='master',
  647. title='closed pullrequest by user pingou on repo test',
  648. user='pingou',
  649. status="Closed",
  650. requestfolder=None,
  651. )
  652. self.session.commit()
  653. repo = pagure.lib.get_authorized_project(self.session, 'test2')
  654. forked_repo = pagure.lib.get_authorized_project(self.session, 'test2')
  655. pagure.lib.new_pull_request(
  656. session=self.session,
  657. repo_from=forked_repo,
  658. branch_from='master',
  659. repo_to=repo,
  660. branch_to='master',
  661. title='closed pullrequest by user pingou on repo test2',
  662. user='pingou',
  663. status="Closed",
  664. requestfolder=None,
  665. )
  666. self.session.commit()
  667. repo = pagure.lib.get_authorized_project(self.session, 'test')
  668. forked_repo = pagure.lib.get_authorized_project(self.session, 'test')
  669. pagure.lib.new_pull_request(
  670. session=self.session,
  671. repo_from=forked_repo,
  672. branch_from='master',
  673. repo_to=repo,
  674. branch_to='master',
  675. title='merged pullrequest by user pingou on repo test',
  676. user='pingou',
  677. status="Merged",
  678. requestfolder=None,
  679. )
  680. self.session.commit()
  681. repo = pagure.lib.get_authorized_project(self.session, 'test2')
  682. forked_repo = pagure.lib.get_authorized_project(self.session, 'test2')
  683. pagure.lib.new_pull_request(
  684. session=self.session,
  685. repo_from=forked_repo,
  686. branch_from='master',
  687. repo_to=repo,
  688. branch_to='master',
  689. title='merged pullrequest by user pingou on repo test2',
  690. user='pingou',
  691. status="Merged",
  692. requestfolder=None,
  693. )
  694. self.session.commit()
  695. @patch('pagure.lib.notify.send_email')
  696. def test_api_view_user_requests_filed(self, mockemail):
  697. """ Test the api_view_user_requests_filed method of the flask user
  698. api """
  699. # First we test without the status parameter. It should default to `open`
  700. output = self.app.get(
  701. '/api/0/user/pingou/requests/filed')
  702. self.assertEqual(output.status_code, 200)
  703. data = json.loads(output.data)
  704. self.assertEqual(len(data['requests']), 2)
  705. self.assertEqual(data['requests'][0]['user']['name'], "pingou")
  706. self.assertEqual(data['requests'][1]['user']['name'], "pingou")
  707. self.assertEqual(data['requests'][0]['status'], "Open")
  708. self.assertEqual(data['requests'][1]['status'], "Open")
  709. self.assertEqual(data['requests'][0]['title'], "open pullrequest by user pingou on repo test2")
  710. self.assertEqual(data['requests'][1]['title'], "open pullrequest by user pingou on repo test")
  711. self.assertEqual(data['args']['status'], "open")
  712. self.assertEqual(data['args']['page'], 1)
  713. # Next test with the status parameter set to `open`.
  714. output = self.app.get(
  715. '/api/0/user/pingou/requests/filed?status=open')
  716. self.assertEqual(output.status_code, 200)
  717. data = json.loads(output.data)
  718. self.assertEqual(len(data['requests']), 2)
  719. self.assertEqual(data['requests'][0]['user']['name'], "pingou")
  720. self.assertEqual(data['requests'][1]['user']['name'], "pingou")
  721. self.assertEqual(data['requests'][0]['status'], "Open")
  722. self.assertEqual(data['requests'][1]['status'], "Open")
  723. self.assertEqual(data['requests'][0]['title'], "open pullrequest by user pingou on repo test2")
  724. self.assertEqual(data['requests'][1]['title'], "open pullrequest by user pingou on repo test")
  725. self.assertEqual(data['args']['status'], "open")
  726. self.assertEqual(data['args']['page'], 1)
  727. # Next test with the status parameter set to `closed`.
  728. output = self.app.get(
  729. '/api/0/user/pingou/requests/filed?status=closed')
  730. self.assertEqual(output.status_code, 200)
  731. data = json.loads(output.data)
  732. self.assertEqual(len(data['requests']), 2)
  733. self.assertEqual(data['requests'][0]['user']['name'], "pingou")
  734. self.assertEqual(data['requests'][1]['user']['name'], "pingou")
  735. self.assertEqual(data['requests'][0]['status'], "Closed")
  736. self.assertEqual(data['requests'][1]['status'], "Closed")
  737. self.assertEqual(data['requests'][0]['title'], "closed pullrequest by user pingou on repo test2")
  738. self.assertEqual(data['requests'][1]['title'], "closed pullrequest by user pingou on repo test")
  739. self.assertEqual(data['args']['status'], "closed")
  740. self.assertEqual(data['args']['page'], 1)
  741. # Next test with the status parameter set to `merged`.
  742. output = self.app.get(
  743. '/api/0/user/pingou/requests/filed?status=merged')
  744. self.assertEqual(output.status_code, 200)
  745. data = json.loads(output.data)
  746. self.assertEqual(len(data['requests']), 2)
  747. self.assertEqual(data['requests'][0]['user']['name'], "pingou")
  748. self.assertEqual(data['requests'][1]['user']['name'], "pingou")
  749. self.assertEqual(data['requests'][0]['status'], "Merged")
  750. self.assertEqual(data['requests'][1]['status'], "Merged")
  751. self.assertEqual(data['requests'][0]['title'], "merged pullrequest by user pingou on repo test2")
  752. self.assertEqual(data['requests'][1]['title'], "merged pullrequest by user pingou on repo test")
  753. self.assertEqual(data['args']['status'], "merged")
  754. self.assertEqual(data['args']['page'], 1)
  755. # Finally, test with the status parameter set to `all`.
  756. output = self.app.get(
  757. '/api/0/user/pingou/requests/filed?status=all')
  758. self.assertEqual(output.status_code, 200)
  759. data = json.loads(output.data)
  760. self.assertEqual(len(data['requests']), 6)
  761. self.assertEqual(data['requests'][0]['user']['name'], "pingou")
  762. self.assertEqual(data['requests'][1]['user']['name'], "pingou")
  763. self.assertEqual(data['requests'][2]['user']['name'], "pingou")
  764. self.assertEqual(data['requests'][3]['user']['name'], "pingou")
  765. self.assertEqual(data['requests'][4]['user']['name'], "pingou")
  766. self.assertEqual(data['requests'][5]['user']['name'], "pingou")
  767. self.assertEqual(data['requests'][0]['status'], "Merged")
  768. self.assertEqual(data['requests'][1]['status'], "Merged")
  769. self.assertEqual(data['requests'][2]['status'], "Closed")
  770. self.assertEqual(data['requests'][3]['status'], "Closed")
  771. self.assertEqual(data['requests'][4]['status'], "Open")
  772. self.assertEqual(data['requests'][5]['status'], "Open")
  773. self.assertEqual(data['requests'][0]['title'], "merged pullrequest by user pingou on repo test2")
  774. self.assertEqual(data['requests'][1]['title'], "merged pullrequest by user pingou on repo test")
  775. self.assertEqual(data['requests'][2]['title'], "closed pullrequest by user pingou on repo test2")
  776. self.assertEqual(data['requests'][3]['title'], "closed pullrequest by user pingou on repo test")
  777. self.assertEqual(data['requests'][4]['title'], "open pullrequest by user pingou on repo test2")
  778. self.assertEqual(data['requests'][5]['title'], "open pullrequest by user pingou on repo test")
  779. self.assertEqual(data['args']['status'], "all")
  780. self.assertEqual(data['args']['page'], 1)
  781. # Test page 2 with the status parameter set to `all`.
  782. output = self.app.get(
  783. '/api/0/user/pingou/requests/filed?status=all&page=2')
  784. self.assertEqual(output.status_code, 200)
  785. data = json.loads(output.data)
  786. self.assertEqual(len(data['requests']), 0)
  787. self.assertEqual(data['args']['page'], 2)
  788. @patch('pagure.lib.notify.send_email')
  789. def test_api_view_user_requests_actionable(self, mockemail):
  790. """ Test the api_view_user_requests_actionable method of the flask user
  791. api """
  792. # First we test without the status parameter. It should default to `open`
  793. output = self.app.get(
  794. '/api/0/user/pingou/requests/actionable')
  795. self.assertEqual(output.status_code, 200)
  796. data = json.loads(output.data)
  797. self.assertEqual(len(data['requests']), 2)
  798. self.assertEqual(data['requests'][0]['user']['name'], "foo")
  799. self.assertEqual(data['requests'][1]['user']['name'], "foo")
  800. self.assertEqual(data['requests'][0]['status'], "Open")
  801. self.assertEqual(data['requests'][1]['status'], "Open")
  802. self.assertEqual(data['requests'][0]['title'], "open pullrequest by user foo on repo test2")
  803. self.assertEqual(data['requests'][1]['title'], "open pullrequest by user foo on repo test")
  804. self.assertEqual(data['args']['status'], "open")
  805. self.assertEqual(data['args']['page'], 1)
  806. # Next test with the status parameter set to `open`.
  807. output = self.app.get(
  808. '/api/0/user/pingou/requests/actionable?status=open')
  809. self.assertEqual(output.status_code, 200)
  810. data = json.loads(output.data)
  811. self.assertEqual(len(data['requests']), 2)
  812. self.assertEqual(data['requests'][0]['user']['name'], "foo")
  813. self.assertEqual(data['requests'][1]['user']['name'], "foo")
  814. self.assertEqual(data['requests'][0]['status'], "Open")
  815. self.assertEqual(data['requests'][1]['status'], "Open")
  816. self.assertEqual(data['requests'][0]['title'], "open pullrequest by user foo on repo test2")
  817. self.assertEqual(data['requests'][1]['title'], "open pullrequest by user foo on repo test")
  818. self.assertEqual(data['args']['status'], "open")
  819. self.assertEqual(data['args']['page'], 1)
  820. # Next test with the status parameter set to `closed`.
  821. output = self.app.get(
  822. '/api/0/user/pingou/requests/actionable?status=closed')
  823. self.assertEqual(output.status_code, 200)
  824. data = json.loads(output.data)
  825. self.assertEqual(len(data['requests']), 2)
  826. self.assertEqual(data['requests'][0]['user']['name'], "foo")
  827. self.assertEqual(data['requests'][1]['user']['name'], "foo")
  828. self.assertEqual(data['requests'][0]['status'], "Closed")
  829. self.assertEqual(data['requests'][1]['status'], "Closed")
  830. self.assertEqual(data['requests'][0]['title'], "closed pullrequest by user foo on repo test2")
  831. self.assertEqual(data['requests'][1]['title'], "closed pullrequest by user foo on repo test")
  832. self.assertEqual(data['args']['status'], "closed")
  833. self.assertEqual(data['args']['page'], 1)
  834. # Next test with the status parameter set to `merged`.
  835. output = self.app.get(
  836. '/api/0/user/pingou/requests/actionable?status=merged')
  837. self.assertEqual(output.status_code, 200)
  838. data = json.loads(output.data)
  839. self.assertEqual(len(data['requests']), 2)
  840. self.assertEqual(data['requests'][0]['user']['name'], "foo")
  841. self.assertEqual(data['requests'][1]['user']['name'], "foo")
  842. self.assertEqual(data['requests'][0]['status'], "Merged")
  843. self.assertEqual(data['requests'][1]['status'], "Merged")
  844. self.assertEqual(data['requests'][0]['title'], "merged pullrequest by user foo on repo test2")
  845. self.assertEqual(data['requests'][1]['title'], "merged pullrequest by user foo on repo test")
  846. self.assertEqual(data['args']['status'], "merged")
  847. self.assertEqual(data['args']['page'], 1)
  848. # Finally, test with the status parameter set to `all`.
  849. output = self.app.get(
  850. '/api/0/user/pingou/requests/actionable?status=all')
  851. self.assertEqual(output.status_code, 200)
  852. data = json.loads(output.data)
  853. self.assertEqual(len(data['requests']), 6)
  854. self.assertEqual(data['requests'][0]['user']['name'], "foo")
  855. self.assertEqual(data['requests'][1]['user']['name'], "foo")
  856. self.assertEqual(data['requests'][2]['user']['name'], "foo")
  857. self.assertEqual(data['requests'][3]['user']['name'], "foo")
  858. self.assertEqual(data['requests'][4]['user']['name'], "foo")
  859. self.assertEqual(data['requests'][5]['user']['name'], "foo")
  860. self.assertEqual(data['requests'][0]['status'], "Merged")
  861. self.assertEqual(data['requests'][1]['status'], "Merged")
  862. self.assertEqual(data['requests'][2]['status'], "Closed")
  863. self.assertEqual(data['requests'][3]['status'], "Closed")
  864. self.assertEqual(data['requests'][4]['status'], "Open")
  865. self.assertEqual(data['requests'][5]['status'], "Open")
  866. self.assertEqual(data['requests'][0]['title'], "merged pullrequest by user foo on repo test2")
  867. self.assertEqual(data['requests'][1]['title'], "merged pullrequest by user foo on repo test")
  868. self.assertEqual(data['requests'][2]['title'], "closed pullrequest by user foo on repo test2")
  869. self.assertEqual(data['requests'][3]['title'], "closed pullrequest by user foo on repo test")
  870. self.assertEqual(data['requests'][4]['title'], "open pullrequest by user foo on repo test2")
  871. self.assertEqual(data['requests'][5]['title'], "open pullrequest by user foo on repo test")
  872. self.assertEqual(data['args']['status'], "all")
  873. self.assertEqual(data['args']['page'], 1)
  874. # Test page 2 with the status parameter set to `all`.
  875. output = self.app.get(
  876. '/api/0/user/pingou/requests/actionable?status=all&page=2')
  877. self.assertEqual(output.status_code, 200)
  878. data = json.loads(output.data)
  879. self.assertEqual(len(data['requests']), 0)
  880. self.assertEqual(data['args']['page'], 2)
  881. class PagureFlaskApiUsertestissues(tests.Modeltests):
  882. """ Tests for the user issues endpoints """
  883. maxDiff = None
  884. def setUp(self):
  885. """ Set up the environnment, ran before every tests. """
  886. super(PagureFlaskApiUsertestissues, self).setUp()
  887. pagure.config.config['REQUESTS_FOLDER'] = None
  888. tests.create_projects(self.session)
  889. repo = pagure.lib._get_project(self.session, 'test')
  890. # Create issues to play with
  891. msg = pagure.lib.new_issue(
  892. session=self.session,
  893. repo=repo,
  894. title='Test issue',
  895. content='We should work on this',
  896. user='pingou',
  897. ticketfolder=None
  898. )
  899. self.session.commit()
  900. self.assertEqual(msg.title, 'Test issue')
  901. def test_user_issues_empty(self):
  902. """ Return the list of issues associated with the specified user. """
  903. output = self.app.get('/api/0/user/foo/issues')
  904. self.assertEqual(output.status_code, 200)
  905. data = json.loads(output.data)
  906. self.assertEqual(
  907. data,
  908. {
  909. "args": {
  910. "assignee": True,
  911. "author": True,
  912. "milestones": [],
  913. "no_stones": None,
  914. "order": None,
  915. "order_key": None,
  916. "page": 1,
  917. "since": None,
  918. "status": None,
  919. "tags": []
  920. },
  921. "issues_assigned": [],
  922. "issues_created": [],
  923. "total_issues_assigned": 0,
  924. "total_issues_assigned_pages": 1,
  925. "total_issues_created": 0,
  926. "total_issues_created_pages": 1
  927. }
  928. )
  929. def test_user_issues(self):
  930. """ Return the list of issues associated with the specified user. """
  931. output = self.app.get('/api/0/user/pingou/issues')
  932. self.assertEqual(output.status_code, 200)
  933. data = json.loads(output.data)
  934. issues = []
  935. for issue in data['issues_created']:
  936. issue['date_created'] = '1513111778'
  937. issue['last_updated'] = '1513111778'
  938. issue['project']['date_created'] = '1513111778'
  939. issue['project']['date_modified'] = '1513111778'
  940. issues.append(issue)
  941. data['issues_created'] = issues
  942. self.assertEqual(
  943. data,
  944. {
  945. "args": {
  946. "assignee": True,
  947. "author": True,
  948. "milestones": [],
  949. "no_stones": None,
  950. "order": None,
  951. "order_key": None,
  952. "page": 1,
  953. "since": None,
  954. "status": None,
  955. "tags": []
  956. },
  957. "issues_assigned": [],
  958. "issues_created": [
  959. {
  960. "assignee": None,
  961. "blocks": [],
  962. "close_status": None,
  963. "closed_at": None,
  964. "comments": [],
  965. "content": "We should work on this",
  966. "custom_fields": [],
  967. "date_created": "1513111778",
  968. "depends": [],
  969. "id": 1,
  970. "last_updated": "1513111778",
  971. "milestone": None,
  972. "priority": None,
  973. "private": False,
  974. "project": {
  975. "access_groups": {
  976. "admin": [],
  977. "commit": [],
  978. "ticket": []
  979. },
  980. "access_users": {
  981. "admin": [],
  982. "commit": [],
  983. "owner": [
  984. "pingou"
  985. ],
  986. "ticket": []
  987. },
  988. "close_status": [
  989. "Invalid",
  990. "Insufficient data",
  991. "Fixed",
  992. "Duplicate"
  993. ],
  994. "custom_keys": [],
  995. "date_created": "1513111778",
  996. "date_modified": "1513111778",
  997. "description": "test project #1",
  998. "fullname": "test",
  999. "id": 1,
  1000. "milestones": {},
  1001. "name": "test",
  1002. "namespace": None,
  1003. "parent": None,
  1004. "priorities": {},
  1005. "tags": [],
  1006. "url_path": "test",
  1007. "user": {
  1008. "fullname": "PY C",
  1009. "name": "pingou"
  1010. }
  1011. },
  1012. "status": "Open",
  1013. "tags": [],
  1014. "title": "Test issue",
  1015. "user": {
  1016. "fullname": "PY C",
  1017. "name": "pingou"
  1018. }
  1019. }
  1020. ],
  1021. "total_issues_assigned": 0,
  1022. "total_issues_assigned_pages": 1,
  1023. "total_issues_created": 1,
  1024. "total_issues_created_pages": 1
  1025. }
  1026. )
  1027. if __name__ == '__main__':
  1028. unittest.main(verbosity=2)