# -*- coding: utf-8 -*- """ (c) 2015 - Copyright Red Hat Inc Authors: Pierre-Yves Chibon """ from __future__ import unicode_literals, absolute_import import unittest import shutil import sys import os import json from mock import patch, MagicMock import pygit2 import pytest sys.path.insert( 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") ) import pagure.api import pagure.flask_app import pagure.lib.query import tests def set_projects_up(self): tests.create_projects(self.session) tests.create_projects_git(os.path.join(self.path, "repos"), bare=True) tests.add_content_git_repo(os.path.join(self.path, "repos", "test.git")) tests.create_tokens(self.session) tests.create_tokens_acl(self.session) tag = pagure.lib.model.TagColored( tag="dev", tag_color="DeepBlueSky", project_id=1 ) self.session.add(tag) tag = pagure.lib.model.TagColored( tag="infra", tag_color="DeepGreen", project_id=1 ) self.session.add(tag) self.session.commit() def set_up_board(self): headers = { "Authorization": "token aaabbbcccddd", "Content-Type": "application/json", } data = json.dumps({"dev": {"active": True, "tag": "dev"}}) output = self.app.post("/api/0/test/boards", headers=headers, data=data) self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) self.assertDictEqual( data, { "boards": [ { "active": True, "name": "dev", "status": [], "tag": { "tag": "dev", "tag_color": "DeepBlueSky", "tag_description": "", }, } ] }, ) class PagureFlaskUiBoardstests(tests.SimplePagureTest): """ Tests for flask UI Boards controller of pagure """ maxDiff = None def setUp(self): super(PagureFlaskUiBoardstests, self).setUp() set_projects_up(self) set_up_board(self) # Set up the ticket repo tests.create_projects_git( os.path.join(self.path, "repos", "tickets"), bare=True ) # Set up some status to the board headers = { "Authorization": "token aaabbbcccddd", "Content-Type": "application/json", } data = json.dumps( { "Backlog": { "close": False, "close_status": "", "bg_color": "#FFB300", "default": True, "rank": 1, }, "In Progress": { "close": False, "close_status": "", "bg_color": "#ca0eef", "default": False, "rank": 2, }, "Done": { "close": True, "close_status": "Fixed", "bg_color": "#34d240", "default": False, "rank": 4, }, } ) output = self.app.post( "/api/0/test/boards/dev/status", headers=headers, data=data ) self.assertEqual(output.status_code, 200) # Create two issues to play with repo = pagure.lib.query.get_authorized_project(self.session, "test") msg = pagure.lib.query.new_issue( session=self.session, repo=repo, title="Test issue", content="We should work on this", user="pingou", ) self.session.commit() self.assertEqual(msg.title, "Test issue") self.assertEqual(repo.open_tickets, 1) self.assertEqual(repo.open_tickets_public, 1) msg = pagure.lib.query.new_issue( session=self.session, repo=repo, title="Test issue #2", content="We should work on this for the second time", user="foo", status="Open", ) self.session.commit() self.assertEqual(msg.title, "Test issue #2") self.assertEqual(repo.open_tickets, 2) self.assertEqual(repo.open_tickets_public, 2) msg = pagure.lib.query.new_issue( session=self.session, repo=repo, title="Private issue #3", content="We should work on this for the second time", user="foo", status="Open", private=True, ) self.session.commit() self.assertEqual(msg.title, "Private issue #3") self.assertEqual(repo.open_tickets, 3) self.assertEqual(repo.open_tickets_public, 2) self.tickets_uid = [t.uid for t in repo.issues] def test_view_board_empty(self): output = self.app.get("/test/boards/dev") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # There are 3 columns self.assertEqual(output_text.count("drag-inner-list"), 3) self.assertEqual(output_text.count("drag-inner"), 3) # No tickets self.assertEqual(output_text.count("text-success"), 0) # One (!) in the nav bar on the issues title self.assertEqual(output_text.count("fa-exclamation-circle"), 1) @patch("pagure.lib.git.update_git", MagicMock(return_value=True)) @patch("pagure.lib.notify.send_email", MagicMock(return_value=True)) def test_update_issue_add_tags_check_board_not_tagged(self): """ Test the update_issue endpoint. """ # Before update, list tags repo = pagure.lib.query.get_authorized_project(self.session, "test") tags = pagure.lib.query.get_tags_of_project(self.session, repo) self.assertEqual([tag.tag for tag in tags], ["dev", "infra"]) self.assertEqual(repo.issues[0].tags_text, []) user = tests.FakeUser() user.username = "pingou" with tests.user_set(self.app.application, user): csrf_token = self.get_csrf() # Tag to the issue data = {"csrf_token": csrf_token, "tag": "infra"} output = self.app.post( "/test/issue/1/update", data=data, follow_redirects=True ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertIn( "Issue #1: Test issue - test - Pagure", output_text, ) self.assertIn( '', output_text, ) self.assertIn(" Issue tagged with: infra", output_text) # After update, list tags self.session = pagure.lib.query.create_session(self.dbpath) repo = pagure.lib.query.get_authorized_project(self.session, "test") tags = pagure.lib.query.get_tags_of_project(self.session, repo) self.assertEqual([tag.tag for tag in tags], ["dev", "infra"]) self.assertEqual(repo.issues[0].tags_text, ["infra"]) self.assertEqual(repo.issues[1].tags_text, []) # Check the board - No changes since the ticket was tagged `infra` output = self.app.get("/test/boards/dev") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # There are 3 columns self.assertEqual(output_text.count("drag-inner-list"), 3) self.assertEqual(output_text.count("drag-inner"), 3) # 0 ticket self.assertEqual(output_text.count("id_txt"), 0) self.assertEqual(output_text.count("text-success"), 0) self.assertEqual(output_text.count("text-danger"), 0) # One (!) in the nav bar on the issues title self.assertEqual(output_text.count("fa-exclamation-circle"), 1) @patch("pagure.lib.git.update_git", MagicMock(return_value=True)) @patch("pagure.lib.notify.send_email", MagicMock(return_value=True)) def test_update_issue_add_tags_check_board(self): """ Test the update_issue endpoint. """ # Before update, list tags repo = pagure.lib.query.get_authorized_project(self.session, "test") tags = pagure.lib.query.get_tags_of_project(self.session, repo) self.assertEqual([tag.tag for tag in tags], ["dev", "infra"]) self.assertEqual(repo.issues[0].tags_text, []) user = tests.FakeUser() user.username = "pingou" with tests.user_set(self.app.application, user): csrf_token = self.get_csrf() # Tag to the issue data = {"csrf_token": csrf_token, "tag": "dev"} output = self.app.post( "/test/issue/1/update", data=data, follow_redirects=True ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertIn( "Issue #1: Test issue - test - Pagure", output_text, ) self.assertIn( '', output_text, ) self.assertIn(" Issue tagged with: dev", output_text) # After update, list tags self.session = pagure.lib.query.create_session(self.dbpath) repo = pagure.lib.query.get_authorized_project(self.session, "test") tags = pagure.lib.query.get_tags_of_project(self.session, repo) self.assertEqual([tag.tag for tag in tags], ["dev", "infra"]) self.assertEqual(repo.issues[0].tags_text, ["dev"]) self.assertEqual(repo.issues[1].tags_text, []) # Check the board - Ticket added output = self.app.get("/test/boards/dev") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # There are 3 columns self.assertEqual(output_text.count("drag-inner-list"), 3) self.assertEqual(output_text.count("drag-inner"), 3) # One ticket self.assertEqual(output_text.count(" id_txt"), 1) self.assertEqual(output_text.count(" text-success"), 1) self.assertEqual(output_text.count(" text-danger"), 0) # Two (!) in the nav bar on the issues title + the ticket self.assertEqual(output_text.count("fa-exclamation-circle"), 2) @patch("pagure.lib.git.update_git", MagicMock(return_value=True)) @patch("pagure.lib.notify.send_email", MagicMock(return_value=True)) def test_update_issue_add_tags_check_board_remove_tag_check_board(self): """ Test the update_issue endpoint. """ # Before update, list tags repo = pagure.lib.query.get_authorized_project(self.session, "test") tags = pagure.lib.query.get_tags_of_project(self.session, repo) self.assertEqual([tag.tag for tag in tags], ["dev", "infra"]) self.assertEqual(repo.issues[0].tags_text, []) user = tests.FakeUser() user.username = "pingou" with tests.user_set(self.app.application, user): csrf_token = self.get_csrf() # Tag to the issue data = {"csrf_token": csrf_token, "tag": "dev"} output = self.app.post( "/test/issue/1/update", data=data, follow_redirects=True ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertIn( "Issue #1: Test issue - test - Pagure", output_text, ) self.assertIn( '', output_text, ) self.assertIn(" Issue tagged with: dev", output_text) # After update, list tags self.session = pagure.lib.query.create_session(self.dbpath) repo = pagure.lib.query.get_authorized_project(self.session, "test") tags = pagure.lib.query.get_tags_of_project(self.session, repo) self.assertEqual([tag.tag for tag in tags], ["dev", "infra"]) self.assertEqual(repo.issues[0].tags_text, ["dev"]) self.assertEqual(repo.issues[1].tags_text, []) # Check the board - Ticket added output = self.app.get("/test/boards/dev") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # There are 3 columns self.assertEqual(output_text.count("drag-inner-list"), 3) self.assertEqual(output_text.count("drag-inner"), 3) # One ticket self.assertEqual(output_text.count(" id_txt"), 1) self.assertEqual(output_text.count(" text-success"), 1) self.assertEqual(output_text.count(" text-danger"), 0) # Two (!) in the nav bar on the issues title + the ticket self.assertEqual(output_text.count("fa-exclamation-circle"), 2) # Now remove the "dev" tag in favor of the "infra" one user = tests.FakeUser() user.username = "pingou" with tests.user_set(self.app.application, user): csrf_token = self.get_csrf() # Tag to the issue data = {"csrf_token": csrf_token, "tag": "infra"} output = self.app.post( "/test/issue/1/update", data=data, follow_redirects=True ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertIn( "Issue #1: Test issue - test - Pagure", output_text, ) self.assertIn( '', output_text, ) self.assertIn(" Issue tagged with: infra", output_text) # After update, list tags self.session = pagure.lib.query.create_session(self.dbpath) repo = pagure.lib.query.get_authorized_project(self.session, "test") tags = pagure.lib.query.get_tags_of_project(self.session, repo) self.assertEqual([tag.tag for tag in tags], ["dev", "infra"]) self.assertEqual(repo.issues[0].tags_text, ["infra"]) self.assertEqual(repo.issues[1].tags_text, []) # Check the board - Ticket added output = self.app.get("/test/boards/dev") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # There are 3 columns self.assertEqual(output_text.count("drag-inner-list"), 3) self.assertEqual(output_text.count("drag-inner"), 3) # 0 ticket self.assertEqual(output_text.count(" id_txt"), 0) self.assertEqual(output_text.count(" text-success"), 0) self.assertEqual(output_text.count(" text-danger"), 0) # One (!) in the nav bar on the issues title self.assertEqual(output_text.count("fa-exclamation-circle"), 1) def test_view_board_ticket_closed(self): headers = {"Content-Type": "application/json"} data = json.dumps({"2": {"status": "Done", "rank": 2}}) user = tests.FakeUser() user.username = "pingou" with tests.user_set(self.app.application, user): output = self.app.post( "/api/0/test/boards/dev/add_issue", headers=headers, data=data ) self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) self.session = pagure.lib.query.create_session(self.dbpath) repo = pagure.lib.query.get_authorized_project(self.session, "test") self.assertEqual(repo.issues[0].status, "Open") self.assertEqual(repo.issues[1].status, "Closed") self.assertEqual(repo.issues[1].close_status, "Fixed") # Check the board - Ticket added - as Done output = self.app.get("/test/boards/dev") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # There are 3 columns self.assertEqual(output_text.count("drag-inner-list"), 3) self.assertEqual(output_text.count("drag-inner"), 3) # One ticket self.assertEqual(output_text.count(" id_txt"), 1) self.assertEqual(output_text.count(" text-success"), 0) self.assertEqual(output_text.count(" text-danger"), 1) # Two (!) in the nav bar on the issues title + the ticket self.assertEqual(output_text.count("fa-exclamation-circle"), 2) def test_view_board_private_ticket(self): user = tests.FakeUser() user.username = "pingou" with tests.user_set(self.app.application, user): headers = {"Content-Type": "application/json"} data = json.dumps({"3": {"status": "Done", "rank": 2}}) output = self.app.post( "/api/0/test/boards/dev/add_issue", headers=headers, data=data ) self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) self.session = pagure.lib.query.create_session(self.dbpath) repo = pagure.lib.query.get_authorized_project(self.session, "test") self.assertEqual(repo.issues[0].status, "Open") self.assertEqual(len(repo.issues[0].boards_issues), 0) self.assertEqual(repo.issues[1].status, "Open") self.assertEqual(len(repo.issues[1].boards_issues), 0) self.assertEqual(repo.issues[2].status, "Closed") self.assertEqual(repo.issues[2].close_status, "Fixed") self.assertEqual(len(repo.issues[2].boards_issues), 1) # Check the board - Looks empty user not authenticated output = self.app.get("/test/boards/dev") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # There are 3 columns self.assertEqual(output_text.count("drag-inner-list"), 3) self.assertEqual(output_text.count("drag-inner"), 3) # 0 ticket self.assertEqual(output_text.count(" id_txt"), 0) self.assertEqual(output_text.count("text-success"), 0) self.assertEqual(output_text.count("text-danger"), 0) # 1 (!) in the nav bar on the issues title self.assertEqual(output_text.count("fa-exclamation-circle"), 1) self.assertEqual(output_text.count('title="Private ticket"'), 0) user = tests.FakeUser() user.username = "ralph" with tests.user_set(self.app.application, user): # Check the board - Looks empty user not allowed output = self.app.get("/test/boards/dev") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # There are 3 columns self.assertEqual(output_text.count("drag-inner-list"), 3) self.assertEqual(output_text.count("drag-inner"), 3) # 0 ticket self.assertEqual(output_text.count(" id_txt"), 0) self.assertEqual(output_text.count("text-success"), 0) self.assertEqual(output_text.count("text-danger"), 0) # 1 (!) in the nav bar on the issues title self.assertEqual(output_text.count("fa-exclamation-circle"), 2) self.assertEqual(output_text.count('title="Private ticket"'), 0) user = tests.FakeUser() user.username = "foo" with tests.user_set(self.app.application, user): # Check the board - 1 ticket output = self.app.get("/test/boards/dev") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # There are 3 columns self.assertEqual(output_text.count("drag-inner-list"), 3) self.assertEqual(output_text.count("drag-inner"), 3) # 1 ticket self.assertEqual(output_text.count(" id_txt"), 1) self.assertEqual(output_text.count(" text-success"), 0) self.assertEqual(output_text.count(" text-danger"), 1) # 2 (!) in the nav bar on the issues title self.assertEqual(output_text.count("fa-exclamation-circle"), 3) self.assertEqual(output_text.count('title="Private ticket"'), 1) user = tests.FakeUser() user.username = "pingou" with tests.user_set(self.app.application, user): # Check the board - 1 ticket output = self.app.get("/test/boards/dev") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) # There are 3 columns self.assertEqual(output_text.count("drag-inner-list"), 3) self.assertEqual(output_text.count("drag-inner"), 3) # 1 ticket self.assertEqual(output_text.count(" id_txt"), 1) self.assertEqual(output_text.count(" text-success"), 0) self.assertEqual(output_text.count(" text-danger"), 1) # 2 (!) in the nav bar on the issues title self.assertEqual(output_text.count("fa-exclamation-circle"), 3) self.assertEqual(output_text.count('title="Private ticket"'), 1) @patch("pagure.lib.notify.send_email", new=MagicMock(return_value=True)) def test_ticket_representation_in_git(self): user = tests.FakeUser() user.username = "pingou" with tests.user_set(self.app.application, user): csrf_token = self.get_csrf() # Tag to the issue data = {"csrf_token": csrf_token, "tag": "dev"} output = self.app.post( "/test/issue/1/update", data=data, follow_redirects=True ) self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) self.assertIn( "Issue #1: Test issue - test - Pagure", output_text, ) self.assertIn( '', output_text, ) self.assertIn(" Issue tagged with: dev", output_text) # After update, list tags self.session = pagure.lib.query.create_session(self.dbpath) repo = pagure.lib.query.get_authorized_project(self.session, "test") tags = pagure.lib.query.get_tags_of_project(self.session, repo) self.assertEqual([tag.tag for tag in tags], ["dev", "infra"]) self.assertEqual(repo.issues[0].tags_text, ["dev"]) self.assertEqual(repo.issues[1].tags_text, []) self.session = pagure.lib.query.create_session(self.dbpath) repo = pagure.lib.query.get_authorized_project(self.session, "test") self.assertEqual(repo.issues[1].status, "Open") self.assertEqual(repo.issues[1].close_status, None) # Clone the repo so it isn't a bare repo pygit2.clone_repository( os.path.join(self.path, "repos", "tickets", "test.git"), os.path.join(self.path, "repos", "tickets", "test"), ) exp = { "assignee": None, "blocks": [], "boards": [ { "board": { "active": True, "name": "dev", "status": [ { "bg_color": "#FFB300", "close": False, "close_status": None, "default": True, "name": "Backlog", }, { "bg_color": "#ca0eef", "close": False, "close_status": None, "default": False, "name": "In Progress", }, { "bg_color": "#34d240", "close": True, "close_status": "Fixed", "default": False, "name": "Done", }, ], "tag": { "tag": "dev", "tag_color": "DeepBlueSky", "tag_description": "", }, }, "rank": 1, "status": { "bg_color": "#FFB300", "close": False, "close_status": None, "default": True, "name": "Backlog", }, } ], "close_status": None, "closed_at": None, "closed_by": None, "comments": [ { "comment": "**Metadata Update from @pingou**:\n" "- Issue tagged with: dev", "date_created": "1594654596", "edited_on": None, "editor": None, "id": 1, "notification": True, "parent": None, "reactions": {}, "user": { "default_email": "bar@pingou.com", "emails": ["bar@pingou.com", "foo@pingou.com"], "fullname": "PY C", "name": "pingou", "url_path": "user/pingou", }, } ], "content": "We should work on this", "custom_fields": [], "date_created": "1594654596", "depends": [], "id": 1, "last_updated": "1594654596", "milestone": None, "priority": None, "private": False, "related_prs": [], "status": "Open", "tags": ["dev"], "title": "Test issue", "user": { "default_email": "bar@pingou.com", "emails": ["bar@pingou.com", "foo@pingou.com"], "fullname": "PY C", "name": "pingou", "url_path": "user/pingou", }, } with open( os.path.join( self.path, "repos", "tickets", "test", repo.issues[0].uid ) ) as stream: data = json.load(stream) # Make the date fix for idx, com in enumerate(data["comments"]): com["date_created"] = "1594654596" data["comments"][idx] = com data["date_created"] = "1594654596" data["last_updated"] = "1594654596" self.assertDictEqual(data, exp) if __name__ == "__main__": unittest.main(verbosity=2)