# (c) cavaliba.com - tests dataview graceful fallback on structurally invalid content

from django.test import TestCase

import app_home.cache as cache
from app_data.dataview import DataView
from tests import helper

_BUILTIN_DEFAULT_COLUMNS = [
    {"label": "keyname", "fieldname": "keyname", "popover": True, "filter": True},
    {"label": "displayname", "fieldname": "displayname", "popover": True, "filter": True},
    {"label": "last_update", "fieldname": "last_update", "popover": True, "filter": True},
]


class TestDataViewInvalidContentStructure(TestCase):
    def setUp(self):
        cache.clear()
        helper.add_schema(
            classname="invalidview",
            field_definition={
                "mystring": {"dataformat": "string", "displayname": "MyString"},
            },
        )

    def _make_dataview(self, keyname, content):
        helper.add_instance(
            classname="_dataview",
            keyname=keyname,
            fields={"target_class": "invalidview", "content": content},
        )
        return DataView(keyname=keyname)

    def test_empty_content_falls_back_to_default_columns(self):
        # yaml.safe_load("") == None: valid syntax, not a mapping
        dataview = self._make_dataview("empty_content", "")
        self.assertEqual(dataview.content, {"columns": ["keyname", "displayname", "last_update"]})
        self.assertEqual(dataview.columns, _BUILTIN_DEFAULT_COLUMNS)

    def test_scalar_content_falls_back_to_default_columns(self):
        # valid YAML, but a bare string instead of a mapping
        dataview = self._make_dataview("scalar_content", "hello")
        self.assertEqual(dataview.content, {"columns": ["keyname", "displayname", "last_update"]})
        self.assertEqual(dataview.columns, _BUILTIN_DEFAULT_COLUMNS)

    def test_list_content_falls_back_to_default_columns(self):
        # valid YAML, but a list instead of a mapping
        dataview = self._make_dataview("list_content", "- a\n- b\n")
        self.assertEqual(dataview.content, {"columns": ["keyname", "displayname", "last_update"]})
        self.assertEqual(dataview.columns, _BUILTIN_DEFAULT_COLUMNS)

    def test_columns_not_a_list_yields_no_columns_without_crashing(self):
        dataview = self._make_dataview("scalar_columns", "columns: 5\n")
        self.assertEqual(dataview.columns, [])

    def test_column_entry_with_non_dict_value_is_skipped_without_crashing(self):
        # columns: [{mycol: 123}] - dict value isn't itself a dict (no "from"/
        # "popover"/"filter"), so it's an unresolvable label, not a crash
        dataview = self._make_dataview("badentry_columns", "columns:\n  - mycol: 123\n")
        self.assertEqual(len(dataview.columns), 1)
        col = dataview.columns[0]
        self.assertEqual(col["label"], "mycol")
        self.assertIsNone(col["fieldname"])
        self.assertTrue(col["popover"])
        self.assertTrue(col["filter"])

    def test_invalid_yaml_syntax_still_falls_back_to_default_columns(self):
        dataview = self._make_dataview("bad_syntax", "columns: [a, b")
        self.assertEqual(dataview.content, {"columns": ["keyname", "displayname", "last_update"]})
        self.assertEqual(dataview.columns, _BUILTIN_DEFAULT_COLUMNS)
