# (c) cavaliba.com - tests / apikey builtin secret


from django.test import TestCase, override_settings

import app_home.cache as cache
from app_data import crypto
from app_data.data import Instance
from app_home.migrator import sync_apikey_secret


class ApikeyBuiltinSecretTest(TestCase):
    """api_builtin is seeded once for the whole suite by CavalibaTestRunner
    (core/test_runner.py, calling cavaliba_start()) - reset its secret to
    empty here rather than (re)creating the instance, to keep each test
    isolated regardless of run order."""

    def setUp(self):
        cache.clear()
        instance = Instance.from_keyname(classname="_apikey", keyname="api_builtin")
        instance.set_field_value_single(fieldname="secret", value="")
        instance.save(action="update", skip_revision=True)
        cache.clear()

    @override_settings(CAVALIBA_APIKEY_SECRET="somesecret123")
    def test_sets_secret_when_empty(self):
        sync_apikey_secret()
        instance = Instance.from_keyname(classname="_apikey", keyname="api_builtin")
        stored = instance.get_attribute_first("secret")
        self.assertTrue(crypto.hash_check("somesecret123", stored))

    @override_settings(CAVALIBA_APIKEY_SECRET="somesecret123")
    def test_does_not_overwrite_existing_secret(self):
        sync_apikey_secret()
        instance = Instance.from_keyname(classname="_apikey", keyname="api_builtin")
        first_stored = instance.get_attribute_first("secret")

        with override_settings(CAVALIBA_APIKEY_SECRET="anothersecret456"):
            sync_apikey_secret()

        instance = Instance.from_keyname(classname="_apikey", keyname="api_builtin")
        second_stored = instance.get_attribute_first("secret")
        self.assertEqual(first_stored, second_stored)
        self.assertTrue(crypto.hash_check("somesecret123", second_stored))
        self.assertFalse(crypto.hash_check("anothersecret456", second_stored))

    @override_settings(CAVALIBA_APIKEY_SECRET=None)
    def test_noop_when_env_var_unset(self):
        sync_apikey_secret()
        instance = Instance.from_keyname(classname="_apikey", keyname="api_builtin")
        self.assertEqual(instance.get_attribute_first("secret"), "")

    @override_settings(CAVALIBA_APIKEY_SECRET="somesecret123")
    def test_noop_when_instance_missing(self):
        instance = Instance.from_keyname(classname="_apikey", keyname="api_builtin")
        instance.delete()
        sync_apikey_secret()
        instance = Instance.from_keyname(classname="_apikey", keyname="api_builtin")
        self.assertIsNone(instance)
