content: import types
  
  import orjson
  import pytest
  from tests.views.fake_components import (
      FakeAuthenticationComponent,
      FakeValidationComponent,
  )
  
  from django_unicorn.components import UnicornView
  from django_unicorn.serializer import InvalidFieldNameError
  
  
  class ExampleComponent(UnicornView):
      name = "World"
  
      def get_name(self):
          return "World"
  
  
  @pytest.fixture()
  def component():
      return ExampleComponent(component_id="asdf1234", component_name="example")
  
  
  def test_init_with_template_name():
      class TestComponent(UnicornView):
          template_name = "unicorn/test.html"
  
      component = TestComponent(component_id="test_init_with_template_name", component_name="hello-world")
      assert component.template_name == "unicorn/test.html"
  
  
  def test_init_with_get_template_names():
      class TestComponent(UnicornView):
          def get_template_names(self):
              return []
  
      component = TestComponent(component_id="test_init_with_get_template_names", component_name="hello-world")
      assert component.template_name is None
  
  
  def test_init_attribute_names_cache(component):
      attribute_names_cache = component._attribute_names_cache
      assert len(attribute_names_cache) == 1
      assert attribute_names_cache[0] == "name"
  
  
  def test_init_attribute_names(component):
      attribute_names = component._attribute_names()
      assert len(attribute_names) == 1
      assert attribute_names[0] == "name"
  
  
  def test_init_attributes(component):
      attributes = component._attributes()
      assert len(attributes) == 1
      assert attributes["name"] == "World"
  
  
  def test_init_properties():
      class TestComponent(UnicornView):
          @property
          def name(self):
              return "World"
  
      component = TestComponent(component_id="test_init_properties", component_name="hello-world")
      attributes = component._attributes()
      assert len(attributes) == 1
      assert attributes["name"] == "World"
  
  
  def test_init_methods_cache(component):
      assert len(component._methods_cache) == 1
  
  
  def test_init_methods(component):
      methods = component._methods()
      assert len(methods) == 1
      assert methods["get_name"]() == "World"
  
  
  def test_get_frontend_context_variables_javascript_exclude(component):
      class Meta:
          javascript_exclude = ("name",)
  
      component.Meta = Meta
  
      frontend_context_variables = component.get_frontend_context_variables()
      frontend_context_variables_dict = orjson.loads(frontend_context_variables)
      assert len(frontend_context_variables_dict) == 0
      assert "name" not in frontend_context_variables_dict
  
  
  def test_get_frontend_context_variables_javascript_exclude_invalid_field(component):
      class Meta:
          javascript_exclude = ("blob",)
  
      component.Meta = Meta
  
      with pytest.raises(InvalidFieldNameError):
          component.get_frontend_context_variables()
  
  
  def test_get_frontend_context_variables_exclude_field(component):
      # Use internal class prevent class cache from causing issues
      class ExampleComponentWithMetaExclude(UnicornView):
          name = "world"
  
          class Meta:
              exclude = ("name",)
  
      component = ExampleComponentWithMetaExclude(
          component_id="test_get_frontend_context_variables_exclude_field", component_name="example"
      )
  
      frontend_context_variables = component.get_frontend_context_variables()
      frontend_context_variables_dict = orjson.loads(frontend_context_variables)
      assert len(frontend_context_variables_dict) == 0
      assert "name" not in frontend_context_variables_dict
  
  
  def test_get_frontend_context_variables_exclude_field_invalid_type():
      # Use internal class prevent class cache from causing issues
      class ExampleComponentWithMetaInvalidExclude(UnicornView):
          name = "world"
  
          class Meta:
              exclude = ""
  
      with pytest.raises(AssertionError):
          ExampleComponentWithMetaInvalidExclude(
              component_id="test_get_frontend_context_variables_exclude_field_invalid_type", component_name="example"
          )
  
  
  def test_get_frontend_context_variables_exclude_invalid_field():
      # Use internal class prevent class cache from causing issues
      class ExampleComponentWithMetaInvalidExclude(UnicornView):
          pass
  
          class Meta:
              exclude = ("blob",)
  
      with pytest.raises(InvalidFieldNameError):
          ExampleComponentWithMetaInvalidExclude(
              component_id="test_get_frontend_context_variables_exclude_invalid_field", component_name="example"
          )
  
  
  def test_get_frontend_context_variables(component):
      frontend_context_variables = component.get_frontend_context_variables()
      frontend_context_variables_dict = orjson.loads(frontend_context_variables)
      assert len(frontend_context_variables_dict) == 1
      assert frontend_context_variables_dict.get("name") == "World"
  
  
  def test_get_context_data(component):
      context_data = component.get_context_data()
      assert len(context_data) == 4  # `unicorn` and `view` are added to context data by default
      assert context_data.get("name") == "World"
      assert isinstance(context_data.get("get_name"), types.MethodType)
  
  
  def test_get_context_data_component():
      class TestComponent(UnicornView):
          pass
  
      component = TestComponent(component_id="test_get_context_data_component", component_name="hello-world")
      actual = component.get_context_data()
  
      assert actual["unicorn"]
      assert actual["unicorn"]["component"] == component
  
  
  def test_get_context_data_component_id():
      class TestComponent(UnicornView):
          pass
  
      component = TestComponent(component_id="test_get_context_data_component_id", component_name="hello-world")
      actual = component.get_context_data()
  
      assert actual["unicorn"]
      assert actual["unicorn"]["component_id"] == "test_get_context_data_component_id"
  
  
  def test_get_context_data_component_name():
      class TestComponent(UnicornView):
          pass
  
      component = TestComponent(component_id="test_get_context_data_component_name", component_name="hello-world")
      actual = component.get_context_data()
  
      assert actual["unicorn"]
      assert actual["unicorn"]["component_name"] == "hello-world"
  
  
  def test_get_context_data_component_key():
      class TestComponent(UnicornView):
          pass
  
      component = TestComponent(
          component_id="test_get_context_data_component_key",
          component_name="hello-world",
          component_key="key-key-key",
      )
      actual = component.get_context_data()
  
      assert actual["unicorn"]
      assert actual["unicorn"]["component_key"] == "key-key-key"
  
  
  def test_is_public(component):
      assert component._is_public("test_name")
  
  
  def test_is_public_protected(component):
      assert component._is_public("_test_name") is False
  
  
  def test_is_public_http_method_names(component):
      assert component._is_public("http_method_names") is False
  
  
  def test_meta_javascript_exclude():
      class TestComponent(UnicornView):
          name = "World"
  
          class Meta:
              javascript_exclude = ("name",)
  
      component = TestComponent(component_id="test_meta_javascript_exclude", component_name="hello-world")
      assert "name" not in component.get_frontend_context_variables()
      assert "name" in component.get_context_data()
  
  
  def test_meta_javascript_exclude_nested_with_tuple():
      class TestComponent(UnicornView):
          name = {"Universe": {"World": "Earth"}}  # noqa: RUF012
  
          class Meta:
              javascript_exclude = ("name.Universe",)
  
      expected = '{"name":{}}'
      component = TestComponent(
          component_id="test_meta_javascript_exclude_nested_with_tuple", component_name="hello-world"
      )
      assert expected == component.get_frontend_context_variables()
  
  
  def test_meta_javascript_exclude_nested_multiple_with_spaces():
      class TestComponent(UnicornView):
          name = {"Universe": {"World": "Earth"}}  # noqa: RUF012
          another = {"Neutral Milk Hotel": {"album": {"On Avery Island": 1996}}}  # noqa: RUF012
  
          class Meta:
              javascript_exclude = ("another.Neutral Milk Hotel.album",)
  
      expected = '{"another":{"Neutral Milk Hotel":{}},"name":{"Universe":{"World":"Earth"}}}'
      component = TestComponent(
          component_id="test_meta_javascript_exclude_nested_multiple_with_spaces", component_name="hello-world"
      )
      actual = component.get_frontend_context_variables()
      assert expected == actual
  
  
  def test_meta_javascript_exclude_nested_with_list():
      class TestComponent(UnicornView):
          name = {"Universe": {"World": "Earth"}}  # noqa: RUF012
  
          class Meta:
              javascript_exclude = [  # noqa: RUF012
                  "name.Universe",
              ]
  
      expected = '{"name":{}}'
      component = TestComponent(
          component_id="test_meta_javascript_exclude_nested_with_list", component_name="hello-world"
      )
      assert expected == component.get_frontend_context_variables()
  
  
  def test_meta_exclude():
      class TestComponent(UnicornView):
          name = "World"
  
          class Meta:
              exclude = ("name",)
  
      component = TestComponent(component_id="test_meta_exclude", component_name="hello-world")
      assert "name" not in component.get_frontend_context_variables()
      assert "name" not in component.get_context_data()
  
  
  def test_get_frontend_context_variables_form_with_boolean_field(component):
      """
      Form classes with BooleanField and CheckboxInput widget set the bool values to `None`
      without an explicit fix.
      """
  
      component = FakeValidationComponent(
          component_id="test_get_frontend_context_variables_form_with_boolean_field", component_name="example"
      )
  
      frontend_context_variables = component.get_frontend_context_variables()
      frontend_context_variables_dict = orjson.loads(frontend_context_variables)
  
      assert frontend_context_variables_dict.get("permanent") is not None
  
  
  def test_get_frontend_context_variables_authentication_form(component):
      """
      `AuthenticationForm` have `request` as the first argument so `form_class` should
      init with data as a kwarg.
      """
  
      component = FakeAuthenticationComponent(
          component_id="test_get_frontend_context_variables_authentication_form", component_name="example"
      )
  
      component.get_frontend_context_variables()
  