94 lines
2.5 KiB
Python
94 lines
2.5 KiB
Python
"""Tests for core domain invariants around artifacts & relationships."""
|
|
|
|
from datetime import datetime, timezone
|
|
from uuid import uuid4
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from asf_domain import (
|
|
Artifact,
|
|
ArtifactCreate,
|
|
ArtifactRelationshipCreate,
|
|
ArtifactRelationship,
|
|
ArtifactType,
|
|
RelationshipType,
|
|
generate_id,
|
|
)
|
|
|
|
|
|
NOW = datetime(2026, 9, 7, 12, 0, 0, tzinfo=timezone.utc)
|
|
|
|
|
|
def test_generate_id_returns_unique_uuid4() -> None:
|
|
a = generate_id()
|
|
b = generate_id()
|
|
assert a != b
|
|
assert a.version == 4
|
|
|
|
|
|
def test_artifact_create_minimal() -> None:
|
|
body = ArtifactCreate(
|
|
project_id=uuid4(),
|
|
type=ArtifactType.REQUIREMENT,
|
|
title="Login page must support MFA",
|
|
)
|
|
assert body.type == ArtifactType.REQUIREMENT
|
|
assert body.metadata == {}
|
|
|
|
|
|
def test_artifact_stored_round_trip() -> None:
|
|
tenant_id = uuid4()
|
|
project_id = uuid4()
|
|
|
|
a = Artifact(
|
|
tenant_id=tenant_id,
|
|
project_id=project_id,
|
|
type=ArtifactType.TASK,
|
|
title="Wire MFA provider",
|
|
content="- [ ] choose TOTP lib\n- [ ] enroll flow",
|
|
metadata={"estimated_points": 5, "labels": ["auth", "security"]},
|
|
created_at=NOW,
|
|
updated_at=NOW,
|
|
)
|
|
d = a.model_dump(mode="json")
|
|
# ensure UTC serialization works
|
|
assert d["created_at"].endswith("Z")
|
|
assert d["metadata"]["labels"] == ["auth", "security"]
|
|
|
|
|
|
def test_artifact_rejects_empty_title() -> None:
|
|
with pytest.raises(ValidationError):
|
|
ArtifactCreate(project_id=uuid4(), type=ArtifactType.STORY, title="")
|
|
|
|
|
|
def test_relationship_create() -> None:
|
|
a = uuid4()
|
|
b = uuid4()
|
|
rel = ArtifactRelationshipCreate(
|
|
relationship_type=RelationshipType.IMPLEMENTED_BY,
|
|
source_artifact_id=a,
|
|
target_artifact_id=b,
|
|
)
|
|
assert rel.source_artifact_id == a
|
|
|
|
|
|
def test_relationship_stored_enforces_tenancy() -> None:
|
|
tenant_id = uuid4()
|
|
a, b = uuid4(), uuid4()
|
|
pa, pb = uuid4(), uuid4()
|
|
rel = ArtifactRelationship(
|
|
tenant_id=tenant_id,
|
|
source_project_id=pa,
|
|
target_project_id=pb,
|
|
relationship_type=RelationshipType.VERIFIED_BY,
|
|
source_artifact_id=a,
|
|
target_artifact_id=b,
|
|
created_at=NOW,
|
|
updated_at=NOW,
|
|
)
|
|
# a relationship carries both project ids for tenant isolation queries
|
|
assert rel.tenant_id == tenant_id
|
|
assert rel.source_project_id == pa
|
|
assert rel.target_project_id == pb
|