fix(products): conservative dialect detection — canonical-distinctive columns veto Shopify (SLICE-8 review)
Addresses adversarial-review findings: a canonical file carrying a stray Shopify-signature name (e.g. SEO Title) no longer misdetects as Shopify and silently drops canonical Type / corrupts the weight unit (kg->g). A canonical-distinctive column (Description/Variant Cost/Variant Weight/Google Product Category/Variant Volume/Tax ID/Position) now vetoes detection, so detection leans conservative (under-detection warns; over-detection corrupts). Also closes the dual-named-column shadow (Body (HTML)+Description) and the stale-weight-unit-on-clear case. Tests cover all three. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -76,3 +76,46 @@ def test_shopify_fixture_maps_exhaustively():
|
||||
):
|
||||
assert col in parsed.unknown_columns, col
|
||||
assert "Variant Compare At Price" not in first
|
||||
|
||||
|
||||
# --- Detection robustness (review findings #1, #2): bias conservative ----------------
|
||||
|
||||
|
||||
def test_canonical_distinctive_column_vetoes_shopify_detection():
|
||||
# A canonical file carrying a stray Shopify-signature name (`SEO Title`) stays
|
||||
# canonical because it also has canonical-distinctive columns — no misparse,
|
||||
# no dropped Type, no corrupted weight unit (review finding #2).
|
||||
header = ["Handle", "Title", "Type", "Variant Weight", "Variant Weight Unit", "SEO Title"]
|
||||
assert is_shopify_header(header) is False
|
||||
|
||||
|
||||
def test_dual_named_file_stays_canonical_and_warns_shopify_name():
|
||||
# A malformed file with BOTH `Body (HTML)` and canonical `Description`: the
|
||||
# canonical column vetoes detection, so `Body (HTML)` is honestly warned as an
|
||||
# unknown column rather than silently shadowing `Description` (review finding #1).
|
||||
data = (
|
||||
b"Handle,Title,Body (HTML),Description,Variant Price\n"
|
||||
b"mug,Moon Mug,FROM_BODY,FROM_DESC,18.00\n"
|
||||
)
|
||||
parsed = parse_csv(data)
|
||||
assert parsed.dialect == "canonical"
|
||||
assert parsed.rows[0].cells["Description"] == "FROM_DESC"
|
||||
assert "Body (HTML)" in parsed.unknown_columns
|
||||
|
||||
|
||||
def test_real_shopify_export_still_detected():
|
||||
# The conservative veto must not break a genuine Shopify export (no canonical-
|
||||
# distinctive columns present).
|
||||
parsed = parse_csv(_FIXTURE.read_bytes())
|
||||
assert parsed.dialect == "shopify"
|
||||
|
||||
|
||||
def test_shopify_grams_clear_clears_weight_unit_together():
|
||||
# An empty Variant Grams (a clear) clears the synthesized unit too — weight and
|
||||
# unit move together, never a stale unit (review finding #3).
|
||||
data = b"Handle,Title,Body (HTML),Variant Grams\nmug,Moon Mug,<p>x</p>,\n"
|
||||
parsed = parse_csv(data)
|
||||
assert parsed.dialect == "shopify"
|
||||
cells = parsed.rows[0].cells
|
||||
assert cells["Variant Weight"] == ""
|
||||
assert cells["Variant Weight Unit"] == ""
|
||||
|
||||
Reference in New Issue
Block a user