from pathlib import Path from l4d2web.db import init_db, session_scope from l4d2web.models import GlobalOverlayItem, GlobalOverlayItemFile, GlobalOverlaySource from l4d2web.services.global_map_sources import GlobalMapManifestItem def test_refresh_global_overlays_updates_manifest_items_and_invokes_builders(tmp_path, monkeypatch): monkeypatch.setenv("DATABASE_URL", f"sqlite:///{tmp_path/'refresh.db'}") monkeypatch.setenv("LEFT4ME_ROOT", str(tmp_path)) init_db() from l4d2web.services import global_overlay_refresh monkeypatch.setattr( global_overlay_refresh, "fetch_l4d2center_manifest", lambda: ("hash-center", [GlobalMapManifestItem("carriedoff.vpk", "carriedoff.vpk", "https://example.invalid/carriedoff.7z", "carriedoff.vpk", 3, "" )]), ) monkeypatch.setattr( global_overlay_refresh, "fetch_cedapug_manifest", lambda: ("hash-ceda", [GlobalMapManifestItem("FatalFreight.zip", "Fatal Freight", "https://example.invalid/FatalFreight.zip")]), ) def fake_download_and_extract(source_key, item, *, should_cancel): target = tmp_path / "global_overlay_cache" / source_key / "vpks" / (item.expected_vpk_name or item.item_key.replace(".zip", ".vpk")) target.parent.mkdir(parents=True, exist_ok=True) target.write_bytes(b"vpk") return [(target.name, f"{source_key}/vpks/{target.name}", 3, "")], "etag", "last-modified", 3 built: list[str] = [] monkeypatch.setattr(global_overlay_refresh, "download_and_extract_item", fake_download_and_extract) monkeypatch.setattr(global_overlay_refresh, "build_global_overlay", lambda overlay, **kwargs: built.append(overlay.name)) out: list[str] = [] result = global_overlay_refresh.refresh_global_overlays(on_stdout=out.append, on_stderr=out.append, should_cancel=lambda: False) assert result == ["cedapug-maps", "l4d2center-maps"] assert set(built) == {"cedapug-maps", "l4d2center-maps"} with session_scope() as db: assert db.query(GlobalOverlaySource).count() == 2 assert db.query(GlobalOverlayItem).count() == 2 assert db.query(GlobalOverlayItemFile).count() == 2 def test_refresh_removes_items_absent_from_manifest(tmp_path, monkeypatch): monkeypatch.setenv("DATABASE_URL", f"sqlite:///{tmp_path/'remove.db'}") monkeypatch.setenv("LEFT4ME_ROOT", str(tmp_path)) init_db() from l4d2web.services.global_overlays import ensure_global_overlays from l4d2web.services import global_overlay_refresh with session_scope() as db: ensure_global_overlays(db) source = db.query(GlobalOverlaySource).filter_by(source_key="l4d2center-maps").one() item = GlobalOverlayItem(source_id=source.id, item_key="old.vpk", display_name="old.vpk", download_url="https://example.invalid/old.7z") db.add(item) db.flush() db.add(GlobalOverlayItemFile(item_id=item.id, vpk_name="old.vpk", cache_path="l4d2center-maps/vpks/old.vpk", size=3)) monkeypatch.setattr(global_overlay_refresh, "fetch_l4d2center_manifest", lambda: ("empty-center", [])) monkeypatch.setattr(global_overlay_refresh, "fetch_cedapug_manifest", lambda: ("empty-ceda", [])) monkeypatch.setattr(global_overlay_refresh, "build_global_overlay", lambda overlay, **kwargs: None) global_overlay_refresh.refresh_global_overlays(on_stdout=lambda line: None, on_stderr=lambda line: None, should_cancel=lambda: False) with session_scope() as db: assert db.query(GlobalOverlayItem).filter_by(item_key="old.vpk").count() == 0