diff --git a/repoapi/settings/prod.py b/repoapi/settings/prod.py index be0bced..c45373a 100644 --- a/repoapi/settings/prod.py +++ b/repoapi/settings/prod.py @@ -71,7 +71,11 @@ GERRIT_REST_HTTP_PASSWD = server_config.get("gerrit", "HTTP_PASSWD") TRACKER_MANTIS_URL = server_config.get("mantis", "URL") TRACKER_MANTIS_TOKEN = server_config.get("mantis", "TOKEN") - +mantis_parsed = urlparse(TRACKER_MANTIS_URL) +TRACKER_MANTIS_MAPPER_URL = ( + f"{mantis_parsed.scheme}://{mantis_parsed.netloc}/view.php?id=" + + "{mantis_id}" +) DOCKER_REGISTRY_URL = server_config.get("server", "DOCKER_REGISTRY_URL") AUTH_LDAP_SERVER_URI = server_config.get("server", "AUTH_LDAP_SERVER_URI") AUTH_LDAP_USER_BASE = server_config.get("server", "AUTH_LDAP_USER_BASE") diff --git a/repoapi/urls.py b/repoapi/urls.py index 529ae83..916d138 100644 --- a/repoapi/urls.py +++ b/repoapi/urls.py @@ -126,4 +126,5 @@ urlpatterns = [ r"^release_panel/", include("release_dashboard.urls"), ), + path("tracker/", include("tracker.urls")), ] diff --git a/tracker/conf.py b/tracker/conf.py index 422cb73..bb68c08 100644 --- a/tracker/conf.py +++ b/tracker/conf.py @@ -41,6 +41,7 @@ class TrackerConf(AppConf): ] WORKFRONT_CREDENTIALS = "fake.txt" MANTIS_URL = "https://support.local/api/rest/{}" + MANTIS_MAPPER_URL = "https://support.local/view.php?id={mantis_id}" MANTIS_TOKEN = "fake_mantis_token" MANTIS_TARGET_RELEASE = { "id": 75, diff --git a/tracker/fixtures/test_mapper.yaml b/tracker/fixtures/test_mapper.yaml new file mode 100644 index 0000000..55f53bb --- /dev/null +++ b/tracker/fixtures/test_mapper.yaml @@ -0,0 +1,28 @@ +- model: tracker.trackermapper + pk: 22203 + fields: + mapper_type: MapperType.ISSUE + mantis_id: '33066' + workfront_id: '1022' + workfront_uuid: 577a4dfb004111d28a015ed5a24512a4 +- model: tracker.trackermapper + pk: 22204 + fields: + mapper_type: MapperType.ISSUE + mantis_id: '33067' + workfront_id: '1409' + workfront_uuid: 578361d400272e6da7322db6892afad7 +- model: tracker.trackermapper + pk: 44403 + fields: + mapper_type: MapperType.TASK + mantis_id: '55281' + workfront_id: '190550' + workfront_uuid: 631a44c3003b6b837d569b4f15a2d4dd +- model: tracker.trackermapper + pk: 44404 + fields: + mapper_type: MapperType.TASK + mantis_id: '55282' + workfront_id: '190650' + workfront_uuid: 631ee19a0283b8913a3ed6e6938bbd6d diff --git a/tracker/models.py b/tracker/models.py index 6842ca3..70d3d8b 100644 --- a/tracker/models.py +++ b/tracker/models.py @@ -15,6 +15,7 @@ import re from django.db import models +from django.db.models import Q from . import utils from .conf import MapperType @@ -77,6 +78,20 @@ class MantisInfo(TrackerInfo): return utils.mantis_set_release_target(self.mantis_id, release) +class TrackerMapperManager(models.Manager): + def get_workfront_issue_qs(self, _id): + return self.get_queryset().filter( + Q(workfront_id=_id) | Q(workfront_uuid=_id), + mapper_type=MapperType.ISSUE, + ) + + def get_workfront_task_qs(self, _id): + return self.get_queryset().filter( + Q(workfront_id=_id) | Q(workfront_uuid=_id), + mapper_type=MapperType.TASK, + ) + + class TrackerMapper(models.Model): mapper_type = models.CharField( max_length=50, choices=[(tag, tag.value) for tag in MapperType] @@ -84,6 +99,7 @@ class TrackerMapper(models.Model): mantis_id = models.CharField(max_length=50, null=False, unique=True) workfront_id = models.CharField(max_length=50, null=False, unique=True) workfront_uuid = models.CharField(max_length=50, null=False, unique=True) + objects = TrackerMapperManager() def __str__(self): return f"{self.mapper_type}:TT#{self.workfront_id}:MT#{self.mantis_id}" diff --git a/tracker/test/test_conf.py b/tracker/test/test_conf.py new file mode 100644 index 0000000..e781bab --- /dev/null +++ b/tracker/test/test_conf.py @@ -0,0 +1,42 @@ +# 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 . +import unittest +from urllib.parse import urlparse + +from django.test import SimpleTestCase + + +class TestTrackerConf(SimpleTestCase): + @unittest.expectedFailure + def test_django_settings(self): + from django.conf import settings + + self.assertIsNotNone(settings.TRACKER_MANTIS_URL) + + @unittest.expectedFailure + def test_tracker_settings(self): + from tracker.conf import settings + + self.assertIsNotNone(settings.TRACKER_MANTIS_URL) + + def test_dynamic(self): + from tracker.conf import TrackerConf + + tracker_settings = TrackerConf() + parsed = urlparse(tracker_settings.MANTIS_URL) + MANTIS_MAPPER_URL = ( + f"{parsed.scheme}://{parsed.netloc}/view.php?id=" + "{mantis_id}" + ) + self.assertEqual(MANTIS_MAPPER_URL, tracker_settings.MANTIS_MAPPER_URL) diff --git a/tracker/test/test_models.py b/tracker/test/test_models.py new file mode 100644 index 0000000..e758213 --- /dev/null +++ b/tracker/test/test_models.py @@ -0,0 +1,34 @@ +# 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 repoapi.test.base import BaseTest +from tracker.models import TrackerMapper + + +class TrackerMapperTest(BaseTest): + fixtures = ["test_mapper"] + ISSUE_id = "1022" + ISSUE_uuid = "577a4dfb004111d28a015ed5a24512a4" + TASK_id = "190650" + TASK_uuid = "631ee19a0283b8913a3ed6e6938bbd6d" + + def test_get_workfront_issue_qs(self): + qs_uuid = TrackerMapper.objects.get_workfront_issue_qs(self.ISSUE_uuid) + qs_id = TrackerMapper.objects.get_workfront_issue_qs(self.ISSUE_id) + self.assertEqual(qs_uuid.count(), 1) + self.assertEqual(qs_id.first(), qs_uuid.first()) + + def test_get_workfront_issue_qs_ko(self): + qs_uuid = TrackerMapper.objects.get_workfront_issue_qs("fake") + self.assertEqual(qs_uuid.count(), 0) diff --git a/tracker/test/test_views.py b/tracker/test/test_views.py new file mode 100644 index 0000000..6d5f7ab --- /dev/null +++ b/tracker/test/test_views.py @@ -0,0 +1,78 @@ +# 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.urls import reverse + +from repoapi.test.base import BaseTest +from tracker.conf import TrackerConf + +tracker_settings = TrackerConf() + + +class TrackerMapperTest(BaseTest): + fixtures = ["test_mapper"] + ISSUE_mantis = "33066" + ISSUE_id = "1022" + ISSUE_uuid = "577a4dfb004111d28a015ed5a24512a4" + TASK_mantis = "55282" + TASK_id = "190650" + TASK_uuid = "631ee19a0283b8913a3ed6e6938bbd6d" + + def test_issue_uuid(self): + res = self.client.get( + reverse("tracker:mapper-issues", args=[self.ISSUE_uuid]) + ) + self.assertEqual(res.status_code, 301) + self.assertEqual( + res.url, + tracker_settings.MANTIS_MAPPER_URL.format( + mantis_id=self.ISSUE_mantis + ), + ) + + def test_issue_id(self): + res = self.client.get( + reverse("tracker:mapper-issues", args=[self.ISSUE_id]) + ) + self.assertEqual(res.status_code, 301) + self.assertEqual( + res.url, + tracker_settings.MANTIS_MAPPER_URL.format( + mantis_id=self.ISSUE_mantis + ), + ) + + def test_task_uuid(self): + res = self.client.get( + reverse("tracker:mapper-tasks", args=[self.TASK_uuid]) + ) + self.assertEqual(res.status_code, 301) + self.assertEqual( + res.url, + tracker_settings.MANTIS_MAPPER_URL.format( + mantis_id=self.TASK_mantis + ), + ) + + def test_task_id(self): + res = self.client.get( + reverse("tracker:mapper-tasks", args=[self.TASK_id]) + ) + self.assertEqual(res.status_code, 301) + self.assertEqual( + res.url, + tracker_settings.MANTIS_MAPPER_URL.format( + mantis_id=self.TASK_mantis + ), + ) diff --git a/tracker/urls.py b/tracker/urls.py new file mode 100644 index 0000000..ebb5e7c --- /dev/null +++ b/tracker/urls.py @@ -0,0 +1,31 @@ +# 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.urls import path + +from . import views + +app_name = "tracker" +urlpatterns = [ + path( + "mapper/issue//", + views.WFIssueRedirectView.as_view(), + name="mapper-issues", + ), + path( + "mapper/task//", + views.WFTaskRedirectView.as_view(), + name="mapper-tasks", + ), +] diff --git a/tracker/views.py b/tracker/views.py new file mode 100644 index 0000000..f107f00 --- /dev/null +++ b/tracker/views.py @@ -0,0 +1,52 @@ +# 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.shortcuts import get_object_or_404 +from django.views.generic.base import RedirectView + +from .conf import MapperType +from .conf import TrackerConf +from .models import TrackerMapper + +tracker_settings = TrackerConf() + + +class WFIssueRedirectView(RedirectView): + permanent = True + query_string = True + url = tracker_settings.MANTIS_MAPPER_URL + + def get_redirect_url(self, *args, **kwargs): + issue = get_object_or_404( + TrackerMapper.objects.get_workfront_issue_qs( + kwargs["workfront_id"] + ), + mapper_type=MapperType.ISSUE, + ) + return self.url.format(mantis_id=issue.mantis_id) + + +class WFTaskRedirectView(RedirectView): + permanent = True + query_string = True + url = tracker_settings.MANTIS_MAPPER_URL + + def get_redirect_url(self, *args, **kwargs): + issue = get_object_or_404( + TrackerMapper.objects.get_workfront_task_qs( + kwargs["workfront_id"] + ), + mapper_type=MapperType.TASK, + ) + return self.url.format(mantis_id=issue.mantis_id)