# (c) cavaliba.com - tests dataview datapoint/UI-table alignment

from django.test import TestCase

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


class TestDataViewDatapointAlignment(TestCase):
    def setUp(self):
        """Schema + instance + views mirroring the instance_list table setup, plus
        views that omit keyname/classname from their own columns - the case that
        used to desync the table header from row data."""

        cache.clear()
        helper.add_schema(
            classname="dpalign",
            field_definition={
                "keep_me": {"dataformat": "string", "displayname": "Keep Me"},
            },
        )
        helper.add_instance(
            classname="dpalign",
            keyname="obj01",
            fields={"keep_me": "keepvalue"},
        )
        helper.add_instance(
            classname="_dataview",
            keyname="dpalign_no_identity",
            fields={
                "target_class": "dpalign",
                "content": "columns:\n  - keep_me\n",
            },
        )
        helper.add_instance(
            classname="_dataview",
            keyname="dpalign_plain",
            fields={
                "target_class": "dpalign",
                "content": "columns:\n  - keyname\n  - keep_me\n",
            },
        )

    def test_default_view_datapoint_row_matches_header_length(self):
        dataview = DataView(keyname=None)
        instance = Instance.from_keyname("dpalign", "obj01")
        values = dataview.filter(instance=instance, mode="datapoint")
        self.assertEqual(len(values), len(dataview.columns))

    def test_default_view_datapoint_keyname_column_holds_keyname(self):
        dataview = DataView(keyname=None)
        instance = Instance.from_keyname("dpalign", "obj01")
        values = dataview.filter(instance=instance, mode="datapoint")
        index = dataview.columns.index("keyname")
        self.assertEqual(values[index], "obj01")

    def test_view_without_identity_columns_datapoint_row_matches_header_length(self):
        dataview = DataView(keyname="dpalign_no_identity")
        instance = Instance.from_keyname("dpalign", "obj01")
        values = dataview.filter(instance=instance, mode="datapoint")
        self.assertEqual(len(values), len(dataview.columns))

    def test_view_without_identity_columns_datapoint_first_cell_is_keep_me(self):
        # dataview.columns is ["keep_me"]; without the mode=datapoint guard,
        # filter() used to prepend classname/keyname, shifting this cell out.
        dataview = DataView(keyname="dpalign_no_identity")
        instance = Instance.from_keyname("dpalign", "obj01")
        values = dataview.filter(instance=instance, mode="datapoint")
        self.assertEqual(values[0]["fieldname"], "keep_me")

    def test_csv_mode_still_guarantees_identity_columns(self):
        # export modes are untouched by the datapoint-mode fix
        dataview = DataView(keyname="dpalign_no_identity")
        instance = Instance.from_keyname("dpalign", "obj01")
        values = dataview.filter(instance=instance, mode="csv")
        columns = dataview.get_columns()
        self.assertEqual(len(values), len(columns))
        self.assertEqual(dict(zip(columns, values))["classname"], "dpalign")
        self.assertEqual(dict(zip(columns, values))["keyname"], "obj01")
