const assert = require('node:assert/strict'); const test = require('node:test'); const { validatePassengerTelemetryPayload } = require('../src/services/passengerTelemetryValidator'); const NOW = new Date('2026-05-20T12:30:00Z'); test('validates and normalizes passenger telemetry payload', () => { const payload = validatePassengerTelemetryPayload({ session_id: ' temporary-anonymous-id ', latitude: '55.485', longitude: '28.768', accuracy_m: '18.5', speed_kmh: '32', heading: '91', observed_at: '2026-05-20T12:29:30Z', route_id: '12', stop_id: '123', app_state: 'foreground' }, { now: NOW }); assert.equal(payload.sessionId, 'temporary-anonymous-id'); assert.equal(payload.latitude, 55.485); assert.equal(payload.longitude, 28.768); assert.equal(payload.accuracyM, 18.5); assert.equal(payload.speedKmh, 32); assert.equal(payload.heading, 91); assert.equal(payload.routeId, 12); assert.equal(payload.stopId, 123); assert.equal(payload.appState, 'foreground'); }); test('rejects invalid latitude and longitude', () => { assert.throws(() => validatePassengerTelemetryPayload({ session_id: 's1', latitude: 91, longitude: 28.768 }, { now: NOW }), /latitude must be between -90 and 90/); assert.throws(() => validatePassengerTelemetryPayload({ session_id: 's1', latitude: 55.485, longitude: 181 }, { now: NOW }), /longitude must be between -180 and 180/); }); test('rejects stale and far-future observations', () => { assert.throws(() => validatePassengerTelemetryPayload({ session_id: 's1', latitude: 55.485, longitude: 28.768, observed_at: '2026-05-20T12:10:00Z' }, { now: NOW }), /observed_at is too old/); assert.throws(() => validatePassengerTelemetryPayload({ session_id: 's1', latitude: 55.485, longitude: 28.768, observed_at: '2026-05-20T12:40:00Z' }, { now: NOW }), /observed_at is too far in the future/); }); test('rejects implausible city transit speed', () => { assert.throws(() => validatePassengerTelemetryPayload({ session_id: 's1', latitude: 55.485, longitude: 28.768, speed_kmh: 180 }, { now: NOW }), /speed_kmh must be between 0 and 120/); });