# pylint: disable=no-self-use
import traceback
from django import forms
from django.conf import settings
from django.contrib import admin, messages
from django.forms.widgets import Select
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.module_loading import import_string
from django.utils.translation import gettext_lazy as _
from tcms.core.admin import ObjectPermissionsAdminMixin
from tcms.core.history import ReadOnlyHistoryAdmin
from tcms.core.widgets import SimpleMDE
from tcms.testcases.models import (
BugSystem,
Category,
Template,
TestCase,
TestCaseStatus,
)
[docs]
class TestCaseStatusAdmin(admin.ModelAdmin):
_for_more_info = _(
"""For more information about customizing test case statuses see
<a href="https://kiwitcms.readthedocs.io/en/latest/admin.html#test-case-statuses">
the documentation</a>!"""
)
list_display = ("id", "name", "is_confirmed")
ordering = ["-is_confirmed", "id"]
fieldsets = [
(
"",
{
"fields": ("name", "description", "is_confirmed"),
"description": f"<h1>{_for_more_info}</h1>",
},
),
]
[docs]
@admin.options.csrf_protect_m
def delete_view(self, request, object_id, extra_context=None):
obj = self.model.objects.get(pk=object_id)
if (
not self.model.objects.filter(is_confirmed=obj.is_confirmed)
.exclude(pk=object_id)
.exists()
):
messages.add_message(
request,
messages.ERROR,
_("1 confirmed & 1 uncomfirmed status required!"),
)
return HttpResponseRedirect(
reverse("admin:testcases_testcasestatus_changelist")
)
return super().delete_view(request, object_id, extra_context)
[docs]
class TestCaseAdmin(ObjectPermissionsAdminMixin, ReadOnlyHistoryAdmin):
[docs]
def add_view(self, request, form_url="", extra_context=None):
return HttpResponseRedirect(reverse("testcases-new"))
[docs]
def change_view(self, request, object_id, form_url="", extra_context=None):
return HttpResponseRedirect(reverse("testcases-get", args=[object_id]))
[docs]
class CategoryAdmin(admin.ModelAdmin):
search_fields = ("name",)
list_display = ("id", "name", "product", "description")
list_filter = ("product",)
[docs]
class IssueTrackerTypeField(forms.ChoiceField):
"""Special choice field which uses the widget above"""
widget = IssueTrackerTypeSelectWidget
[docs]
def valid_value(self, value):
return True
[docs]
class BugSystemAdmin(admin.ModelAdmin):
search_fields = ("name",)
list_display = ("id", "name", "base_url")
fieldsets = [
(
"",
{
"fields": ("name",),
},
),
(
_("External Issue Tracker Integration"),
{
"fields": (
"tracker_type",
"base_url",
"api_url",
"api_username",
"api_password",
),
"description": _(
"""<h1>Warning: read the
<a href="http://kiwitcms.readthedocs.io/en/latest/admin.html#configure-external-bug-trackers">
Configure external bug trackers</a> section before editting the values below!</h1>"""
),
},
),
(
_("Configuration health check"),
{
"fields": ("hc_bug_url",),
"description": _(
"Kiwi TCMS will try fetching details for the given bug URL using the "
"integration defined above! Click the `Save and continue` button and "
"watch out for messages at the top of the screen. <strong>WARNING:</strong> "
"in case of failures some issue trackers will fall back to fetching details "
"via the OpenGraph protocol. In that case the result will include field named "
"`from_open_graph`."
),
},
),
]
form = BugSystemAdminForm
[docs]
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
# try health check
bug_url = form.cleaned_data["hc_bug_url"]
if bug_url:
try:
tracker = import_string(obj.tracker_type)(obj, request)
if not tracker:
raise RuntimeError(_("Failed creating Issue Tracker"))
details = tracker.details(bug_url)
if details.get("from_open_graph", False):
messages.add_message(
request,
messages.WARNING,
_(
"Details extracted via OpenGraph. "
"Issue Tracker may still be configured incorrectly!"
),
)
else:
messages.add_message(
request,
messages.SUCCESS,
_(
"Details extracted via API. Issue Tracker configuration looks good!"
),
)
messages.add_message(
request,
messages.INFO,
details,
)
except Exception: # pylint: disable=broad-except
messages.add_message(
request,
messages.ERROR,
_("Issue Tracker configuration check failed"),
)
# show the actual exception with traceback b/c it can help debug failures
messages.add_message(
request,
messages.ERROR,
traceback.format_exc(),
)
[docs]
class TemplateAdmin(admin.ModelAdmin):
form = TemplateAdminForm
admin.site.register(BugSystem, BugSystemAdmin)
admin.site.register(Category, CategoryAdmin)
admin.site.register(TestCase, TestCaseAdmin)
admin.site.register(TestCaseStatus, TestCaseStatusAdmin)
admin.site.register(Template, TemplateAdmin)