Files
gods-eye-view/src/data/cctvNswSource.test.mjs
T
12790b36c6 feat(cctv): seven camera packs, semantic labels, terrain-clear monitor planes (#433)
Seven contributed CCTV camera packs (Ontario 511, Fintraffic Finland, DriveBC, TxDOT Texas, Estonia Tallinn + Tarktee, Warendorf, Live Traffic NSW) on a fair per-pack catalog cap; semantic camera labels; monitor planes lifted clear of the terrain from a precomputed, bundled ground-height dataset. Default catalog 800 → 3,446 cameras. Full context in PR #433.

Co-authored-by: sendmebits <[email protected]>
Co-authored-by: avocadoAgent <[email protected]>
Co-authored-by: Alex Harvey <[email protected]>
Co-authored-by: Jason Meredith <[email protected]>
Co-authored-by: Daniel Smith <[email protected]>
Co-authored-by: Vladimir Sobolev <[email protected]>
Co-authored-by: Matthias Schneider <[email protected]>
Co-authored-by: Cyber Knight <[email protected]>
Co-authored-by: NovaSoft Australia <[email protected]>
2026-09-13 21:48:33 -05:00

197 lines
6.1 KiB
JavaScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import {
loadNswSourcesFromOpenData,
nswCameraLabel,
nswCameraToSource,
} from '../../server/providers/cctv/sources.js';
import {
cctvUpstreamUserAgent,
fetchCctvImageFromUpstream,
} from '../../server/providers/cctv/media.js';
import {
NSW_CAMERAS_URL,
NSW_IMAGE_USER_AGENT,
} from '../../server/providers/cctv/constants.js';
const feature = (overrides = {}, props = {}) => ({
type: 'Feature',
id: '5_ways_miranda',
geometry: { type: 'Point', coordinates: [151.1036, -34.0337] },
properties: {
region: 'SYD_SOUTH',
title: '5 Ways (Miranda)',
view: '5 Ways at The Boulevarde looking west towards Sutherland.',
direction: 'W',
href: 'https://webcams.transport.nsw.gov.au/livetraffic-webcams/cameras/5_ways_miranda.jpeg',
...props,
},
...overrides,
});
test('NSW label prefers the view sentence and falls back to the title for works notices', () => {
assert.equal(
nswCameraLabel({ title: '5 Ways (Miranda)', view: '5 Ways looking west.' }),
'5 Ways looking west.',
);
assert.equal(
nswCameraLabel({ title: 'Victoria Pass', view: 'x'.repeat(200) }),
'Victoria Pass',
);
assert.equal(nswCameraLabel({ title: 'T', view: 'line one\nline two' }), 'T');
assert.equal(nswCameraLabel({}), '');
});
test('NSW feature maps to a source with a compass heading and a pinned image host', () => {
const source = nswCameraToSource(feature({}, { direction: 'N-E' }));
assert.equal(source.id, 'nsw-5_ways_miranda');
assert.equal(source.city, 'SYD SOUTH');
assert.equal(source.provider, 'Live Traffic NSW');
assert.equal(source.lat, -34.0337);
assert.equal(source.lon, 151.1036);
assert.equal(source.headingDeg, 45);
assert.equal(source.headingConfidence, 'high');
assert.equal(source.sourceKind, 'nsw-livetraffic');
assert.match(source.license, /CC BY 4.0/);
assert.equal(source.url, source.snapshotUrl);
});
test('NSW mapping rejects off-host images and unusable geometry', () => {
assert.equal(
nswCameraToSource(feature({}, { href: 'https://evil.example/x.jpeg' })),
null,
);
assert.equal(nswCameraToSource(feature({ geometry: null })), null);
assert.equal(nswCameraToSource(feature({ id: '' })), null);
const noBearing = nswCameraToSource(feature({}, { direction: '' }));
assert.equal(noBearing.headingConfidence, 'low');
assert.ok(Number.isFinite(noBearing.headingDeg));
});
test('NSW loader reads the keyless feed and caps around Sydney', async (t) => {
t.mock.method(console, 'log', () => {});
const requested = [];
t.mock.method(globalThis, 'fetch', async (url) => {
requested.push(String(url));
return Response.json({
type: 'FeatureCollection',
features: [
feature(),
feature({ id: 'other' }, { href: 'https://evil.example/x.jpeg' }),
],
});
});
const cameras = await loadNswSourcesFromOpenData();
assert.deepEqual(requested, [NSW_CAMERAS_URL]);
assert.deepEqual(
cameras.map((camera) => camera.id),
['nsw-5_ways_miranda'],
);
});
test('the browser User-Agent applies to the NSW image host only', async () => {
assert.equal(
cctvUpstreamUserAgent(
'https://webcams.transport.nsw.gov.au/livetraffic-webcams/cameras/x.jpeg',
),
NSW_IMAGE_USER_AGENT,
);
assert.equal(
cctvUpstreamUserAgent(
'https://webcams.transport.nsw.gov.au.evil.test/x.jpeg',
),
'gods-eye-view-cctv-proxy/1.0',
);
assert.equal(
cctvUpstreamUserAgent(
'https://example.test/webcams.transport.nsw.gov.au/x.jpeg',
),
'gods-eye-view-cctv-proxy/1.0',
);
assert.equal(
cctvUpstreamUserAgent('not a url'),
'gods-eye-view-cctv-proxy/1.0',
);
const seen = [];
await fetchCctvImageFromUpstream(
'https://cctv.austinmobility.io/image/1.jpg',
{
timeoutMs: 100,
fetchImpl: async (url, init) => {
seen.push(init.headers['User-Agent']);
return new Response(Buffer.from([0xff, 0xd8, 0xff]), {
headers: { 'Content-Type': 'image/jpeg' },
});
},
},
);
assert.deepEqual(seen, ['gods-eye-view-cctv-proxy/1.0']);
});
test('the frame path follows redirects within the host only', async () => {
const jpeg = () =>
new Response(Buffer.from([0xff, 0xd8, 0xff]), {
headers: { 'Content-Type': 'image/jpeg' },
});
const redirect = (location) =>
new Response(null, { status: 302, headers: { location } });
const start = 'https://cctv.austinmobility.io/image/1.jpg';
const sameHost = [];
const followed = await fetchCctvImageFromUpstream(start, {
timeoutMs: 100,
fetchImpl: async (url, init) => {
assert.equal(init.redirect, 'manual', 'the fetch itself never follows');
sameHost.push(url);
return sameHost.length === 1 ? redirect('/image/moved/1.jpg') : jpeg();
},
});
assert.equal(followed?.ok, true);
assert.deepEqual(sameHost, [
start,
'https://cctv.austinmobility.io/image/moved/1.jpg',
]);
const offHost = [];
const refused = await fetchCctvImageFromUpstream(start, {
timeoutMs: 100,
fetchImpl: async (url) => {
offHost.push(url);
return redirect('https://evil.example/1.jpg');
},
});
assert.equal(refused, null);
assert.deepEqual(offHost, [start], 'the off-host target is never requested');
// Same host on another port, a plaintext downgrade, and a protocol-relative
// other host are all a different origin and are refused.
for (const target of [
'https://cctv.austinmobility.io:8443/image/1.jpg',
'http://cctv.austinmobility.io/image/1.jpg',
'//evil.example/1.jpg',
]) {
const seen = [];
const result = await fetchCctvImageFromUpstream(start, {
timeoutMs: 100,
fetchImpl: async (url) => {
seen.push(url);
return redirect(target);
},
});
assert.equal(result, null, target);
assert.deepEqual(seen, [start], target);
}
let hops = 0;
const looped = await fetchCctvImageFromUpstream(start, {
timeoutMs: 100,
fetchImpl: async () => {
hops += 1;
return redirect('/image/again.jpg');
},
});
assert.equal(looped, null);
assert.equal(hops, 3, 'at most two redirect hops are followed');
});