199 lines
5.8 KiB
JavaScript
199 lines
5.8 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,
|
|
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.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.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 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="Сбросить камеру"/);
|
|
});
|