# (c) cavaliba.com - test / field templates / detail mode golden markup

"""
Golden markup for display_mode "detail" (instance_detail value cells), one
assertion per dataformat. Pins the markup each fields/_<dataformat>.html renders
in this mode. Written against the pre-unification
fields/_datapoint_detail.html and unchanged since, which is what proves the
unification moved markup without altering it - see
project/claude_doc/2026-10-03-FIELD-TEMPLATE-UNIFICATION-DONE.md.

Detail mode is the only display mode that turns a "url" string into an anchor
and renders schema references as buttons rather than plain links, and it shows
text untruncated. Those differences from list/print mode are asserted here on
purpose.
"""

from django.template.loader import render_to_string
from django.test import TestCase

import app_home.cache as cache
from tests import helper


class TestFieldRenderDetail(TestCase):
    def setUp(self):
        """fieldrender schema + one fully populated instance."""
        cache.clear()
        self.instance = helper.add_fieldrender_fixture()

    def render(self, fieldname):
        """Normalized detail-mode markup for one field of the fixture instance."""
        return helper.render_field(self.instance, fieldname, "detail")

    def render_raw(self, fieldname):
        """Unnormalized detail-mode markup, for assertions on whitespace that
        normalize_html() would collapse (newlines inside <pre>)."""
        datapoint = self.instance.fields[fieldname].get_datapoint_ui_detail()
        template = helper.template_for_mode("detail")
        return render_to_string(template, {"item": datapoint, "display_mode": "detail"})

    def test_string(self):
        self.assertEqual(self.render("f_string"), "plain string value")

    def test_string_safe_is_not_escaped(self):
        self.assertEqual(self.render("f_string_safe"), "<b>bold</b>")

    def test_string_url_becomes_an_anchor(self):
        self.assertEqual(
            self.render("f_string_url"),
            '<a href="https://example.test/doc">https://example.test/doc</a>',
        )

    def test_string_multi_is_comma_joined(self):
        self.assertEqual(self.render("f_string_multi"), "multi one, multi two")

    def test_int_is_plain(self):
        self.assertEqual(self.render("f_int"), "42")

    def test_float_is_plain(self):
        self.assertEqual(self.render("f_float"), "3.5")

    def test_boolean_is_a_check(self):
        self.assertEqual(
            self.render("f_boolean"),
            '<div class="d-flex"><i class="fa fa-check" aria-hidden="true"></i></div>',
        )

    def test_date_is_a_plain_value(self):
        self.assertEqual(self.render("f_date"), "2026-01-15")

    def test_datetime_is_a_plain_value(self):
        self.assertEqual(self.render("f_datetime"), "2026-01-15 10:20:30")

    def test_time_is_a_plain_value(self):
        self.assertEqual(self.render("f_time"), "10:20:30")

    def test_ipv4_links_to_ip_jump(self):
        self.assertEqual(
            self.render("f_ipv4"),
            '<a class="cv-ipam-link" href="/data/private/ipam_ip/jump/?ip=10.1.2.3"> 10.1.2.3</a>',
        )

    def test_ipv4_subnet_links_to_subnet_list_with_a_marker_icon(self):
        # the fa-map-marker is detail-only: list mode has no icon
        self.assertEqual(
            self.render("f_ipv4_subnet"),
            '<a class="cv-ipam-link" '
            'href="/data/private/c/ipam_subnet/list/?query=10.1.2.0/24">'
            '<i class="fa fa-map-marker"></i>10.1.2.0/24</a>',
        )

    def test_text_is_not_truncated(self):
        self.assertEqual(self.render("f_text"), f"<pre>{helper.LONG_TEXT}</pre>")

    def test_text_html_is_unescaped(self):
        self.assertEqual(self.render("f_text_html"), "<div><p>html body</p></div>")

    def test_text_yaml_keeps_newlines_inside_pre(self):
        # normalize_html() collapses these, so assert on the raw render
        self.assertIn("<pre>a: 1\nb: 2\n</pre>", self.render_raw("f_text_yaml"))

    def test_schema_is_an_outline_button(self):
        self.assertEqual(
            self.render("f_schema"),
            '<div class="d-flex flex-wrap">'
            '<a class="btn btn-outline-success btn-sm mx-1 my-1" '
            f'href="/data/private/instance/detail/{helper.site_id("site01")}/" '
            'role="button"> Site 01</a></div>',
        )

    def test_schema_multi_is_one_button_per_reference(self):
        self.assertEqual(
            self.render("f_schema_multi"),
            '<div class="d-flex flex-wrap">'
            '<a class="btn btn-outline-success btn-sm mx-1 my-1" '
            f'href="/data/private/instance/detail/{helper.site_id("site01")}/" '
            'role="button"> Site 01</a>'
            '<a class="btn btn-outline-success btn-sm mx-1 my-1" '
            f'href="/data/private/instance/detail/{helper.site_id("site02")}/" '
            'role="button"> Site 02</a></div>',
        )

    def test_enumerate_shows_widget_and_value(self):
        self.assertEqual(
            self.render("f_enumerate"),
            '<div class="d-flex flex-wrap"> &#x1f534; Major <br></div>',
        )

    def test_permission_is_one_key_per_line(self):
        self.assertEqual(
            self.render("f_permission"),
            '<div class="d-flex flex-wrap"> p_data_admin<br></div>',
        )

    def test_password_is_masked(self):
        self.assertEqual(
            self.render("f_password"),
            '<div class="d-flex justify-content-left"> **************************** </div>',
        )

    def test_file_is_a_download_link(self):
        self.assertEqual(
            self.render("f_file"),
            '<div class="d-flex flex-wrap">'
            f'<a href="/data/private/file/{helper.FIELDRENDER_FILEID}/">'
            '<i class="fa fa-file me-2"></i> Report (2048) </a></div>',
        )

    def test_external_renders_an_empty_italic_wrapper(self):
        self.assertEqual(
            self.render("_f_ext"),
            '<div class="d-flex flex-wrap"><i></i></div>',
        )
