from contextlib import contextmanager from pathlib import Path from app.native.wndb.core.database import ChangeSet from app.native.wndb.inp import importer def test_import_inp_uses_unique_file_and_always_removes_it(monkeypatch) -> None: paths: list[str] = [] def fake_read_inp(_project: str, path: str, _version: str) -> bool: assert Path(path).read_text(encoding="utf-8") == "[TITLE]\nmodel" paths.append(path) return True monkeypatch.setattr(importer, "read_inp", fake_read_inp) change_set = ChangeSet({"inp": "[TITLE]\nmodel"}) assert importer.import_inp("project_a", change_set) is True assert importer.import_inp("project_a", change_set) is True assert paths[0] != paths[1] assert all(not Path(path).exists() for path in paths) def test_read_inp_refreshes_after_committed_replace_when_cleanup_fails( monkeypatch, ) -> None: events: list[str] = [] @contextmanager def fake_transaction(_project: str): yield monkeypatch.setattr(importer, "have_project", lambda _project: True) monkeypatch.setattr( importer, "temporary_project_name", lambda _project, _purpose: "staging" ) monkeypatch.setattr( importer, "copy_project", lambda source, _target, **kwargs: events.append( f"copy:{source}:{kwargs.get('allow_template_source')}" ), ) monkeypatch.setattr(importer, "project_transaction", fake_transaction) monkeypatch.setattr( importer, "parse_file", lambda *_args: events.append("parse") ) monkeypatch.setattr( importer, "replace_project_model", lambda *_args: events.append("replace"), ) def fail_cleanup(_project: str) -> None: events.append("cleanup-failed") raise RuntimeError("drop failed") monkeypatch.setattr(importer, "delete_project", fail_cleanup) monkeypatch.setattr( importer, "refresh_materialized_views_after_commit", lambda _project: events.append("refresh"), ) assert importer.read_inp("project_a", "model.inp") is True assert events == [ "copy:tjwater_v2_schema_template:True", "parse", "replace", "cleanup-failed", "refresh", ]