test_pagure_flask_api_group.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2017-2018 - Copyright Red Hat Inc
  4. Authors:
  5. Matt Prahl <mprahl@redhat.com>
  6. Pierre-Yves Chibon <pingou@pingoured.fr>
  7. """
  8. from __future__ import unicode_literals, absolute_import
  9. import unittest
  10. import sys
  11. import os
  12. import json
  13. sys.path.insert(
  14. 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
  15. )
  16. import pagure.api
  17. import pagure.lib.query
  18. import tests
  19. class PagureFlaskApiGroupTests(tests.SimplePagureTest):
  20. """ Tests for the flask API of pagure for issue """
  21. maxDiff = None
  22. def setUp(self):
  23. """ Set up the environnment, ran before every tests. """
  24. super(PagureFlaskApiGroupTests, self).setUp()
  25. pagure.config.config["REQUESTS_FOLDER"] = None
  26. msg = pagure.lib.query.add_group(
  27. self.session,
  28. group_name="some_group",
  29. display_name="Some Group",
  30. description=None,
  31. group_type="bar",
  32. user="pingou",
  33. is_admin=False,
  34. blacklist=[],
  35. )
  36. self.session.commit()
  37. tests.create_projects(self.session)
  38. project = pagure.lib.query._get_project(self.session, "test2")
  39. msg = pagure.lib.query.add_group_to_project(
  40. session=self.session,
  41. project=project,
  42. new_group="some_group",
  43. user="pingou",
  44. )
  45. self.session.commit()
  46. self.assertEqual(msg, "Group added")
  47. def test_api_groups(self):
  48. """ Test the api_groups function. """
  49. # Add a couple of groups so that we can list them
  50. item = pagure.lib.model.PagureGroup(
  51. group_name="group1",
  52. group_type="user",
  53. display_name="User group",
  54. user_id=1, # pingou
  55. )
  56. self.session.add(item)
  57. item = pagure.lib.model.PagureGroup(
  58. group_name="rel-eng",
  59. group_type="user",
  60. display_name="Release engineering group",
  61. user_id=1, # pingou
  62. )
  63. self.session.add(item)
  64. self.session.commit()
  65. output = self.app.get("/api/0/groups")
  66. self.assertEqual(output.status_code, 200)
  67. data = json.loads(output.get_data(as_text=True))
  68. self.assertEqual(data["groups"], ["group1", "rel-eng", "some_group"])
  69. self.assertEqual(
  70. sorted(data.keys()), ["groups", "pagination", "total_groups"]
  71. )
  72. self.assertEqual(data["total_groups"], 3)
  73. output = self.app.get("/api/0/groups?pattern=re")
  74. self.assertEqual(output.status_code, 200)
  75. data = json.loads(output.get_data(as_text=True))
  76. self.assertEqual(data["groups"], ["rel-eng"])
  77. self.assertEqual(
  78. sorted(data.keys()), ["groups", "pagination", "total_groups"]
  79. )
  80. self.assertEqual(data["total_groups"], 1)
  81. def test_api_groups_extended(self):
  82. """ Test the api_groups function. """
  83. # Add a couple of groups so that we can list them
  84. item = pagure.lib.model.PagureGroup(
  85. group_name="group1",
  86. group_type="user",
  87. display_name="User group",
  88. user_id=1, # pingou
  89. )
  90. self.session.add(item)
  91. item = pagure.lib.model.PagureGroup(
  92. group_name="rel-eng",
  93. group_type="user",
  94. display_name="Release engineering group",
  95. user_id=1, # pingou
  96. )
  97. self.session.add(item)
  98. self.session.commit()
  99. output = self.app.get("/api/0/groups?extended=1")
  100. self.assertEqual(output.status_code, 200)
  101. data = json.loads(output.get_data(as_text=True))
  102. for k in ["first", "last"]:
  103. self.assertIsNotNone(data["pagination"][k])
  104. data["pagination"][k] = "http://localhost..."
  105. self.assertEqual(
  106. data,
  107. {
  108. "groups": [
  109. {"description": None, "name": "group1"},
  110. {"description": None, "name": "rel-eng"},
  111. {"description": None, "name": "some_group"},
  112. ],
  113. "pagination": {
  114. "first": "http://localhost...",
  115. "last": "http://localhost...",
  116. "next": None,
  117. "page": 1,
  118. "pages": 1,
  119. "per_page": 20,
  120. "prev": None,
  121. },
  122. "total_groups": 3,
  123. },
  124. )
  125. def test_api_view_group_authenticated(self):
  126. """
  127. Test the api_view_group method of the flask api with an
  128. authenticated user. The tested group has one member.
  129. """
  130. tests.create_tokens(self.session)
  131. headers = {"Authorization": "token aaabbbcccddd"}
  132. output = self.app.get("/api/0/group/some_group", headers=headers)
  133. self.assertEqual(output.status_code, 200)
  134. exp = {
  135. "display_name": "Some Group",
  136. "description": None,
  137. "creator": {
  138. "fullname": "PY C",
  139. "url_path": "user/pingou",
  140. "default_email": "bar@pingou.com",
  141. "emails": ["bar@pingou.com", "foo@pingou.com"],
  142. "name": "pingou",
  143. },
  144. "members": ["pingou"],
  145. "date_created": "1492020239",
  146. "group_type": "user",
  147. "name": "some_group",
  148. }
  149. data = json.loads(output.get_data(as_text=True))
  150. data["date_created"] = "1492020239"
  151. self.assertDictEqual(data, exp)
  152. def test_api_view_group_unauthenticated(self):
  153. """
  154. Test the api_view_group method of the flask api with an
  155. unauthenticated user. The tested group has one member.
  156. """
  157. output = self.app.get("/api/0/group/some_group")
  158. self.assertEqual(output.status_code, 200)
  159. exp = {
  160. "display_name": "Some Group",
  161. "description": None,
  162. "creator": {
  163. "fullname": "PY C",
  164. "name": "pingou",
  165. "url_path": "user/pingou",
  166. },
  167. "members": ["pingou"],
  168. "date_created": "1492020239",
  169. "group_type": "user",
  170. "name": "some_group",
  171. }
  172. data = json.loads(output.get_data(as_text=True))
  173. data["date_created"] = "1492020239"
  174. self.assertDictEqual(data, exp)
  175. def test_api_view_group_two_members_authenticated(self):
  176. """
  177. Test the api_view_group method of the flask api with an
  178. authenticated user. The tested group has two members.
  179. """
  180. user = pagure.lib.model.User(
  181. user="mprahl",
  182. fullname="Matt Prahl",
  183. password="foo",
  184. default_email="mprahl@redhat.com",
  185. )
  186. self.session.add(user)
  187. self.session.commit()
  188. group = pagure.lib.query.search_groups(
  189. self.session, group_name="some_group"
  190. )
  191. result = pagure.lib.query.add_user_to_group(
  192. self.session, user.username, group, user.username, True
  193. )
  194. self.assertEqual(
  195. result, "User `mprahl` added to the group `some_group`."
  196. )
  197. self.session.commit()
  198. tests.create_tokens(self.session)
  199. headers = {"Authorization": "token aaabbbcccddd"}
  200. output = self.app.get("/api/0/group/some_group", headers=headers)
  201. self.assertEqual(output.status_code, 200)
  202. exp = {
  203. "display_name": "Some Group",
  204. "description": None,
  205. "creator": {
  206. "fullname": "PY C",
  207. "default_email": "bar@pingou.com",
  208. "emails": ["bar@pingou.com", "foo@pingou.com"],
  209. "name": "pingou",
  210. "url_path": "user/pingou",
  211. },
  212. "members": ["pingou", "mprahl"],
  213. "date_created": "1492020239",
  214. "group_type": "user",
  215. "name": "some_group",
  216. }
  217. self.maxDiff = None
  218. data = json.loads(output.get_data(as_text=True))
  219. data["date_created"] = "1492020239"
  220. self.assertDictEqual(data, exp)
  221. def test_api_view_group_no_group_error(self):
  222. """
  223. Test the api_view_group method of the flask api
  224. The tested group has one member.
  225. """
  226. output = self.app.get("/api/0/group/some_group3")
  227. self.assertEqual(output.status_code, 404)
  228. data = json.loads(output.get_data(as_text=True))
  229. self.assertEqual(data["error"], "Group not found")
  230. self.assertEqual(data["error_code"], "ENOGROUP")
  231. def test_api_view_group_w_projects_and_acl(self):
  232. """
  233. Test the api_view_group method with project info and restricted
  234. to the admin ACL
  235. """
  236. tests.create_tokens(self.session)
  237. headers = {"Authorization": "token aaabbbcccddd"}
  238. output = self.app.get(
  239. "/api/0/group/some_group?projects=1", headers=headers
  240. )
  241. self.assertEqual(output.status_code, 200)
  242. exp = {
  243. "display_name": "Some Group",
  244. "description": None,
  245. "creator": {
  246. "fullname": "PY C",
  247. "default_email": "bar@pingou.com",
  248. "emails": ["bar@pingou.com", "foo@pingou.com"],
  249. "name": "pingou",
  250. "url_path": "user/pingou",
  251. },
  252. "members": ["pingou"],
  253. "date_created": "1492020239",
  254. "group_type": "user",
  255. "name": "some_group",
  256. "pagination": {
  257. "first": "http://localhost...",
  258. "last": "http://localhost...",
  259. "next": None,
  260. "page": 1,
  261. "pages": 1,
  262. "per_page": 20,
  263. "prev": None,
  264. },
  265. "projects": [
  266. {
  267. "access_groups": {
  268. "admin": ["some_group"],
  269. "collaborator": [],
  270. "commit": [],
  271. "ticket": [],
  272. },
  273. "access_users": {
  274. "admin": [],
  275. "collaborator": [],
  276. "commit": [],
  277. "owner": ["pingou"],
  278. "ticket": [],
  279. },
  280. "close_status": [
  281. "Invalid",
  282. "Insufficient data",
  283. "Fixed",
  284. "Duplicate",
  285. ],
  286. "custom_keys": [],
  287. "date_created": "1492020239",
  288. "date_modified": "1492020239",
  289. "description": "test project #2",
  290. "fullname": "test2",
  291. "id": 2,
  292. "milestones": {},
  293. "name": "test2",
  294. "namespace": None,
  295. "parent": None,
  296. "priorities": {},
  297. "tags": [],
  298. "url_path": "test2",
  299. "user": {
  300. "fullname": "PY C",
  301. "name": "pingou",
  302. "url_path": "user/pingou",
  303. },
  304. }
  305. ],
  306. "total_projects": 1,
  307. }
  308. data = json.loads(output.get_data(as_text=True))
  309. data["date_created"] = "1492020239"
  310. self.assertIsNotNone(data["pagination"]["first"])
  311. data["pagination"]["first"] = "http://localhost..."
  312. self.assertIsNotNone(data["pagination"]["last"])
  313. data["pagination"]["last"] = "http://localhost..."
  314. projects = []
  315. for p in data["projects"]:
  316. p["date_created"] = "1492020239"
  317. p["date_modified"] = "1492020239"
  318. projects.append(p)
  319. data["projects"] = projects
  320. self.assertDictEqual(data, exp)
  321. output = self.app.get(
  322. "/api/0/group/some_group?projects=1&acl=admin", headers=headers
  323. )
  324. data = json.loads(output.get_data(as_text=True))
  325. data["date_created"] = "1492020239"
  326. self.assertIsNotNone(data["pagination"]["first"])
  327. data["pagination"]["first"] = "http://localhost..."
  328. self.assertIsNotNone(data["pagination"]["last"])
  329. data["pagination"]["last"] = "http://localhost..."
  330. projects = []
  331. for p in data["projects"]:
  332. p["date_created"] = "1492020239"
  333. p["date_modified"] = "1492020239"
  334. projects.append(p)
  335. data["projects"] = projects
  336. self.assertDictEqual(data, exp)
  337. def test_api_view_group_w_projects_and_acl_commit(self):
  338. """
  339. Test the api_view_group method with project info and restricted
  340. to the commit ACL
  341. """
  342. output = self.app.get("/api/0/group/some_group?projects=1&acl=commit")
  343. self.assertEqual(output.status_code, 200)
  344. exp = {
  345. "display_name": "Some Group",
  346. "description": None,
  347. "creator": {
  348. "fullname": "PY C",
  349. "name": "pingou",
  350. "url_path": "user/pingou",
  351. },
  352. "members": ["pingou"],
  353. "date_created": "1492020239",
  354. "group_type": "user",
  355. "name": "some_group",
  356. "pagination": {
  357. "first": "http://localhost...",
  358. "last": "http://localhost...",
  359. "next": None,
  360. "page": 1,
  361. "pages": 1,
  362. "per_page": 20,
  363. "prev": None,
  364. },
  365. "projects": [
  366. {
  367. "access_groups": {
  368. "admin": ["some_group"],
  369. "collaborator": [],
  370. "commit": [],
  371. "ticket": [],
  372. },
  373. "access_users": {
  374. "admin": [],
  375. "collaborator": [],
  376. "commit": [],
  377. "owner": ["pingou"],
  378. "ticket": [],
  379. },
  380. "close_status": [
  381. "Invalid",
  382. "Insufficient data",
  383. "Fixed",
  384. "Duplicate",
  385. ],
  386. "custom_keys": [],
  387. "date_created": "1492020239",
  388. "date_modified": "1492020239",
  389. "description": "test project #2",
  390. "fullname": "test2",
  391. "id": 2,
  392. "milestones": {},
  393. "name": "test2",
  394. "namespace": None,
  395. "parent": None,
  396. "priorities": {},
  397. "tags": [],
  398. "url_path": "test2",
  399. "user": {
  400. "fullname": "PY C",
  401. "name": "pingou",
  402. "url_path": "user/pingou",
  403. },
  404. }
  405. ],
  406. "total_projects": 1,
  407. }
  408. data = json.loads(output.get_data(as_text=True))
  409. data["date_created"] = "1492020239"
  410. self.assertIsNotNone(data["pagination"]["first"])
  411. data["pagination"]["first"] = "http://localhost..."
  412. self.assertIsNotNone(data["pagination"]["last"])
  413. data["pagination"]["last"] = "http://localhost..."
  414. projects = []
  415. for p in data["projects"]:
  416. p["date_created"] = "1492020239"
  417. p["date_modified"] = "1492020239"
  418. projects.append(p)
  419. data["projects"] = projects
  420. self.assertDictEqual(data, exp)
  421. def test_api_view_group_w_projects_and_acl_ticket(self):
  422. """
  423. Test the api_view_group method with project info and restricted
  424. to the ticket ACL
  425. """
  426. output = self.app.get("/api/0/group/some_group?projects=1&acl=ticket")
  427. self.assertEqual(output.status_code, 200)
  428. exp = {
  429. "display_name": "Some Group",
  430. "description": None,
  431. "creator": {
  432. "fullname": "PY C",
  433. "name": "pingou",
  434. "url_path": "user/pingou",
  435. },
  436. "members": ["pingou"],
  437. "date_created": "1492020239",
  438. "group_type": "user",
  439. "name": "some_group",
  440. "pagination": {
  441. "first": "http://localhost...",
  442. "last": "http://localhost...",
  443. "next": None,
  444. "page": 1,
  445. "pages": 1,
  446. "per_page": 20,
  447. "prev": None,
  448. },
  449. "projects": [
  450. {
  451. "access_groups": {
  452. "admin": ["some_group"],
  453. "collaborator": [],
  454. "commit": [],
  455. "ticket": [],
  456. },
  457. "access_users": {
  458. "admin": [],
  459. "collaborator": [],
  460. "commit": [],
  461. "owner": ["pingou"],
  462. "ticket": [],
  463. },
  464. "close_status": [
  465. "Invalid",
  466. "Insufficient data",
  467. "Fixed",
  468. "Duplicate",
  469. ],
  470. "custom_keys": [],
  471. "date_created": "1492020239",
  472. "date_modified": "1492020239",
  473. "description": "test project #2",
  474. "fullname": "test2",
  475. "id": 2,
  476. "milestones": {},
  477. "name": "test2",
  478. "namespace": None,
  479. "parent": None,
  480. "priorities": {},
  481. "tags": [],
  482. "url_path": "test2",
  483. "user": {
  484. "fullname": "PY C",
  485. "name": "pingou",
  486. "url_path": "user/pingou",
  487. },
  488. }
  489. ],
  490. "total_projects": 1,
  491. }
  492. data = json.loads(output.get_data(as_text=True))
  493. data["date_created"] = "1492020239"
  494. self.assertIsNotNone(data["pagination"]["first"])
  495. data["pagination"]["first"] = "http://localhost..."
  496. self.assertIsNotNone(data["pagination"]["last"])
  497. data["pagination"]["last"] = "http://localhost..."
  498. projects = []
  499. for p in data["projects"]:
  500. p["date_created"] = "1492020239"
  501. p["date_modified"] = "1492020239"
  502. projects.append(p)
  503. data["projects"] = projects
  504. self.assertDictEqual(data, exp)
  505. def test_api_view_group_w_projects_and_acl_admin_no_project(self):
  506. """
  507. Test the api_view_group method with project info and restricted
  508. to the admin ACL
  509. """
  510. # Make the group having only commit access
  511. project = pagure.lib.query._get_project(self.session, "test2")
  512. msg = pagure.lib.query.add_group_to_project(
  513. session=self.session,
  514. project=project,
  515. new_group="some_group",
  516. user="pingou",
  517. access="commit",
  518. )
  519. self.session.commit()
  520. self.assertEqual(msg, "Group access updated")
  521. output = self.app.get("/api/0/group/some_group?projects=1&acl=admin")
  522. self.assertEqual(output.status_code, 200)
  523. exp = {
  524. "display_name": "Some Group",
  525. "description": None,
  526. "creator": {
  527. "fullname": "PY C",
  528. "name": "pingou",
  529. "url_path": "user/pingou",
  530. },
  531. "members": ["pingou"],
  532. "date_created": "1492020239",
  533. "group_type": "user",
  534. "name": "some_group",
  535. "pagination": {
  536. "first": "http://localhost...",
  537. "last": "http://localhost...",
  538. "next": None,
  539. "page": 1,
  540. "pages": 0,
  541. "per_page": 20,
  542. "prev": None,
  543. },
  544. "projects": [],
  545. "total_projects": 0,
  546. }
  547. data = json.loads(output.get_data(as_text=True))
  548. data["date_created"] = "1492020239"
  549. self.assertIsNotNone(data["pagination"]["first"])
  550. data["pagination"]["first"] = "http://localhost..."
  551. self.assertIsNotNone(data["pagination"]["last"])
  552. data["pagination"]["last"] = "http://localhost..."
  553. self.assertDictEqual(data, exp)
  554. def test_api_view_group_w_projects_and_acl_commit_no_project(self):
  555. """
  556. Test the api_view_group method with project info and restricted
  557. to the commit ACL
  558. """
  559. # Make the group having only ticket access
  560. project = pagure.lib.query._get_project(self.session, "test2")
  561. msg = pagure.lib.query.add_group_to_project(
  562. session=self.session,
  563. project=project,
  564. new_group="some_group",
  565. user="pingou",
  566. access="ticket",
  567. )
  568. self.session.commit()
  569. self.assertEqual(msg, "Group access updated")
  570. output = self.app.get("/api/0/group/some_group?projects=1&acl=commit")
  571. self.assertEqual(output.status_code, 200)
  572. exp = {
  573. "display_name": "Some Group",
  574. "description": None,
  575. "creator": {
  576. "fullname": "PY C",
  577. "name": "pingou",
  578. "url_path": "user/pingou",
  579. },
  580. "members": ["pingou"],
  581. "date_created": "1492020239",
  582. "group_type": "user",
  583. "name": "some_group",
  584. "pagination": {
  585. "first": "http://localhost...",
  586. "last": "http://localhost...",
  587. "next": None,
  588. "page": 1,
  589. "pages": 0,
  590. "per_page": 20,
  591. "prev": None,
  592. },
  593. "projects": [],
  594. "total_projects": 0,
  595. }
  596. data = json.loads(output.get_data(as_text=True))
  597. data["date_created"] = "1492020239"
  598. self.assertIsNotNone(data["pagination"]["first"])
  599. data["pagination"]["first"] = "http://localhost..."
  600. self.assertIsNotNone(data["pagination"]["last"])
  601. data["pagination"]["last"] = "http://localhost..."
  602. self.assertDictEqual(data, exp)
  603. def test_api_view_group_w_projects_and_acl_ticket_no_project(self):
  604. """
  605. Test the api_view_group method with project info and restricted
  606. to the ticket ACL
  607. """
  608. # Create a group not linked to any project
  609. item = pagure.lib.model.PagureGroup(
  610. group_name="rel-eng",
  611. group_type="user",
  612. display_name="Release engineering group",
  613. user_id=1, # pingou
  614. )
  615. self.session.add(item)
  616. self.session.commit()
  617. output = self.app.get("/api/0/group/rel-eng?projects=1&acl=ticket")
  618. self.assertEqual(output.status_code, 200)
  619. exp = {
  620. "display_name": "Release engineering group",
  621. "description": None,
  622. "creator": {
  623. "fullname": "PY C",
  624. "name": "pingou",
  625. "url_path": "user/pingou",
  626. },
  627. "members": [],
  628. "date_created": "1492020239",
  629. "group_type": "user",
  630. "name": "rel-eng",
  631. "pagination": {
  632. "first": "http://localhost...",
  633. "last": "http://localhost...",
  634. "next": None,
  635. "page": 1,
  636. "pages": 0,
  637. "per_page": 20,
  638. "prev": None,
  639. },
  640. "projects": [],
  641. "total_projects": 0,
  642. }
  643. data = json.loads(output.get_data(as_text=True))
  644. data["date_created"] = "1492020239"
  645. self.assertIsNotNone(data["pagination"]["first"])
  646. data["pagination"]["first"] = "http://localhost..."
  647. self.assertIsNotNone(data["pagination"]["last"])
  648. data["pagination"]["last"] = "http://localhost..."
  649. self.assertDictEqual(data, exp)
  650. if __name__ == "__main__":
  651. unittest.main(verbosity=2)