# (c) cavaliba.com - test / views / instance_duplicate

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

import app_home.cache as cache
from app_data.data import Instance
from app_data.models import DataInstance
from tests import helper


class TestViewsInstanceDuplicate(TestCase):
    def setUp(self):
        """Clear caches so schema/permission lookups reflect fixtures created per test."""
        cache.clear()

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_duplicate_prefills_fields_and_leaves_keyname_empty(self):
        helper.add_admin_user(login="unittest")
        helper.add_instance(
            classname="site", keyname="site01", fields={"description": "Original description"}
        )
        site = DataInstance.objects.get(classname="site", keyname="site01")

        response = self.client.get(
            reverse("app_data:instance_duplicate", kwargs={"id": site.id}), follow=True
        )
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "csrfmiddlewaretoken")
        # target the real create URL, not the (nonexistent) duplicate-page URL
        self.assertContains(
            response, reverse("app_data:instance_new", kwargs={"classname": "site"})
        )
        # field value copied from the source
        self.assertContains(response, "Original description")
        # keyname left empty for the user to fill in
        self.assertContains(response, 'name="keyname" value="">')

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_duplicate_then_submit_creates_new_instance(self):
        helper.add_admin_user(login="unittest")
        helper.add_instance(
            classname="site", keyname="site01", fields={"description": "Original description"}
        )
        site = DataInstance.objects.get(classname="site", keyname="site01")

        response = self.client.get(
            reverse("app_data:instance_duplicate", kwargs={"id": site.id}), follow=True
        )
        self.assertEqual(response.status_code, 200)

        post_data = {
            "keyname": "site01-copy",
            "displayname": "site01",
            "description": "Original description",
        }
        response = self.client.post(
            reverse("app_data:instance_new", kwargs={"classname": "site"}),
            data=post_data,
            follow=True,
        )
        self.assertEqual(response.status_code, 200)

        new_site = DataInstance.objects.filter(classname="site", keyname="site01-copy").first()
        self.assertIsNotNone(new_site)
        new_instance = Instance.from_keyname(classname="site", keyname="site01-copy")
        self.assertEqual(new_instance.fields["description"].value, ["Original description"])

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_duplicate_missing_source_redirects(self):
        helper.add_admin_user(login="unittest")
        response = self.client.get(reverse("app_data:instance_duplicate", kwargs={"id": 999999}))
        self.assertEqual(response.status_code, 302)

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_duplicate_without_read_permission_on_source_redirects(self):
        helper.add_instance(classname="site", keyname="site01")
        site = DataInstance.objects.get(classname="site", keyname="site01")
        helper.add_user_with_perm(login="unittest", perms=["p_data_access"])

        response = self.client.get(reverse("app_data:instance_duplicate", kwargs={"id": site.id}))
        self.assertEqual(response.status_code, 302)

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_duplicate_without_create_permission_redirects(self):
        helper.add_instance(classname="site", keyname="site01")
        site = DataInstance.objects.get(classname="site", keyname="site01")
        helper.add_user_with_perm(login="unittest", perms=["p_data_access", "p_data_site_read"])

        response = self.client.get(reverse("app_data:instance_duplicate", kwargs={"id": site.id}))
        self.assertEqual(response.status_code, 302)

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_instance_detail_shows_duplicate_action_when_allowed(self):
        helper.add_admin_user(login="unittest")
        helper.add_instance(classname="site", keyname="site01")
        site = DataInstance.objects.get(classname="site", keyname="site01")

        response = self.client.get(
            reverse("app_data:instance_detail", kwargs={"id": site.id}), follow=True
        )
        self.assertEqual(response.status_code, 200)
        self.assertContains(
            response, reverse("app_data:instance_duplicate", kwargs={"id": site.id})
        )

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_instance_detail_hides_duplicate_action_without_create_permission(self):
        helper.add_instance(classname="site", keyname="site01")
        site = DataInstance.objects.get(classname="site", keyname="site01")
        helper.add_user_with_perm(login="unittest", perms=["p_data_access", "p_data_site_read"])

        response = self.client.get(
            reverse("app_data:instance_detail", kwargs={"id": site.id}), follow=True
        )
        self.assertEqual(response.status_code, 200)
        self.assertNotContains(
            response, reverse("app_data:instance_duplicate", kwargs={"id": site.id})
        )

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_instance_list_shows_duplicate_action_when_allowed(self):
        helper.add_admin_user(login="unittest")
        helper.add_instance(classname="site", keyname="site01")
        site = DataInstance.objects.get(classname="site", keyname="site01")

        response = self.client.get(
            reverse("app_data:instance_list", kwargs={"classname": "site"}), follow=True
        )
        self.assertEqual(response.status_code, 200)
        self.assertContains(
            response, reverse("app_data:instance_duplicate", kwargs={"id": site.id})
        )

    @override_settings(CAVALIBA_AUTH_MODE="unittest")
    def test_instance_list_hides_duplicate_action_without_create_permission(self):
        helper.add_instance(classname="site", keyname="site01")
        site = DataInstance.objects.get(classname="site", keyname="site01")
        helper.add_user_with_perm(login="unittest", perms=["p_data_access", "p_data_site_read"])

        response = self.client.get(
            reverse("app_data:instance_list", kwargs={"classname": "site"}), follow=True
        )
        self.assertEqual(response.status_code, 200)
        self.assertNotContains(
            response, reverse("app_data:instance_duplicate", kwargs={"id": site.id})
        )
