from __future__ import annotations import pytest from sqlmodel import Session, SQLModel, create_engine from backend.app.db.models import Secret from backend.app.services import repopulse_secret_import as importer from backend.app.services.secret_store import get_secret @pytest.fixture def session(tmp_path, monkeypatch): engine = create_engine(f"sqlite:///{tmp_path / 'secrets.db'}") SQLModel.metadata.create_all(engine) monkeypatch.setattr(importer, "secret_storage_status", lambda: {"productionReady": True}) with Session(engine) as value: yield value def test_import_is_write_only_and_idempotent(session): assert importer.import_repopulse_gitea_token(session, "test-token") == "imported" assert importer.import_repopulse_gitea_token(session, "test-token") == "already_present" assert get_secret(session, importer.SECRET_REF, touch=False) == "test-token" def test_import_rejects_replacement_and_malformed_input(session): importer.import_repopulse_gitea_token(session, "first") with pytest.raises(ValueError, match="different value"): importer.import_repopulse_gitea_token(session, "second") for value in ("", " leading", "trailing ", "line\nbreak", "x" * 8193): with pytest.raises(ValueError): importer.import_repopulse_gitea_token(session, value) assert get_secret(session, importer.SECRET_REF, touch=False) == "first" def test_import_requires_production_secret_storage(session, monkeypatch): monkeypatch.setattr(importer, "secret_storage_status", lambda: {"productionReady": False}) with pytest.raises(ValueError, match="not ready"): importer.import_repopulse_gitea_token(session, "test-token") assert get_secret(session, importer.SECRET_REF, touch=False) is None def test_import_does_not_overwrite_an_undecryptable_secret(session): importer.import_repopulse_gitea_token(session, "original") row = session.get(Secret, importer.SECRET_REF) assert row is not None row.encrypted_value = "corrupted-ciphertext" session.add(row) session.commit() with pytest.raises(ValueError, match="cannot be decrypted"): importer.import_repopulse_gitea_token(session, "replacement") assert session.get(Secret, importer.SECRET_REF).encrypted_value == "corrupted-ciphertext" def test_controller_bootstrap_import_uses_fixed_distinct_reference(session): assert importer.import_controller_bootstrap(session, "bootstrap-test-token") == "imported" assert importer.import_controller_bootstrap(session, "bootstrap-test-token") == "already_present" assert get_secret(session, importer.BOOTSTRAP_SECRET_REF, touch=False) == "bootstrap-test-token" assert get_secret(session, importer.SECRET_REF, touch=False) is None with pytest.raises(ValueError, match="different value"): importer.import_controller_bootstrap(session, "other-token")