92aaa91a49
Round 3's two HIGHs: _fill_version resolved versions with the LAST same-title entry's cues (photo-aware lookup existed since round 1 but this caller never used it), and the round-2 diff rework let an earlier row's disagreement consume the exact-version copy a later row matched. Diff claims now settle strongest-first across all rows (exact matches, then versionless upgrades, then disagreement/second-copy), unvetoed bare duplicates stay owned per spec, and updates are withheld with a manual-fix note whenever any copy of the game already carries a version (the row edit targets by name and could hit the wrong copy). Also: entry-to-row pairing matches by photo overlap before position (titles.json order churn from reshoot filenames could swap editions); BGGQueueTimeout defers a title like a missing token; DismissStore writes atomically, mutates memory only after the write, and quarantines a torn file instead of bricking the server; version-picker page-limit exhaustion stays retryable; verify's copy-count shortfall reports once per game (the old guard was dead code); the upload log header is created atomically; transient version-lookup failures record a retryable version_error, not terminal version_unknown; extract isolates per-photo failures and salvages JSON followed by prose; a state revision counter stops stale poll responses reverting decisions; plus the shared-predicate/fsio/docstring consolidation and CLI wiring, live-diff, verify-wiring, and search-guard tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
"""Record the BGG XML fixtures the test suite replays.
|
|
|
|
Runs the real resolve logic with the cache pointed at tests/fixtures/
|
|
bgg_cache/, so exactly the responses resolve needs get recorded (live,
|
|
rate-limited). Run once; commit the fixtures. Re-running only fetches
|
|
whatever is not already recorded.
|
|
|
|
Usage: uv run python scripts/record_fixtures.py
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
from fixture_common import FIXTURE_CACHE
|
|
|
|
from bggpipe.bgg_client import BGGClient
|
|
from bggpipe.resolve import load_titles, resolve_entry
|
|
|
|
FIXTURE_CACHE = FIXTURE_CACHE
|
|
|
|
|
|
def main() -> None:
|
|
if not os.environ.get("BGG_API_TOKEN"):
|
|
raise SystemExit(
|
|
"BGG_API_TOKEN is not set. The XML API requires a registered "
|
|
"application token (https://boardgamegeek.com/applications). "
|
|
"Until one exists, the committed fixtures are the hand-crafted "
|
|
"stubs from scripts/write_stub_fixtures.py; delete "
|
|
f"{FIXTURE_CACHE} and re-run this script to replace them with "
|
|
"real recordings."
|
|
)
|
|
client = BGGClient(cache_dir=FIXTURE_CACHE)
|
|
for entry in load_titles(Path("tests/data/titles.json")):
|
|
row = resolve_entry(client, entry)
|
|
print(
|
|
f"{entry.title_raw!r}: {row.match_status} "
|
|
f"{row.bgg_name or '-'} ({row.bgg_id or '-'}) {row.version_status}"
|
|
)
|
|
print(f"\nFixtures recorded in {FIXTURE_CACHE}:")
|
|
for f in sorted(FIXTURE_CACHE.iterdir()):
|
|
print(f" {f.name}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|