feat(ui): add environment media playlists
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { after, before, test } from "node:test";
|
||||
import React from "react";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
|
||||
import { createServer } from "vite";
|
||||
|
||||
let server;
|
||||
let backgroundMedia;
|
||||
|
||||
before(async () => {
|
||||
server = await createServer({
|
||||
appType: "custom",
|
||||
logLevel: "silent",
|
||||
server: { middlewareMode: true },
|
||||
});
|
||||
backgroundMedia = await server.ssrLoadModule(
|
||||
"/src/components/EnvironmentBackgroundMedia.tsx",
|
||||
);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await server?.close();
|
||||
});
|
||||
|
||||
test("background playlist starts with its oldest media item", () => {
|
||||
const markup = renderToStaticMarkup(
|
||||
React.createElement(backgroundMedia.EnvironmentBackgroundMedia, {
|
||||
background: {
|
||||
enabled: true,
|
||||
imageDurationSeconds: 10,
|
||||
items: [
|
||||
{
|
||||
id: "media-oldest",
|
||||
source: "url",
|
||||
url: "https://example.test/oldest.png",
|
||||
mediaKind: "image",
|
||||
fileName: null,
|
||||
},
|
||||
{
|
||||
id: "media-newest",
|
||||
source: "url",
|
||||
url: "https://example.test/newest.mp4",
|
||||
mediaKind: "video",
|
||||
fileName: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
assert.match(markup, /oldest\.png/);
|
||||
assert.doesNotMatch(markup, /newest\.mp4/);
|
||||
});
|
||||
|
||||
test("disabled background renders no media", () => {
|
||||
const markup = renderToStaticMarkup(
|
||||
React.createElement(backgroundMedia.EnvironmentBackgroundMedia, {
|
||||
background: {
|
||||
enabled: false,
|
||||
imageDurationSeconds: 10,
|
||||
items: [
|
||||
{
|
||||
id: "media-hidden",
|
||||
source: "url",
|
||||
url: "https://example.test/hidden.png",
|
||||
mediaKind: "image",
|
||||
fileName: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
assert.equal(markup, "");
|
||||
});
|
||||
@@ -24,7 +24,7 @@ after(async () => {
|
||||
function serverDocument(overrides = {}) {
|
||||
const defaults = environment.defaultEnvironmentSettings();
|
||||
return {
|
||||
schema_version: "missioncore.operator-environment/v2",
|
||||
schema_version: "missioncore.operator-environment/v3",
|
||||
revision: defaults.revision,
|
||||
pages: Object.fromEntries(
|
||||
Object.entries(defaults.pages).map(([surfaceId, page]) => [
|
||||
@@ -38,10 +38,14 @@ function serverDocument(overrides = {}) {
|
||||
secondary_workspace_id: page.secondaryWorkspaceId,
|
||||
background: {
|
||||
enabled: page.background.enabled,
|
||||
source: page.background.source,
|
||||
url: page.background.url,
|
||||
media_kind: page.background.mediaKind,
|
||||
file_name: page.background.fileName,
|
||||
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,
|
||||
})),
|
||||
},
|
||||
},
|
||||
]),
|
||||
@@ -81,10 +85,23 @@ test("server document decodes and re-encodes the complete page contract", () =>
|
||||
primary_workspace_id: "contour-health",
|
||||
background: {
|
||||
enabled: true,
|
||||
source: "file",
|
||||
url: `/api/v1/environment/media/fleet?generation=${"a".repeat(64)}`,
|
||||
media_kind: "video",
|
||||
file_name: "stage.mp4",
|
||||
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,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -95,8 +112,11 @@ test("server document decodes and re-encodes the complete page contract", () =>
|
||||
assert.equal(decoded.revision, 4);
|
||||
assert.equal(decoded.pages.observation.headerLabel, "Контроль");
|
||||
assert.equal(decoded.pages.observation.title, "Контроль пространства");
|
||||
assert.equal(decoded.pages.fleet.background.mediaKind, "video");
|
||||
assert.equal(encoded.pages.fleet.background.media_kind, "video");
|
||||
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);
|
||||
});
|
||||
@@ -115,7 +135,11 @@ test("editing a cloned page cannot mutate accepted settings", () => {
|
||||
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);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user