diff --git a/backend/taxonomy.py b/backend/taxonomy.py index 2890527..59c17d8 100644 --- a/backend/taxonomy.py +++ b/backend/taxonomy.py @@ -19,7 +19,14 @@ def _now_iso() -> str: def _scoped_tags(tags: list[dict]) -> list[dict]: - return [t for t in tags if t.get("name", "").startswith(("fig-", "feat-"))] + # The fig-/feat- family marker is on the tag SLUG (e.g. slug 'fig-chat', + # name 'Chatoyant'), not the display name. Match either so a store that + # prefixes the name instead of the slug is also kept. + return [ + t for t in tags + if (t.get("slug", "").startswith(("fig-", "feat-")) + or t.get("name", "").startswith(("fig-", "feat-"))) + ] def _normalize_category(c: dict) -> tuple: diff --git a/backend/tests/test_woo.py b/backend/tests/test_woo.py index 8645db9..2258215 100644 --- a/backend/tests/test_woo.py +++ b/backend/tests/test_woo.py @@ -145,6 +145,24 @@ def test_sync_populates_scoped(db_dir): assert conn.execute("SELECT value FROM settings WHERE key='taxonomy_last_sync_at'").fetchone()[0] +def test_sync_keeps_slug_prefixed_bare_name_tags(db_dir): + # Live-store shape: the fig- family marker is on the SLUG, the display name + # is bare (slug 'fig-chat', name 'Chatoyant'). These must be kept. + tags = (200, {"X-WP-TotalPages": "1"}, json.dumps([ + {"id": 300, "name": "Birdseye", "slug": "fig-brdseye", "woo_id": 300}, + {"id": 310, "name": "Chatoyant", "slug": "fig-chat", "woo_id": 310}, + {"id": 500, "name": "Knot", "slug": "feat-knot", "woo_id": 500}, + {"id": 600, "name": "Rustic", "slug": "rustic", "woo_id": 600}, # bare non-fig: dropped + ]).encode()) + cats = (200, {"X-WP-TotalPages": "1"}, json.dumps([{"id": 1, "name": "Cedar", "slug": "cedar", "parent_id": None, "woo_id": 10}]).encode()) + attrs = (200, {"X-WP-TotalPages": "1"}, json.dumps([]).encode()) + c, _ = _client([cats, tags, attrs]) + taxonomy_mod.sync(c, db_mod.get_connection()) + conn = db_mod.get_connection() + tag_ids = {r[0] for r in conn.execute("SELECT id FROM woo_tags")} + assert tag_ids == {300, 310, 500} # slug-prefixed fig/feat kept, bare 'rustic' dropped + + def test_sync_failure_keeps_previous_cache(db_dir): conn = db_mod.get_connection() conn.execute("INSERT INTO woo_categories(id,name,slug,parent_id,woo_id) VALUES (99,'Old','old',NULL,1)")