# (c) cavaliba.com - tests / migrator add_builtin_schema_field()

"""
add_builtin_schema_field() adds one field to an already-installed schema,
reading its definition from builtin/init/<file> rather than repeating it in
migrator.py. Unlike reload_builtin(), it must leave everything else on the
schema alone: an admin-customized definition of that same field, and any field
a user added to a builtin schema. It also has to be replayable, since the
version block it sits in re-runs on every start while the version is tagged -RC.
"""

from django.test import TestCase

import app_home.cache as cache
from app_data.schema import Schema
from app_home.migrator import add_builtin_schema_field
from tests import helper

MESSAGE = "unittest add builtin schema field"


class TestMigratorAddBuiltinSchemaField(TestCase):
    def setUp(self):
        cache.clear()
        helper.add_admin_user(login="unittest")

    @staticmethod
    def _drop_query_field():
        helper.add_schema_field(classname="_dataview", fields={"query": {"_action": "delete"}})
        cache.clear()

    @staticmethod
    def _dataview_fields():
        cache.clear()
        return Schema.from_name("_dataview").fields

    def test_adds_the_field_with_the_builtin_definition(self):
        self._drop_query_field()
        self.assertNotIn("query", self._dataview_fields())

        ok = add_builtin_schema_field(MESSAGE, "005_schema.yml", "_dataview", "query")

        self.assertTrue(ok)
        field = self._dataview_fields()["query"]
        self.assertEqual(field["displayname"], "Query")
        self.assertEqual(field["dataformat"], "string")
        self.assertEqual(field["order"], 115)

    def test_keeps_a_user_added_field_on_the_builtin_schema(self):
        helper.add_schema_field(
            classname="_dataview",
            fields={"mycustom": {"dataformat": "string", "displayname": "Mine"}},
        )
        self._drop_query_field()

        add_builtin_schema_field(MESSAGE, "005_schema.yml", "_dataview", "query")

        fields = self._dataview_fields()
        self.assertIn("query", fields)
        self.assertIn("mycustom", fields)
        self.assertEqual(fields["mycustom"]["displayname"], "Mine")

    def test_does_not_overwrite_an_existing_field_definition(self):
        helper.add_schema_field(
            classname="_dataview", fields={"query": {"displayname": "Custom Label"}}
        )
        cache.clear()

        add_builtin_schema_field(MESSAGE, "005_schema.yml", "_dataview", "query")

        self.assertEqual(self._dataview_fields()["query"]["displayname"], "Custom Label")

    def test_replaying_is_a_noop(self):
        self._drop_query_field()

        add_builtin_schema_field(MESSAGE, "005_schema.yml", "_dataview", "query")
        add_builtin_schema_field(MESSAGE, "005_schema.yml", "_dataview", "query")

        self.assertEqual(self._dataview_fields()["query"]["displayname"], "Query")

    def test_unknown_field_fails(self):
        ok = add_builtin_schema_field(MESSAGE, "005_schema.yml", "_dataview", "nosuchfield")
        self.assertFalse(ok)

    def test_unknown_schema_fails(self):
        ok = add_builtin_schema_field(MESSAGE, "005_schema.yml", "_nosuchschema", "query")
        self.assertFalse(ok)

    def test_unknown_file_fails(self):
        ok = add_builtin_schema_field(MESSAGE, "nosuchfile.yml", "_dataview", "query")
        self.assertFalse(ok)
