Add template syntax validation tests

Validates all 51 Jinja2 templates can be parsed without syntax errors.
Includes specific tests for key templates: base, product, content, cart,
checkout, shop, invoice, billing, crypto_checkout, home, product_edit,
user_settings, and user_purchases.

Catches issues like mismatched {% if %}/{% endif %} blocks before deployment.
This commit is contained in:
russell@unturf.com 2026-01-22 12:48:50 -05:00
parent 4f43aa7104
commit bbc03b0c6d

View file

@ -0,0 +1,179 @@
"""
Template validation tests.
These tests ensure all Jinja2 templates have valid syntax and can be compiled.
This catches errors like mismatched {% if %}/{% endif %} blocks before deployment.
"""
import os
import unittest
from pathlib import Path
from jinja2 import Environment, FileSystemLoader, TemplateSyntaxError
class TestTemplateValidation(unittest.TestCase):
"""Test that all Jinja2 templates have valid syntax."""
@classmethod
def setUpClass(cls):
"""Set up Jinja2 environment for template testing."""
# Find templates directory
tests_dir = Path(__file__).parent
templates_dir = tests_dir.parent / "templates"
cls.templates_dir = templates_dir
# Create Jinja2 environment matching the app configuration
cls.env = Environment(
loader=FileSystemLoader(str(templates_dir)),
# Don't fail on undefined variables during syntax check
autoescape=True,
)
def test_all_templates_have_valid_syntax(self):
"""
Verify all .j2 templates can be parsed without syntax errors.
This catches issues like:
- Mismatched {% if %}/{% endif %} blocks
- Unclosed {% block %} tags
- Invalid Jinja2 syntax
"""
errors = []
# Walk through all templates
for root, dirs, files in os.walk(self.templates_dir):
for filename in files:
if filename.endswith(".j2"):
# Get relative path for Jinja2 loader
full_path = Path(root) / filename
rel_path = full_path.relative_to(self.templates_dir)
template_name = str(rel_path)
try:
# Attempt to parse the template
self.env.get_template(template_name)
except TemplateSyntaxError as e:
errors.append(
f"{template_name}:{e.lineno}: {e.message}"
)
if errors:
self.fail(
f"Template syntax errors found:\n" + "\n".join(errors)
)
def test_base_template_exists(self):
"""Verify the base template exists and is valid."""
try:
template = self.env.get_template("base.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"base.j2 has syntax error at line {e.lineno}: {e.message}")
def test_product_template_exists(self):
"""Verify product.j2 template exists and is valid."""
try:
template = self.env.get_template("product.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"product.j2 has syntax error at line {e.lineno}: {e.message}")
def test_content_template_exists(self):
"""Verify content.j2 template exists and is valid."""
try:
template = self.env.get_template("content.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"content.j2 has syntax error at line {e.lineno}: {e.message}")
def test_cart_template_exists(self):
"""Verify cart.j2 template exists and is valid."""
try:
template = self.env.get_template("cart.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"cart.j2 has syntax error at line {e.lineno}: {e.message}")
def test_cart_checkout_template_exists(self):
"""Verify cart_checkout.j2 template exists and is valid."""
try:
template = self.env.get_template("cart_checkout.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"cart_checkout.j2 has syntax error at line {e.lineno}: {e.message}")
def test_shop_template_exists(self):
"""Verify shop.j2 template exists and is valid."""
try:
template = self.env.get_template("shop.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"shop.j2 has syntax error at line {e.lineno}: {e.message}")
def test_shop_settings_template_exists(self):
"""Verify shop_settings.j2 template exists and is valid."""
try:
template = self.env.get_template("shop_settings.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"shop_settings.j2 has syntax error at line {e.lineno}: {e.message}")
def test_invoice_template_exists(self):
"""Verify invoice.j2 template exists and is valid."""
try:
template = self.env.get_template("invoice.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"invoice.j2 has syntax error at line {e.lineno}: {e.message}")
def test_billing_template_exists(self):
"""Verify billing.j2 template exists and is valid."""
try:
template = self.env.get_template("billing.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"billing.j2 has syntax error at line {e.lineno}: {e.message}")
def test_crypto_checkout_template_exists(self):
"""Verify crypto_checkout.j2 template exists and is valid."""
try:
template = self.env.get_template("crypto_checkout.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"crypto_checkout.j2 has syntax error at line {e.lineno}: {e.message}")
def test_home_template_exists(self):
"""Verify home.j2 template exists and is valid."""
try:
template = self.env.get_template("home.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"home.j2 has syntax error at line {e.lineno}: {e.message}")
def test_product_edit_template_exists(self):
"""Verify product_edit.j2 template exists and is valid."""
try:
template = self.env.get_template("product_edit.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"product_edit.j2 has syntax error at line {e.lineno}: {e.message}")
def test_user_settings_template_exists(self):
"""Verify user_settings.j2 template exists and is valid."""
try:
template = self.env.get_template("user_settings.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"user_settings.j2 has syntax error at line {e.lineno}: {e.message}")
def test_user_purchases_template_exists(self):
"""Verify user_purchases.j2 template exists and is valid."""
try:
template = self.env.get_template("user_purchases.j2")
self.assertIsNotNone(template)
except TemplateSyntaxError as e:
self.fail(f"user_purchases.j2 has syntax error at line {e.lineno}: {e.message}")
if __name__ == "__main__":
unittest.main()