fix: correct tojson|safe usage in templates and update validator

- Remove |safe from |tojson in HTML attributes (x-data) - quotes must
  become " for browsers to parse correctly
- Update LANG-002 and LANG-003 architecture rules to document correct
  |tojson usage patterns:
  - HTML attributes: |tojson (no |safe)
  - Script blocks: |tojson|safe
- Fix validator to warn when |tojson|safe is used in x-data (breaks
  HTML attribute parsing)
- Improve code quality across services, APIs, and tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-13 22:59:51 +01:00
parent 94d268f330
commit 9920430b9e
123 changed files with 1408 additions and 840 deletions

View File

@@ -1,5 +1,6 @@
# tests/unit/services/test_inventory_service.py
"""Unit tests for InventoryService."""
import uuid
import pytest
@@ -352,23 +353,21 @@ class TestInventoryService:
self, db, test_inventory, test_product, test_vendor
):
"""Test getting product inventory summary."""
result = self.service.get_product_inventory(
db, test_vendor.id, test_product.id
)
result = self.service.get_product_inventory(db, test_vendor.id, test_product.id)
assert result.product_id == test_product.id
assert result.vendor_id == test_vendor.id
assert result.total_quantity >= test_inventory.quantity
assert len(result.locations) >= 1
def test_get_product_inventory_no_inventory(
self, db, test_product, test_vendor
):
def test_get_product_inventory_no_inventory(self, db, test_product, test_vendor):
"""Test getting inventory for product with no inventory entries."""
# Create a new product without inventory
from models.database.product import Product
from models.database.marketplace_product import MarketplaceProduct
from models.database.marketplace_product_translation import MarketplaceProductTranslation
from models.database.marketplace_product_translation import (
MarketplaceProductTranslation,
)
from models.database.product import Product
unique_id = str(uuid.uuid4())[:8]
mp = MarketplaceProduct(
@@ -412,9 +411,7 @@ class TestInventoryService:
# ==================== Get Vendor Inventory Tests ====================
def test_get_vendor_inventory_success(
self, db, test_inventory, test_vendor
):
def test_get_vendor_inventory_success(self, db, test_inventory, test_vendor):
"""Test getting all vendor inventory."""
result = self.service.get_vendor_inventory(db, test_vendor.id)
@@ -433,9 +430,7 @@ class TestInventoryService:
for inv in result:
assert test_inventory.location[:10].upper() in inv.location.upper()
def test_get_vendor_inventory_with_low_stock_filter(
self, db, test_vendor
):
def test_get_vendor_inventory_with_low_stock_filter(self, db, test_vendor):
"""Test getting vendor inventory filtered by low stock threshold."""
result = self.service.get_vendor_inventory(
db, test_vendor.id, low_stock_threshold=5
@@ -446,17 +441,13 @@ class TestInventoryService:
def test_get_vendor_inventory_pagination(self, db, test_vendor):
"""Test vendor inventory pagination."""
result = self.service.get_vendor_inventory(
db, test_vendor.id, skip=0, limit=10
)
result = self.service.get_vendor_inventory(db, test_vendor.id, skip=0, limit=10)
assert len(result) <= 10
# ==================== Update Inventory Tests ====================
def test_update_inventory_quantity(
self, db, test_inventory, test_vendor
):
def test_update_inventory_quantity(self, db, test_inventory, test_vendor):
"""Test updating inventory quantity."""
inventory_update = InventoryUpdate(quantity=500)
@@ -466,9 +457,7 @@ class TestInventoryService:
assert result.quantity == 500
def test_update_inventory_reserved_quantity(
self, db, test_inventory, test_vendor
):
def test_update_inventory_reserved_quantity(self, db, test_inventory, test_vendor):
"""Test updating inventory reserved quantity."""
inventory_update = InventoryUpdate(reserved_quantity=20)
@@ -478,9 +467,7 @@ class TestInventoryService:
assert result.reserved_quantity == 20
def test_update_inventory_location(
self, db, test_inventory, test_vendor
):
def test_update_inventory_location(self, db, test_inventory, test_vendor):
"""Test updating inventory location."""
unique_id = str(uuid.uuid4())[:8].upper()
new_location = f"NEW_LOCATION_{unique_id}"
@@ -499,9 +486,7 @@ class TestInventoryService:
with pytest.raises(InventoryNotFoundException):
self.service.update_inventory(db, test_vendor.id, 99999, inventory_update)
def test_update_inventory_wrong_vendor(
self, db, test_inventory, other_company
):
def test_update_inventory_wrong_vendor(self, db, test_inventory, other_company):
"""Test updating inventory from wrong vendor raises InventoryNotFoundException."""
from models.database.vendor import Vendor
@@ -525,9 +510,7 @@ class TestInventoryService:
# ==================== Delete Inventory Tests ====================
def test_delete_inventory_success(
self, db, test_inventory, test_vendor
):
def test_delete_inventory_success(self, db, test_inventory, test_vendor):
"""Test deleting inventory entry."""
inventory_id = test_inventory.id
@@ -544,9 +527,7 @@ class TestInventoryService:
with pytest.raises(InventoryNotFoundException):
self.service.delete_inventory(db, test_vendor.id, 99999)
def test_delete_inventory_wrong_vendor(
self, db, test_inventory, other_company
):
def test_delete_inventory_wrong_vendor(self, db, test_inventory, other_company):
"""Test deleting inventory from wrong vendor raises InventoryNotFoundException."""
from models.database.vendor import Vendor
@@ -563,4 +544,3 @@ class TestInventoryService:
with pytest.raises(InventoryNotFoundException):
self.service.delete_inventory(db, other_vendor.id, test_inventory.id)