Add standardized HTMX conventions, interaction patterns, and migration guide for ThrillWiki UX

This commit is contained in:
pacnpal
2025-12-22 16:56:27 -05:00
parent 2e35f8c5d9
commit ae31e889d7
144 changed files with 25792 additions and 4440 deletions

View File

@@ -0,0 +1,203 @@
"""
Tests for meta tag utilities.
These tests verify that meta tag helpers generate
correct SEO and social sharing metadata.
"""
import pytest
from django.test import RequestFactory
from apps.core.utils.meta import (
build_canonical_url,
build_meta_context,
generate_meta_description,
get_og_image,
)
class TestGenerateMetaDescription:
"""Tests for generate_meta_description function."""
def test_basic_text(self):
"""Should return text as description."""
description = generate_meta_description(text="This is a test description.")
assert description == "This is a test description."
def test_truncates_long_text(self):
"""Should truncate text longer than max_length."""
long_text = "A" * 200
description = generate_meta_description(text=long_text, max_length=160)
assert len(description) <= 160
assert description.endswith("...")
def test_custom_max_length(self):
"""Should respect custom max_length."""
text = "A" * 100
description = generate_meta_description(text=text, max_length=50)
assert len(description) <= 50
def test_strips_html(self):
"""Should strip HTML tags from text."""
html_text = "<p>This is <strong>bold</strong> text.</p>"
description = generate_meta_description(text=html_text)
assert "<p>" not in description
assert "<strong>" not in description
assert "bold" in description
def test_handles_none(self):
"""Should return empty string for None input."""
description = generate_meta_description(text=None)
assert description == ""
def test_handles_empty_string(self):
"""Should return empty string for empty input."""
description = generate_meta_description(text="")
assert description == ""
class TestGetOgImage:
"""Tests for get_og_image function."""
def test_returns_image_url(self):
"""Should return provided image URL."""
url = get_og_image(image_url="https://example.com/image.jpg")
assert url == "https://example.com/image.jpg"
def test_returns_default_when_none(self):
"""Should return default OG image when no image provided."""
url = get_og_image()
# Should return some default or empty string
assert url is not None
def test_makes_url_absolute(self):
"""Should convert relative URL to absolute when request provided."""
factory = RequestFactory()
request = factory.get("/")
request.META["HTTP_HOST"] = "example.com"
url = get_og_image(image_url="/static/images/og.jpg", request=request)
assert "example.com" in url or url.startswith("/")
class TestBuildCanonicalUrl:
"""Tests for build_canonical_url function."""
def test_returns_path(self):
"""Should return provided path."""
url = build_canonical_url(path="/parks/test/")
assert "/parks/test/" in url
def test_builds_from_request(self):
"""Should build URL from request."""
factory = RequestFactory()
request = factory.get("/parks/")
request.META["HTTP_HOST"] = "example.com"
url = build_canonical_url(request=request)
assert "/parks/" in url
def test_handles_none(self):
"""Should return empty string when nothing provided."""
url = build_canonical_url()
assert url == "" or url is not None
class TestBuildMetaContext:
"""Tests for build_meta_context function."""
def test_basic_meta_context(self):
"""Should build basic meta context with title."""
context = build_meta_context(title="Test Page")
assert "title" in context
assert context["title"] == "Test Page"
def test_includes_description(self):
"""Should include description when provided."""
context = build_meta_context(
title="Test Page",
description="This is a test page description.",
)
assert "description" in context
assert context["description"] == "This is a test page description."
def test_includes_og_tags(self):
"""Should include Open Graph tags."""
context = build_meta_context(
title="Test Page",
description="Description here.",
)
assert "og_title" in context or "title" in context
assert "og_description" in context or "description" in context
def test_includes_canonical_url(self):
"""Should include canonical URL when request provided."""
factory = RequestFactory()
request = factory.get("/test/")
request.META["HTTP_HOST"] = "example.com"
context = build_meta_context(
title="Test",
request=request,
)
assert "canonical_url" in context
def test_includes_og_image(self):
"""Should include OG image when provided."""
context = build_meta_context(
title="Test",
og_image="https://example.com/image.jpg",
)
assert "og_image" in context
assert context["og_image"] == "https://example.com/image.jpg"
def test_includes_og_type(self):
"""Should include OG type."""
context = build_meta_context(
title="Test",
og_type="article",
)
assert "og_type" in context
assert context["og_type"] == "article"
def test_default_og_type(self):
"""Should default to 'website' for OG type."""
context = build_meta_context(title="Test")
if "og_type" in context:
assert context["og_type"] == "website"
class TestMetaContextProcessor:
"""Tests for page_meta context processor."""
def test_empty_meta_when_not_set(self):
"""Should return empty dict when not set on request."""
from apps.core.context_processors import page_meta
factory = RequestFactory()
request = factory.get("/")
context = page_meta(request)
assert context["page_meta"] == {}
def test_returns_meta_from_request(self):
"""Should return page_meta when set on request."""
from apps.core.context_processors import page_meta
factory = RequestFactory()
request = factory.get("/")
request.page_meta = {
"title": "Test Page",
"description": "Test description",
}
context = page_meta(request)
assert context["page_meta"]["title"] == "Test Page"
assert context["page_meta"]["description"] == "Test description"