Historical working copy retained for audit before consolidation into main. The canonicalized plugin architecture and later fixes already live in main; this snapshot is not a release or a request to restore obsolete source layout.
208 lines
6.1 KiB
JavaScript
208 lines
6.1 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { after, before, test } from "node:test";
|
|
|
|
import { createServer } from "vite";
|
|
|
|
let server;
|
|
let environment;
|
|
|
|
before(async () => {
|
|
server = await createServer({
|
|
appType: "custom",
|
|
logLevel: "silent",
|
|
server: { middlewareMode: true },
|
|
});
|
|
environment = await server.ssrLoadModule(
|
|
"/src/core/environment/environmentSettings.ts",
|
|
);
|
|
});
|
|
|
|
after(async () => {
|
|
await server?.close();
|
|
});
|
|
|
|
function serverDocument(overrides = {}) {
|
|
const defaults = environment.defaultEnvironmentSettings();
|
|
return {
|
|
schema_version: "missioncore.operator-environment/v3",
|
|
revision: defaults.revision,
|
|
pages: Object.fromEntries(
|
|
Object.entries(defaults.pages).map(([surfaceId, page]) => [
|
|
surfaceId,
|
|
{
|
|
header_label: page.headerLabel,
|
|
eyebrow: page.eyebrow,
|
|
title: page.title,
|
|
description: page.description,
|
|
primary_workspace_id: page.primaryWorkspaceId,
|
|
secondary_workspace_id: page.secondaryWorkspaceId,
|
|
background: {
|
|
enabled: page.background.enabled,
|
|
image_duration_seconds: page.background.imageDurationSeconds,
|
|
items: page.background.items.map((item) => ({
|
|
id: item.id,
|
|
source: item.source,
|
|
url: item.url,
|
|
media_kind: item.mediaKind,
|
|
file_name: item.fileName,
|
|
})),
|
|
},
|
|
},
|
|
]),
|
|
),
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
test("default environment exposes every current product page", () => {
|
|
const defaults = environment.defaultEnvironmentSettings();
|
|
assert.deepEqual(Object.keys(defaults.pages), [
|
|
"home",
|
|
"fleet",
|
|
"observation",
|
|
"missions",
|
|
"data",
|
|
"system",
|
|
"polygon",
|
|
]);
|
|
assert.equal(defaults.pages.fleet.primaryWorkspaceId, "vehicles");
|
|
assert.equal(defaults.pages.observation.primaryWorkspaceId, "spatial-scene");
|
|
});
|
|
|
|
test("server document decodes and re-encodes the complete page contract", () => {
|
|
const base = serverDocument();
|
|
const payload = serverDocument({
|
|
revision: 4,
|
|
pages: {
|
|
...base.pages,
|
|
observation: {
|
|
...base.pages.observation,
|
|
header_label: "Контроль",
|
|
title: "Контроль пространства",
|
|
},
|
|
fleet: {
|
|
...base.pages.fleet,
|
|
primary_workspace_id: "contour-health",
|
|
background: {
|
|
enabled: true,
|
|
image_duration_seconds: 12,
|
|
items: [
|
|
{
|
|
id: "media-11111111-1111-4111-8111-111111111111",
|
|
source: "file",
|
|
url: `/api/v1/environment/media/fleet?generation=${"a".repeat(64)}`,
|
|
media_kind: "video",
|
|
file_name: "stage.mp4",
|
|
},
|
|
{
|
|
id: "media-22222222-2222-4222-8222-222222222222",
|
|
source: "url",
|
|
url: "https://example.test/background.png",
|
|
media_kind: "image",
|
|
file_name: null,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
});
|
|
const decoded = environment.decodeEnvironmentSettings(payload);
|
|
const encoded = environment.encodeEnvironmentSettings(decoded);
|
|
|
|
assert.equal(decoded.revision, 4);
|
|
assert.equal(decoded.pages.observation.headerLabel, "Контроль");
|
|
assert.equal(decoded.pages.observation.title, "Контроль пространства");
|
|
assert.equal(decoded.pages.fleet.background.items.length, 2);
|
|
assert.equal(decoded.pages.fleet.background.items[0].mediaKind, "video");
|
|
assert.equal(decoded.pages.fleet.background.imageDurationSeconds, 12);
|
|
assert.equal(encoded.pages.fleet.background.items[1].media_kind, "image");
|
|
assert.equal(encoded.pages.fleet.background.image_duration_seconds, 12);
|
|
assert.equal(encoded.pages.fleet.primary_workspace_id, "contour-health");
|
|
assert.equal("schema_version" in encoded, false);
|
|
});
|
|
|
|
test("decoder fails closed on an unknown environment schema", () => {
|
|
assert.throws(
|
|
() => environment.decodeEnvironmentSettings(
|
|
serverDocument({ schema_version: "future/v9" }),
|
|
),
|
|
/не поддерживается/,
|
|
);
|
|
});
|
|
|
|
test("editing a cloned page cannot mutate accepted settings", () => {
|
|
const accepted = environment.decodeEnvironmentSettings(serverDocument());
|
|
const draft = environment.cloneEnvironmentSettings(accepted);
|
|
draft.pages.observation.headerLabel = "Изменено";
|
|
draft.pages.fleet.background.enabled = true;
|
|
draft.pages.fleet.background.items.push(
|
|
environment.createEnvironmentMediaItem(),
|
|
);
|
|
|
|
assert.equal(accepted.pages.observation.headerLabel, "Наблюдение");
|
|
assert.equal(accepted.pages.fleet.background.enabled, false);
|
|
assert.equal(accepted.pages.fleet.background.items.length, 0);
|
|
});
|
|
|
|
test("repopulating an emptied playlist restores its background lifecycle", () => {
|
|
const original = {
|
|
enabled: true,
|
|
imageDurationSeconds: 10,
|
|
items: [
|
|
{
|
|
id: "media-original",
|
|
source: "url",
|
|
url: "https://example.test/original.mp4",
|
|
mediaKind: "video",
|
|
fileName: null,
|
|
},
|
|
],
|
|
};
|
|
const emptied = environment.removeEnvironmentMediaItem(
|
|
original,
|
|
"media-original",
|
|
);
|
|
const replacement = {
|
|
id: "media-replacement",
|
|
source: "file",
|
|
url: null,
|
|
mediaKind: null,
|
|
fileName: null,
|
|
};
|
|
const repopulated = environment.appendEnvironmentMediaItem(
|
|
emptied,
|
|
replacement,
|
|
);
|
|
|
|
assert.equal(emptied.enabled, false);
|
|
assert.equal(emptied.items.length, 0);
|
|
assert.equal(repopulated.enabled, true);
|
|
assert.deepEqual(repopulated.items, [replacement]);
|
|
});
|
|
|
|
test("adding to an intentionally disabled nonempty playlist keeps it disabled", () => {
|
|
const disabled = {
|
|
enabled: false,
|
|
imageDurationSeconds: 10,
|
|
items: [
|
|
{
|
|
id: "media-hidden",
|
|
source: "url",
|
|
url: "https://example.test/hidden.png",
|
|
mediaKind: "image",
|
|
fileName: null,
|
|
},
|
|
],
|
|
};
|
|
const next = environment.appendEnvironmentMediaItem(disabled, {
|
|
id: "media-second",
|
|
source: "file",
|
|
url: null,
|
|
mediaKind: null,
|
|
fileName: null,
|
|
});
|
|
|
|
assert.equal(next.enabled, false);
|
|
assert.equal(next.items.length, 2);
|
|
});
|