Skip to content

Commit 4b14428

Browse files
Copilotmwvolo
andauthored
Add test coverage for get_page_content template tag (#1658)
* Initial plan * Add comprehensive test coverage for get_page_content template tag Co-authored-by: mwvolo <3905516+mwvolo@users.noreply.github.com> * Improve test quality based on code review feedback Co-authored-by: mwvolo <3905516+mwvolo@users.noreply.github.com> * Fix test robustness issues from code review Co-authored-by: mwvolo <3905516+mwvolo@users.noreply.github.com> * Remove unused import from test Co-authored-by: mwvolo <3905516+mwvolo@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mwvolo <3905516+mwvolo@users.noreply.github.com>
1 parent 0c6d3f6 commit 4b14428

File tree

1 file changed

+208
-0
lines changed

1 file changed

+208
-0
lines changed

pages/tests.py

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,3 +704,211 @@ def test_groups_link(self):
704704
def test_admin_search(self):
705705
response = self.client.get('/admin/pages/search/?q=openstax')
706706
self.assertEqual(response.status_code, 302)
707+
708+
709+
class TemplateTagTests(WagtailPageTestCase):
710+
"""Test cases for custom template tags in pages app"""
711+
712+
def setUp(self):
713+
"""Set up test data"""
714+
mock_user_login()
715+
716+
# Get root page
717+
root_page = Page.objects.get(title="Root")
718+
719+
# Create a test page with various field types
720+
self.test_page = page_models.HomePage(
721+
title="Test HomePage",
722+
slug="test-home",
723+
banner_headline="Test Headline",
724+
banner_description="Test description text",
725+
features_headline="Features Test",
726+
)
727+
root_page.add_child(instance=self.test_page)
728+
729+
def test_get_page_content_extracts_char_field(self):
730+
"""Test that get_page_content extracts CharField values"""
731+
from django.template import Context, Template
732+
733+
template = Template('{% load pages_tags %}{% get_page_content page as content %}{{ content|length }}')
734+
context = Context({'page': self.test_page})
735+
result = template.render(context)
736+
737+
# Should extract multiple fields
738+
self.assertGreater(int(result), 0)
739+
740+
# Test actual content extraction
741+
template = Template('{% load pages_tags %}{% get_page_content page as content %}{% for item in content %}{{ item.name }}:{{ item.value }}|{% endfor %}')
742+
context = Context({'page': self.test_page})
743+
result = template.render(context)
744+
745+
# Should contain our test data
746+
self.assertIn('banner_headline:Test Headline', result)
747+
self.assertIn('banner_description:Test description text', result)
748+
749+
def test_get_page_content_extracts_text_field(self):
750+
"""Test that get_page_content extracts TextField values"""
751+
from django.template import Context, Template
752+
753+
template = Template('{% load pages_tags %}{% get_page_content page as content %}{% for item in content %}{% if item.name == "banner_description" %}{{ item.value }}{% endif %}{% endfor %}')
754+
context = Context({'page': self.test_page})
755+
result = template.render(context)
756+
757+
self.assertEqual(result.strip(), 'Test description text')
758+
759+
def test_get_page_content_extracts_stream_field(self):
760+
"""Test that get_page_content extracts StreamField values"""
761+
from django.template import Context, Template
762+
763+
# Update the test page with StreamField data
764+
self.test_page.features_tab1_features = [
765+
('feature_text', 'Feature One'),
766+
('feature_text', 'Feature Two'),
767+
]
768+
self.test_page.save()
769+
770+
template = Template('{% load pages_tags %}{% get_page_content page as content %}{% for item in content %}{% if item.name == "features_tab1_features" %}{{ item.value }}{% endif %}{% endfor %}')
771+
context = Context({'page': self.test_page})
772+
result = template.render(context)
773+
774+
# Should contain the StreamField content
775+
self.assertIn('Feature One', result)
776+
self.assertIn('Feature Two', result)
777+
778+
def test_get_page_content_filters_system_fields(self):
779+
"""Test that get_page_content filters out internal/system fields"""
780+
from django.template import Context, Template
781+
782+
template = Template('{% load pages_tags %}{% get_page_content page as content %}{% for item in content %}{{ item.name }}|{% endfor %}')
783+
context = Context({'page': self.test_page})
784+
result = template.render(context)
785+
786+
# Should NOT contain system fields
787+
self.assertNotIn('id|', result)
788+
self.assertNotIn('path|', result)
789+
self.assertNotIn('depth|', result)
790+
self.assertNotIn('slug|', result)
791+
self.assertNotIn('seo_title|', result)
792+
self.assertNotIn('content_type|', result)
793+
794+
def test_get_page_content_handles_none_values(self):
795+
"""Test that get_page_content handles None values gracefully"""
796+
from django.template import Context, Template
797+
798+
# Create a page with minimal data
799+
root_page = Page.objects.get(title="Root")
800+
minimal_page = page_models.HomePage(
801+
title="Minimal Page",
802+
slug="minimal",
803+
)
804+
root_page.add_child(instance=minimal_page)
805+
806+
template = Template('{% load pages_tags %}{% get_page_content page as content %}{{ content|length }}')
807+
context = Context({'page': minimal_page})
808+
result = template.render(context)
809+
810+
# Should not crash and should return a number
811+
result_int = int(result)
812+
self.assertGreaterEqual(result_int, 0)
813+
814+
def test_get_page_content_handles_empty_values(self):
815+
"""Test that get_page_content filters out empty values"""
816+
from django.template import Context, Template
817+
from pages.templatetags.pages_tags import get_page_content
818+
819+
# Get content directly using the template tag function
820+
context = Context({'page': self.test_page})
821+
content = get_page_content(context, self.test_page)
822+
823+
# All returned items should have non-empty values
824+
for item in content:
825+
self.assertIn('name', item, "Item missing 'name' key")
826+
self.assertIn('value', item, "Item missing 'value' key")
827+
self.assertTrue(item.get('value', '').strip(),
828+
f"Item {item.get('name', 'unknown')} has empty value")
829+
830+
def test_get_page_content_with_none_page(self):
831+
"""Test that get_page_content handles None page gracefully"""
832+
from django.template import Context, Template
833+
834+
template = Template('{% load pages_tags %}{% get_page_content page as content %}{{ content|length }}')
835+
context = Context({'page': None})
836+
result = template.render(context)
837+
838+
self.assertEqual(result.strip(), '0')
839+
840+
def test_extract_content_handles_primitives(self):
841+
"""Test that extract_content handles primitive types"""
842+
from pages.templatetags.pages_tags import extract_content
843+
844+
self.assertEqual(extract_content("test string"), "test string")
845+
self.assertEqual(extract_content(123), "123")
846+
self.assertEqual(extract_content(45.67), "45.67")
847+
self.assertEqual(extract_content(None), "")
848+
849+
def test_extract_content_handles_richtext(self):
850+
"""Test that extract_content handles RichText objects"""
851+
from pages.templatetags.pages_tags import extract_content
852+
from wagtail.rich_text import RichText
853+
854+
rich = RichText("<p>Rich text content</p>")
855+
result = extract_content(rich)
856+
857+
self.assertIn("Rich text content", result)
858+
859+
def test_extract_content_handles_lists(self):
860+
"""Test that extract_content handles list values"""
861+
from pages.templatetags.pages_tags import extract_content
862+
863+
test_list = ["item1", "item2", "item3"]
864+
result = extract_content(test_list)
865+
866+
self.assertIn("item1", result)
867+
self.assertIn("item2", result)
868+
self.assertIn("item3", result)
869+
870+
def test_extract_content_handles_nested_structures(self):
871+
"""Test that extract_content recursively extracts from nested structures"""
872+
from pages.templatetags.pages_tags import extract_content
873+
874+
# Test with nested list
875+
nested = [["inner1", "inner2"], "outer"]
876+
result = extract_content(nested)
877+
878+
self.assertIn("inner1", result)
879+
self.assertIn("inner2", result)
880+
self.assertIn("outer", result)
881+
882+
def test_extract_content_handles_dict_like_objects(self):
883+
"""Test that extract_content handles dict-like objects with values() method"""
884+
from pages.templatetags.pages_tags import extract_content
885+
886+
# Create a mock object with values() method
887+
class MockStructValue:
888+
def values(self):
889+
return ["value1", "value2"]
890+
891+
mock = MockStructValue()
892+
result = extract_content(mock)
893+
894+
self.assertIn("value1", result)
895+
self.assertIn("value2", result)
896+
897+
def test_get_page_content_returns_proper_structure(self):
898+
"""Test that get_page_content returns items with correct structure"""
899+
from django.template import Context, Template
900+
from pages.templatetags.pages_tags import get_page_content
901+
902+
# Get content directly to check structure
903+
context = Context({'page': self.test_page})
904+
content = get_page_content(context, self.test_page)
905+
906+
# Each item should be a dict with required keys
907+
for item in content:
908+
self.assertIsInstance(item, dict, "Content item should be a dictionary")
909+
self.assertIn('name', item, "Item missing 'name' key")
910+
self.assertIn('type', item, "Item missing 'type' key")
911+
self.assertIn('value', item, "Item missing 'value' key")
912+
self.assertIsInstance(item['name'], str, "Item name should be a string")
913+
self.assertIsInstance(item['type'], str, "Item type should be a string")
914+
self.assertIsInstance(item['value'], str, "Item value should be a string")

0 commit comments

Comments
 (0)