diff --git a/repoapi/test/__init__.py b/repoapi/test/__init__.py index 819ab3b..b04586f 100644 --- a/repoapi/test/__init__.py +++ b/repoapi/test/__init__.py @@ -14,6 +14,7 @@ # with this program. If not, see . import filecmp from difflib import unified_diff +from io import StringIO from pathlib import Path @@ -32,3 +33,19 @@ def check_output(output_file, test_file): for line in diff: print(line, end="") assert filecmp.cmp(output_file, test_file) + + +def check_stdoutput(stdout: StringIO, test_file: Path): + assert test_file.exists() + flag = False + with open(test_file) as test: + diff = unified_diff( + stdout.getvalue().splitlines(), + test.readlines(), + fromfile="stdout", + tofile=str(test_file.absolute()), + ) + for line in diff: + flag = True + print(line, end="") + assert not flag diff --git a/tracker/management/commands/mantis.py b/tracker/management/commands/mantis.py new file mode 100644 index 0000000..548525c --- /dev/null +++ b/tracker/management/commands/mantis.py @@ -0,0 +1,63 @@ +# Copyright (C) 2022 The Sipwise Team - http://sipwise.com +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +from django.core.management.base import BaseCommand +from django.core.management.base import CommandError + +from tracker.utils import mantis_get_issue +from tracker.utils import mantis_get_issue_id +from tracker.utils import mantis_get_target_releases +from tracker.utils import mantis_set_release_target + + +class Command(BaseCommand): + help = "mantis API helper" + + def add_arguments(self, parser): + parser.add_argument( + "command", + choices=["get-issue", "set-target-release", "get-target-release"], + ) + parser.add_argument("--mantis-id", type=int) + parser.add_argument("--value", type=str) + parser.add_argument("--force", action="store_true", default=False) + + def get_mantis_id(self, **options): + if options["mantis_id"] is None: + raise CommandError("--mantis-id missing") + return options["mantis_id"] + + def handle(self, *args, **options): + if options["command"] == "get-issue": + mantis_id = self.get_mantis_id(**options) + issue = mantis_get_issue(mantis_id) + self.stdout.write(f"{issue}") + elif options["command"] == "get-target-release": + mantis_id = self.get_mantis_id(**options) + issue = mantis_get_issue(mantis_id) + releases = mantis_get_target_releases(issue) + self.stdout.write(f"{releases}") + elif options["command"] == "set-target-release": + mantis_id = self.get_mantis_id(**options) + if options["value"] is None: + raise CommandError("--value missing") + res = mantis_set_release_target( + mantis_id, options["value"], options["force"] + ) + if res: + issue = mantis_get_issue_id(res.json(), mantis_id) + releases = mantis_get_target_releases(issue) + self.stdout.write(f"{releases}") + else: + self.stdout.write("value already in target_release") diff --git a/tracker/test/test_commands.py b/tracker/test/test_commands.py index bfa531d..90f50f8 100644 --- a/tracker/test/test_commands.py +++ b/tracker/test/test_commands.py @@ -13,19 +13,30 @@ # You should have received a copy of the GNU General Public License along # with this program. If not, see . from io import StringIO +from unittest.mock import call +from unittest.mock import patch from django.conf import settings from django.core.management import call_command +from django.core.management.base import CommandError from django.test import TestCase +from .test_utils import FakeResponse +from .test_utils import FakeResponseFile +from .test_utils import set_target_release_value +from tracker import utils from tracker.conf import MapperType +from tracker.exceptions import IssueNotFound from tracker.models import TrackerMapper FIXTURES_PATH = settings.BASE_DIR.joinpath("tracker", "fixtures") DB_FILE = FIXTURES_PATH.joinpath("mapper.db") +MANTIS_ISSUE_JSON = FIXTURES_PATH.joinpath("mantis_issue.json") +MANTIS_ISSUE_ID = 36018 +ISSUE_URL = "https://support.local/api/rest/issues/36018" -class createFakeBuildReleaseTest(TestCase): +class mapperImportTest(TestCase): fixtures = ["test_models"] def test_ok(self): @@ -38,3 +49,72 @@ class createFakeBuildReleaseTest(TestCase): self.assertEqual(val, 10) val = qs.filter(mapper_type=MapperType.TASK).count() self.assertEqual(val, 10) + + +class mantisTest(TestCase): + def setUp(self): + self.out = StringIO() + + def test_get_issue_ko(self): + with self.assertRaises(CommandError): + call_command("mantis", stdout=self.out) + + @patch( + "tracker.utils.mantis_query", + return_value=FakeResponseFile(MANTIS_ISSUE_JSON), + ) + def test_get_issue_wrong_id(self, mq): + wrong_id = 36017 + with self.assertRaises(IssueNotFound): + call_command( + "mantis", "get-issue", "--mantis-id", wrong_id, stdout=self.out + ) + calls = [ + call("GET", f"https://support.local/api/rest/issues/{wrong_id}") + ] + mq.assert_has_calls(calls) + + @patch( + "tracker.utils.mantis_query", + return_value=FakeResponseFile(MANTIS_ISSUE_JSON), + ) + def test_get_issue(self, mq): + call_command( + "mantis", + "get-issue", + "--mantis-id", + MANTIS_ISSUE_ID, + stdout=self.out, + ) + calls = [ + call( + "GET", + ISSUE_URL, + ) + ] + mq.assert_has_calls(calls) + + @patch("tracker.utils.mantis_query") + def test_get_target_release(self, mq): + fake_issue_patched = utils.mantis_get_issue_id( + FakeResponseFile(MANTIS_ISSUE_JSON).json(), MANTIS_ISSUE_ID + ) + fake_issues = {"issues": [fake_issue_patched]} + set_target_release_value(fake_issue_patched, "mr10.1,mr10.1.1") + mq.configure_mock(return_value=FakeResponse(fake_issues)) + call_command( + "mantis", + "get-target-release", + "--mantis-id", + MANTIS_ISSUE_ID, + stdout=self.out, + ) + calls = [ + call( + "GET", + ISSUE_URL, + ) + ] + mq.assert_has_calls(calls) + mq.assert_called_once_with("GET", ISSUE_URL) + self.assertRegex(self.out.getvalue(), "[mr10.1, ,r10.1.1]")