import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import test from "node:test"; import { normalizeMapPresentationProfile, normalizeMapPresentationProfiles } from "./map-presentation-profile.mjs"; const registry = JSON.parse(await readFile(new URL("../registry/map-presentation-profiles.json", import.meta.url), "utf8")); const mapFixtureSource = await readFile(new URL("../apps/catalog/src/MapFixturePreview.tsx", import.meta.url), "utf8"); const catalogStyles = await readFile(new URL("../apps/catalog/src/styles.css", import.meta.url), "utf8"); test("canonical moving-object profile is provider-neutral and internally consistent", () => { assert.equal(registry.schemaVersion, "nodedc.map-presentation-profiles/v1"); const profiles = normalizeMapPresentationProfiles(registry.profiles); assert.equal(profiles.length, 2); const profile = profiles.find((item) => item.id === "map.moving-object.operational.default"); assert.ok(profile); assert.equal(profile.id, "map.moving-object.operational.default"); assert.deepEqual(profile.semanticTypes, ["map.moving_object"]); assert.equal(profile.target.variant, "elevated-spike"); assert.equal(profile.target.stemHeightMeters, 1500); assert.equal(profile.target.headSizePx, 9); assert.equal(profile.target.stemWidthPx, 5); assert.equal(profile.label.mode, "subject_id"); assert.equal(profile.label.sizePx, 18); assert.equal(profile.label.backgroundOpacity, 0.86); assert.equal(profile.styles.find((style) => style.id === "online")?.color, "#86fdb8"); assert.equal(profile.styles.find((style) => style.id === "moving")?.color, "#6fb5fb"); assert.equal(JSON.stringify(profile).toLowerCase().includes("gelios"), false); assert.deepEqual(profile.facets.map((facet) => facet.field), [ "availability_state", "motion_state", ]); assert.deepEqual(profile.facets.flatMap((facet) => facet.values.map((value) => value.label)), [ "Онлайн", "Офлайн", "В движении", "Стоят", ]); assert.equal(JSON.stringify(profile).includes("Неизвестно"), false); }); test("canonical zone profile renders provider-neutral surfaces", () => { const profiles = normalizeMapPresentationProfiles(registry.profiles); const profile = profiles.find((item) => item.id === "map.zone.operational.default"); assert.ok(profile); assert.deepEqual(profile.semanticTypes, ["map.zone"]); assert.equal(profile.target.variant, "surface-fill"); assert.equal(profile.label.mode, "attributes"); assert.deepEqual(profile.facets.map((facet) => facet.field), ["geometry_kind", "source_kind"]); assert.equal(JSON.stringify(profile).toLowerCase().includes("gelios"), false); assert.equal(JSON.stringify(profile).includes("http"), false); }); test("fleet filter window is one compact vertical list without group rows or All", () => { assert.match(mapFixtureSource, /catalog-map-fixture__target-filter-list/); assert.doesNotMatch(mapFixtureSource, /catalog-map-fixture__target-profile/); assert.doesNotMatch(mapFixtureSource, /catalog-map-fixture__target-facet/); assert.doesNotMatch(mapFixtureSource, />Все /); assert.match(catalogStyles, /\.catalog-map-fixture__target-filter-list\s*\{[\s\S]*grid-template-columns:\s*minmax\(0, 1fr\)/); assert.match(catalogStyles, /\.catalog-map-fixture__target-filter-list button\s*\{[\s\S]*width:\s*100%/); }); test("profile rejects undeclared state matches and renderer transport", () => { const source = registry.profiles[0]; const undeclared = structuredClone(source); undeclared.classes[0].match[0].equals = "provider_magic"; assert.throws(() => normalizeMapPresentationProfile(undeclared), /map_presentation_profile_class_condition_not_declared/); const transport = structuredClone(source); transport.providerUrl = "https://example.test"; assert.throws(() => normalizeMapPresentationProfile(transport), /invalid_map_presentation_profile_fields/); }); test("legacy pin profiles normalize into the provider-neutral target contract", () => { const legacy = structuredClone(registry.profiles[0]); legacy.pin = legacy.target; delete legacy.target; const normalized = normalizeMapPresentationProfile(legacy); assert.equal(normalized.target.stemHeightMeters, 1500); assert.equal(Object.hasOwn(normalized, "pin"), false); });