# 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 collection UI helper."""

from typing import ClassVar, override

from django.test import RequestFactory, override_settings
from django.urls import reverse

from debusine.artifacts.models import CollectionCategory
from debusine.db.models import Collection, CollectionItem
from debusine.db.playground import scenarios
from debusine.test.django import TestCase
from debusine.web.views.places import IndexPlace, ResourcePlace
from debusine.web.views.ui.collections import CollectionItemUI, CollectionUI


class CollectionUITests(TestCase):
    """Test the :py:class:`CollectionUI` class."""

    scenario = scenarios.DefaultContext(set_current=True)

    sid: ClassVar[Collection]

    @override
    @classmethod
    def setUpTestData(cls) -> None:
        super().setUpTestData()
        cls.sid = cls.playground.create_collection(
            "sid", CollectionCategory.SUITE
        )

    def get_helper(self, collection: Collection) -> CollectionUI:
        """Instantiate a UI helper for a workspace."""
        factory = RequestFactory()
        request = factory.get("/")
        return CollectionUI(request, collection)

    def test_place(self) -> None:
        place = self.get_helper(self.sid).place
        self.assertIsInstance(place, ResourcePlace)

    def test_place_search(self) -> None:
        helper = self.get_helper(self.sid)
        place = helper.place_search
        self.assertIsInstance(place, IndexPlace)
        self.assertIs(
            place.parent,
            self.scenario.workspace.ui(helper.request).place_collection_list,
        )

    def test_place_update(self) -> None:
        helper = self.get_helper(self.sid)
        place = helper.place_update
        self.assertIsInstance(place, IndexPlace)
        self.assertIs(place.parent, helper.place)

    def test_place_delete(self) -> None:
        helper = self.get_helper(self.sid)
        place = helper.place_delete
        self.assertIsInstance(place, IndexPlace)
        self.assertIs(place.parent, helper.place)

    @override_settings(ROOT_URLCONF="debusine.web.archives.urls")
    def test_place_suite_root(self) -> None:
        helper = self.get_helper(self.sid)
        place = helper.place_suite_root
        self.assertEqual(place.title, f"Suite <code>{self.sid}</code>")
        self.assertEqual(
            place.url,
            reverse(
                "suite-root",
                kwargs={
                    "scope": self.sid.workspace.scope.name,
                    "workspace": self.sid.workspace.name,
                    "suite": self.sid.name,
                },
            ),
        )
        self.assertIs(
            place.parent,
            self.scenario.workspace.ui(helper.request).place_suite_list,
        )


class CollectionItemUITests(TestCase):
    """Test the :py:class:`CollectionItemUI` class."""

    scenario = scenarios.DefaultContext(set_current=True)

    sid: ClassVar[Collection]
    item: ClassVar[CollectionItem]

    @override
    @classmethod
    def setUpTestData(cls) -> None:
        super().setUpTestData()
        source = cls.playground.create_source_artifact()
        cls.sid = cls.playground.create_collection(
            "sid", CollectionCategory.SUITE
        )
        cls.item = cls.sid.manager.add_artifact(
            source,
            user=cls.scenario.user,
            variables={"component": "main", "section": "extra"},
        )

    def get_helper(self, item: CollectionItem) -> CollectionItemUI:
        """Instantiate a UI helper for a workspace."""
        factory = RequestFactory()
        request = factory.get("/")
        return CollectionItemUI(request, item)

    def test_place(self) -> None:
        helper = self.get_helper(self.item)
        place = helper.place
        self.assertIsInstance(place, ResourcePlace)
        self.assertIs(place.parent, self.sid.ui(helper.request).place)
