MapWorkspace.tsx was 3.157 lines: a props interface, 1.200 lines of derived state and handlers, and two complete render paths — the map-first explorer and the advanced workbench behind it. It is now five modules, and the container is nineteen lines that choose between the two. The obstacle was the props signature. The explorer reads 97 derived values and the workbench 40, so passing them individually would have produced a 97-field interface — worse than the file it replaced. Extracting the derived state into a hook that returns one object solves it: MapWorkspaceViewModel is ReturnType<typeof useMapWorkspaceViewModel>, so the shape is derived from what the hook actually produces and cannot drift from it. Each view then names two typed objects, and the JSX moved unchanged. The contract tests found the one place where widening a negative assertion is wrong. "The map workspace performs no transport" was true of the old file and false of the whole feature, because the hooks call the API by design. It is now scoped to the presentational modules, which is what it always meant. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
83 lines
3.5 KiB
Python
83 lines
3.5 KiB
Python
from pathlib import Path
|
|
from tests.frontend_contract import read_feature
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def read(path: str) -> str:
|
|
return (ROOT / path).read_text(encoding="utf-8")
|
|
|
|
|
|
def test_national_workspace_is_automatic_and_map_has_one_scope_selector() -> None:
|
|
project_hook = read("frontend/src/hooks/useProjectWorkspace.ts")
|
|
map_workspace = read_feature("map_workspace")
|
|
|
|
national_check = project_hook.index("const nationalProject")
|
|
regional_check = project_hook.index("const regionalProject")
|
|
assert national_check < regional_check
|
|
assert "return nationalProject.id" in project_hook
|
|
assert "const municipalityProject" not in project_hook
|
|
assert 'aria-label="Regio"' not in map_workspace
|
|
assert 'aria-label="Ingeladen regiobereik"' in map_workspace
|
|
assert "Zoek optioneel een gemeente" in map_workspace
|
|
assert 'aria-label="Werkgebied"' in map_workspace
|
|
|
|
|
|
def test_primary_navigation_uses_end_user_language_and_keeps_management_secondary() -> None:
|
|
app = read_feature("shell")
|
|
|
|
for label in ("Kaart", "Bronnen", "Kwaliteit", "Beeldanalyse", "Downloads"):
|
|
assert f"label: '{label}'" in app
|
|
assert "{ label: 'Beheer', keys: ['overview', 'system'] }" in app
|
|
assert 'className="secondary-analysis-disclosure segmentation-disclosure"' in app
|
|
|
|
|
|
def test_technical_projects_and_metadata_are_progressively_disclosed() -> None:
|
|
projects = read("frontend/src/components/project/ProjectPanel.tsx")
|
|
areas = read("frontend/src/components/project/AreaPanel.tsx")
|
|
datasets = read_feature("datasets")
|
|
dataset_names = read("frontend/src/lib/datasetDisplay.ts")
|
|
|
|
assert "TECHNICAL_PROJECT_PATTERN" in projects
|
|
assert "project.name === LEGACY_MOL_PROJECT_NAME" in projects
|
|
assert "alternatieve en technische werkruimtes" in projects
|
|
assert "Kempen · volledige regionale werkruimte" in projects
|
|
assert "area-catalog-disclosure" in areas
|
|
assert "dataset-technical-details" in datasets
|
|
assert "getDatasetDisplayName" in datasets
|
|
assert "dataset.source_metadata?.layer_type" in dataset_names
|
|
assert "regional_boundary: 'Grens vervoerregio Kempen'" in dataset_names
|
|
|
|
|
|
def test_configured_yolo_and_active_asset_are_selected_without_hiding_limitations() -> None:
|
|
hook = read_feature("detection")
|
|
lab = read_feature("detection")
|
|
|
|
assert "useState('yolo-configured')" in hook
|
|
assert "useState(0.15)" in hook
|
|
assert "asset.active" in hook
|
|
assert "getYoloPreflight" in hook
|
|
assert 'aria-label="Status gebouwdetectie"' in lab
|
|
assert "Nog niet nationaal gevalideerd" in lab
|
|
assert "selectedDetectionModel?.nationally_validated !== true" in lab
|
|
assert "selectedDetectionModel?.validation_scope" in lab
|
|
assert "vereisen lokale referentiedata en QA" in lab
|
|
assert "Modelkalibratie voor beheerders" in lab
|
|
|
|
|
|
def test_visible_ai_and_quality_labels_are_end_user_facing() -> None:
|
|
profiles = read_feature("detection")
|
|
quality = read_feature("quality")
|
|
export_preview = read("frontend/src/components/exports/ExportPreview.tsx")
|
|
providers = read("frontend/src/components/providers/ProviderPanel.tsx")
|
|
|
|
assert "Aanbevolen controleprofiel kleine gebouwen" in profiles
|
|
assert "Slechts drie pure-achtergrondbeelden" in profiles
|
|
assert "controlekandidaat en niet als grondwaarheid" in profiles
|
|
assert "qualityStatusLabel" in quality
|
|
assert "nog niet uitgevoerd" in quality
|
|
assert "Nog geen bestand gekozen." in export_preview
|
|
assert "providerLayerLabel" in providers
|
|
assert "custom: 'eigen laag'" in providers
|