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

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

from debusine.db.models import Workspace
from debusine.db.playground import scenarios
from debusine.test.django import TestCase
from debusine.web.views.tests.utils import ViewTestMixin
from debusine.web.views.ui.workspaces import WorkspaceUI


class WorkspaceUITests(ViewTestMixin, TestCase):
    """Test the :py:class:`WorkspaceUI` class."""

    scenario = scenarios.DefaultContext(set_current=True)

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

    def test_candidate_parents_empty(self) -> None:
        helper = self.get_helper(self.scenario.workspace)
        self.assertEqual(helper.candidate_parents, [])

    def test_candidate_parents_other_scope(self) -> None:
        other_scope = self.playground.get_or_create_scope("other")
        other_workspace = self.playground.create_workspace(
            name="other", scope=other_scope, public=True
        )
        helper = self.get_helper(self.scenario.workspace)
        self.assertEqual(helper.candidate_parents, [other_workspace])

    def test_candidate_parents_only_visible(self) -> None:
        self.playground.create_workspace(name="other")
        helper = self.get_helper(self.scenario.workspace)
        self.assertEqual(helper.candidate_parents, [])

    def test_candidate_parents_current_parents(self) -> None:
        """Current parents are candidates even if not normally accessible."""
        public = self.playground.create_workspace(name="public", public=True)
        private = self.playground.create_workspace(name="private")
        self.scenario.workspace.set_inheritance([private, public])
        helper = self.get_helper(self.scenario.workspace)
        self.assertEqual(helper.candidate_parents, [private, public])

    def test_candidate_parents_ordering(self) -> None:
        other_scope = self.playground.get_or_create_scope("other")
        b = self.playground.create_workspace(name="b", public=True)
        a = self.playground.create_workspace(name="a", public=True)
        c = self.playground.create_workspace(name="c", public=True)
        ob = self.playground.create_workspace(
            name="b", public=True, scope=other_scope
        )
        oa = self.playground.create_workspace(
            name="a", public=True, scope=other_scope
        )
        oc = self.playground.create_workspace(
            name="c", public=True, scope=other_scope
        )
        helper = self.get_helper(self.scenario.workspace)
        self.assertEqual(helper.candidate_parents, [a, b, c, oa, ob, oc])

    @override_settings(ROOT_URLCONF="debusine.web.archives.urls")
    def test_place_suite_list(self) -> None:
        helper = self.get_helper(self.scenario.workspace)
        place = helper.place_suite_list
        self.assertPlaceValueEqual(
            place.title,
            "Suites",
            page=f"Suites in <code>{self.scenario.workspace}</code>",
        )
        self.assertEqual(
            place.url,
            reverse(
                "archive-root",
                kwargs={
                    "scope": self.scenario.scope.name,
                    "workspace": self.scenario.workspace.name,
                },
            ),
        )
        self.assertIs(place.parent, helper.place)
