Files
ss-tools/backend/tests/services/clean_release/test_dto.py
busya ce0369ae5c test(backend): add 55+ test files to push coverage to 98%
Subagents delivered tests across all uncovered backend modules:

Schemas (100%): agent, auth, health, profile, settings, validation
Services (98-100%): auth, profile, health, llm, mapping, resource,
  security, git, superset_lookup, sql_table_extractor, rbac
API routes (new): auth, admin, health, environments, plugins,
  dashboards (helpers, projection, actions, listing),
  git (config, deps, env, helpers)
Clean Release (100%): DTO, facade, policy_engine, stages,
  repos, preparation, source_isolation, compliance
Git services: base, remote_providers
Agent module: app, run, middleware, langgraph_setup
Core: trace, cleanup, ws_log_handler, timezone, auth (config/oauth/security), matching
Reports: normalizer, report_service, type_profiles
Notifications: service, providers

Also:
- .gitignore: add .coverage, *.cover, coverage-* dirs
- src/schemas/auth.py: fix AD group DN regex (comma in CN=...)
- Remove co-located src/services/__tests__/ (caused pytest module collision)
2026-06-15 13:55:57 +03:00

177 lines
6.9 KiB
Python

# #region Test.CleanRelease.DTO [C:2] [TYPE Module] [SEMANTICS test,clean-release,dto,schema]
# @BRIEF Tests for clean release DTO models — construction, serialization, defaults, field types.
# @RELATION BINDS_TO -> [clean_release_dto]
from datetime import datetime
import pytest
from src.services.clean_release.dto import (
ArtifactDTO,
CandidateDTO,
CandidateOverviewDTO,
ComplianceRunDTO,
ManifestDTO,
ReportDTO,
)
from src.services.clean_release.enums import CandidateStatus, ComplianceDecision, RunStatus
class TestCandidateDTO:
"""CandidateDTO — construction and field validation."""
# #region test_candidate_dto_basic [C:2] [TYPE Function]
def test_candidate_dto_basic(self):
"""Basic CandidateDTO constructed with required fields."""
now = datetime.now()
dto = CandidateDTO(
id="cand-1", version="1.0.0", source_snapshot_ref="git:sha",
build_id="build-1", created_at=now, created_by="tester",
status=CandidateStatus.DRAFT,
)
assert dto.id == "cand-1"
assert dto.version == "1.0.0"
assert dto.build_id == "build-1"
assert dto.status == CandidateStatus.DRAFT
# #endregion test_candidate_dto_basic
# #region test_candidate_dto_default_build_id [C:2] [TYPE Function]
def test_candidate_dto_default_build_id(self):
"""build_id defaults to None."""
now = datetime.now()
dto = CandidateDTO(
id="cand-1", version="1.0.0", source_snapshot_ref="git:sha",
created_at=now, created_by="tester", status=CandidateStatus.PREPARED,
)
assert dto.build_id is None
# #endregion test_candidate_dto_default_build_id
class TestArtifactDTO:
"""ArtifactDTO — field defaults and construction."""
# #region test_artifact_dto_basic [C:2] [TYPE Function]
def test_artifact_dto_basic(self):
"""Basic ArtifactDTO constructed."""
dto = ArtifactDTO(
id="art-1", candidate_id="cand-1", path="bin/app",
sha256="abc123", size=42,
)
assert dto.id == "art-1"
assert dto.size == 42
assert dto.detected_category is None
assert dto.metadata == {}
# #endregion test_artifact_dto_basic
# #region test_artifact_dto_with_all_fields [C:2] [TYPE Function]
def test_artifact_dto_with_all_fields(self):
"""All optional fields populated."""
dto = ArtifactDTO(
id="art-1", candidate_id="cand-1", path="bin/app",
sha256="abc", size=42, detected_category="binary",
declared_category="executable", source_uri="https://src",
source_host="internal.local", metadata={"key": "val"},
)
assert dto.detected_category == "binary"
assert dto.source_host == "internal.local"
assert dto.metadata == {"key": "val"}
# #endregion test_artifact_dto_with_all_fields
class TestManifestDTO:
"""ManifestDTO — construction."""
# #region test_manifest_dto_basic [C:2] [TYPE Function]
def test_manifest_dto_basic(self):
"""ManifestDTO constructed with all fields."""
now = datetime.now()
dto = ManifestDTO(
id="man-1", candidate_id="cand-1", manifest_version=1,
manifest_digest="digest", artifacts_digest="adigest",
created_at=now, created_by="tester",
source_snapshot_ref="ref", content_json={"items": []},
)
assert dto.manifest_version == 1
assert dto.content_json == {"items": []}
# #endregion test_manifest_dto_basic
class TestComplianceRunDTO:
"""ComplianceRunDTO — status tracking DTO."""
# #region test_compliance_run_dto [C:2] [TYPE Function]
def test_compliance_run_dto(self):
"""ComplianceRunDTO with minimal fields."""
dto = ComplianceRunDTO(
run_id="run-1", candidate_id="cand-1", status=RunStatus.RUNNING,
)
assert dto.run_id == "run-1"
assert dto.status == RunStatus.RUNNING
assert dto.final_status is None
assert dto.report_id is None
# #endregion test_compliance_run_dto
# #region test_compliance_run_dto_full [C:2] [TYPE Function]
def test_compliance_run_dto_full(self):
"""ComplianceRunDTO with all optional fields."""
dto = ComplianceRunDTO(
run_id="run-1", candidate_id="cand-1", status=RunStatus.SUCCEEDED,
final_status=ComplianceDecision.PASSED, report_id="CCR-1", task_id="task-1",
)
assert dto.final_status == ComplianceDecision.PASSED
assert dto.task_id == "task-1"
# #endregion test_compliance_run_dto_full
class TestReportDTO:
"""ReportDTO — compact report view."""
# #region test_report_dto [C:2] [TYPE Function]
def test_report_dto(self):
"""ReportDTO constructed."""
now = datetime.now()
dto = ReportDTO(
report_id="CCR-1", candidate_id="cand-1",
final_status=ComplianceDecision.PASSED, policy_version="1.0",
manifest_digest="digest", violation_count=0, generated_at=now,
)
assert dto.report_id == "CCR-1"
assert dto.violation_count == 0
assert dto.final_status == ComplianceDecision.PASSED
# #endregion test_report_dto
class TestCandidateOverviewDTO:
"""CandidateOverviewDTO — read model for candidate overview."""
# #region test_candidate_overview_dto_basic [C:2] [TYPE Function]
def test_candidate_overview_dto_basic(self):
"""CandidateOverviewDTO with only required fields."""
dto = CandidateOverviewDTO(
candidate_id="cand-1", version="1.0.0",
source_snapshot_ref="ref", status=CandidateStatus.DRAFT,
)
assert dto.candidate_id == "cand-1"
assert dto.latest_manifest_id is None
assert dto.latest_approval_decision is None
# #endregion test_candidate_overview_dto_basic
# #region test_candidate_overview_dto_full [C:2] [TYPE Function]
def test_candidate_overview_dto_full(self):
"""CandidateOverviewDTO with all optional fields."""
dto = CandidateOverviewDTO(
candidate_id="cand-1", version="1.0.0",
source_snapshot_ref="ref", status=CandidateStatus.APPROVED,
latest_manifest_id="man-1", latest_manifest_digest="digest",
latest_run_id="run-1", latest_run_status=RunStatus.SUCCEEDED,
latest_report_id="CCR-1", latest_report_final_status=ComplianceDecision.PASSED,
latest_policy_snapshot_id="policy-1", latest_policy_version="1.0",
latest_registry_snapshot_id="reg-1", latest_registry_version="1.0",
latest_approval_decision="APPROVED",
latest_publication_id="pub-1", latest_publication_status="ACTIVE",
)
assert dto.latest_manifest_id == "man-1"
assert dto.latest_approval_decision == "APPROVED"
assert dto.latest_publication_status == "ACTIVE"
assert dto.latest_run_status == RunStatus.SUCCEEDED
# #endregion test_candidate_overview_dto_full