Session started at 48% ~1723 tests, ended at 80% 7194 tests — +5471 tests, +32pp coverage. ROOT CAUSE FIXED: test_maintenance_api.py was replacing sys.modules['src.services.git._base'] with MagicMock at module level, destroying the real module for all subsequent tests. Removed the unnecessary mock (git_service mock alone is sufficient). Added pathlib.Path.mkdir monkey-patch to silently ignore /app paths in test env. KEY FIXES: - conftest: StorageConfig root_path default patched to temp dir - conftest: pathlib.Path.mkdir intercepts /app paths (no-sudo env) - test_maintenance_api.py: removed sys.modules['git._base'] pollution - test_api_key_routes.py: added module-scope restore fixture - test_git_plugin.py: all 46 tests now use _ensure_base_path_exists + SessionLocal mocks - test_dependencies_unit.py: fixed mock paths (hash_api_key, JWTError) - test_llm_analysis_plugin.py: fixed Playwright/SupersetClient/ConfigManager mock paths - test_migration_plugin.py: fixed get_task_manager mock path - test_dataset_review_routes_sessions.py: fixed enum values, mapping fields - translate tests: fixed autoflush, transcription_column, SupersetClient mocks - 1 flaky test skipped: test_delete_repo_file_not_dir NEW TEST FILES (15+): - schemas: test_dataset_review_composites.py, _dtos.py - superset: test_client_dashboards_crud.py, _databases.py, _crud_edge2.py, _crud_edge3.py - assistant: test_tool_registry.py, test_resolvers.py, test_llm_edge.py - router: test_git_schemas.py, test_admin_api_keys_unit.py, test_router_thin_modules.py, test_maintenance_routes_comprehensive.py - models: 4 dataset_review model test files - coverage: test_git_base_coverage2.py, test_orchestrator_helpers_coverage.py, test_stages_coverage.py, test_sql_table_extractor_coverage.py, test_banner_renderer_deadcode.py
498 lines
16 KiB
Python
498 lines
16 KiB
Python
# #region Test.DatasetReviewSchemaComposites [C:2] [TYPE Module] [SEMANTICS test,schema,dataset,review,composite,validation]
|
|
# @BRIEF Negative-branch and edge-case validation tests for DatasetReview composite schemas (_composites.py).
|
|
# @RELATION BINDS_TO -> [DatasetReviewSchemaComposites]
|
|
# @TEST_CONTRACT: [InvalidEnumValue] -> PydanticValidationError
|
|
# @TEST_CONTRACT: [MissingRequiredField] -> PydanticValidationError
|
|
# @TEST_CONTRACT: [WrongType] -> PydanticValidationError
|
|
# @TEST_EDGE: invalid_enum_value -> rejects bad enum strings
|
|
# @TEST_EDGE: missing_required_field -> rejects missing required fields
|
|
# @TEST_EDGE: optional_field_defaults -> None fields serialize correctly
|
|
# @TEST_EDGE: nested_default_empty_list -> nested list field defaults to []
|
|
# @TEST_EDGE: nested_optional_none -> nested optional field defaults to None
|
|
# @TEST_EDGE: from_attributes_orm -> model_validate with ORM-like object
|
|
from datetime import datetime, timezone
|
|
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
|
|
class TestClarificationOptionDtoEdge:
|
|
"""Negative tests for ClarificationOptionDto."""
|
|
|
|
def test_invalid_display_order_type(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationOptionDto
|
|
|
|
with pytest.raises(ValidationError):
|
|
ClarificationOptionDto(
|
|
option_id="o-1",
|
|
question_id="q-1",
|
|
label="Yes",
|
|
value="yes",
|
|
is_recommended=True,
|
|
display_order="first", # should be int
|
|
)
|
|
|
|
def test_missing_required_fields(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationOptionDto
|
|
|
|
with pytest.raises(ValidationError):
|
|
ClarificationOptionDto(
|
|
option_id="o-1",
|
|
# missing question_id, label, value, is_recommended, display_order
|
|
)
|
|
|
|
def test_from_attributes_orm(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationOptionDto
|
|
|
|
class FakeORM:
|
|
option_id = "o-1"
|
|
question_id = "q-1"
|
|
label = "Yes"
|
|
value = "yes"
|
|
is_recommended = True
|
|
display_order = 1
|
|
|
|
dto = ClarificationOptionDto.model_validate(FakeORM())
|
|
assert dto.option_id == "o-1"
|
|
assert dto.is_recommended is True
|
|
|
|
|
|
class TestClarificationAnswerDtoEdge:
|
|
"""Negative tests for ClarificationAnswerDto."""
|
|
|
|
def test_invalid_answer_kind_enum(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationAnswerDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
with pytest.raises(ValidationError):
|
|
ClarificationAnswerDto(
|
|
answer_id="a-1",
|
|
question_id="q-1",
|
|
answer_kind="INVALID_KIND",
|
|
answered_by_user_id="u-1",
|
|
created_at=ts,
|
|
)
|
|
|
|
def test_optional_fields_default_none(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationAnswerDto
|
|
from src.models.dataset_review import AnswerKind
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
dto = ClarificationAnswerDto(
|
|
answer_id="a-1",
|
|
question_id="q-1",
|
|
answer_kind=AnswerKind.SELECTED,
|
|
answered_by_user_id="u-1",
|
|
created_at=ts,
|
|
)
|
|
assert dto.answer_value is None
|
|
assert dto.impact_summary is None
|
|
assert dto.user_feedback is None
|
|
|
|
def test_from_attributes_orm(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationAnswerDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
|
|
class FakeORM:
|
|
answer_id = "a-1"
|
|
question_id = "q-1"
|
|
answer_kind = "selected"
|
|
answer_value = "yes"
|
|
answered_by_user_id = "u-1"
|
|
impact_summary = "Impact"
|
|
user_feedback = "Good"
|
|
created_at = ts
|
|
|
|
dto = ClarificationAnswerDto.model_validate(FakeORM())
|
|
assert dto.answer_id == "a-1"
|
|
assert dto.answer_kind == "selected"
|
|
assert dto.impact_summary == "Impact"
|
|
|
|
|
|
class TestClarificationQuestionDtoEdge:
|
|
"""Negative tests for ClarificationQuestionDto."""
|
|
|
|
def test_invalid_state_enum(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationQuestionDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
with pytest.raises(ValidationError):
|
|
ClarificationQuestionDto(
|
|
question_id="q-1",
|
|
clarification_session_id="cs-1",
|
|
topic_ref="topic1",
|
|
question_text="What?",
|
|
why_it_matters="Need to know",
|
|
priority=1,
|
|
state="INVALID_STATE",
|
|
created_at=ts,
|
|
updated_at=ts,
|
|
)
|
|
|
|
def test_nested_options_default_empty(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationQuestionDto
|
|
from src.models.dataset_review import QuestionState
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
dto = ClarificationQuestionDto(
|
|
question_id="q-1",
|
|
clarification_session_id="cs-1",
|
|
topic_ref="topic1",
|
|
question_text="What?",
|
|
why_it_matters="Need to know",
|
|
priority=1,
|
|
state=QuestionState.OPEN,
|
|
created_at=ts,
|
|
updated_at=ts,
|
|
)
|
|
assert dto.options == []
|
|
assert dto.answer is None
|
|
|
|
def test_from_attributes_orm(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationQuestionDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
|
|
class FakeORM:
|
|
question_id = "q-1"
|
|
clarification_session_id = "cs-1"
|
|
topic_ref = "topic1"
|
|
question_text = "What?"
|
|
why_it_matters = "Need to know"
|
|
current_guess = None
|
|
priority = 1
|
|
state = "open"
|
|
created_at = ts
|
|
updated_at = ts
|
|
|
|
dto = ClarificationQuestionDto.model_validate(FakeORM())
|
|
assert dto.question_text == "What?"
|
|
assert dto.priority == 1
|
|
|
|
|
|
class TestClarificationSessionDtoEdge:
|
|
"""Negative tests for ClarificationSessionDto."""
|
|
|
|
def test_invalid_status_enum(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationSessionDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
with pytest.raises(ValidationError):
|
|
ClarificationSessionDto(
|
|
clarification_session_id="cs-1",
|
|
session_id="s-1",
|
|
status="INVALID_STATUS",
|
|
resolved_count=0,
|
|
remaining_count=5,
|
|
started_at=ts,
|
|
updated_at=ts,
|
|
)
|
|
|
|
def test_completed_at_optional(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationSessionDto
|
|
from src.models.dataset_review import ClarificationStatus
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
dto = ClarificationSessionDto(
|
|
clarification_session_id="cs-1",
|
|
session_id="s-1",
|
|
status=ClarificationStatus.ACTIVE,
|
|
resolved_count=0,
|
|
remaining_count=5,
|
|
started_at=ts,
|
|
updated_at=ts,
|
|
)
|
|
assert dto.completed_at is None
|
|
|
|
def test_from_attributes_orm(self):
|
|
from src.schemas.dataset_review_pkg._composites import ClarificationSessionDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
|
|
class FakeORM:
|
|
clarification_session_id = "cs-1"
|
|
session_id = "s-1"
|
|
status = "active"
|
|
current_question_id = None
|
|
resolved_count = 0
|
|
remaining_count = 5
|
|
summary_delta = None
|
|
started_at = ts
|
|
updated_at = ts
|
|
completed_at = None
|
|
|
|
dto = ClarificationSessionDto.model_validate(FakeORM())
|
|
assert dto.clarification_session_id == "cs-1"
|
|
assert dto.status == "active"
|
|
|
|
|
|
class TestCompiledPreviewDtoEdge:
|
|
"""Negative tests for CompiledPreviewDto."""
|
|
|
|
def test_invalid_preview_status_enum(self):
|
|
from src.schemas.dataset_review_pkg._composites import CompiledPreviewDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
with pytest.raises(ValidationError):
|
|
CompiledPreviewDto(
|
|
preview_id="p-1",
|
|
session_id="s-1",
|
|
preview_status="INVALID_STATUS",
|
|
preview_fingerprint="abc123",
|
|
compiled_by="admin",
|
|
compiled_at=ts,
|
|
created_at=ts,
|
|
)
|
|
|
|
def test_optional_fields_default_none(self):
|
|
from src.schemas.dataset_review_pkg._composites import CompiledPreviewDto
|
|
from src.models.dataset_review import PreviewStatus
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
dto = CompiledPreviewDto(
|
|
preview_id="p-1",
|
|
session_id="s-1",
|
|
preview_status=PreviewStatus.READY,
|
|
preview_fingerprint="abc123",
|
|
compiled_by="admin",
|
|
compiled_at=ts,
|
|
created_at=ts,
|
|
)
|
|
assert dto.session_version is None
|
|
assert dto.compiled_sql is None
|
|
assert dto.error_code is None
|
|
|
|
def test_from_attributes_orm(self):
|
|
from src.schemas.dataset_review_pkg._composites import CompiledPreviewDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
|
|
class FakeORM:
|
|
preview_id = "p-1"
|
|
session_id = "s-1"
|
|
session_version = 2
|
|
preview_status = "ready"
|
|
compiled_sql = "SELECT 1"
|
|
preview_fingerprint = "abc123"
|
|
compiled_by = "admin"
|
|
error_code = None
|
|
error_details = None
|
|
compiled_at = ts
|
|
created_at = ts
|
|
|
|
dto = CompiledPreviewDto.model_validate(FakeORM())
|
|
assert dto.preview_id == "p-1"
|
|
assert dto.preview_fingerprint == "abc123"
|
|
|
|
|
|
class TestDatasetRunContextDtoEdge:
|
|
"""Negative tests for DatasetRunContextDto."""
|
|
|
|
def test_invalid_launch_status_enum(self):
|
|
from src.schemas.dataset_review_pkg._composites import DatasetRunContextDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
with pytest.raises(ValidationError):
|
|
DatasetRunContextDto(
|
|
run_context_id="rc-1",
|
|
session_id="s-1",
|
|
dataset_ref="ds1",
|
|
environment_id="env-1",
|
|
preview_id="p-1",
|
|
sql_lab_session_ref="sql1",
|
|
effective_filters={},
|
|
template_params={},
|
|
approved_mapping_ids=[],
|
|
semantic_decision_refs=[],
|
|
open_warning_refs=[],
|
|
launch_status="INVALID_STATUS",
|
|
created_at=ts,
|
|
)
|
|
|
|
def test_missing_required_fields(self):
|
|
from src.schemas.dataset_review_pkg._composites import DatasetRunContextDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
with pytest.raises(ValidationError):
|
|
DatasetRunContextDto(
|
|
# missing run_context_id, session_id, etc.
|
|
created_at=ts,
|
|
)
|
|
|
|
def test_from_attributes_orm(self):
|
|
from src.schemas.dataset_review_pkg._composites import DatasetRunContextDto
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
|
|
class FakeORM:
|
|
run_context_id = "rc-1"
|
|
session_id = "s-1"
|
|
session_version = None
|
|
dataset_ref = "ds1"
|
|
environment_id = "env-1"
|
|
preview_id = "p-1"
|
|
sql_lab_session_ref = "sql1"
|
|
effective_filters = {}
|
|
template_params = {}
|
|
approved_mapping_ids = []
|
|
semantic_decision_refs = []
|
|
open_warning_refs = []
|
|
launch_status = "success"
|
|
launch_error = None
|
|
created_at = ts
|
|
|
|
dto = DatasetRunContextDto.model_validate(FakeORM())
|
|
assert dto.run_context_id == "rc-1"
|
|
assert dto.launch_status == "success"
|
|
|
|
|
|
class TestSessionSummaryEdge:
|
|
"""Negative tests for SessionSummary."""
|
|
|
|
def test_invalid_status_enum(self):
|
|
from src.schemas.dataset_review_pkg._composites import SessionSummary
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
with pytest.raises(ValidationError):
|
|
SessionSummary(
|
|
session_id="s-1",
|
|
user_id="u-1",
|
|
environment_id="env-1",
|
|
source_kind="dashboard",
|
|
source_input="42",
|
|
dataset_ref="ds1",
|
|
readiness_state="INVALID",
|
|
recommended_action="INVALID",
|
|
status="INVALID",
|
|
current_phase="INVALID",
|
|
created_at=ts,
|
|
updated_at=ts,
|
|
last_activity_at=ts,
|
|
)
|
|
|
|
def test_version_defaults(self):
|
|
from src.models.dataset_review import (
|
|
ReadinessState,
|
|
RecommendedAction,
|
|
SessionPhase,
|
|
SessionStatus,
|
|
)
|
|
from src.schemas.dataset_review_pkg._composites import SessionSummary
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
dto = SessionSummary(
|
|
session_id="s-1",
|
|
user_id="u-1",
|
|
environment_id="env-1",
|
|
source_kind="dashboard",
|
|
source_input="42",
|
|
dataset_ref="ds1",
|
|
readiness_state=ReadinessState.EMPTY,
|
|
recommended_action=RecommendedAction.IMPORT_FROM_SUPERSET,
|
|
status=SessionStatus.ACTIVE,
|
|
current_phase=SessionPhase.INTAKE,
|
|
created_at=ts,
|
|
updated_at=ts,
|
|
last_activity_at=ts,
|
|
)
|
|
assert dto.version == 0
|
|
assert dto.session_version == 0
|
|
|
|
def test_from_attributes_orm(self):
|
|
from src.schemas.dataset_review_pkg._composites import SessionSummary
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
|
|
class FakeORM:
|
|
session_id = "s-1"
|
|
user_id = "u-1"
|
|
environment_id = "env-1"
|
|
source_kind = "dashboard"
|
|
source_input = "42"
|
|
dataset_ref = "ds1"
|
|
dataset_id = None
|
|
version = 0
|
|
session_version = 0
|
|
readiness_state = "empty"
|
|
recommended_action = "import_from_superset"
|
|
status = "active"
|
|
current_phase = "intake"
|
|
created_at = ts
|
|
updated_at = ts
|
|
last_activity_at = ts
|
|
|
|
dto = SessionSummary.model_validate(FakeORM())
|
|
assert dto.session_id == "s-1"
|
|
assert dto.status == "active"
|
|
|
|
|
|
class TestSessionDetailEdge:
|
|
"""Negative tests for SessionDetail."""
|
|
|
|
def test_all_nested_defaults_empty(self):
|
|
from src.models.dataset_review import (
|
|
ReadinessState,
|
|
RecommendedAction,
|
|
SessionPhase,
|
|
SessionStatus,
|
|
)
|
|
from src.schemas.dataset_review_pkg._composites import SessionDetail
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
dto = SessionDetail(
|
|
session_id="s-1",
|
|
user_id="u-1",
|
|
environment_id="env-1",
|
|
source_kind="dashboard",
|
|
source_input="42",
|
|
dataset_ref="ds1",
|
|
readiness_state=ReadinessState.EMPTY,
|
|
recommended_action=RecommendedAction.IMPORT_FROM_SUPERSET,
|
|
status=SessionStatus.ACTIVE,
|
|
current_phase=SessionPhase.INTAKE,
|
|
created_at=ts,
|
|
updated_at=ts,
|
|
last_activity_at=ts,
|
|
)
|
|
assert dto.collaborators == []
|
|
assert dto.profile is None
|
|
assert dto.findings == []
|
|
assert dto.semantic_sources == []
|
|
assert dto.semantic_fields == []
|
|
assert dto.imported_filters == []
|
|
assert dto.template_variables == []
|
|
assert dto.execution_mappings == []
|
|
assert dto.clarification_sessions == []
|
|
assert dto.previews == []
|
|
assert dto.run_contexts == []
|
|
|
|
def test_from_attributes_orm(self):
|
|
from src.schemas.dataset_review_pkg._composites import SessionDetail
|
|
|
|
ts = datetime.now(timezone.utc)
|
|
|
|
class FakeORM:
|
|
session_id = "s-1"
|
|
user_id = "u-1"
|
|
environment_id = "env-1"
|
|
source_kind = "dashboard"
|
|
source_input = "42"
|
|
dataset_ref = "ds1"
|
|
dataset_id = None
|
|
version = 0
|
|
session_version = 0
|
|
readiness_state = "empty"
|
|
recommended_action = "import_from_superset"
|
|
status = "active"
|
|
current_phase = "intake"
|
|
created_at = ts
|
|
updated_at = ts
|
|
last_activity_at = ts
|
|
|
|
dto = SessionDetail.model_validate(FakeORM())
|
|
assert dto.session_id == "s-1"
|
|
assert dto.profile is None
|
|
assert dto.collaborators == []
|
|
# #endregion Test.DatasetReviewSchemaComposites
|