# (c) cavaliba.com - tests / views / admintools keyname rename - dry run

from django.core.cache import cache as cache_django
from django.test import TestCase, override_settings
from django.urls import reverse

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

URL = "app_home:admintools_keyname"


@override_settings(CAVALIBA_AUTH_MODE="unittest")
class TestAdmintoolsKeynameDryrun(TestCase):
    def setUp(self):
        cache.clear()
        cache_django.clear()
        helper.add_admin_user(login="unittest")
        helper.add_schema("tkn_target", displayname="Target Schema")
        helper.add_schema(
            "tkn_ref",
            displayname="Referrer Schema",
            field_definition={
                "ref_target": {
                    "dataformat": "schema",
                    "dataformat_ext": "tkn_target",
                    "cardinal_max": 1,
                }
            },
        )
        helper.add_instance("tkn_target", "old_key")
        helper.add_instance("tkn_ref", "ref01", fields={"ref_target": "old_key"})

    def _post(self, extra=None):
        data = {
            "mode": "dryrun",
            "classname": "tkn_target",
            "oldkeyname": "old_key",
            "newkeyname": "new_key",
        }
        if extra:
            data.update(extra)
        return self.client.post(reverse(URL), data, follow=True)

    def test_dryrun_shows_result_card(self):
        response = self._post()
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Dry-run result", status_code=200)
        self.assertContains(response, "Referrers changed", status_code=200)

    def test_dryrun_writes_nothing(self):
        self._post()
        self.assertTrue(
            DataInstance.objects.filter(classname="tkn_target", keyname="old_key").exists()
        )
        self.assertFalse(
            DataInstance.objects.filter(classname="tkn_target", keyname="new_key").exists()
        )

    def test_dryrun_lists_the_referrer(self):
        response = self._post()
        self.assertContains(response, "ref01", status_code=200)
        self.assertContains(response, "ref_target", status_code=200)

    def test_dryrun_offers_real_run_and_new_dryrun(self):
        response = self._post()
        self.assertContains(response, "Run for real", status_code=200)
        self.assertContains(response, "New dry run", status_code=200)
        self.assertContains(response, 'value="real"', status_code=200)

    def test_dryrun_error_shows_no_real_run_button(self):
        response = self._post({"oldkeyname": "does_not_exist"})
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "instance not found", status_code=200)
        self.assertNotContains(response, "Run for real", status_code=200)

    def test_dryrun_same_keyname_is_an_error(self):
        response = self._post({"newkeyname": "old_key"})
        self.assertContains(response, "identical to oldkeyname", status_code=200)

    def test_dryrun_existing_new_keyname_is_an_error(self):
        helper.add_instance("tkn_target", "taken_key")
        response = self._post({"newkeyname": "taken_key"})
        self.assertContains(response, "newkeyname already exists", status_code=200)

    def test_dryrun_missing_schema_is_an_error(self):
        response = self._post({"classname": ""})
        self.assertContains(response, "classname is required", status_code=200)
        self.assertTrue(
            DataInstance.objects.filter(classname="tkn_target", keyname="old_key").exists()
        )

    def test_get_shows_no_report(self):
        response = self.client.get(reverse(URL), follow=True)
        self.assertNotContains(response, "Dry-run result", status_code=200)
