Files

225 lines
6.7 KiB
JavaScript

import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import { after, before, test } from "node:test";
import { createServer } from "vite";
let server;
let mapView;
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
mapView = await server.ssrLoadModule("/src/core/map/mapView.ts");
});
after(async () => {
await server?.close();
});
function serverDocument(overrides = {}) {
return {
schema_version: "missioncore.map-view/v3",
revision: 0,
view: {
camera: {
longitude: 37.618423,
latitude: 55.751244,
height: 40000,
heading: 0,
pitch: -51.56620156177409,
roll: 0,
},
visual_settings: {
atmosphere_enabled: false,
atmosphere_hue: 0,
atmosphere_saturation: 0,
atmosphere_brightness: 0,
fog_enabled: true,
fog_density: 2,
sun_enabled: true,
sun_hour: 12,
sun_intensity: 200,
shadows_enabled: true,
monochrome_enabled: false,
monochrome_color: "#15151b",
imagery_brightness: 118,
imagery_contrast: 102,
imagery_saturation: 0,
imagery_gamma: 57,
imagery_hue: 13,
imagery_alpha: 27,
globe_color: "#15151b",
background_color: "#08090d",
terrain_exaggeration: 1,
buildings_color: "#a27aff",
buildings_opacity: 1,
buildings_maximum_screen_space_error: 4,
grid_lod_enabled: true,
grid_height_meters: 500,
grid_lod_1_max_height_km: 10,
grid_lod_1_step_km: 1,
grid_lod_2_max_height_km: 50,
grid_lod_2_step_km: 5,
grid_lod_3_step_km: 25,
grid_radius_km: 40,
grid_line_width: 4,
grid_color: "#f5f5f5",
grid_opacity: 12,
grid_dots_enabled: true,
grid_dots_size: 7,
grid_dots_color: "#ffffff",
grid_dots_opacity: 58,
camera_animation_enabled: true,
},
map_height: 694,
inspector_open_sections: [],
cache_intent: {
enabled: true,
no_overwrite: true,
},
selected_subject_id: null,
layer_visibility: {
imagery: true,
terrain: true,
buildings: true,
grid: true,
targets: true,
},
ghost_pins: {
count: 12,
radius_meters: 5000,
maximum_speed_meters_per_second: 18,
simulation_enabled: false,
anchor: null,
positions: [],
presentation: {
color: "#6fb5fb",
opacity: 0.9,
stem_height_meters: 1500,
head_size_px: 6,
stem_width_px: 3,
outline_color: "#0c0d12",
outline_opacity: 0.6,
outline_width_px: 1,
label_mode: "attributes",
label_font_weight: 600,
label_size_px: 13,
label_color: "#f5f5f5",
label_background_color: "#0c0d12",
label_background_opacity: 0.86,
label_padding_x: 8,
label_padding_y: 5,
label_offset_x: 15,
label_offset_y: 10,
label_max_length: 48,
label_hide_camera_height_meters: 70000,
target_hide_camera_height_meters: 100000,
},
},
},
...overrides,
};
}
test("map view starts from the canonical Foundry camera without a fabricated subject", () => {
const document = mapView.defaultMapViewDocument();
assert.equal(document.view.camera.longitude, 37.618423);
assert.equal(document.view.camera.latitude, 55.751244);
assert.equal(document.view.visualSettings.imagerySaturation, 0);
assert.equal(document.view.visualSettings.gridDotsOpacity, 58);
assert.equal(document.view.selectedSubjectId, null);
assert.equal(document.view.cacheIntent.enabled, true);
assert.equal(document.view.cacheIntent.noOverwrite, true);
assert.equal(document.view.ghostPins.count, 12);
assert.equal(document.view.ghostPins.maximumSpeedMetersPerSecond, 18);
assert.equal(document.view.ghostPins.positions.length, 0);
});
test("map view decodes and re-encodes the complete versioned contract", () => {
const decoded = mapView.decodeMapViewDocument(serverDocument({
revision: 3,
view: {
...serverDocument().view,
camera: {
longitude: 37.6176,
latitude: 55.7558,
height: 2500,
heading: 12,
pitch: -48,
roll: 0,
},
inspector_open_sections: ["camera"],
},
}));
const encoded = mapView.encodeMapViewPut(decoded);
assert.equal(decoded.revision, 3);
assert.equal(decoded.view.camera.longitude, 37.6176);
assert.equal(decoded.view.inspectorOpenSections[0], "camera");
assert.equal(encoded.view.camera.latitude, 55.7558);
assert.equal(encoded.view.cache_intent.no_overwrite, true);
assert.equal(encoded.view.ghost_pins.maximum_speed_meters_per_second, 18);
assert.equal(encoded.view.ghost_pins.presentation.stem_height_meters, 1500);
assert.equal("schema_version" in encoded, false);
});
test("map view fails closed on credentials, runtime URLs and unbound selection", () => {
assert.throws(
() => mapView.decodeMapViewDocument(serverDocument({
view: {
...serverDocument().view,
token: "forbidden",
},
})),
);
assert.throws(
() => mapView.decodeMapViewDocument(serverDocument({
view: {
...serverDocument().view,
inspector_open_sections: ["selection"],
},
})),
/stable subject id|стабильный subject id/i,
);
});
test("map view rejects a ghost pin faster than its configured maximum", () => {
assert.throws(
() => mapView.decodeMapViewDocument(serverDocument({
view: {
...serverDocument().view,
ghost_pins: {
...serverDocument().view.ghost_pins,
maximum_speed_meters_per_second: 5,
positions: [{
id: "ghost-fast-1",
label: "123456",
longitude: 37.618423,
latitude: 55.751244,
heading_degrees: 90,
speed_meters_per_second: 6,
}],
},
},
})),
/превышает настроенный максимум/i,
);
});
test("map workspace keeps the canonical top actions without a bottom toolbar", async () => {
const source = await readFile(
new URL("../src/workspaces/map/WorldMapWorkspace.tsx", import.meta.url),
"utf8",
);
assert.doesNotMatch(source, /<Toolbar/);
assert.match(source, /className="mission-map__map-actions"/);
assert.match(source, /label="Настройки карты"/);
assert.match(source, /label="Слои карты"/);
assert.doesNotMatch(source, /label="Сбросить камеру"/);
});