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:
@@ -3,6 +3,7 @@
|
||||
|
||||
Tests the /api/v1/admin/auth/* endpoints.
|
||||
"""
|
||||
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
import pytest
|
||||
@@ -46,7 +47,10 @@ class TestAdminAuthAPI:
|
||||
"""Test login with wrong password."""
|
||||
response = client.post(
|
||||
"/api/v1/admin/auth/login",
|
||||
json={"email_or_username": test_admin.username, "password": "wrongpassword"},
|
||||
json={
|
||||
"email_or_username": test_admin.username,
|
||||
"password": "wrongpassword",
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 401
|
||||
@@ -73,7 +77,10 @@ class TestAdminAuthAPI:
|
||||
try:
|
||||
response = client.post(
|
||||
"/api/v1/admin/auth/login",
|
||||
json={"email_or_username": test_admin.username, "password": "adminpass123"},
|
||||
json={
|
||||
"email_or_username": test_admin.username,
|
||||
"password": "adminpass123",
|
||||
},
|
||||
)
|
||||
|
||||
assert response.status_code == 403
|
||||
@@ -153,7 +160,8 @@ class TestAdminAuthAPI:
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
"/api/v1/admin/auth/me", headers={"Authorization": f"Bearer {expired_token}"}
|
||||
"/api/v1/admin/auth/me",
|
||||
headers={"Authorization": f"Bearer {expired_token}"},
|
||||
)
|
||||
|
||||
assert response.status_code == 401
|
||||
|
||||
@@ -4,6 +4,7 @@ Integration tests for admin dashboard and statistics endpoints.
|
||||
|
||||
Tests the /api/v1/admin/dashboard/* endpoints.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -34,7 +35,9 @@ class TestAdminDashboardAPI:
|
||||
data = response.json()
|
||||
assert data["error_code"] == "ADMIN_REQUIRED"
|
||||
|
||||
def test_get_comprehensive_stats(self, client, admin_headers, test_marketplace_product):
|
||||
def test_get_comprehensive_stats(
|
||||
self, client, admin_headers, test_marketplace_product
|
||||
):
|
||||
"""Test getting comprehensive statistics."""
|
||||
response = client.get("/api/v1/admin/dashboard/stats", headers=admin_headers)
|
||||
|
||||
@@ -47,7 +50,9 @@ class TestAdminDashboardAPI:
|
||||
assert "unique_vendors" in data
|
||||
assert data["total_products"] >= 0
|
||||
|
||||
def test_get_marketplace_stats(self, client, admin_headers, test_marketplace_product):
|
||||
def test_get_marketplace_stats(
|
||||
self, client, admin_headers, test_marketplace_product
|
||||
):
|
||||
"""Test getting marketplace statistics."""
|
||||
response = client.get(
|
||||
"/api/v1/admin/dashboard/stats/marketplace", headers=admin_headers
|
||||
|
||||
@@ -9,8 +9,9 @@ Tests cover:
|
||||
4. Order management for vendors
|
||||
"""
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
@@ -20,13 +21,9 @@ from unittest.mock import patch, MagicMock
|
||||
class TestAdminLetzshopVendorsAPI:
|
||||
"""Test admin Letzshop vendor overview endpoints."""
|
||||
|
||||
def test_list_vendors_letzshop_status(
|
||||
self, client, admin_headers, test_vendor
|
||||
):
|
||||
def test_list_vendors_letzshop_status(self, client, admin_headers, test_vendor):
|
||||
"""Test listing vendors with Letzshop status."""
|
||||
response = client.get(
|
||||
"/api/v1/admin/letzshop/vendors", headers=admin_headers
|
||||
)
|
||||
response = client.get("/api/v1/admin/letzshop/vendors", headers=admin_headers)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
@@ -41,12 +38,10 @@ class TestAdminLetzshopVendorsAPI:
|
||||
break
|
||||
# Vendor may not be found if inactive, that's ok
|
||||
|
||||
def test_list_vendors_configured_only(
|
||||
self, client, db, admin_headers, test_vendor
|
||||
):
|
||||
def test_list_vendors_configured_only(self, client, db, admin_headers, test_vendor):
|
||||
"""Test listing only configured vendors."""
|
||||
from models.database.letzshop import VendorLetzshopCredentials
|
||||
from app.utils.encryption import encrypt_value
|
||||
from models.database.letzshop import VendorLetzshopCredentials
|
||||
|
||||
# Configure credentials for test vendor
|
||||
credentials = VendorLetzshopCredentials(
|
||||
@@ -87,9 +82,7 @@ class TestAdminLetzshopCredentialsAPI:
|
||||
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_create_vendor_credentials(
|
||||
self, client, admin_headers, test_vendor
|
||||
):
|
||||
def test_create_vendor_credentials(self, client, admin_headers, test_vendor):
|
||||
"""Test creating credentials for a vendor."""
|
||||
response = client.post(
|
||||
f"/api/v1/admin/letzshop/vendors/{test_vendor.id}/credentials",
|
||||
@@ -129,9 +122,7 @@ class TestAdminLetzshopCredentialsAPI:
|
||||
data = response.json()
|
||||
assert data["vendor_id"] == test_vendor.id
|
||||
|
||||
def test_update_vendor_credentials(
|
||||
self, client, admin_headers, test_vendor
|
||||
):
|
||||
def test_update_vendor_credentials(self, client, admin_headers, test_vendor):
|
||||
"""Test partial update of vendor credentials."""
|
||||
# Create first
|
||||
client.post(
|
||||
@@ -151,9 +142,7 @@ class TestAdminLetzshopCredentialsAPI:
|
||||
data = response.json()
|
||||
assert data["auto_sync_enabled"] is True
|
||||
|
||||
def test_delete_vendor_credentials(
|
||||
self, client, admin_headers, test_vendor
|
||||
):
|
||||
def test_delete_vendor_credentials(self, client, admin_headers, test_vendor):
|
||||
"""Test deleting vendor credentials."""
|
||||
# Create first
|
||||
client.post(
|
||||
@@ -218,9 +207,7 @@ class TestAdminLetzshopConnectionAPI:
|
||||
assert data["success"] is True
|
||||
|
||||
@patch("app.services.letzshop.client_service.requests.Session.post")
|
||||
def test_test_api_key_directly(
|
||||
self, mock_post, client, admin_headers
|
||||
):
|
||||
def test_test_api_key_directly(self, mock_post, client, admin_headers):
|
||||
"""Test any API key without associating with vendor."""
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
@@ -245,9 +232,7 @@ class TestAdminLetzshopConnectionAPI:
|
||||
class TestAdminLetzshopOrdersAPI:
|
||||
"""Test admin Letzshop order management endpoints."""
|
||||
|
||||
def test_list_vendor_orders_empty(
|
||||
self, client, admin_headers, test_vendor
|
||||
):
|
||||
def test_list_vendor_orders_empty(self, client, admin_headers, test_vendor):
|
||||
"""Test listing vendor orders when none exist."""
|
||||
response = client.get(
|
||||
f"/api/v1/admin/letzshop/vendors/{test_vendor.id}/orders",
|
||||
@@ -259,9 +244,7 @@ class TestAdminLetzshopOrdersAPI:
|
||||
assert data["orders"] == []
|
||||
assert data["total"] == 0
|
||||
|
||||
def test_list_vendor_orders_with_data(
|
||||
self, client, db, admin_headers, test_vendor
|
||||
):
|
||||
def test_list_vendor_orders_with_data(self, client, db, admin_headers, test_vendor):
|
||||
"""Test listing vendor orders with data."""
|
||||
from models.database.letzshop import LetzshopOrder
|
||||
|
||||
@@ -288,9 +271,7 @@ class TestAdminLetzshopOrdersAPI:
|
||||
assert data["orders"][0]["customer_email"] == "admin-test@example.com"
|
||||
|
||||
@patch("app.services.letzshop.client_service.requests.Session.post")
|
||||
def test_trigger_vendor_sync(
|
||||
self, mock_post, client, admin_headers, test_vendor
|
||||
):
|
||||
def test_trigger_vendor_sync(self, mock_post, client, admin_headers, test_vendor):
|
||||
"""Test triggering sync for a vendor."""
|
||||
# Mock response
|
||||
mock_response = MagicMock()
|
||||
@@ -343,9 +324,7 @@ class TestAdminLetzshopOrdersAPI:
|
||||
class TestAdminLetzshopAccessControl:
|
||||
"""Test admin access control for Letzshop endpoints."""
|
||||
|
||||
def test_non_admin_cannot_access(
|
||||
self, client, auth_headers, test_vendor
|
||||
):
|
||||
def test_non_admin_cannot_access(self, client, auth_headers, test_vendor):
|
||||
"""Test that non-admin users cannot access admin endpoints."""
|
||||
response = client.get(
|
||||
"/api/v1/admin/letzshop/vendors",
|
||||
@@ -368,9 +347,7 @@ class TestAdminLetzshopAccessControl:
|
||||
class TestAdminLetzshopExportAPI:
|
||||
"""Test admin Letzshop product export endpoints."""
|
||||
|
||||
def test_export_vendor_products_empty(
|
||||
self, client, admin_headers, test_vendor
|
||||
):
|
||||
def test_export_vendor_products_empty(self, client, admin_headers, test_vendor):
|
||||
"""Test exporting products when vendor has no products."""
|
||||
response = client.get(
|
||||
f"/api/v1/admin/vendors/{test_vendor.id}/export/letzshop",
|
||||
@@ -387,11 +364,11 @@ class TestAdminLetzshopExportAPI:
|
||||
self, client, db, admin_headers, test_vendor
|
||||
):
|
||||
"""Test exporting products with actual data."""
|
||||
from models.database.product import Product
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
from models.database.marketplace_product_translation import (
|
||||
MarketplaceProductTranslation,
|
||||
)
|
||||
from models.database.product import Product
|
||||
|
||||
# Create marketplace product
|
||||
mp = MarketplaceProduct(
|
||||
@@ -441,11 +418,11 @@ class TestAdminLetzshopExportAPI:
|
||||
self, client, db, admin_headers, test_vendor
|
||||
):
|
||||
"""Test exporting products in French."""
|
||||
from models.database.product import Product
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
from models.database.marketplace_product_translation import (
|
||||
MarketplaceProductTranslation,
|
||||
)
|
||||
from models.database.product import Product
|
||||
|
||||
mp = MarketplaceProduct(
|
||||
marketplace_product_id="EXPORT-FR-001",
|
||||
@@ -487,11 +464,11 @@ class TestAdminLetzshopExportAPI:
|
||||
self, client, db, admin_headers, test_vendor
|
||||
):
|
||||
"""Test exporting including inactive products."""
|
||||
from models.database.product import Product
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
from models.database.marketplace_product_translation import (
|
||||
MarketplaceProductTranslation,
|
||||
)
|
||||
from models.database.product import Product
|
||||
|
||||
# Create inactive product
|
||||
mp = MarketplaceProduct(
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
Tests the /api/v1/admin/marketplace-import-jobs/* endpoints.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ Integration tests for admin marketplace product catalog endpoints.
|
||||
|
||||
Tests the /api/v1/admin/products endpoints.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -84,9 +85,7 @@ class TestAdminProductsAPI:
|
||||
data = response.json()
|
||||
assert data["total"] >= 1
|
||||
|
||||
def test_get_products_pagination(
|
||||
self, client, admin_headers, multiple_products
|
||||
):
|
||||
def test_get_products_pagination(self, client, admin_headers, multiple_products):
|
||||
"""Test admin products pagination."""
|
||||
# Test first page
|
||||
response = client.get(
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
Tests the /api/v1/admin/users/* endpoints.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ Integration tests for admin vendor product catalog endpoints.
|
||||
|
||||
Tests the /api/v1/admin/vendor-products endpoints.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -88,9 +89,7 @@ class TestAdminVendorProductsAPI:
|
||||
for product in data["products"]:
|
||||
assert product["is_featured"] is False
|
||||
|
||||
def test_get_vendor_products_pagination(
|
||||
self, client, admin_headers, test_product
|
||||
):
|
||||
def test_get_vendor_products_pagination(self, client, admin_headers, test_product):
|
||||
"""Test admin vendor products pagination."""
|
||||
response = client.get(
|
||||
"/api/v1/admin/vendor-products",
|
||||
@@ -103,9 +102,7 @@ class TestAdminVendorProductsAPI:
|
||||
assert data["skip"] == 0
|
||||
assert data["limit"] == 10
|
||||
|
||||
def test_get_vendor_product_stats_admin(
|
||||
self, client, admin_headers, test_product
|
||||
):
|
||||
def test_get_vendor_product_stats_admin(self, client, admin_headers, test_product):
|
||||
"""Test admin getting vendor product statistics."""
|
||||
response = client.get(
|
||||
"/api/v1/admin/vendor-products/stats", headers=admin_headers
|
||||
@@ -148,9 +145,7 @@ class TestAdminVendorProductsAPI:
|
||||
vendor_ids = [v["id"] for v in data["vendors"]]
|
||||
assert test_vendor.id in vendor_ids
|
||||
|
||||
def test_get_vendor_product_detail_admin(
|
||||
self, client, admin_headers, test_product
|
||||
):
|
||||
def test_get_vendor_product_detail_admin(self, client, admin_headers, test_product):
|
||||
"""Test admin getting vendor product detail."""
|
||||
response = client.get(
|
||||
f"/api/v1/admin/vendor-products/{test_product.id}",
|
||||
@@ -175,9 +170,7 @@ class TestAdminVendorProductsAPI:
|
||||
data = response.json()
|
||||
assert data["error_code"] == "PRODUCT_NOT_FOUND"
|
||||
|
||||
def test_remove_vendor_product_admin(
|
||||
self, client, admin_headers, test_product, db
|
||||
):
|
||||
def test_remove_vendor_product_admin(self, client, admin_headers, test_product, db):
|
||||
"""Test admin removing product from vendor catalog."""
|
||||
product_id = test_product.id
|
||||
|
||||
@@ -209,9 +202,7 @@ class TestAdminVendorProductsAPI:
|
||||
data = response.json()
|
||||
assert data["error_code"] == "PRODUCT_NOT_FOUND"
|
||||
|
||||
def test_remove_vendor_product_non_admin(
|
||||
self, client, auth_headers, test_product
|
||||
):
|
||||
def test_remove_vendor_product_non_admin(self, client, auth_headers, test_product):
|
||||
"""Test non-admin trying to remove product."""
|
||||
response = client.delete(
|
||||
f"/api/v1/admin/vendor-products/{test_product.id}",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
Tests the /api/v1/admin/vendors/* endpoints.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
|
||||
@@ -90,7 +90,9 @@ class TestVendorDashboardAPI:
|
||||
db.commit()
|
||||
|
||||
# Get stats for vendor
|
||||
response = client.get("/api/v1/vendor/dashboard/stats", headers=vendor_user_headers)
|
||||
response = client.get(
|
||||
"/api/v1/vendor/dashboard/stats", headers=vendor_user_headers
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Tests the /api/v1/vendor/inventory/* endpoints.
|
||||
All endpoints require vendor JWT authentication.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -14,11 +15,17 @@ class TestVendorInventoryAPI:
|
||||
"""Test vendor inventory management endpoints at /api/v1/vendor/inventory/*."""
|
||||
|
||||
def test_set_inventory_success(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test setting inventory for a product."""
|
||||
# Ensure test_product belongs to the vendor
|
||||
from models.database.product import Product
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
db.commit()
|
||||
@@ -41,10 +48,16 @@ class TestVendorInventoryAPI:
|
||||
assert data["quantity"] == 100
|
||||
|
||||
def test_adjust_inventory_success(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test adjusting inventory quantity."""
|
||||
from models.database.product import Product
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
db.commit()
|
||||
@@ -102,10 +115,16 @@ class TestVendorInventoryAPI:
|
||||
assert "total" in data
|
||||
|
||||
def test_get_product_inventory_success(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test getting inventory for a specific product."""
|
||||
from models.database.product import Product
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
db.commit()
|
||||
@@ -128,10 +147,16 @@ class TestVendorInventoryAPI:
|
||||
assert data["error_code"] == "INVALID_TOKEN"
|
||||
|
||||
def test_reserve_inventory_success(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test reserving inventory for an order."""
|
||||
from models.database.product import Product
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
db.commit()
|
||||
@@ -165,11 +190,15 @@ class TestVendorInventoryAPI:
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_update_inventory_success(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test updating inventory record."""
|
||||
from models.database.product import Product
|
||||
from models.database.inventory import Inventory
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
@@ -203,7 +232,12 @@ class TestVendorInventoryAPI:
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_delete_inventory_success(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test deleting inventory record."""
|
||||
from models.database.product import Product
|
||||
|
||||
11
tests/integration/api/v1/vendor/test_letzshop.py
vendored
11
tests/integration/api/v1/vendor/test_letzshop.py
vendored
@@ -8,8 +8,9 @@ Tests cover:
|
||||
3. Order listing
|
||||
"""
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
@@ -524,11 +525,11 @@ class TestVendorLetzshopExportAPI:
|
||||
self, client, db, vendor_user_headers, test_vendor_with_vendor_user
|
||||
):
|
||||
"""Test exporting products with actual data."""
|
||||
from models.database.product import Product
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
from models.database.marketplace_product_translation import (
|
||||
MarketplaceProductTranslation,
|
||||
)
|
||||
from models.database.product import Product
|
||||
|
||||
# Create marketplace product
|
||||
mp = MarketplaceProduct(
|
||||
@@ -577,11 +578,11 @@ class TestVendorLetzshopExportAPI:
|
||||
self, client, db, vendor_user_headers, test_vendor_with_vendor_user
|
||||
):
|
||||
"""Test exporting products in French."""
|
||||
from models.database.product import Product
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
from models.database.marketplace_product_translation import (
|
||||
MarketplaceProductTranslation,
|
||||
)
|
||||
from models.database.product import Product
|
||||
|
||||
mp = MarketplaceProduct(
|
||||
marketplace_product_id="VENDOR-FR-001",
|
||||
@@ -623,11 +624,11 @@ class TestVendorLetzshopExportAPI:
|
||||
self, client, db, vendor_user_headers, test_vendor_with_vendor_user
|
||||
):
|
||||
"""Test exporting products in German."""
|
||||
from models.database.product import Product
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
from models.database.marketplace_product_translation import (
|
||||
MarketplaceProductTranslation,
|
||||
)
|
||||
from models.database.product import Product
|
||||
|
||||
mp = MarketplaceProduct(
|
||||
marketplace_product_id="VENDOR-DE-001",
|
||||
@@ -667,11 +668,11 @@ class TestVendorLetzshopExportAPI:
|
||||
self, client, db, vendor_user_headers, test_vendor_with_vendor_user
|
||||
):
|
||||
"""Test exporting including inactive products."""
|
||||
from models.database.product import Product
|
||||
from models.database.marketplace_product import MarketplaceProduct
|
||||
from models.database.marketplace_product_translation import (
|
||||
MarketplaceProductTranslation,
|
||||
)
|
||||
from models.database.product import Product
|
||||
|
||||
mp = MarketplaceProduct(
|
||||
marketplace_product_id="VENDOR-INACTIVE-001",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Tests the /api/v1/vendor/marketplace/* endpoints.
|
||||
All endpoints require vendor JWT authentication.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -78,8 +79,12 @@ class TestVendorMarketplaceImportJobAPI:
|
||||
"""Test vendor marketplace import job management."""
|
||||
|
||||
def test_get_import_job_success(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user,
|
||||
test_marketplace_import_job, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_marketplace_import_job,
|
||||
db,
|
||||
):
|
||||
"""Test getting import job status by ID."""
|
||||
# Ensure the import job belongs to the vendor
|
||||
|
||||
53
tests/integration/api/v1/vendor/test_products.py
vendored
53
tests/integration/api/v1/vendor/test_products.py
vendored
@@ -4,6 +4,7 @@
|
||||
Tests the /api/v1/vendor/products/* endpoints.
|
||||
All endpoints require vendor JWT authentication.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -40,11 +41,17 @@ class TestVendorProductsAPI:
|
||||
assert data["marketplace_product"]["id"] == unique_product.id
|
||||
|
||||
def test_add_product_duplicate_returns_error(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test adding product that already exists returns error."""
|
||||
# Ensure test_product belongs to the vendor
|
||||
from models.database.product import Product
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
db.commit()
|
||||
@@ -65,9 +72,7 @@ class TestVendorProductsAPI:
|
||||
data = response.json()
|
||||
assert data["error_code"] in ["PRODUCT_ALREADY_EXISTS", "VALIDATION_ERROR"]
|
||||
|
||||
def test_add_nonexistent_product_returns_error(
|
||||
self, client, vendor_user_headers
|
||||
):
|
||||
def test_add_nonexistent_product_returns_error(self, client, vendor_user_headers):
|
||||
"""Test adding nonexistent marketplace product returns error."""
|
||||
product_data = {
|
||||
"marketplace_product_id": 99999,
|
||||
@@ -126,11 +131,17 @@ class TestVendorProductsAPI:
|
||||
assert data["error_code"] == "INVALID_TOKEN"
|
||||
|
||||
def test_get_product_detail_success(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test getting product details."""
|
||||
# Ensure test_product belongs to the vendor
|
||||
from models.database.product import Product
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
db.commit()
|
||||
@@ -154,11 +165,17 @@ class TestVendorProductsAPI:
|
||||
assert response.status_code == 404
|
||||
|
||||
def test_update_product_success(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test updating product details."""
|
||||
# Ensure test_product belongs to the vendor
|
||||
from models.database.product import Product
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
db.commit()
|
||||
@@ -180,11 +197,17 @@ class TestVendorProductsAPI:
|
||||
assert data["is_featured"] is True
|
||||
|
||||
def test_toggle_product_active(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test toggling product active status."""
|
||||
# Ensure test_product belongs to the vendor
|
||||
from models.database.product import Product
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
db.commit()
|
||||
@@ -200,11 +223,17 @@ class TestVendorProductsAPI:
|
||||
assert "message" in data
|
||||
|
||||
def test_toggle_product_featured(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test toggling product featured status."""
|
||||
# Ensure test_product belongs to the vendor
|
||||
from models.database.product import Product
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
db.commit()
|
||||
@@ -220,11 +249,17 @@ class TestVendorProductsAPI:
|
||||
assert "message" in data
|
||||
|
||||
def test_delete_product_success(
|
||||
self, client, vendor_user_headers, test_vendor_with_vendor_user, test_product, db
|
||||
self,
|
||||
client,
|
||||
vendor_user_headers,
|
||||
test_vendor_with_vendor_user,
|
||||
test_product,
|
||||
db,
|
||||
):
|
||||
"""Test removing product from catalog."""
|
||||
# Ensure test_product belongs to the vendor
|
||||
from models.database.product import Product
|
||||
|
||||
product = db.query(Product).filter(Product.id == test_product.id).first()
|
||||
product.vendor_id = test_vendor_with_vendor_user.id
|
||||
db.commit()
|
||||
|
||||
Reference in New Issue
Block a user