feat: add slug-only dashboard profile filter and unify backend imports
This commit is contained in:
@@ -8,13 +8,13 @@
|
||||
from types import SimpleNamespace
|
||||
import json
|
||||
|
||||
from backend.src.dependencies import get_clean_release_repository, get_config_manager
|
||||
from src.dependencies import get_clean_release_repository, get_config_manager
|
||||
from datetime import datetime, timezone
|
||||
from uuid import uuid4
|
||||
|
||||
from backend.src.models.clean_release import CleanPolicySnapshot, ComplianceReport, ReleaseCandidate, SourceRegistrySnapshot
|
||||
from backend.src.services.clean_release.enums import CandidateStatus, ComplianceDecision
|
||||
from backend.src.scripts.clean_release_cli import main as cli_main
|
||||
from src.models.clean_release import CleanPolicySnapshot, ComplianceReport, ReleaseCandidate, SourceRegistrySnapshot
|
||||
from src.services.clean_release.enums import CandidateStatus, ComplianceDecision
|
||||
from src.scripts.clean_release_cli import main as cli_main
|
||||
|
||||
|
||||
def test_cli_candidate_register_scaffold() -> None:
|
||||
@@ -302,4 +302,4 @@ def test_cli_release_gate_commands_scaffold() -> None:
|
||||
assert revoke_exit == 0
|
||||
|
||||
|
||||
# [/DEF:test_clean_release_cli:Module]
|
||||
# [/DEF:test_clean_release_cli:Module]
|
||||
|
||||
@@ -14,8 +14,8 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from backend.src.scripts.clean_release_tui import CleanReleaseTUI, main, tui_main
|
||||
from backend.src.models.clean_release import CheckFinalStatus
|
||||
from src.scripts.clean_release_tui import CleanReleaseTUI, main, tui_main
|
||||
from src.models.clean_release import CheckFinalStatus
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -31,7 +31,7 @@ def test_headless_fallback(capsys):
|
||||
@TEST_EDGE: stdout_unavailable
|
||||
Tests that non-TTY startup is explicitly refused and wrapper is not invoked.
|
||||
"""
|
||||
with mock.patch("backend.src.scripts.clean_release_tui.curses.wrapper") as curses_wrapper_mock:
|
||||
with mock.patch("src.scripts.clean_release_tui.curses.wrapper") as curses_wrapper_mock:
|
||||
with mock.patch("sys.stdout.isatty", return_value=False):
|
||||
exit_code = main()
|
||||
|
||||
@@ -43,7 +43,7 @@ def test_headless_fallback(capsys):
|
||||
assert "Use CLI/API workflow instead" in captured.err
|
||||
|
||||
|
||||
@patch("backend.src.scripts.clean_release_tui.curses")
|
||||
@patch("src.scripts.clean_release_tui.curses")
|
||||
def test_tui_initial_render(mock_curses_module, mock_stdscr: MagicMock):
|
||||
"""
|
||||
Simulates the initial rendering cycle of the TUI application to ensure
|
||||
@@ -76,7 +76,7 @@ def test_tui_initial_render(mock_curses_module, mock_stdscr: MagicMock):
|
||||
assert any("F5 Run" in str(call) for call in addstr_calls)
|
||||
|
||||
|
||||
@patch("backend.src.scripts.clean_release_tui.curses")
|
||||
@patch("src.scripts.clean_release_tui.curses")
|
||||
def test_tui_run_checks_f5(mock_curses_module, mock_stdscr: MagicMock):
|
||||
"""
|
||||
Simulates pressing F5 to transition into the RUNNING checks flow.
|
||||
@@ -111,7 +111,7 @@ def test_tui_run_checks_f5(mock_curses_module, mock_stdscr: MagicMock):
|
||||
assert len(app.violations_list) > 0
|
||||
|
||||
|
||||
@patch("backend.src.scripts.clean_release_tui.curses")
|
||||
@patch("src.scripts.clean_release_tui.curses")
|
||||
def test_tui_exit_f10(mock_curses_module, mock_stdscr: MagicMock):
|
||||
"""
|
||||
Simulates pressing F10 to exit the application immediately without running checks.
|
||||
@@ -128,7 +128,7 @@ def test_tui_exit_f10(mock_curses_module, mock_stdscr: MagicMock):
|
||||
assert app.status == "READY"
|
||||
|
||||
|
||||
@patch("backend.src.scripts.clean_release_tui.curses")
|
||||
@patch("src.scripts.clean_release_tui.curses")
|
||||
def test_tui_clear_history_f7(mock_curses_module, mock_stdscr: MagicMock):
|
||||
"""
|
||||
Simulates pressing F7 to clear history.
|
||||
@@ -153,4 +153,3 @@ def test_tui_clear_history_f7(mock_curses_module, mock_stdscr: MagicMock):
|
||||
|
||||
|
||||
# [/DEF:backend.tests.scripts.test_clean_release_tui:Module]
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ from __future__ import annotations
|
||||
import curses
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from backend.src.models.clean_release import CheckFinalStatus
|
||||
from backend.src.scripts.clean_release_tui import CleanReleaseTUI, main
|
||||
from src.models.clean_release import CheckFinalStatus
|
||||
from src.scripts.clean_release_tui import CleanReleaseTUI, main
|
||||
|
||||
|
||||
def _build_mock_stdscr() -> MagicMock:
|
||||
@@ -22,7 +22,7 @@ def _build_mock_stdscr() -> MagicMock:
|
||||
return stdscr
|
||||
|
||||
|
||||
@patch("backend.src.scripts.clean_release_tui.curses")
|
||||
@patch("src.scripts.clean_release_tui.curses")
|
||||
def test_tui_f5_dispatches_run_action(mock_curses_module: MagicMock) -> None:
|
||||
"""F5 should dispatch run action from TUI loop."""
|
||||
mock_curses_module.KEY_F10 = curses.KEY_F10
|
||||
@@ -40,7 +40,7 @@ def test_tui_f5_dispatches_run_action(mock_curses_module: MagicMock) -> None:
|
||||
run_checks_mock.assert_called_once_with()
|
||||
|
||||
|
||||
@patch("backend.src.scripts.clean_release_tui.curses")
|
||||
@patch("src.scripts.clean_release_tui.curses")
|
||||
def test_tui_f5_run_smoke_reports_blocked_state(mock_curses_module: MagicMock) -> None:
|
||||
"""F5 smoke test should expose blocked outcome state after run action."""
|
||||
mock_curses_module.KEY_F10 = curses.KEY_F10
|
||||
@@ -76,7 +76,7 @@ def test_tui_non_tty_refuses_startup(capsys) -> None:
|
||||
assert "Use CLI/API workflow instead" in captured.err
|
||||
|
||||
|
||||
@patch("backend.src.scripts.clean_release_tui.curses")
|
||||
@patch("src.scripts.clean_release_tui.curses")
|
||||
def test_tui_f8_blocked_without_facade_binding(mock_curses_module: MagicMock) -> None:
|
||||
"""F8 should not perform hidden state mutation when facade action is not bound."""
|
||||
mock_curses_module.KEY_F10 = curses.KEY_F10
|
||||
@@ -94,4 +94,4 @@ def test_tui_f8_blocked_without_facade_binding(mock_curses_module: MagicMock) ->
|
||||
assert "F8 disabled" in app.last_error
|
||||
|
||||
|
||||
# [/DEF:test_clean_release_tui_v2:Module]
|
||||
# [/DEF:test_clean_release_tui_v2:Module]
|
||||
|
||||
@@ -9,10 +9,10 @@ from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from src.core.database import Base
|
||||
from src.models.clean_release import ReleaseCandidate, DistributionManifest, CandidateArtifact
|
||||
from backend.src.services.clean_release.enums import CandidateStatus
|
||||
from backend.src.services.clean_release.candidate_service import register_candidate
|
||||
from backend.src.services.clean_release.manifest_service import build_manifest_snapshot
|
||||
from backend.src.services.clean_release.repository import CleanReleaseRepository
|
||||
from src.services.clean_release.enums import CandidateStatus
|
||||
from src.services.clean_release.candidate_service import register_candidate
|
||||
from src.services.clean_release.manifest_service import build_manifest_snapshot
|
||||
from src.services.clean_release.repository import CleanReleaseRepository
|
||||
|
||||
@pytest.fixture
|
||||
def db_session():
|
||||
@@ -43,7 +43,7 @@ def test_candidate_lifecycle_transitions(db_session):
|
||||
assert candidate.status == CandidateStatus.PREPARED
|
||||
|
||||
# Invalid transition: PREPARED -> DRAFT (should raise IllegalTransitionError)
|
||||
from backend.src.services.clean_release.exceptions import IllegalTransitionError
|
||||
from src.services.clean_release.exceptions import IllegalTransitionError
|
||||
with pytest.raises(IllegalTransitionError, match="Forbidden transition"):
|
||||
candidate.transition_to(CandidateStatus.DRAFT)
|
||||
|
||||
@@ -200,4 +200,4 @@ def test_manifest_service_rejects_missing_candidate():
|
||||
with pytest.raises(ValueError, match="not found"):
|
||||
build_manifest_snapshot(repository=repository, candidate_id="missing-candidate", created_by="operator")
|
||||
|
||||
# [/DEF:test_candidate_manifest_services:Module]
|
||||
# [/DEF:test_candidate_manifest_services:Module]
|
||||
|
||||
@@ -13,17 +13,17 @@ from datetime import datetime, timezone
|
||||
|
||||
import pytest
|
||||
|
||||
from backend.src.models.clean_release import (
|
||||
from src.models.clean_release import (
|
||||
CleanPolicySnapshot,
|
||||
ComplianceDecision,
|
||||
DistributionManifest,
|
||||
ReleaseCandidate,
|
||||
SourceRegistrySnapshot,
|
||||
)
|
||||
from backend.src.services.clean_release.compliance_orchestrator import CleanComplianceOrchestrator
|
||||
from backend.src.services.clean_release.enums import CandidateStatus, RunStatus
|
||||
from backend.src.services.clean_release.report_builder import ComplianceReportBuilder
|
||||
from backend.src.services.clean_release.repository import CleanReleaseRepository
|
||||
from src.services.clean_release.compliance_orchestrator import CleanComplianceOrchestrator
|
||||
from src.services.clean_release.enums import CandidateStatus, RunStatus
|
||||
from src.services.clean_release.report_builder import ComplianceReportBuilder
|
||||
from src.services.clean_release.repository import CleanReleaseRepository
|
||||
|
||||
|
||||
# [DEF:_seed_with_candidate_policy_registry:Function]
|
||||
@@ -170,4 +170,4 @@ def test_blocked_run_finalization_blocks_report_builder():
|
||||
builder.build_report_payload(run, [])
|
||||
# [/DEF:test_blocked_run_finalization_blocks_report_builder:Function]
|
||||
|
||||
# [/DEF:backend.tests.services.clean_release.test_compliance_execution_service:Module]
|
||||
# [/DEF:backend.tests.services.clean_release.test_compliance_execution_service:Module]
|
||||
|
||||
@@ -151,8 +151,8 @@ class _PluginLoaderStub:
|
||||
def _make_task_manager() -> TaskManager:
|
||||
plugin_loader = _PluginLoaderStub(CleanReleaseCompliancePlugin())
|
||||
|
||||
with patch("backend.src.core.task_manager.manager.TaskPersistenceService") as mock_persistence, patch(
|
||||
"backend.src.core.task_manager.manager.TaskLogPersistenceService"
|
||||
with patch("src.core.task_manager.manager.TaskPersistenceService") as mock_persistence, patch(
|
||||
"src.core.task_manager.manager.TaskLogPersistenceService"
|
||||
) as mock_log_persistence:
|
||||
mock_persistence.return_value.load_tasks.return_value = []
|
||||
mock_persistence.return_value.persist_task = MagicMock()
|
||||
@@ -247,4 +247,4 @@ async def test_compliance_run_missing_manifest_marks_task_failed():
|
||||
manager._flusher_thread.join(timeout=2)
|
||||
# [/DEF:test_compliance_run_missing_manifest_marks_task_failed:Function]
|
||||
|
||||
# [/DEF:backend.tests.services.clean_release.test_compliance_task_integration:Module]
|
||||
# [/DEF:backend.tests.services.clean_release.test_compliance_task_integration:Module]
|
||||
|
||||
@@ -9,8 +9,8 @@ from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from backend.src.models.clean_release import ReleaseCandidate
|
||||
from backend.src.services.clean_release.demo_data_service import (
|
||||
from src.models.clean_release import ReleaseCandidate
|
||||
from src.services.clean_release.demo_data_service import (
|
||||
build_namespaced_id,
|
||||
create_isolated_repository,
|
||||
resolve_namespace,
|
||||
@@ -84,4 +84,4 @@ def test_create_isolated_repository_keeps_mode_data_separate() -> None:
|
||||
assert real_repo.get_candidate(demo_candidate_id) is None
|
||||
# [/DEF:test_create_isolated_repository_keeps_mode_data_separate:Function]
|
||||
|
||||
# [/DEF:backend.tests.services.clean_release.test_demo_mode_isolation:Module]
|
||||
# [/DEF:backend.tests.services.clean_release.test_demo_mode_isolation:Module]
|
||||
|
||||
@@ -14,10 +14,10 @@ from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from backend.src.models.clean_release import CleanPolicySnapshot, SourceRegistrySnapshot
|
||||
from backend.src.services.clean_release.exceptions import PolicyResolutionError
|
||||
from backend.src.services.clean_release.policy_resolution_service import resolve_trusted_policy_snapshots
|
||||
from backend.src.services.clean_release.repository import CleanReleaseRepository
|
||||
from src.models.clean_release import CleanPolicySnapshot, SourceRegistrySnapshot
|
||||
from src.services.clean_release.exceptions import PolicyResolutionError
|
||||
from src.services.clean_release.policy_resolution_service import resolve_trusted_policy_snapshots
|
||||
from src.services.clean_release.repository import CleanReleaseRepository
|
||||
|
||||
|
||||
# [DEF:_config_manager:Function]
|
||||
@@ -102,4 +102,4 @@ def test_resolve_trusted_policy_snapshots_rejects_override_attempt():
|
||||
)
|
||||
# [/DEF:test_resolve_trusted_policy_snapshots_rejects_override_attempt:Function]
|
||||
|
||||
# [/DEF:backend.tests.services.clean_release.test_policy_resolution_service:Module]
|
||||
# [/DEF:backend.tests.services.clean_release.test_policy_resolution_service:Module]
|
||||
|
||||
Reference in New Issue
Block a user