# Copyright © The Debusine Developers
# See the AUTHORS file at the top-level directory of this distribution
#
# This file is part of Debusine. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution. No part of Debusine, including this file, may be copied,
# modified, propagated, or distributed except according to the terms
# contained in the LICENSE file.

"""Tests the artifact UI helper."""

from typing import ClassVar, override

from django.core.exceptions import ImproperlyConfigured
from django.test import RequestFactory
from django.urls import reverse

from debusine.db.context import context
from debusine.db.models import Group
from debusine.db.permissioncontext import PermissionContext
from debusine.db.playground import scenarios
from debusine.test.django import TestCase
from debusine.web.views.places import ResourcePlace
from debusine.web.views.ui.auth import GroupUI


class GroupUITests(TestCase):
    """Test the :py:class:`GroupUI` class."""

    scenario = scenarios.DefaultContext()

    group: ClassVar[Group]

    @override
    @classmethod
    def setUpTestData(cls) -> None:
        super().setUpTestData()
        cls.group = cls.playground.create_group("test")

    def get_helper(self, group: Group) -> GroupUI:
        """Instantiate a UI helper for a group."""
        assert context.user
        factory = RequestFactory()
        request = factory.get("/")
        request.user = context.user
        return GroupUI(request, group)

    def test_place_unauthenticated(self) -> None:
        context.set_permission_context_scoped(
            self.scenario.scope, PermissionContext.for_ui_anonymous()
        )
        with self.assertRaisesRegex(
            ImproperlyConfigured, "GroupUI.place invoked by an anonymous user"
        ):
            self.get_helper(self.group).place

    def test_place_authenticated(self) -> None:
        self.scenario.set_current()
        place = self.get_helper(self.group).place
        assert isinstance(place, ResourcePlace)
        self.assertEqual(place.title, f"Group {self.group}")
        self.assertEqual(place.breadcrumb, self.group.name)
        self.assertEqual(place.url, self.group.get_absolute_url())

        assert place.parent is not None
        self.assertEqual(
            place.parent.url,
            reverse(
                "user:groups", kwargs={"username": self.scenario.user.username}
            ),
        )
        assert place.parent.parent is not None
        self.assertEqual(place.parent.parent.url, reverse("scopes:detail"))
