django-components/tests/test_component_url.py

104 lines
3.3 KiB
Python

from typing import Any
import pytest
from django.http import HttpRequest
from django.test import Client
from django_components import Component, get_component_url
from django_components.testing import djc_test
from .testutils import setup_test_config
# DO NOT REMOVE!
#
# This is intentionally defined before `setup_test_config()` in order to test that
# the URL extension works even before the Django has been set up.
#
# Because if we define the component before `django.setup()`, then we store it in
# event queue, and will register it when `AppConfig.ready()` is finally called.
#
# This test relies on the "url" extension calling `add_extension_urls()` from within
# the `on_component_class_created()` hook.
class ComponentBeforeReady(Component):
class Url:
public = True
template = "Hello"
setup_test_config({"autodiscover": False})
@djc_test
class TestComponentUrl:
def test_public_url(self):
did_call_get = False
did_call_post = False
class TestComponent(Component):
template = "Hello"
class Url:
public = True
class View:
def get(self, request: HttpRequest, **kwargs: Any):
nonlocal did_call_get
did_call_get = True
component: Component = self.component # type: ignore[attr-defined]
return component.render_to_response()
def post(self, request: HttpRequest, **kwargs: Any):
nonlocal did_call_post
did_call_post = True
component: Component = self.component # type: ignore[attr-defined]
return component.render_to_response()
# Check if the URL is correctly generated
component_url = get_component_url(TestComponent)
assert component_url == f"/components/ext/url/components/{TestComponent.class_id}/"
client = Client()
response = client.get(component_url)
assert response.status_code == 200
assert response.content == b"Hello"
assert did_call_get
response = client.post(component_url)
assert response.status_code == 200
assert response.content == b"Hello"
assert did_call_get
def test_non_public_url(self):
did_call_get = False
class TestComponent(Component):
template = "Hi"
class Url:
public = False
class View:
def get(self, request: HttpRequest, **attrs: Any):
nonlocal did_call_get
did_call_get = True
component: Component = self.component # type: ignore[attr-defined]
return component.render_to_response()
# Attempt to get the URL should raise RuntimeError
with pytest.raises(
RuntimeError,
match="Component URL is not available - Component is not public",
):
get_component_url(TestComponent)
# Even calling the URL directly should raise an error
component_url = f"/components/ext/url/components/{TestComponent.class_id}/"
client = Client()
response = client.get(component_url)
assert response.status_code == 404
assert not did_call_get