import assert from 'node:assert/strict'; import { before, after, test } from 'node:test'; import { createServer } from 'vite'; import { readFile } from 'node:fs/promises'; let server, api; before(async () => { server = await createServer({ appType: 'custom', logLevel: 'silent', server: { middlewareMode: true } }); api = await server.ssrLoadModule('/src/core/observation/sessionOverviewSpatial.ts'); }); after(async () => { await server?.close(); }); test('comparison pins identity and changes geometry without requesting a camera reset', async () => { const oldFetch = globalThis.fetch, oldWindow = globalThis.window; const requests = []; globalThis.window = { location: { origin: 'http://localhost:8000' } }; globalThis.fetch = async (url, options) => { requests.push({ url: String(url), body: JSON.parse(options.body) }); return { ok: true, arrayBuffer: async () => new ArrayBuffer(8), headers: new Headers({ 'X-Overview-Visible-Points': '42' }) }; }; try { const source = '/api/v1/observation-sessions/example/overview/scene.rrd?generation=' + 'a'.repeat(64); const signal = new AbortController().signal; for (const representation of ['original', 'corrected', 'original']) { const result = await api.updateOverviewSpatial(source, 80, null, 1.5, signal, 'b'.repeat(64), representation); assert.equal(result.eye, null); assert.equal(result.visiblePoints, 42); } assert.deepEqual(requests.map(r => r.body.representation), ['original', 'corrected', 'original']); for (const request of requests) { assert.equal(request.body.mode, null); assert.equal(request.body.comparison_generation, 'b'.repeat(64)); assert.equal(request.body.generation, 'a'.repeat(64)); assert.ok(request.url.endsWith('/overview/spatial')); } await assert.rejects(api.updateOverviewSpatial(source, null, null, 1, signal, null, 'corrected'), /недоступна/); assert.equal(requests.length, 3); } finally { globalThis.fetch = oldFetch; globalThis.window = oldWindow; } }); test('comparison control is opt-in while default geometry and pinned planner versions are shared', async () => { const source = await readFile(new URL('../src/components/observation/SessionOverviewScene.tsx', import.meta.url), 'utf8'); assert.match(source, /compareVersions=false/); assert.match(source, /}, \[sourceUrl, retry\]\);/); assert.match(source, /appliedMode.current === mode \? null : mode/); assert.doesNotMatch(source, /key=\{representation\}|setRetry\([^\n]*representation/); assert.match(source, /label="Версия облака"/); assert.match(source, /setAppliedRepresentation\(comparison \? representation/); assert.match(source, /setRepresentation\(data.default_representation/); assert.match(source, /const comparison = metadata\?\.comparison/); assert.match(source, /compareVersions && comparison/); const planner = await readFile(new URL('../src/components/missions/MissionZonePreview.tsx', import.meta.url), 'utf8'); assert.doesNotMatch(planner, /compareVersions/); assert.match(planner, /reference_generation=\$\{encodeURIComponent\(generation\)\}/); const logic = await readFile(new URL('../src/core/missions/useMissionPlanner.ts', import.meta.url), 'utf8'); assert.match(logic, /setPinnedGeneration\(next.zone.generation\)/); assert.match(logic, /setPinnedGeneration\(null\)/); });