96 lines
3.8 KiB
Python
96 lines
3.8 KiB
Python
|
|
import importlib
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
from fastapi import HTTPException
|
||
|
|
|
||
|
|
products_router = importlib.import_module("app.products.backend.router")
|
||
|
|
|
||
|
|
|
||
|
|
def test_normalize_apigw_product_accepts_nested_aliases():
|
||
|
|
normalized = products_router._normalize_apigw_product(
|
||
|
|
{
|
||
|
|
"product": {
|
||
|
|
"productName": "Managed switch",
|
||
|
|
"part_number": "SW-24",
|
||
|
|
"barcode": "570000000001",
|
||
|
|
"net_price": 499.95,
|
||
|
|
"legacy_category": "Netværk",
|
||
|
|
"supplier": {"name": "Grossist", "code": "grossist"},
|
||
|
|
}
|
||
|
|
}
|
||
|
|
)
|
||
|
|
|
||
|
|
assert normalized["product_name"] == "Managed switch"
|
||
|
|
assert normalized["sku"] == "SW-24"
|
||
|
|
assert normalized["ean"] == "570000000001"
|
||
|
|
assert normalized["price"] == 499.95
|
||
|
|
assert normalized["category"] == "Netværk"
|
||
|
|
assert normalized["supplier_name"] == "Grossist"
|
||
|
|
assert normalized["supplier_code"] == "grossist"
|
||
|
|
|
||
|
|
|
||
|
|
def test_normalize_apigw_product_builds_name_from_item_code():
|
||
|
|
normalized = products_router._normalize_apigw_product(
|
||
|
|
{"sku": "ABC-123", "supplier_name": "DCS"}
|
||
|
|
)
|
||
|
|
|
||
|
|
assert normalized["product_name"] == "DCS · ABC-123"
|
||
|
|
|
||
|
|
|
||
|
|
def test_normalize_apigw_product_does_not_unwrap_a_real_product_data_field():
|
||
|
|
normalized = products_router._normalize_apigw_product(
|
||
|
|
{"product_name": "Router", "sku": "RTR-1", "data": {"irrelevant": True}}
|
||
|
|
)
|
||
|
|
|
||
|
|
assert normalized["product_name"] == "Router"
|
||
|
|
assert normalized["sku"] == "RTR-1"
|
||
|
|
|
||
|
|
|
||
|
|
def test_import_apigw_product_rejects_only_truly_unidentifiable_item():
|
||
|
|
with pytest.raises(HTTPException) as exc_info:
|
||
|
|
products_router._import_apigw_product_to_local({"product": {"id": 123}})
|
||
|
|
|
||
|
|
assert exc_info.value.status_code == 400
|
||
|
|
assert "mangler både navn og varenummer" in exc_info.value.detail
|
||
|
|
|
||
|
|
|
||
|
|
def test_products_page_handles_gateway_errors_and_prevents_double_import():
|
||
|
|
template = Path("app/products/frontend/list.html").read_text()
|
||
|
|
|
||
|
|
assert "const data = await res.json().catch(() => ({}));" in template
|
||
|
|
assert "escapeHtml(e.message || 'Fejl ved søgning')" in template
|
||
|
|
assert "async function importGatewayProduct(product, button = null)" in template
|
||
|
|
assert "button.disabled = true;" in template
|
||
|
|
assert "importGatewayProduct(product, button);" in template
|
||
|
|
assert "Angiv mindst ét søgekriterium" in template
|
||
|
|
assert "function safeGatewayUrl(value)" in template
|
||
|
|
|
||
|
|
|
||
|
|
def test_gateway_catalog_search_is_read_only_until_explicit_import():
|
||
|
|
template = Path("app/products/frontend/list.html").read_text()
|
||
|
|
|
||
|
|
assert "Søg hos alle grossister" in template
|
||
|
|
assert "Søgningen opretter ikke varer i Hub'en" in template
|
||
|
|
assert "function searchGatewayCatalogFromLocalQuery()" in template
|
||
|
|
assert "openGatewaySearchModal(query, Boolean(query));" in template
|
||
|
|
assert "params.append('per_page', '100');" in template
|
||
|
|
assert "Importér til Hub" in template
|
||
|
|
assert "auto_create: 'true'" not in template
|
||
|
|
|
||
|
|
|
||
|
|
def test_gateway_catalog_results_show_supplier_and_product_details():
|
||
|
|
template = Path("app/products/frontend/list.html").read_text()
|
||
|
|
|
||
|
|
assert "function renderGatewayProductCard(product, tokens)" in template
|
||
|
|
assert "gatewayInfoItem('Grossist', supplier)" in template
|
||
|
|
assert "gatewayInfoItem('Varenummer', product.sku)" in template
|
||
|
|
assert "gatewayInfoItem('EAN / GTIN', product.ean)" in template
|
||
|
|
assert "gatewayInfoItem('Producent', product.manufacturer)" in template
|
||
|
|
assert "gatewayInfoItem('Kategori', product.category)" in template
|
||
|
|
assert "gatewayInfoItem('Lager', stockParts.join(' · '))" in template
|
||
|
|
assert "formatGatewayCurrency(product.price, product.currency)" in template
|
||
|
|
assert "gateway-catalog-dialog" in template
|
||
|
|
assert "gateway-search-panel" in template
|
||
|
|
assert "gateway-results-grid" in template
|