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, /