extract the map workspace's domain layer out of the component
MapWorkspace.tsx opened with ~590 lines of theme catalogue, dataset matching and label formatting above a 3.200-line component. None of it is React, all of it is independently testable, and both render paths read from it, so it belongs beside the pure helpers that already live in mapWorkspaceUtils. The contract tests that read MapWorkspace.tsx would have gone red for a move that changes no behaviour at all — 24 of them. That is the brittleness the frontend_contract helper exists to remove, so it gains read_map_workspace(): the workspace is one feature spread over several modules, and a contract belongs to the feature rather than to whichever file currently holds it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,12 +22,46 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
FRONTEND_SRC = ROOT / "frontend" / "src"
|
||||
|
||||
|
||||
# The map workspace is one feature split across several modules: the container
|
||||
# component, its domain layer and its pure helpers. A contract belongs to the
|
||||
# feature, not to whichever file currently holds it, so splitting a 4.000-line
|
||||
# component must not red the suite.
|
||||
MAP_WORKSPACE_SOURCES = (
|
||||
"components/map/MapWorkspace.tsx",
|
||||
"components/map/mapWorkspaceThemes.ts",
|
||||
"components/map/mapWorkspaceUtils.ts",
|
||||
"components/map/MapExplorerView.tsx",
|
||||
"components/map/MapAdvancedWorkbench.tsx",
|
||||
)
|
||||
|
||||
|
||||
def read_frontend(relative_path: str) -> str:
|
||||
"""Read one frontend source file relative to ``frontend/src``."""
|
||||
|
||||
return (FRONTEND_SRC / relative_path).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def read_frontend_area(*relative_paths: str) -> str:
|
||||
"""Read several related sources as one body of code.
|
||||
|
||||
Files that do not exist are skipped, so this survives a module being split
|
||||
further or merged back.
|
||||
"""
|
||||
|
||||
parts: list[str] = []
|
||||
for relative_path in relative_paths:
|
||||
path = FRONTEND_SRC / relative_path
|
||||
if path.is_file():
|
||||
parts.append(path.read_text(encoding="utf-8"))
|
||||
return chr(10).join(parts)
|
||||
|
||||
|
||||
def read_map_workspace() -> str:
|
||||
"""The whole map workspace feature, whichever modules it is split into."""
|
||||
|
||||
return read_frontend_area(*MAP_WORKSPACE_SOURCES)
|
||||
|
||||
|
||||
def assert_wired(source: str, *identifiers: str, context: str = "frontend source") -> None:
|
||||
"""Every identifier must appear in ``source``.
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ from app.models import Area, Dataset, Project
|
||||
from app.schemas.coverage import CoverageBBox
|
||||
from app.services.coverage_registry_service import CoverageRegistryService, THEMES, ZONES
|
||||
from app.services.vector_feature_service import VectorFeatureService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
class FakeQuery:
|
||||
@@ -151,9 +152,7 @@ def test_national_and_maritime_reference_layers_are_selection_analyzable() -> No
|
||||
def test_national_scope_operator_assigns_explicit_map_themes() -> None:
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
operator = (root / "scripts" / "provision_belgium_north_sea_scope.py").read_text(encoding="utf-8")
|
||||
map_workspace = (root / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
map_workspace = read_map_workspace()
|
||||
|
||||
assert '"belgium_municipalities": "administrative"' in operator
|
||||
assert '"marine_legal_scopes": "marine_environment"' in operator
|
||||
@@ -476,7 +475,7 @@ def test_frontend_prefers_materialized_national_workspace_and_resolves_drawn_bbo
|
||||
focus = (root / "frontend" / "src" / "config" / "primaryFocus.ts").read_text(encoding="utf-8")
|
||||
workspace_hook = (root / "frontend" / "src" / "hooks" / "useProjectWorkspace.ts").read_text(encoding="utf-8")
|
||||
coverage_hook = (root / "frontend" / "src" / "hooks" / "useCoverageResolver.ts").read_text(encoding="utf-8")
|
||||
map_workspace = (root / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
map_workspace = read_map_workspace()
|
||||
|
||||
assert "Belgium and North Sea Workbench" in focus
|
||||
assert "nationalProject" in workspace_hook
|
||||
|
||||
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -20,9 +21,7 @@ def test_rc9_ux_audit_is_wired_into_frontend_and_readiness() -> None:
|
||||
|
||||
def test_rc9_loading_and_accessibility_states_are_explicit() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
map_workspace = (
|
||||
ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx"
|
||||
).read_text(encoding="utf-8")
|
||||
map_workspace = read_map_workspace()
|
||||
geo_map = (ROOT / "frontend" / "src" / "components" / "GeoMap.tsx").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
@@ -42,9 +41,7 @@ def test_rc9_performance_budgets_are_documented_and_visible() -> None:
|
||||
ROOT / "frontend" / "src" / "lib" / "performanceBudget.ts"
|
||||
).read_text(encoding="utf-8")
|
||||
docs = (ROOT / "docs" / "UX_PERFORMANCE_BUDGETS.md").read_text(encoding="utf-8")
|
||||
map_workspace = (
|
||||
ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx"
|
||||
).read_text(encoding="utf-8")
|
||||
map_workspace = read_map_workspace()
|
||||
|
||||
assert "COVERAGE_RESPONSE_BUDGET_MS = 4_000" in budget
|
||||
assert "MAP_ANALYSIS_BUDGET_MS = 15_000" in budget
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def test_map_workspace_exposes_feature_extract_actions() -> None:
|
||||
map_workspace = (ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
map_workspace = read_map_workspace()
|
||||
|
||||
assert "Selectie en extractie" in map_workspace
|
||||
assert "downloadSelectedMapFeature" in map_workspace
|
||||
|
||||
@@ -11,7 +11,7 @@ from shapely.geometry import Polygon, box
|
||||
from app.core.errors import AppError
|
||||
from app.models import Dataset, VectorFeature
|
||||
from app.services.vector_feature_service import VectorFeatureService
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired, read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -338,7 +338,7 @@ def test_vector_select_route_rejects_area_from_another_project(monkeypatch) -> N
|
||||
|
||||
def test_frontend_exposes_map_bbox_selection_contracts() -> None:
|
||||
api_client = (ROOT / "frontend" / "src" / "services" / "api" / "datasets.ts").read_text(encoding="utf-8")
|
||||
map_workspace = (ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
map_workspace = read_map_workspace()
|
||||
geomap = (ROOT / "frontend" / "src" / "components" / "GeoMap.tsx").read_text(encoding="utf-8")
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
extract_hook = (ROOT / "frontend" / "src" / "hooks" / "useMapSelectionExtract.ts").read_text(encoding="utf-8")
|
||||
|
||||
@@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
import re
|
||||
|
||||
from pathlib import Path
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired, read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -15,7 +15,7 @@ def read(path: str) -> str:
|
||||
|
||||
def test_map_first_explorer_is_the_default_product_flow() -> None:
|
||||
app = read("frontend/src/App.tsx")
|
||||
workspace = read("frontend/src/components/map/MapWorkspace.tsx")
|
||||
workspace = read_map_workspace()
|
||||
|
||||
assert "useState<WorkspaceKey>('map')" in app
|
||||
assert "Gebied analyseren" in workspace
|
||||
@@ -36,7 +36,7 @@ def test_map_first_explorer_is_the_default_product_flow() -> None:
|
||||
|
||||
|
||||
def test_map_rectangle_drag_is_wired_to_automatic_analysis() -> None:
|
||||
workspace = read("frontend/src/components/map/MapWorkspace.tsx")
|
||||
workspace = read_map_workspace()
|
||||
geomap = read("frontend/src/components/GeoMap.tsx")
|
||||
styles = read("frontend/src/styles/app.css")
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ from app.schemas.temporal import TemporalComparisonRequest, TemporalObjectChange
|
||||
from app.services.dataset_service import DatasetService
|
||||
from app.services.temporal_analysis_service import TemporalAnalysisService
|
||||
from app.services.vector_feature_service import VectorFeatureService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).parents[2]
|
||||
@@ -513,7 +514,7 @@ def test_legacy_grb_identity_requires_complete_partition_evidence() -> None:
|
||||
|
||||
|
||||
def test_temporal_frontend_and_official_operator_contracts_exist() -> None:
|
||||
workspace = (ROOT / "frontend/src/components/map/MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
workspace = read_map_workspace()
|
||||
temporal_api = (ROOT / "frontend/src/services/api/temporal.ts").read_text(encoding="utf-8")
|
||||
population = (ROOT / "scripts/provision_mol_population_history.py").read_text(encoding="utf-8")
|
||||
landuse = (ROOT / "scripts/provision_mol_historical_landuse.py").read_text(encoding="utf-8")
|
||||
|
||||
@@ -11,6 +11,7 @@ import rasterio
|
||||
from rasterio.transform import from_origin
|
||||
from shapely.geometry import Polygon, shape
|
||||
from shapely.ops import transform
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -179,7 +180,7 @@ def test_official_landuse_operator_paginates_within_api_limit() -> None:
|
||||
def test_official_landuse_operator_is_packaged_and_readiness_checked() -> None:
|
||||
readiness = (ROOT / "scripts/run_readiness_check.sh").read_text(encoding="utf-8")
|
||||
dockerfile = (ROOT / "deploy/unraid/Dockerfile.all-in-one").read_text(encoding="utf-8")
|
||||
workspace = (ROOT / "frontend/src/components/map/MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
workspace = read_map_workspace()
|
||||
geo_map = (ROOT / "frontend/src/components/GeoMap.tsx").read_text(encoding="utf-8")
|
||||
premium_css = (ROOT / "frontend/src/styles/premium.css").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from pathlib import Path
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired, read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -10,7 +10,7 @@ def read(path: str) -> str:
|
||||
|
||||
|
||||
def test_work_area_change_clears_stale_spatial_results_before_switching_area() -> None:
|
||||
workspace = read("frontend/src/components/map/MapWorkspace.tsx")
|
||||
workspace = read_map_workspace()
|
||||
|
||||
assert "const handleSelectMapArea = (areaId: string) => {" in workspace
|
||||
assert "clearAreaSelection()\n onSelectMapArea(areaId)" in workspace
|
||||
|
||||
@@ -4,6 +4,7 @@ import importlib.util
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -118,9 +119,7 @@ def test_readiness_compiles_false_negative_review_validator() -> None:
|
||||
|
||||
|
||||
def test_map_explains_strict_and_diagnostic_detection_matching() -> None:
|
||||
workspace = (
|
||||
ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx"
|
||||
).read_text(encoding="utf-8")
|
||||
workspace = read_map_workspace()
|
||||
# Both matching methods must be named; the exact label may change.
|
||||
assert "strikte" in workspace.casefold()
|
||||
assert "Rechthoekcontrole" in workspace
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from pathlib import Path
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired, read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -10,7 +10,7 @@ def read(path: str) -> str:
|
||||
|
||||
|
||||
def test_evolution_mode_falls_back_to_an_available_series() -> None:
|
||||
workspace = read("frontend/src/components/map/MapWorkspace.tsx")
|
||||
workspace = read_map_workspace()
|
||||
|
||||
assert "themeTemporalSeriesMap" in workspace
|
||||
assert "availableEvolutionThemes[0]" in workspace
|
||||
@@ -20,7 +20,7 @@ def test_evolution_mode_falls_back_to_an_available_series() -> None:
|
||||
|
||||
|
||||
def test_evolution_theme_catalog_distinguishes_history_from_current_only_data() -> None:
|
||||
workspace = read("frontend/src/components/map/MapWorkspace.tsx")
|
||||
workspace = read_map_workspace()
|
||||
|
||||
assert "analysisMode === 'current'" in workspace
|
||||
# Theme availability depends on a dataset or an on-demand product;
|
||||
|
||||
@@ -13,6 +13,7 @@ from shapely.ops import transform as transform_geometry
|
||||
from app.models import Dataset
|
||||
from app.schemas.operations import VectorSelectionSummary
|
||||
from app.services.vector_feature_service import VectorFeatureService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -260,7 +261,7 @@ def test_operator_is_packaged_readiness_checked_and_wired_to_map() -> None:
|
||||
dockerfile = (ROOT / "deploy" / "unraid" / "Dockerfile.all-in-one").read_text(encoding="utf-8")
|
||||
readiness = (ROOT / "scripts" / "run_readiness_check.sh").read_text(encoding="utf-8")
|
||||
service = (ROOT / "backend" / "app" / "services" / "vector_feature_service.py").read_text(encoding="utf-8")
|
||||
map_workspace = (ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
map_workspace = read_map_workspace()
|
||||
source_catalog = (ROOT / "frontend" / "src" / "components" / "datasets" / "SourceCatalogPanel.tsx").read_text(encoding="utf-8")
|
||||
|
||||
assert "COPY scripts/provision_mol_bwk_natura2000.py" in dockerfile
|
||||
|
||||
@@ -14,6 +14,7 @@ from shapely.ops import transform as transform_geometry
|
||||
from app.models import Dataset
|
||||
from app.schemas.operations import VectorSelectionSummary
|
||||
from app.services.vector_feature_service import VectorFeatureService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -261,7 +262,7 @@ def test_operator_uses_canonical_upload_and_is_packaged_for_runtime() -> None:
|
||||
service = (ROOT / "backend" / "app" / "services" / "vector_feature_service.py").read_text(encoding="utf-8")
|
||||
dockerfile = (ROOT / "deploy" / "unraid" / "Dockerfile.all-in-one").read_text(encoding="utf-8")
|
||||
readiness = (ROOT / "scripts" / "run_readiness_check.sh").read_text(encoding="utf-8")
|
||||
map_workspace = (ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
map_workspace = read_map_workspace()
|
||||
source_catalog = (ROOT / "frontend" / "src" / "components" / "datasets" / "SourceCatalogPanel.tsx").read_text(encoding="utf-8")
|
||||
dataset_display = (ROOT / "frontend" / "src" / "lib" / "datasetDisplay.ts").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ from app.models import Area, Dataset, DatasetVersion, Job, Project, SourceRegist
|
||||
from app.schemas.dhmv import DhmvAcquireRequest, TerrainPartitionSelectionRequest, TerrainSelectionRequest
|
||||
from app.services.dhmv_acquisition_service import DhmvAcquisitionService
|
||||
from app.services.terrain_analysis_service import TerrainAnalysisService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -616,7 +617,7 @@ def test_frontend_and_runtime_expose_dhmv_workflow() -> None:
|
||||
capabilities_source = (
|
||||
ROOT / "frontend" / "src" / "lib" / "datasetCapabilities.ts"
|
||||
).read_text(encoding="utf-8")
|
||||
map_source = (ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
map_source = read_map_workspace()
|
||||
hook_source = (ROOT / "frontend" / "src" / "hooks" / "useMapSelectionExtract.ts").read_text(encoding="utf-8")
|
||||
service_source = (ROOT / "frontend" / "src" / "services" / "api" / "datasets.ts").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ from shapely.ops import transform as transform_geometry
|
||||
from app.models import Dataset
|
||||
from app.schemas.operations import VectorSelectionSummary
|
||||
from app.services.vector_feature_service import VectorFeatureService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -352,7 +353,7 @@ def test_operator_is_canonical_packaged_and_mol_scoped_in_explorer() -> None:
|
||||
service = (ROOT / "backend/app/services/vector_feature_service.py").read_text(encoding="utf-8")
|
||||
dockerfile = (ROOT / "deploy/unraid/Dockerfile.all-in-one").read_text(encoding="utf-8")
|
||||
readiness = (ROOT / "scripts/run_readiness_check.sh").read_text(encoding="utf-8")
|
||||
workspace = (ROOT / "frontend/src/components/map/MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
workspace = read_map_workspace()
|
||||
catalog = (ROOT / "frontend/src/components/datasets/SourceCatalogPanel.tsx").read_text(encoding="utf-8")
|
||||
display = (ROOT / "frontend/src/lib/datasetDisplay.ts").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ from app.schemas.assistant import AssistantQueryRequest
|
||||
from app.services.geo_assistant_service import GeoAssistantService
|
||||
from app.services.flood_hazard_acquisition_service import FloodHazardAcquisitionService
|
||||
from app.services.flood_hazard_analysis_service import FloodHazardAnalysisService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -549,7 +550,7 @@ def test_flood_hazard_runtime_contract_is_packaged() -> None:
|
||||
operator = (ROOT / "scripts" / "provision_mol_flood_hazards.py").read_text(encoding="utf-8")
|
||||
readiness = (ROOT / "scripts" / "run_readiness_check.sh").read_text(encoding="utf-8")
|
||||
dockerfile = (ROOT / "deploy" / "unraid" / "Dockerfile.all-in-one").read_text(encoding="utf-8")
|
||||
frontend = (ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
frontend = read_map_workspace()
|
||||
assert "/datasets/flood-hazard/acquire" in operator
|
||||
assert "/raster/flood-hazard/select" in operator
|
||||
assert "concurrent_flood_volume_m3" in operator
|
||||
|
||||
@@ -11,6 +11,7 @@ from shapely.geometry import box, mapping, shape
|
||||
|
||||
from app.models import Dataset
|
||||
from app.services.vector_feature_service import VectorFeatureService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -235,7 +236,7 @@ def test_regional_operator_is_packaged_release_checked_and_exact_area_is_preferr
|
||||
dockerfile = (ROOT / "deploy/unraid/Dockerfile.all-in-one").read_text(encoding="utf-8")
|
||||
readiness = (ROOT / "scripts/run_readiness_check.sh").read_text(encoding="utf-8")
|
||||
service = (ROOT / "backend/app/services/vector_feature_service.py").read_text(encoding="utf-8")
|
||||
workspace = (ROOT / "frontend/src/components/map/MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
workspace = read_map_workspace()
|
||||
catalog = (ROOT / "frontend/src/components/datasets/SourceCatalogPanel.tsx").read_text(encoding="utf-8")
|
||||
model = (ROOT / "backend/app/models/entities.py").read_text(encoding="utf-8")
|
||||
migration = (
|
||||
|
||||
@@ -10,6 +10,7 @@ from shapely.ops import transform as transform_geometry
|
||||
|
||||
from app.models import Dataset
|
||||
from app.services.vector_feature_service import VectorFeatureService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -154,7 +155,7 @@ def test_soil_operator_contract_has_no_direct_persistence_and_is_packaged() -> N
|
||||
operator = (ROOT / "scripts" / "provision_mol_soil_map.py").read_text(encoding="utf-8")
|
||||
dockerfile = (ROOT / "deploy" / "unraid" / "Dockerfile.all-in-one").read_text(encoding="utf-8")
|
||||
readiness = (ROOT / "scripts" / "run_readiness_check.sh").read_text(encoding="utf-8")
|
||||
map_workspace = (ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
map_workspace = read_map_workspace()
|
||||
|
||||
assert "/datasets/upload" in operator
|
||||
assert "vector_features" in operator
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from pathlib import Path
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired, read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -21,7 +21,7 @@ def test_partitioned_raster_routes_are_canonical_and_documented() -> None:
|
||||
|
||||
def test_regional_map_uses_logical_partition_groups_and_exact_analysis() -> None:
|
||||
app = (ROOT / "frontend/src/App.tsx").read_text(encoding="utf-8")
|
||||
workspace = (ROOT / "frontend/src/components/map/MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
workspace = read_map_workspace()
|
||||
hook = (ROOT / "frontend/src/hooks/useMapThemeSelectionInsights.ts").read_text(encoding="utf-8")
|
||||
api = (ROOT / "frontend/src/services/api/datasets.ts").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import pytest
|
||||
from app.core.errors import AppError
|
||||
from app.models import Dataset
|
||||
from app.services.grb_refresh_plan_service import GrbRefreshPlanService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
NOW = datetime(2026, 7, 16, 16, 0, tzinfo=timezone.utc)
|
||||
@@ -252,7 +253,7 @@ def test_refresh_api_and_frontend_remain_explicit_only() -> None:
|
||||
|
||||
def test_map_theme_ranking_prefers_newer_observation_over_feature_count() -> None:
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
workspace = (root / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
workspace = read_map_workspace()
|
||||
observed_sort = workspace.index("const observedAtDifference")
|
||||
feature_tiebreaker = workspace.index("right.feature_count", observed_sort)
|
||||
assert observed_sort < feature_tiebreaker
|
||||
@@ -262,7 +263,7 @@ def test_map_theme_ranking_prefers_newer_observation_over_feature_count() -> Non
|
||||
|
||||
def test_map_workspace_restores_theme_from_selected_dataset() -> None:
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
workspace = (root / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
workspace = read_map_workspace()
|
||||
assert "function themeIdForDataset(" in workspace
|
||||
assert "useState<DataThemeId>(() =>" in workspace
|
||||
assert "return themeIdForDataset(selectedDataset) ?? 'buildings'" in workspace
|
||||
|
||||
@@ -20,7 +20,7 @@ from app.services.storage_service import StorageService
|
||||
from app.services.source_registry_service import SourceRegistryService
|
||||
from app.services.temporal_analysis_service import TemporalAnalysisService
|
||||
from app.services.thematic_raster_analysis_service import ThematicRasterAnalysisService
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired, read_map_workspace
|
||||
|
||||
|
||||
class FakeSession:
|
||||
@@ -364,7 +364,7 @@ def test_map_result_export_endpoint_uses_canonical_envelope(monkeypatch) -> None
|
||||
|
||||
def test_frontend_persists_map_result_before_opening_downloads() -> None:
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
workspace = (root / "frontend/src/components/map/MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
workspace = read_map_workspace()
|
||||
hook = (root / "frontend/src/hooks/useExportWorkflow.ts").read_text(encoding="utf-8")
|
||||
api = (root / "frontend/src/services/api/exports.ts").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ from app.models import Area, Dataset, Job, Project
|
||||
from app.schemas.bathymetry import BathymetryProfileAcquireRequest
|
||||
from app.services.bathymetry_profile_acquisition_service import BathymetryProfileAcquisitionService
|
||||
from app.services.dataset_service import DatasetService
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -360,7 +361,7 @@ def test_bathymetry_contract_and_expansion_roadmap_are_documented() -> None:
|
||||
assert "py_compile scripts/provision_mol_bathymetry_profiles.py" in readiness
|
||||
assert "COPY scripts/provision_mol_bathymetry_profiles.py" in dockerfile
|
||||
operator = (ROOT / "scripts" / "provision_mol_bathymetry_profiles.py").read_text(encoding="utf-8")
|
||||
map_workspace = (ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
map_workspace = read_map_workspace()
|
||||
assert 'DEFAULT_PROJECT_NAME = "Kempen Regional Workbench"' in operator
|
||||
assert "regional_partitions_complete" in map_workspace
|
||||
assert "historische profielen" in map_workspace
|
||||
|
||||
@@ -31,6 +31,7 @@ if str(SCRIPTS) not in sys.path:
|
||||
sys.path.insert(0, str(SCRIPTS))
|
||||
|
||||
import provision_flanders_geographic_scope as flanders_scope # noqa: E402
|
||||
from tests.frontend_contract import read_map_workspace
|
||||
|
||||
|
||||
class BinaryResponse:
|
||||
@@ -463,9 +464,7 @@ def test_frontend_uses_partitioned_bathymetry_selection_for_regional_scope() ->
|
||||
focus = (
|
||||
ROOT / "frontend" / "src" / "config" / "primaryFocus.ts"
|
||||
).read_text(encoding="utf-8")
|
||||
map_workspace = (
|
||||
ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx"
|
||||
).read_text(encoding="utf-8")
|
||||
map_workspace = read_map_workspace()
|
||||
theme_hook = (
|
||||
ROOT / "frontend" / "src" / "hooks" / "useMapThemeSelectionInsights.ts"
|
||||
).read_text(encoding="utf-8")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from pathlib import Path
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired, read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -10,7 +10,7 @@ def read(path: str) -> str:
|
||||
|
||||
|
||||
def test_flanders_workspace_exposes_governed_thematic_products_on_demand() -> None:
|
||||
workspace = read("frontend/src/components/map/MapWorkspace.tsx")
|
||||
workspace = read_map_workspace()
|
||||
product_hook = read("frontend/src/hooks/useOfficialMapProducts.ts")
|
||||
selection_hook = read("frontend/src/hooks/useMapThemeSelectionInsights.ts")
|
||||
api = read("frontend/src/services/api/datasets.ts")
|
||||
@@ -30,7 +30,7 @@ def test_flanders_workspace_exposes_governed_thematic_products_on_demand() -> No
|
||||
|
||||
|
||||
def test_selection_reads_and_bounded_acquires_all_relevant_themes() -> None:
|
||||
workspace = read("frontend/src/components/map/MapWorkspace.tsx")
|
||||
workspace = read_map_workspace()
|
||||
app = read("frontend/src/App.tsx")
|
||||
selection_hook = read("frontend/src/hooks/useMapThemeSelectionInsights.ts")
|
||||
|
||||
@@ -51,7 +51,7 @@ def test_selection_reads_and_bounded_acquires_all_relevant_themes() -> None:
|
||||
|
||||
|
||||
def test_regional_on_demand_sources_require_a_bounded_drawn_selection() -> None:
|
||||
workspace = read("frontend/src/components/map/MapWorkspace.tsx")
|
||||
workspace = read_map_workspace()
|
||||
|
||||
assert "regionalOnDemandThemeActive" in workspace
|
||||
# Both regional source kinds need a bounded selection before acquiring.
|
||||
|
||||
@@ -19,7 +19,7 @@ from app.models import Area, Dataset, Job, Project
|
||||
from app.schemas.grb import GrbAcquireRequest
|
||||
from app.services.dataset_service import DatasetService
|
||||
from app.services.grb_acquisition_service import GrbAcquisitionService
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired
|
||||
from tests.frontend_contract import assert_calls, assert_mentions, assert_wired, read_map_workspace
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -383,7 +383,7 @@ def test_system_capabilities_reports_bounded_grb_integration() -> None:
|
||||
def test_grb_frontend_and_contracts_use_only_the_governed_backend_path() -> None:
|
||||
selection_hook = (ROOT / "frontend/src/hooks/useMapThemeSelectionInsights.ts").read_text(encoding="utf-8")
|
||||
catalog_hook = (ROOT / "frontend/src/hooks/useOfficialMapProducts.ts").read_text(encoding="utf-8")
|
||||
workspace = (ROOT / "frontend/src/components/map/MapWorkspace.tsx").read_text(encoding="utf-8")
|
||||
workspace = read_map_workspace()
|
||||
contracts = (ROOT / "docs/API_CONTRACTS.md").read_text(encoding="utf-8")
|
||||
|
||||
assert "datasetsApi.acquireGrb" in selection_hook
|
||||
|
||||
Reference in New Issue
Block a user