from __future__ import annotations import unittest from datetime import UTC, datetime, timedelta from uuid import uuid4 from packages.hub_core.domain import ( AuditEvent, Operation, Scope, Workspace, ) from packages.hub_core.errors import InvalidTransition, MissingProjectScope from packages.hub_core.state_machines import transition class DomainContractTests(unittest.TestCase): def test_scope_requires_workspace_and_project_scope_is_explicit(self) -> None: workspace_id = uuid4() scope = Scope.workspace(workspace_id) self.assertEqual(scope.workspace_id, workspace_id) with self.assertRaises(MissingProjectScope): scope.require_project() def test_timestamps_must_be_timezone_aware(self) -> None: with self.assertRaises(ValueError): Workspace( id=uuid4(), slug="itworx", name="ITWorx", created_at=datetime.now(), updated_at=datetime.now(), ) def test_state_machines_reject_invalid_moves(self) -> None: self.assertEqual(transition("operation", "requested", "planned"), "planned") with self.assertRaises(InvalidTransition): transition("operation", "requested", "succeeded") def test_audit_domain_rejects_unknown_fields(self) -> None: now = datetime.now(UTC) with self.assertRaises(ValueError): AuditEvent( trace_id="trace", workspace_id=uuid4(), event_type="test", outcome="success", occurred_at=now, unexpected=True, ) def test_operation_contract_has_expiry_and_plan_hash(self) -> None: now = datetime.now(UTC) operation = Operation( workspace_id=uuid4(), project_id=uuid4(), environment_id=uuid4(), operation_type="future-write", target_ref="target", plan_hash="sha256:test", requested_by="subject", expires_at=now + timedelta(minutes=5), created_at=now, updated_at=now, ) self.assertEqual(operation.state, "requested") self.assertEqual(operation.revision, 1) self.assertNotIn("password", operation.model_dump()) if __name__ == "__main__": unittest.main()