NODEDC_DESIGN_GUIDELINE/server/map-presentation-profile.te...

81 lines
4.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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, />Все <span>/);
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);
});