81 lines
4.3 KiB
JavaScript
81 lines
4.3 KiB
JavaScript
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);
|
||
});
|