Files
gods-eye-view/src/layers/ghostMaps/catalog.test.mjs
T
GPTmadeitandClaude Opus 5.5 1f77d2290c feat: add S2 GhostMaps live intel layer
Adds an "S2 GhostMaps" layer (Events group) that renders S2 Underground's
GhostMaps KMZ exports (Common Intelligence Picture, Kinetic 30d, Border
Crisis, Iran CIP/Kinetic, Yemen FLOT, latest incident drop).

- server/providers/ghostMaps.js: watcher polls the repo's git smart-HTTP
  ref advertisement (default every 15s, GHOSTMAPS_POLL_SECONDS), fetches
  the tree only on a new head, caches commit-pinned files by blob sha and
  pushes catalog updates to browsers over SSE (/api/ghostmaps/events).
- src/layers/ghostMaps: KML reader, ArcGIS popup-table parsing, per-product
  data sources, product chips, horizon-culled pins, report cards.
- Unit tests, QA gate (scripts/qa-ghostmaps.mjs), credits (CC BY-NC-SA 4.0),
  i18n, voice manifest, layer-state token 5.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 16:24:53 -04:00

166 lines
5.7 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
buildGhostMapsCatalog,
ghostMapsFileTitle,
ghostMapsRawUrl,
parseGhostMapsEdition,
parseGitRefAdvertisement,
} from './catalog.js';
const ARCGIS = 'ArcGIS Data for ATAK (KMZs)/';
const INCIDENTS = 'Incident Response Products for ATAK (KMZs and Documents)/';
let n = 0;
const blob = (path, size = 1000) => ({
path,
type: 'blob',
size,
sha: (++n).toString(16).padStart(40, '0'),
});
test('editions read the date and export/version number written in the name', () => {
assert.deepEqual(
parseGhostMapsEdition(
'S2Underground_Common_Intelligence_Picture_October_16_2026_Export_1.kmz',
),
{ dateMs: Date.UTC(2026, 9, 16), edition: 1 },
);
assert.deepEqual(
parseGhostMapsEdition(
'S2Underground_Border_Crisis_Map_September_21_2026_Export_v2.kmz',
),
{ dateMs: Date.UTC(2026, 8, 21), edition: 2 },
);
assert.deepEqual(
parseGhostMapsEdition('Reno Wildfires August 24, 2026.kmz'),
{
dateMs: Date.UTC(2026, 7, 24),
edition: 0,
},
);
assert.deepEqual(
parseGhostMapsEdition('Venezuelan_Crisis_Sep_5_2025_v2.kmz'),
{
dateMs: Date.UTC(2025, 8, 5),
edition: 2,
},
);
assert.deepEqual(
parseGhostMapsEdition('Kinetic_Activities_Last_30_Days.kmz'),
{
dateMs: null,
edition: 0,
},
);
// An impossible date is not a date.
assert.equal(parseGhostMapsEdition('X_September_31_2026.kmz').dateMs, null);
});
test('each product keeps its newest edition by date, then edition number', () => {
const master = `${ARCGIS}Common Intelligence Picture/Master Database/`;
const tree = [
blob(
`${master}S2Underground_Common_Intelligence_Picture_October_9_2026_Export_1.kmz`,
),
blob(
`${master}S2Underground_Common_Intelligence_Picture_October_16_2026_Export_1.kmz`,
),
blob(
`${master}S2Underground_Common_Intelligence_Picture_October_1_2026_Export_1.kmz`,
),
blob(
`${master}S2Underground_Common_Intelligence_Picture_September_30_2026_Export_2.kmz`,
),
blob(
`${ARCGIS}Common Intelligence Picture/30-Day Pulls/Kinetic_Activities_Last_30_Days.kmz`,
),
blob(
`${ARCGIS}Border Crisis Map/S2Underground_Border_Crisis_Map_September_21_2026_Export_v1.kmz`,
),
blob(
`${ARCGIS}Border Crisis Map/S2Underground_Border_Crisis_Map_September_21_2026_Export_v2.kmz`,
),
// A European-only subset in a subfolder is not the border map.
blob(
`${ARCGIS}Border Crisis Map/European Layers Only/Europe_Migration_Crisis_June_02_2026_v1.kmz`,
),
blob(`${INCIDENTS}Yemen 2026/Yemen FLOT.kmz`),
blob(`${INCIDENTS}Yemen 2026/Yemen FLOT_October_10_2026.kmz`),
{ path: `${INCIDENTS}Yemen 2026`, type: 'tree', sha: 'f'.repeat(40) },
];
const rows = buildGhostMapsCatalog(tree);
const byId = Object.fromEntries(rows.map((row) => [row.id, row]));
assert.deepEqual(
rows.map(({ id }) => id),
['cip', 'kinetic-30d', 'border-crisis', 'yemen-flot'],
);
assert.match(byId.cip.fileName, /October_16_2026/);
assert.equal(byId.cip.defaultOn, true);
assert.equal(byId['kinetic-30d'].defaultOn, true);
assert.match(byId['border-crisis'].fileName, /Export_v2/);
assert.equal(byId['yemen-flot'].fileName, 'Yemen FLOT_October_10_2026.kmz');
assert.equal(byId.cip.version, tree[1].sha);
assert.equal(
byId.cip.fileTitle,
'Common Intelligence Picture October 16 2026 Export 1',
);
});
test('latest drop is the newest dated incident file outside curated, archived and base data', () => {
const rows = buildGhostMapsCatalog([
blob(`${INCIDENTS}Reno Wildfires August 24, 2026.kmz`),
blob(
`${INCIDENTS}Spokane Fire Disaster - August, 2026/SpokaneDisasterAid_August_8_2026.kmz`,
),
blob(
`${INCIDENTS}0_Archive/Texas Floods/TexasFloods_December_1_2026_v1.kmz`,
),
blob(`${INCIDENTS}Iran 2026/Basedata/Pipelines_December_1_2026.kmz`),
blob(
`${INCIDENTS}Iran 2026/Iran Kinetic Events/Iran_Kinetic_Events_December_2_2026_v1.kmz`,
),
blob(`${INCIDENTS}Undated Product.kmz`),
]);
const drop = rows.find(({ id }) => id === 'latest-drop');
assert.equal(drop.fileName, 'Reno Wildfires August 24, 2026.kmz');
assert.ok(rows.some(({ id }) => id === 'iran-kinetic'));
});
test('oversized, empty, non-KMZ and malformed entries are skipped', () => {
const path = `${ARCGIS}Common Intelligence Picture/Master Database/S2Underground_Common_Intelligence_Picture_October_16_2026_Export_1.kmz`;
assert.deepEqual(
buildGhostMapsCatalog([
{ ...blob(path), size: 51 * 1024 * 1024 },
{ ...blob(path), size: 0 },
{ ...blob(path), sha: 'not-a-sha' },
blob(path.replace(/\.kmz$/, '.zip')),
null,
]),
[],
);
assert.deepEqual(buildGhostMapsCatalog(undefined), []);
});
test('raw URLs are pinned to the commit and encode every path segment', () => {
assert.equal(
ghostMapsRawUrl('a'.repeat(40), 'Folder (KMZs)/Yemen FLOT.kmz'),
`https://raw.githubusercontent.com/s2underground/GhostMaps/${'a'.repeat(40)}/Folder%20(KMZs)/Yemen%20FLOT.kmz`,
);
assert.equal(ghostMapsFileTitle('S2Underground_A__B.kmz'), 'A B');
});
test('the branch head comes from the smart-HTTP ref advertisement', () => {
const head = '142d7630bc8f1f2c4b96e16ee865ca50d1ab578d';
const other = 'b'.repeat(40);
const text = [
'001e# service=git-upload-pack',
`0159${head} HEAD\0multi_ack symref=HEAD:refs/heads/main`,
`003f${other} refs/heads/main-old`,
`003d${head} refs/heads/main`,
'0000',
].join('\n');
assert.equal(parseGitRefAdvertisement(text), head);
assert.equal(parseGitRefAdvertisement(text, 'dev'), null);
assert.equal(parseGitRefAdvertisement(''), null);
});