chore: migrate GRACE-Poly anchors to hierarchical dotted naming

Systematic rename of all semantic anchors (#region, [DEF], @RELATION)
across 1400+ files — backend Python, frontend Svelte/TS, specs, docs:
- Flat anchors become Namespace.Module.Entity
- @RELATION references updated to match new anchor paths
- Zero business logic changes
This commit is contained in:
root
2026-07-22 11:48:15 +03:00
parent 34393adf7e
commit 632b730fff
1438 changed files with 17031 additions and 16802 deletions

View File

@@ -1,6 +1,6 @@
# #region Test.MigrationArchiveParser [C:3] [TYPE Module] [SEMANTICS test,migration,archive,parser]
# @BRIEF Tests for core/migration/archive_parser.py — MigrationArchiveParser.
# @RELATION BINDS_TO -> [MigrationArchiveParserModule]
# @RELATION BINDS_TO -> [Core.ArchiveParser.MigrationArchiveParserModule]
# @TEST_EDGE: invalid_yaml_skipped -> logger.reflect called
# @TEST_EDGE: non_dict_payload -> returns None

View File

@@ -1,6 +1,6 @@
# #region Test.AsyncNetwork [C:4] [TYPE Module] [SEMANTICS test, async, network, client, httpx]
# @BRIEF Tests for core/utils/async_network.py — AsyncAPIClient.
# @RELATION BINDS_TO -> [AsyncNetworkModule]
# @RELATION BINDS_TO -> [Core.AsyncNetwork.AsyncNetworkModule]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.AsyncNetwork.Edge [C:4] [TYPE Module] [SEMANTICS test, async, network, auth, upload, coverage]
# @BRIEF Additional edge case tests for AsyncAPIClient — cache hit after lock, upload status, and remaining branches.
# @RELATION BINDS_TO -> [AsyncNetworkModule]
# @RELATION BINDS_TO -> [Core.AsyncNetwork.AsyncNetworkModule]
import sys
from pathlib import Path

View File

@@ -1,6 +1,6 @@
# #region Test.AsyncNetworkExtra [C:2] [TYPE Module] [SEMANTICS test, async, network, edge, upload]
# @BRIEF Extra edge-case tests for async_network.py and network.py — auth CSRF refresh, expired cache, upload 201.
# @RELATION BINDS_TO -> [AsyncNetworkModule]
# @RELATION BINDS_TO -> [Core.AsyncNetwork.AsyncNetworkModule]
from __future__ import annotations

View File

@@ -1,6 +1,6 @@
# #region Test.AsyncSupersetClient [C:3] [TYPE Module] [SEMANTICS test,superset,async,client]
# @BRIEF Tests for core/async_superset_client.py — AsyncSupersetClient.
# @RELATION BINDS_TO -> [AsyncSupersetClientModule]
# @RELATION BINDS_TO -> [Core.AsyncSupersetClient.AsyncSupersetClientModule]
# @TEST_EDGE: aclose_called -> delegates to client.aclose
from pathlib import Path

View File

@@ -1,6 +1,6 @@
# #region Test.AuthConfig [C:3] [TYPE Module] [SEMANTICS test,auth,config,pydantic]
# @BRIEF Tests for core/auth/config.py — AuthConfig Pydantic settings.
# @RELATION BINDS_TO -> [AuthConfigModule]
# @RELATION BINDS_TO -> [Core.Config.AuthConfigModule]
from pathlib import Path
import sys
@@ -11,7 +11,7 @@ from unittest.mock import patch
import pytest
# #region test_auth_config [C:2] [TYPE Function]
# #region Test.AuthConfig.TestAuthConfig [C:2] [TYPE Function]
# @BRIEF Test AuthConfig validation and default values.
class TestAuthConfig:
def test_requires_secret_key(self):
@@ -89,10 +89,10 @@ class TestAuthConfig:
config = AuthConfig()
assert config.JWT_AUDIENCE == "superset-tools-api"
assert config.JWT_ISSUER == "superset-tools"
# #endregion test_auth_config
# #endregion Test.AuthConfig.TestAuthConfig
# #region test_auth_config_singleton [C:2] [TYPE Function]
# #region Test.AuthConfig.TestAuthConfigSingleton [C:2] [TYPE Function]
# @BRIEF Test auth_config singleton creation.
class TestAuthConfigSingleton:
def test_auth_config_instance(self):
@@ -108,5 +108,5 @@ class TestAuthConfigSingleton:
importlib.reload(config)
assert config.auth_config is not None
assert config.auth_config.SECRET_KEY == "test-key-singleton"
# #endregion test_auth_config_singleton
# #endregion Test.AuthConfig.TestAuthConfigSingleton
# #endregion Test.AuthConfig

View File

@@ -1,6 +1,6 @@
# #region Test.AuthOauth [C:3] [TYPE Module] [SEMANTICS test,auth,oauth,adfs,oidc]
# @BRIEF Tests for core/auth/oauth.py — register_adfs, is_adfs_configured.
# @RELATION BINDS_TO -> [AuthOauthModule]
# @RELATION BINDS_TO -> [Core.Oauth.AuthOauthModule]
from pathlib import Path
import sys
@@ -11,7 +11,7 @@ from unittest.mock import MagicMock, patch
import pytest
# #region test_register_adfs [C:2] [TYPE Function]
# #region Test.AuthOauth.TestRegisterAdfs [C:2] [TYPE Function]
# @BRIEF Test register_adfs and is_adfs_configured.
class TestRegisterAdfs:
def test_register_adfs_when_configured(self):
@@ -49,14 +49,14 @@ class TestRegisterAdfs:
import src.core.auth.oauth as oauth_module
with patch.object(oauth_module.oauth, "_registry", {}):
assert oauth_module.is_adfs_configured() is False
# #endregion test_register_adfs
# #endregion Test.AuthOauth.TestRegisterAdfs
# #region test_oauth_module_init [C:2] [TYPE Function]
# #region Test.AuthOauth.TestOauthModuleInit [C:2] [TYPE Function]
# @BRIEF Test module-level initialization calls register_adfs.
class TestOauthModuleInit:
def test_oauth_instance_exists(self):
import src.core.auth.oauth as oauth_module
assert oauth_module.oauth is not None
# #endregion test_oauth_module_init
# #endregion Test.AuthOauth.TestOauthModuleInit
# #endregion Test.AuthOauth

View File

@@ -1,6 +1,6 @@
# #region Test.Auth.Repository [C:3] [TYPE Module] [SEMANTICS test,auth,repository,sqlalchemy]
# @BRIEF Tests for core/auth/repository.py — AuthRepository CRUD methods.
# @RELATION BINDS_TO -> [AuthRepositoryModule]
# @RELATION BINDS_TO -> [Core.Repository.AuthRepositoryModule]
# @TEST_EDGE: user_not_found -> returns None
# @TEST_EDGE: empty_ad_groups -> returns []

View File

@@ -1,6 +1,6 @@
# #region Test.AuthSecurity [C:3] [TYPE Module] [SEMANTICS test,auth,security,bcrypt,password]
# @BRIEF Tests for core/auth/security.py — verify_password, get_password_hash.
# @RELATION BINDS_TO -> [AuthSecurityModule]
# @RELATION BINDS_TO -> [Core.Security.AuthSecurityModule]
from pathlib import Path
import sys
@@ -11,7 +11,7 @@ from unittest.mock import MagicMock, patch
import pytest
# #region test_get_password_hash [C:2] [TYPE Function]
# #region Test.AuthSecurity.TestGetPasswordHash [C:2] [TYPE Function]
# @BRIEF Test get_password_hash generates valid bcrypt hashes.
class TestGetPasswordHash:
def test_returns_bcrypt_hash(self):
@@ -25,10 +25,10 @@ class TestGetPasswordHash:
h1 = get_password_hash("same-password")
h2 = get_password_hash("same-password")
assert h1 != h2 # bcrypt gensalt produces different salts
# #endregion test_get_password_hash
# #endregion Test.AuthSecurity.TestGetPasswordHash
# #region test_verify_password [C:2] [TYPE Function]
# #region Test.AuthSecurity.TestVerifyPassword [C:2] [TYPE Function]
# @BRIEF Test verify_password for correct and incorrect passwords.
class TestVerifyPassword:
def test_verifies_correct_password(self):
@@ -59,5 +59,5 @@ class TestVerifyPassword:
hashed = get_password_hash("pässwörd-你好")
assert verify_password("pässwörd-你好", hashed) is True
assert verify_password("wrong", hashed) is False
# #endregion test_verify_password
# #endregion Test.AuthSecurity.TestVerifyPassword
# #endregion Test.AuthSecurity

View File

@@ -1,6 +1,6 @@
# #region Test.Core.ClientRegistry [C:3] [TYPE Module] [SEMANTICS test, client, registry, async, superset]
# @BRIEF Tests for SupersetClientRegistry — singleton async client management.
# @RELATION BINDS_TO -> [SupersetClientRegistryModule]
# @RELATION BINDS_TO -> [Core.ClientRegistry.SupersetClientRegistryModule]
import sys
from pathlib import Path

View File

@@ -1,6 +1,6 @@
# #region Test.Core.ConnectionService.Edge [C:3] [TYPE Module] [SEMANTICS test, connections, edge, coverage]
# @BRIEF Edge case tests for ConnectionService — encryption fallback, DB refs, dialect tests, unsupported dialect.
# @RELATION BINDS_TO -> [ConnectionService]
# @RELATION BINDS_TO -> [Core.ConnectionService]
import os
import sys
@@ -262,7 +262,7 @@ class TestDeleteEdgeCases:
class TestConnectionTimeout:
"""Connection test timeout behavior — asyncio.TimeoutError handling."""
# #region test_timeout_error_response [C:2] [TYPE Function] [SEMANTICS test,connection,timeout,error]
# #region Test.Core.TestTimeoutErrorResponse [C:2] [TYPE Function] [SEMANTICS test,connection,timeout,error]
# @BRIEF When _test_postgresql hangs, asyncio.TimeoutError is caught and
# returns {success: false, error: "Connection test timed out after 15s"}.
@pytest.mark.asyncio
@@ -287,9 +287,9 @@ class TestConnectionTimeout:
assert "Connection test timed out" in result["error"]
assert "15" not in result["error"] # we overrode to 0.1
assert "after" in result["error"]
# #endregion test_timeout_error_response
# #endregion Test.Core.TestTimeoutErrorResponse
# #region test_timeout_still_records_latency [C:2] [TYPE Function] [SEMANTICS test,connection,timeout,latency]
# #region Test.Core.TestTimeoutStillRecordsLatency [C:2] [TYPE Function] [SEMANTICS test,connection,timeout,latency]
# @BRIEF Even on timeout, latency_ms field is populated with elapsed time.
@pytest.mark.asyncio
async def test_timeout_still_records_latency(self, mock_cm):
@@ -312,6 +312,6 @@ class TestConnectionTimeout:
assert "latency_ms" in result
assert isinstance(result["latency_ms"], int)
assert result["latency_ms"] >= 0 # should be a non-negative elapsed time
# #endregion test_timeout_still_records_latency
# #endregion Test.Core.TestTimeoutStillRecordsLatency
# #endregion Test.Core.ConnectionService.Edge

View File

@@ -1,6 +1,6 @@
# #region Test.DashboardsFiltersMixin [C:3] [TYPE Module] [SEMANTICS test, dashboard, filter, permalink, mixin]
# @BRIEF Tests for core/superset_client/_dashboards_filters.py — SupersetDashboardsFiltersMixin.
# @RELATION BINDS_TO -> [SupersetDashboardsFiltersMixin]
# @RELATION BINDS_TO -> [Core.DashboardsFilters.SupersetDashboardsFiltersMixin]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.DashboardsWriteMixin [C:3] [TYPE Module] [SEMANTICS test, dashboard, write, markdown, layout]
# @BRIEF Tests for core/superset_client/_dashboards_write.py — SupersetDashboardsWriteMixin.
# @RELATION BINDS_TO -> [SupersetDashboardsWriteMixin]
# @RELATION BINDS_TO -> [Core.DashboardsWrite.SupersetDashboardsWriteMixin]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.DatasetMapper [C:3] [TYPE Module] [SEMANTICS test, dataset, mapper, sqllab, excel]
# @BRIEF Tests for core/utils/dataset_mapper.py — DatasetMapper.
# @RELATION BINDS_TO -> [DatasetMapperModule]
# @RELATION BINDS_TO -> [Core.DatasetMapper.DatasetMapperModule]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.DatasetMapperExtra [C:2] [TYPE Module] [SEMANTICS test, dataset, mapper, metrics, edge]
# @BRIEF Extra tests for dataset_mapper.py — metrics handling in run_mapping (lines 193-206).
# @RELATION BINDS_TO -> [DatasetMapperModule]
# @RELATION BINDS_TO -> [Core.DatasetMapper.DatasetMapperModule]
from __future__ import annotations

View File

@@ -1,6 +1,6 @@
# #region Test.DatasetsMixin [C:3] [TYPE Module] [SEMANTICS test, dataset, superset, crud, detail]
# @BRIEF Tests for core/superset_client/_datasets.py — SupersetDatasetsMixin.
# @RELATION BINDS_TO -> [SupersetDatasetsMixin]
# @RELATION BINDS_TO -> [Core.Datasets.SupersetDatasetsMixin]
# @TEST_EDGE: missing_param -> Null query param handled
# @TEST_EDGE: empty_result -> Empty dataset list returns 0 results
# @TEST_EDGE: external_api_error -> Exception in API call caught and logged

View File

@@ -1,6 +1,6 @@
# #region Test.DatasetsPreviewMixin [C:3] [TYPE Module] [SEMANTICS test, dataset, preview, compile, query]
# @BRIEF Tests for core/superset_client/_datasets_preview.py — SupersetDatasetsPreviewMixin.
# @RELATION BINDS_TO -> [SupersetDatasetsPreviewMixin]
# @RELATION BINDS_TO -> [Core.DatasetsPreview.SupersetDatasetsPreviewMixin]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.DatasetsPreviewFiltersMixin [C:3] [TYPE Module] [SEMANTICS test, dataset, preview, filter, sql, extract]
# @BRIEF Tests for core/superset_client/_datasets_preview_filters.py — filter normalization + SQL extraction.
# @RELATION BINDS_TO -> [SupersetDatasetsPreviewFiltersMixin]
# @RELATION BINDS_TO -> [Core.DatasetsPreviewFilters.SupersetDatasetsPreviewFiltersMixin]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.LayoutUtils [C:2] [TYPE Module] [SEMANTICS test, layout, position, json, banner]
# @BRIEF Tests for core/superset_client/_layout_utils.py — pure position JSON manipulation.
# @RELATION BINDS_TO -> [LayoutUtils]
# @RELATION BINDS_TO -> [Core.LayoutUtils]
from pathlib import Path
import sys

View File

@@ -10,7 +10,7 @@ from src.core.task_manager.log_export import row_to_export_record, redact_text
from src.core.task_manager.models import LogEntry
# #region test_trim_buffer_drops_debug_first [C:2]
# #region Test.Core.TestTrimBufferDropsDebugFirst [C:2]
# @BRIEF Verify buffer trimming drops DEBUG entries first while preserving ERROR/INFO.
def test_trim_buffer_drops_debug_first():
bus = EventBus(MagicMock())
@@ -25,10 +25,10 @@ def test_trim_buffer_drops_debug_first():
assert len(trimmed) <= 5
assert any(e.level == "ERROR" for e in trimmed)
assert bus._dropped_debug >= 1
# #endregion test_trim_buffer_drops_debug_first
# #endregion Test.Core.TestTrimBufferDropsDebugFirst
# #region test_export_record_cot_and_redaction [C:2]
# #region Test.Core.TestExportRecordCotAndRedaction [C:2]
# @BRIEF Verify CoT JSON parse, metadata redaction, and credential stripping.
def test_export_record_cot_and_redaction():
import json
@@ -53,10 +53,10 @@ def test_export_record_cot_and_redaction():
assert rec["intent"] == "Apply policy"
assert rec["metadata"]["password"] == "***"
assert "redacted" in redact_text("API Key decrypted (first 8 chars): sk-abcdefgh")
# #endregion test_export_record_cot_and_redaction
# #endregion Test.Core.TestExportRecordCotAndRedaction
# #region test_add_log_respects_task_log_level [C:2]
# #region Test.Core.TestAddLogRespectsTaskLogLevel [C:2]
# @BRIEF Verify DEBUG log entries are filtered when task_log_level is INFO.
@pytest.mark.asyncio
async def test_add_log_respects_task_log_level(monkeypatch):
@@ -68,10 +68,10 @@ async def test_add_log_respects_task_log_level(monkeypatch):
assert bus._log_buffer.get("t1") in (None, [])
await bus.add_log("t1", "INFO", "ok")
assert len(bus._log_buffer["t1"]) == 1
# #endregion test_add_log_respects_task_log_level
# #endregion Test.Core.TestAddLogRespectsTaskLogLevel
# #region test_task_id_contextvar [C:2]
# #region Test.Core.TestTaskIdContextvar [C:2]
# @BRIEF Verify task_id ContextVar propagates into CotJsonFormatter output.
def test_task_id_contextvar_stamps_formatter():
import json
@@ -101,6 +101,6 @@ def test_task_id_contextvar_stamps_formatter():
assert obj.get("payload", {}).get("task_id") == "task-xyz-123"
finally:
clear_task_id()
# #endregion test_task_id_contextvar
# #endregion Test.Core.TestTaskIdContextvar
# #endregion Test.Core.LogExportBulk

View File

@@ -1,6 +1,6 @@
# #region Test.Logger.Edge [C:3] [TYPE Module] [SEMANTICS test, logging, belief, cot, edge]
# @BRIEF Edge case tests for logger.py — configure_logger, file handler, believed decorator, reflect/explore error extras.
# @RELATION BINDS_TO -> [LoggerModule]
# @RELATION BINDS_TO -> [Core.Logger.LoggerModule]
import sys
from pathlib import Path

View File

@@ -30,7 +30,7 @@ def _build_manager():
return mgr
# #region test_update_global_settings_hot_applies_log_level [C:2]
# #region Test.Core.TestUpdateGlobalSettingsHotAppliesLogLevel [C:2]
def test_update_global_settings_hot_applies_log_level():
"""FR-005: changing settings.logging.level reconfigures live loggers without restart."""
from ss_tools.shared.cot_logger import cot_logger
@@ -77,10 +77,10 @@ def test_update_global_settings_hot_applies_log_level():
assert "INFO" in names
finally:
logger.removeHandler(h)
# #endregion test_update_global_settings_hot_applies_log_level
# #endregion Test.Core.TestUpdateGlobalSettingsHotAppliesLogLevel
# #region test_dashboard_projection_samples_are_debug [C:2]
# #region Test.Core.TestDashboardProjectionSamplesAreDebug [C:2]
@pytest.mark.asyncio
async def test_dashboard_projection_samples_are_debug(caplog):
"""Per-dashboard actor samples must not appear at INFO (high-frequency → DEBUG)."""
@@ -139,10 +139,10 @@ async def test_dashboard_projection_samples_are_debug(caplog):
messages = [r.getMessage() for r in caplog.records]
assert not any("Dashboard actor projection sample" in m for m in messages)
assert any("Dashboard actor projection complete" in m for m in messages)
# #endregion test_dashboard_projection_samples_are_debug
# #endregion Test.Core.TestDashboardProjectionSamplesAreDebug
# #region test_security_event_single_atom [C:2]
# #region Test.Core.TestSecurityEventSingleAtom [C:2]
def test_security_event_single_atom(caplog):
"""Security audit emits one REASON atom (not recorded + details pair)."""
from src.core.auth.logger import log_security_event
@@ -163,10 +163,10 @@ def test_security_event_single_atom(caplog):
assert len(security_msgs) == 1
assert "LOGIN_SUCCESS" in security_msgs[0]
assert "Security event details" not in " ".join(security_msgs)
# #endregion test_security_event_single_atom
# #endregion Test.Core.TestSecurityEventSingleAtom
# #region test_merge_logging_patch_preserves_file_path [C:2]
# #region Test.Core.TestMergeLoggingPatchPreservesFilePath [C:2]
def test_merge_logging_patch_preserves_file_path():
"""Partial admin-style logging update must not clear file_path."""
from src.api.routes.settings import update_logging_config
@@ -208,5 +208,5 @@ def test_merge_logging_patch_preserves_file_path():
assert result.enable_belief_state is False
assert saved["logging"].file_path == "logs/app.log"
assert saved["logging"].max_bytes == 12345
# #endregion test_merge_logging_patch_preserves_file_path
# #endregion Test.Core.TestMergeLoggingPatchPreservesFilePath
# #endregion Test.Core.LoggingHotApply

View File

@@ -1,6 +1,6 @@
# #region Test.IdMappingService [C:4] [TYPE Module] [SEMANTICS test, mapping, service, sync, scheduler]
# @BRIEF Tests for core/mapping_service.py — IdMappingService.
# @RELATION BINDS_TO -> [IdMappingServiceModule]
# @RELATION BINDS_TO -> [Core.MappingService.IdMappingServiceModule]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.FuzzyMatching [C:3] [TYPE Module] [SEMANTICS test,fuzzy,matching,rapidfuzz]
# @BRIEF Tests for core/utils/matching.py — suggest_mappings.
# @RELATION BINDS_TO -> [FuzzyMatching]
# @RELATION BINDS_TO -> [Core.Matching.FuzzyMatching]
from pathlib import Path
import sys
@@ -10,7 +10,7 @@ sys.path.insert(0, str(Path(__file__).parent.parent.parent / "src"))
import pytest
# #region test_suggest_mappings [C:2] [TYPE Function]
# #region Test.FuzzyMatching.TestSuggestMappings [C:2] [TYPE Function]
# @BRIEF Test suggest_mappings for various database name scenarios.
class TestSuggestMappings:
def test_empty_targets_returns_empty(self):
@@ -95,5 +95,5 @@ class TestSuggestMappings:
[{"uuid": "s1"}], # missing database_name
[{"uuid": "t1", "database_name": "db"}],
)
# #endregion test_suggest_mappings
# #endregion Test.FuzzyMatching.TestSuggestMappings
# #endregion Test.FuzzyMatching

View File

@@ -1,6 +1,6 @@
# #region Test.Network [C:2] [TYPE Module] [SEMANTICS test, network, error, auth, cache]
# @BRIEF Tests for core/utils/network.py — error classes and SupersetAuthCache.
# @RELATION BINDS_TO -> [NetworkModule]
# @RELATION BINDS_TO -> [Core.Network.NetworkModule]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.NotificationProvidersExtra [C:3] [TYPE Module] [SEMANTICS test,notification,provider,http-client]
# @BRIEF Additional tests for notifications/providers.py — _get_http_client edge cases.
# @RELATION BINDS_TO -> [providers]
# @RELATION BINDS_TO -> [Services.Providers]
from pathlib import Path
import sys
@@ -11,7 +11,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
# #region test_get_http_client [C:2] [TYPE Function]
# #region Test.NotificationProvidersExtra.TestGetHttpClient [C:2] [TYPE Function]
# @BRIEF Test _get_http_client singleton behavior.
class TestGetHttpClient:
@pytest.mark.asyncio
@@ -38,6 +38,6 @@ class TestGetHttpClient:
client1 = await providers_module._get_http_client()
client2 = await providers_module._get_http_client()
assert client1 is client2 # Same cached instance
# #endregion test_get_http_client
# #endregion Test.NotificationProvidersExtra.TestGetHttpClient
# #endregion Test.NotificationProvidersExtra

View File

@@ -1,6 +1,6 @@
# #region Test.PluginBase [C:3] [TYPE Module] [SEMANTICS test,plugin,base,abstract]
# @BRIEF Tests for core/plugin_base.py — PluginBase, PluginConfig.
# @RELATION BINDS_TO -> [PluginBase]
# @RELATION BINDS_TO -> [Core.PluginBase]
# @TEST_EDGE: missing_required_property -> TypeError on abstract instantiation
# @TEST_EDGE: invalid_plugin_config -> ValidationError on missing fields
# @TEST_EDGE: abstract_method_call -> super().abstract_method returns None

View File

@@ -1,6 +1,6 @@
# #region Test.PluginLoader [C:3] [TYPE Module] [SEMANTICS test, plugin, loader, dynamic, import]
# @BRIEF Tests for core/plugin_loader.py — PluginLoader.
# @RELATION BINDS_TO -> [PluginLoader]
# @RELATION BINDS_TO -> [Core.PluginLoader]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.Migration.RiskAssessor.Edge [C:3] [TYPE Module] [SEMANTICS test, risk, assessor, migration, edge]
# @BRIEF Edge case tests for risk assessor — index_by_uuid, extract_owner_identifiers, build_risks, score_risks.
# @RELATION BINDS_TO -> [RiskAssessorModule]
# @RELATION BINDS_TO -> [Core.RiskAssessor.RiskAssessorModule]
import sys
from pathlib import Path

View File

@@ -1,6 +1,6 @@
# #region Test.Superset.Charts [C:3] [TYPE Module] [SEMANTICS test,superset,charts]
# @BRIEF Tests for core/superset_client/_charts.py — SupersetChartsMixin.
# @RELATION BINDS_TO -> [SupersetChartsMixin]
# @RELATION BINDS_TO -> [Core.Charts.SupersetChartsMixin]
# @TEST_EDGE: extract_chart_ids_non_dict_walks -> empty set
# @TEST_EDGE: extract_chart_ids_chart_n_pattern -> CHART-123 format

View File

@@ -1,6 +1,6 @@
# #region Test.SupersetContextExtractorBase [C:3] [TYPE Module] [SEMANTICS test, superset, context, extract, parse]
# @BRIEF Tests for core/utils/superset_context_extractor/_base.py — SupersetContextExtractorBase.
# @RELATION BINDS_TO -> [SupersetContextExtractorBase]
# @RELATION BINDS_TO -> [Core.Base.SupersetContextExtractorBase]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.SupersetContextFilters [C:3] [TYPE Module] [SEMANTICS test, superset, filter, extract, mixin]
# @BRIEF Tests for _filters.py — SupersetContextFiltersExtractMixin._extract_imported_filters.
# @RELATION BINDS_TO -> [SupersetContextFiltersExtractMixin]
# @RELATION BINDS_TO -> [Core.Filters.SupersetContextFiltersExtractMixin]
import sys
from pathlib import Path
@@ -229,3 +229,4 @@ class TestExtractImportedFilters:
"native_filters": "not_a_list"
})
assert result == []
# #endregion Test.SupersetContextFilters

View File

@@ -1,6 +1,6 @@
# #region Test.SupersetContextFiltersExtra [C:2] [TYPE Module] [SEMANTICS test, superset, filter, edge]
# @BRIEF Extra tests for _filters.py — edge cases that hit lines 76, 107, 144, 167, 173-178, 182-193.
# @RELATION BINDS_TO -> [SupersetContextFiltersExtractMixin]
# @RELATION BINDS_TO -> [Core.Filters.SupersetContextFiltersExtractMixin]
from __future__ import annotations

View File

@@ -1,6 +1,6 @@
# #region Test.SupersetContextParsing [C:3] [TYPE Module] [SEMANTICS test, superset, context, parse, link]
# @BRIEF Tests for _parsing.py — SupersetContextParsingMixin.parse_superset_link full branch coverage.
# @RELATION BINDS_TO -> [SupersetContextParsingMixin]
# @RELATION BINDS_TO -> [Core.Parsing.SupersetContextParsingMixin]
# @TEST_CONTRACT: [link:str] -> [SupersetParsedContext]
# @TEST_SCENARIO: dataset_link -> resolves dataset_id and dataset_ref
# @TEST_SCENARIO: dashboard_permalink -> resolves via get_dashboard_permalink_state

View File

@@ -1,6 +1,6 @@
# #region Test.SupersetContextPII [C:2] [TYPE Module] [SEMANTICS test, superset, pii, mask, sanitize]
# @BRIEF Tests for _pii.py — mask_pii_value, sanitize_imported_filter_for_assistant, _mask_sensitive_text.
# @RELATION BINDS_TO -> [SupersetContextExtractorPII]
# @RELATION BINDS_TO -> [Core.Pii.SupersetContextExtractorPII]
# @TEST_CONTRACT: [value:Any] -> [tuple[Any, bool]]
# @TEST_SCENARIO: email_mask -> replaces local part with ***
# @TEST_SCENARIO: uuid_mask -> preserves last 12 chars

View File

@@ -1,6 +1,6 @@
# #region Test.SupersetContextRecovery [C:3] [TYPE Module] [SEMANTICS test, superset, recovery, filter, dashboard]
# @BRIEF Tests for _recovery.py — SupersetContextRecoveryMixin recover_imported_filters and _normalize_imported_filter_payload.
# @RELATION BINDS_TO -> [SupersetContextRecoveryMixin]
# @RELATION BINDS_TO -> [Core.Recovery.SupersetContextRecoveryMixin]
# @TEST_CONTRACT: [SupersetParsedContext] -> [List[Dict]]
# @TEST_SCENARIO: dashboard_with_native_filters -> recovers from json_metadata
# @TEST_SCENARIO: no_dashboard_id -> URL filters only

View File

@@ -1,6 +1,6 @@
# #region Test.SupersetContextTemplates [C:3] [TYPE Module] [SEMANTICS test, superset, template, variables, jinja]
# @BRIEF Tests for _templates.py — SupersetContextTemplatesMixin pure helpers.
# @RELATION BINDS_TO -> [SupersetContextTemplatesMixin]
# @RELATION BINDS_TO -> [Core.Templates.SupersetContextTemplatesMixin]
import sys
from pathlib import Path
@@ -332,3 +332,4 @@ class TestDiscoverTemplateVariables:
})
country_vars = [v for v in result if v["variable_name"] == "country"]
assert len(country_vars) == 1
# #endregion Test.SupersetContextTemplates

View File

@@ -1,6 +1,6 @@
# #region Test.SupersetContextTemplatesExtra [C:2] [TYPE Module] [SEMANTICS test, superset, template, edge]
# @BRIEF Extra tests for _templates.py — edge cases covering lines 45, 62, 80, 92, 148.
# @RELATION BINDS_TO -> [SupersetContextTemplatesMixin]
# @RELATION BINDS_TO -> [Core.Templates.SupersetContextTemplatesMixin]
from __future__ import annotations

View File

@@ -1,11 +1,11 @@
# #region Test.Superset.Extended [C:3] [TYPE Module] [SEMANTICS test,superset,sql-lab,dashboard,dataset,database,saved-query]
# @BRIEF Unit tests for SupersetClient extended mixins: SQL Lab, dashboards write, datasets, databases, saved queries, audit.
# @RELATION BINDS_TO -> [SupersetSqlLabMixin]
# @RELATION BINDS_TO -> [SupersetDashboardsWriteMixin]
# @RELATION BINDS_TO -> [SupersetDatasetsMixin]
# @RELATION BINDS_TO -> [SupersetDatabasesMixin]
# @RELATION BINDS_TO -> [SupersetSavedQueriesMixin]
# @RELATION BINDS_TO -> [SupersetAuditMixin]
# @RELATION BINDS_TO -> [Core.SqlLab.SupersetSqlLabMixin]
# @RELATION BINDS_TO -> [Core.DashboardsWrite.SupersetDashboardsWriteMixin]
# @RELATION BINDS_TO -> [Core.Datasets.SupersetDatasetsMixin]
# @RELATION BINDS_TO -> [Core.Databases.SupersetDatabasesMixin]
# @RELATION BINDS_TO -> [Core.SavedQueries.SupersetSavedQueriesMixin]
# @RELATION BINDS_TO -> [Core.Audit.SupersetAuditMixin]
# @TEST_EDGE: ddl_guard -> execute_sql blocks dangerous SQL via safety.py
# @TEST_EDGE: external_fail -> Exception in API call is raised
# @TEST_EDGE: missing_field -> Optional parameters omitted from payloads

View File

@@ -1,6 +1,6 @@
# #region Test.SupersetProfileLookup [C:3] [TYPE Module] [SEMANTICS test, superset, profile, lookup, adapter]
# @BRIEF Tests for core/superset_profile_lookup.py — SupersetAccountLookupAdapter.
# @RELATION BINDS_TO -> [SupersetProfileLookup]
# @RELATION BINDS_TO -> [Core.SupersetProfileLookup]
from pathlib import Path
import sys

View File

@@ -1,6 +1,6 @@
# #region Test.Superset.UserProjection [C:3] [TYPE Module] [SEMANTICS test,superset,user,projection]
# @BRIEF Tests for core/superset_client/_user_projection.py — SupersetUserProjectionMixin.
# @RELATION BINDS_TO -> [SupersetUserProjection]
# @RELATION BINDS_TO -> [Core.UserProjection.SupersetUserProjection]
# @TEST_EDGE: owners_payload_none -> []
# @TEST_EDGE: owner_single_dict_wrapped -> normalize as list

View File

@@ -1,6 +1,6 @@
# #region Test.TaskCleanupService [C:3] [TYPE Module] [SEMANTICS test,task,cleanup,retention]
# @BRIEF Tests for core/task_manager/cleanup.py — TaskCleanupService.
# @RELATION BINDS_TO -> [TaskCleanupModule]
# @RELATION BINDS_TO -> [Core.Cleanup.TaskCleanupModule]
from pathlib import Path
import sys
@@ -11,7 +11,7 @@ from unittest.mock import MagicMock, patch
import pytest
# #region test_task_cleanup_service [C:2] [TYPE Function]
# #region Test.TaskCleanupService.TestTaskCleanupService [C:2] [TYPE Function]
# @BRIEF Test TaskCleanupService.run_cleanup and delete_task_with_logs.
class TestTaskCleanupService:
@pytest.fixture
@@ -79,5 +79,5 @@ class TestTaskCleanupService:
mock_persistence.delete_tasks.assert_called_once()
deleted_ids = mock_persistence.delete_tasks.call_args[0][0]
assert len(deleted_ids) == 1
# #endregion test_task_cleanup_service
# #endregion Test.TaskCleanupService.TestTaskCleanupService
# #endregion Test.TaskCleanupService

View File

@@ -1,6 +1,6 @@
# #region Test.TaskContext [C:3] [TYPE Module] [SEMANTICS test,task,context]
# @BRIEF Tests for core/task_manager/context.py — TaskContext class.
# @RELATION BINDS_TO -> [TaskContextModule]
# @RELATION BINDS_TO -> [Core.Context.TaskContextModule]
# @TEST_EDGE: get_param_default -> returns default when key missing
# @TEST_EDGE: create_sub_context_preserves_params

View File

@@ -1,6 +1,6 @@
# #region Test.TaskLogger [C:3] [TYPE Module] [SEMANTICS test,task,logger]
# @BRIEF Tests for core/task_manager/task_logger.py — TaskLogger class.
# @RELATION BINDS_TO -> [TaskLoggerModule]
# @RELATION BINDS_TO -> [Core.TaskLogger.TaskLoggerModule]
# @TEST_EDGE: no_event_loop -> _log drops gracefully
# @TEST_EDGE: with_source_creates_independent_logger

View File

@@ -1,6 +1,6 @@
# #region Test.AppTimezone [C:3] [TYPE Module] [SEMANTICS test,timezone,datetime,utilities]
# @BRIEF Tests for core/timezone.py — all timezone utility functions.
# @RELATION BINDS_TO -> [AppTimezone]
# @RELATION BINDS_TO -> [Core.Timezone.AppTimezone]
from pathlib import Path
import sys
@@ -14,7 +14,7 @@ import pytest
from zoneinfo import ZoneInfo
# #region test_get_default_tz_name [C:2] [TYPE Function]
# #region Test.AppTimezone.TestGetDefaultTzName [C:2] [TYPE Function]
# @BRIEF Test _get_default_tz_name reads env var or default.
class TestGetDefaultTzName:
def test_returns_env_value(self):
@@ -31,10 +31,10 @@ class TestGetDefaultTzName:
# Let's test directly
with patch("src.core.timezone.os.getenv", return_value="Europe/Moscow"):
assert _get_default_tz_name() == "Europe/Moscow"
# #endregion test_get_default_tz_name
# #endregion Test.AppTimezone.TestGetDefaultTzName
# #region test_get_app_timezone [C:2] [TYPE Function]
# #region Test.AppTimezone.TestGetAppTimezone [C:2] [TYPE Function]
# @BRIEF Test get_app_timezone returns cached ZoneInfo.
class TestGetAppTimezone:
def test_returns_zoneinfo(self):
@@ -49,10 +49,10 @@ class TestGetAppTimezone:
tz1 = get_app_timezone()
tz2 = get_app_timezone()
assert tz1 is tz2 # Same cached object
# #endregion test_get_app_timezone
# #endregion Test.AppTimezone.TestGetAppTimezone
# #region test_invalidate_timezone_cache [C:2] [TYPE Function]
# #region Test.AppTimezone.TestInvalidateTimezoneCache [C:2] [TYPE Function]
# @BRIEF Test invalidate_timezone_cache resets the cache.
class TestInvalidateTimezoneCache:
def test_invalidates_cache(self):
@@ -65,10 +65,10 @@ class TestInvalidateTimezoneCache:
tz_mod.invalidate_timezone_cache()
assert tz_mod._APP_TZ_CACHE is None # Cache cleared again
tz_mod._APP_TZ_CACHE = None # Reset for other tests
# #endregion test_invalidate_timezone_cache
# #endregion Test.AppTimezone.TestInvalidateTimezoneCache
# #region test_validate_timezone [C:2] [TYPE Function]
# #region Test.AppTimezone.TestValidateTimezone [C:2] [TYPE Function]
# @BRIEF Test validate_timezone for valid/invalid IANA names.
class TestValidateTimezone:
def test_valid_timezone(self):
@@ -85,10 +85,10 @@ class TestValidateTimezone:
from src.core.timezone import validate_timezone
# This should return False when TypeError is caught
assert validate_timezone(None) is False # type: ignore
# #endregion test_validate_timezone
# #endregion Test.AppTimezone.TestValidateTimezone
# #region test_localize [C:2] [TYPE Function]
# #region Test.AppTimezone.TestLocalize [C:2] [TYPE Function]
# @BRIEF Test localize converts UTC to app timezone.
class TestLocalize:
def test_none_returns_none(self):
@@ -126,10 +126,10 @@ class TestLocalize:
# Should convert to Moscow time
assert result.tzinfo is not None
assert "Europe/Moscow" in str(result.tzinfo) or "+03" in result.isoformat()
# #endregion test_localize
# #endregion Test.AppTimezone.TestLocalize
# #region test_now [C:2] [TYPE Function]
# #region Test.AppTimezone.TestNow [C:2] [TYPE Function]
# @BRIEF Test now returns timezone-aware datetime.
class TestNow:
def test_returns_aware_datetime(self):
@@ -144,10 +144,10 @@ class TestNow:
offset = result.utcoffset()
assert offset is not None
assert offset.total_seconds() == 3 * 3600 # Europe/Moscow
# #endregion test_now
# #endregion Test.AppTimezone.TestNow
# #region test_format_timezone_offset [C:2] [TYPE Function]
# #region Test.AppTimezone.TestFormatTimezoneOffset [C:2] [TYPE Function]
# @BRIEF Test format_timezone_offset returns formatted offset string.
class TestFormatTimezoneOffset:
def test_returns_formatted_offset(self):
@@ -162,5 +162,5 @@ class TestFormatTimezoneOffset:
invalidate_timezone_cache()
result = format_timezone_offset()
assert result == "+03:00"
# #endregion test_format_timezone_offset
# #endregion Test.AppTimezone.TestFormatTimezoneOffset
# #endregion Test.AppTimezone

View File

@@ -1,6 +1,6 @@
# #region Test.TraceContextMiddleware [C:3] [TYPE Module] [SEMANTICS test,middleware,trace,asgi]
# @BRIEF Tests for core/middleware/trace.py — TraceContextMiddleware ASGI middleware.
# @RELATION BINDS_TO -> [TraceContextMiddlewareModule]
# @RELATION BINDS_TO -> [Core.Trace.TraceContextMiddlewareModule]
from pathlib import Path
import sys
@@ -11,7 +11,7 @@ import pytest
from unittest.mock import AsyncMock, MagicMock, patch
# #region test_trace_middleware [C:2] [TYPE Function]
# #region Test.TraceContextMiddleware.TestTraceMiddleware [C:2] [TYPE Function]
# @BRIEF Test TraceContextMiddleware for various ASGI scenarios.
class TestTraceContextMiddleware:
@pytest.fixture
@@ -105,11 +105,11 @@ class TestTraceContextMiddleware:
assert call_args[0][1] == receive
# call_args[0][2] is send_with_trace — a wrapper function, not the original send
assert callable(call_args[0][2])
# #endregion test_trace_middleware
# #endregion Test.TraceContextMiddleware.TestTraceMiddleware
# #region TestTraceResponseHeaders [C:2] [TYPE Class] [SEMANTICS test,middleware,trace,header]
# #region Test.TraceContextMiddleware.TestTraceResponseHeaders [C:2] [TYPE Class] [SEMANTICS test,middleware,trace,header]
# @BRIEF Verify X-Trace-Id response header injection — new, preserved, passthrough.
class TestTraceResponseHeaders:
"""TraceContextMiddleware response header injection."""
@@ -123,7 +123,7 @@ class TestTraceResponseHeaders:
from src.core.middleware.trace import TraceContextMiddleware
return TraceContextMiddleware(mock_app)
# #region test_sets_x_trace_id_header_on_response [C:2] [TYPE Function] [SEMANTICS test,trace,header]
# #region Test.TraceContextMiddleware.TestSetsXTraceIdHeaderOnResponse [C:2] [TYPE Function] [SEMANTICS test,trace,header]
# @BRIEF HTTP response receives x-trace-id header with a valid UUID4 value.
@pytest.mark.asyncio
async def test_sets_x_trace_id_header_on_response(self, middleware, mock_app):
@@ -164,9 +164,9 @@ class TestTraceResponseHeaders:
# Valid UUID4
parsed = uuid.UUID(hex=trace_id)
assert parsed.version == 4, f"Trace ID is not UUID4: got version {parsed.version}"
# #endregion test_sets_x_trace_id_header_on_response
# #endregion Test.TraceContextMiddleware.TestSetsXTraceIdHeaderOnResponse
# #region test_preserves_incoming_trace_id [C:2] [TYPE Function] [SEMANTICS test,trace,header,preserve]
# #region Test.TraceContextMiddleware.TestPreservesIncomingTraceId [C:2] [TYPE Function] [SEMANTICS test,trace,header,preserve]
# @BRIEF When request carries X-Trace-ID, the response header uses the same value.
@pytest.mark.asyncio
async def test_preserves_incoming_trace_id(self, middleware, mock_app):
@@ -207,9 +207,9 @@ class TestTraceResponseHeaders:
assert response_trace_id == incoming_id, (
f"Response trace ID {response_trace_id} != incoming {incoming_id}"
)
# #endregion test_preserves_incoming_trace_id
# #endregion Test.TraceContextMiddleware.TestPreservesIncomingTraceId
# #region test_non_http_scope_passthrough [C:2] [TYPE Function] [SEMANTICS test,trace,websocket,passthrough]
# #region Test.TraceContextMiddleware.TestNonHttpScopePassthrough [C:2] [TYPE Function] [SEMANTICS test,trace,websocket,passthrough]
# @BRIEF Non-HTTP scopes (websocket, lifespan) do not inject X-Trace-Id header.
@pytest.mark.asyncio
async def test_non_http_scope_passthrough(self, middleware, mock_app):
@@ -241,7 +241,7 @@ class TestTraceResponseHeaders:
# The middleware returns early for non-http, calling self.app directly
mock_app.assert_called_once_with(scope, receive, send)
# #endregion test_non_http_scope_passthrough
# #endregion Test.TraceContextMiddleware.TestNonHttpScopePassthrough
# #endregion TestTraceResponseHeaders
# #endregion Test.TraceContextMiddleware.TestTraceResponseHeaders
# #endregion Test.TraceContextMiddleware

View File

@@ -10,7 +10,7 @@ from unittest.mock import MagicMock, patch
import pytest
# #region test_websocket_log_handler [C:2]
# #region Test.WsLogHandler.TestWebsocketLogHandler [C:2]
class TestWebSocketLogHandler:
@pytest.fixture
def handler(self):
@@ -71,5 +71,5 @@ class TestWebSocketLogHandler:
h = WebSocketLogHandler()
assert h.log_buffer.maxlen == 3000
# #endregion test_websocket_log_handler
# #endregion Test.WsLogHandler.TestWebsocketLogHandler
# #endregion Test.WsLogHandler