"""Tests for credential models and storage interface.""" import uuid import pytest from app.git.credentials import AccessTokenCredential, CredentialStorage, GitCredential from app.git.types import CredentialKind class MinimalCredentialStorage(CredentialStorage): """Concrete subclass for testing.""" def create(self, credential: GitCredential) -> uuid.UUID: return credential.id def get(self, credential_id: uuid.UUID) -> GitCredential | None: return None def delete(self, credential_id: uuid.UUID) -> None: return None def test_git_credential_can_be_instantiated() -> None: cred = GitCredential( kind=CredentialKind.ssh_key, encrypted_payload="encrypted-data", ) assert cred.kind == CredentialKind.ssh_key assert cred.encrypted_payload == "encrypted-data" assert isinstance(cred.id, uuid.UUID) def test_access_token_credential_can_be_instantiated() -> None: cred = AccessTokenCredential(encrypted_payload="encrypted-data") assert cred.kind == CredentialKind.access_token assert cred.encrypted_payload == "encrypted-data" def test_credential_storage_cannot_be_instantiated_directly() -> None: with pytest.raises(TypeError): CredentialStorage() # type: ignore[abstract] def test_no_plaintext_secret_fields() -> None: fields = set(GitCredential.model_fields.keys()) assert "token" not in fields assert "private_key" not in fields def test_extra_forbidden() -> None: with pytest.raises(ValueError): GitCredential( kind=CredentialKind.access_token, encrypted_payload="encrypted-data", secret_plaintext="should-fail", # type: ignore[call-arg] ) def test_minimal_credential_storage_implements_all_methods() -> None: storage = MinimalCredentialStorage() cred = GitCredential( kind=CredentialKind.access_token, encrypted_payload="encrypted-data", ) assert storage.create(cred) == cred.id assert storage.get(cred.id) is None storage.delete(cred.id) def test_encrypted_payload_not_in_repr() -> None: cred = GitCredential( kind=CredentialKind.ssh_key, encrypted_payload="secret-value", ) repr_str = repr(cred) assert "secret-value" not in repr_str