File size: 7,958 Bytes
ec8acdf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | import { describe, it, afterEach } from 'node:test';
import assert from 'node:assert/strict';
import { parseCallsign, toIataCallsign, icaoToIata } from '../server/_shared/airline-codes.ts';
import { getWingbitsLiveFlight } from '../server/worldmonitor/military/v1/get-wingbits-live-flight.ts';
const ECS_BASE = 'https://ecs-api.wingbits.com/v1/flights';
const PHOTOS_BASE = 'https://api.planespotters.net/pub/photos/hex';
const originalFetch = globalThis.fetch;
function jsonResp(data, status = 200) {
return new Response(JSON.stringify(data), {
status,
headers: { 'content-type': 'application/json' },
});
}
describe('parseCallsign', () => {
it('parses standard 3-letter ICAO prefix + number', () => {
assert.deepEqual(parseCallsign('UAE528'), { prefix: 'UAE', number: '528' });
assert.deepEqual(parseCallsign('BAW61'), { prefix: 'BAW', number: '61' });
assert.deepEqual(parseCallsign('EZY13BU'), { prefix: 'EZY', number: '13BU' });
assert.deepEqual(parseCallsign('DAL123'), { prefix: 'DAL', number: '123' });
});
it('parses 2-letter prefixes', () => {
assert.deepEqual(parseCallsign('LH123'), { prefix: 'LH', number: '123' });
});
it('parses 4-letter prefixes', () => {
assert.deepEqual(parseCallsign('DUKE41'), { prefix: 'DUKE', number: '41' });
});
it('normalizes whitespace', () => {
assert.deepEqual(parseCallsign(' UAE528 '), { prefix: 'UAE', number: '528' });
});
it('normalizes to uppercase', () => {
assert.deepEqual(parseCallsign('uae528'), { prefix: 'UAE', number: '528' });
assert.deepEqual(parseCallsign('ezy13bu'), { prefix: 'EZY', number: '13BU' });
});
it('returns null for callsigns starting with letter+digit (N-numbers)', () => {
assert.equal(parseCallsign('N123AB'), null);
});
it('returns null for empty string', () => {
assert.equal(parseCallsign(''), null);
});
it('returns null for whitespace-only', () => {
assert.equal(parseCallsign(' '), null);
});
it('returns null for pure alpha (no number suffix)', () => {
assert.equal(parseCallsign('ABCD'), null);
});
});
describe('icaoToIata', () => {
it('returns IATA mapping for known prefixes', () => {
assert.deepEqual(icaoToIata('UAE'), { iata: 'EK', name: 'Emirates' });
assert.deepEqual(icaoToIata('BAW'), { iata: 'BA', name: 'British Airways' });
assert.deepEqual(icaoToIata('EZY'), { iata: 'U2', name: 'easyJet' });
assert.deepEqual(icaoToIata('SWR'), { iata: 'LX', name: 'Swiss International Air Lines' });
assert.deepEqual(icaoToIata('TGW'), { iata: 'TR', name: 'Scoot' });
});
it('is case-insensitive', () => {
assert.deepEqual(icaoToIata('uae'), { iata: 'EK', name: 'Emirates' });
assert.deepEqual(icaoToIata('Baw'), { iata: 'BA', name: 'British Airways' });
});
it('returns undefined for unknown prefixes', () => {
assert.equal(icaoToIata('DUKE'), undefined);
assert.equal(icaoToIata('ELK'), undefined);
assert.equal(icaoToIata('XYZ'), undefined);
assert.equal(icaoToIata(''), undefined);
});
});
describe('toIataCallsign', () => {
it('converts ICAO callsign to IATA equivalent', () => {
assert.deepEqual(toIataCallsign('UAE528'), { callsign: 'EK528', name: 'Emirates' });
assert.deepEqual(toIataCallsign('BAW61'), { callsign: 'BA61', name: 'British Airways' });
assert.deepEqual(toIataCallsign('EZY13BU'), { callsign: 'U213BU', name: 'easyJet' });
assert.deepEqual(toIataCallsign('THY123'), { callsign: 'TK123', name: 'Turkish Airlines' });
assert.deepEqual(toIataCallsign('SWR42'), { callsign: 'LX42', name: 'Swiss International Air Lines' });
assert.deepEqual(toIataCallsign('TGW42'), { callsign: 'TR42', name: 'Scoot' });
});
it('handles whitespace and lowercase input', () => {
assert.deepEqual(toIataCallsign(' uae528 '), { callsign: 'EK528', name: 'Emirates' });
});
it('returns null for unknown ICAO prefix (military/charter)', () => {
assert.equal(toIataCallsign('DUKE41'), null);
assert.equal(toIataCallsign('RCH123'), null);
});
it('returns null for non-standard format', () => {
assert.equal(toIataCallsign('N123AB'), null);
});
it('returns null for empty or whitespace input', () => {
assert.equal(toIataCallsign(''), null);
assert.equal(toIataCallsign(' '), null);
});
});
describe('getWingbitsLiveFlight — IATA schedule fallback', () => {
afterEach(() => {
globalThis.fetch = originalFetch;
});
it('falls back to IATA callsign when ICAO schedule returns 404, populates airline fields', async () => {
const fetchedUrls = [];
globalThis.fetch = async (url) => {
const u = url.toString();
fetchedUrls.push(u);
// Live flight endpoint
if (u === `${ECS_BASE}/ae1234`) {
return jsonResp({
flight: { h: 'ae1234', f: 'UAE528', la: 25.2, lo: 55.3, ab: 35000, gs: 500, tr: 180, rs: 0, og: false, ra: '2024-01-01T12:00:00Z' },
});
}
// ICAO schedule — miss
if (u === `${ECS_BASE}/schedule/UAE528`) {
return new Response('Not Found', { status: 404 });
}
// IATA schedule fallback — hit
if (u === `${ECS_BASE}/schedule/EK528`) {
return jsonResp({
schedule: { depIata: 'DXB', arrIata: 'LHR', depTimeUtc: '2024-01-01T10:00:00Z', arrTimeUtc: '2024-01-01T18:00:00Z', status: 'en-route', duration: 480 },
});
}
// Photo — skip cleanly
if (u.startsWith(PHOTOS_BASE)) {
return new Response('Not Found', { status: 404 });
}
return new Response('Unexpected URL', { status: 500 });
};
const result = await getWingbitsLiveFlight({}, { icao24: 'ae1234' });
assert.ok(result.flight, 'flight should be present');
// Airline fields populated from ICAO→IATA lookup
assert.equal(result.flight.callsignIata, 'EK528');
assert.equal(result.flight.airlineName, 'Emirates');
// Schedule populated via IATA fallback
assert.equal(result.flight.depIata, 'DXB');
assert.equal(result.flight.arrIata, 'LHR');
assert.equal(result.flight.flightStatus, 'en-route');
assert.equal(result.flight.flightDurationMin, 480);
// IATA fallback URL was fetched (not just ICAO)
assert.ok(fetchedUrls.some(u => u.includes('/schedule/EK528')), 'should have fetched IATA schedule');
// Cache key uses ICAO callsign (uppercase), not IATA
assert.ok(fetchedUrls.some(u => u.includes('/schedule/UAE528')), 'should have tried ICAO schedule first');
});
it('uses ICAO schedule when available, skips IATA fallback', async () => {
const fetchedUrls = [];
globalThis.fetch = async (url) => {
const u = url.toString();
fetchedUrls.push(u);
if (u === `${ECS_BASE}/ae1234`) {
return jsonResp({
flight: { h: 'ae1234', f: 'UAE528', la: 25.2, lo: 55.3, ab: 35000, gs: 500, tr: 180, rs: 0, og: false, ra: '2024-01-01T12:00:00Z' },
});
}
if (u === `${ECS_BASE}/schedule/UAE528`) {
return jsonResp({ schedule: { depIata: 'DXB', arrIata: 'LHR', status: 'en-route', duration: 480 } });
}
if (u.startsWith(PHOTOS_BASE)) return new Response('Not Found', { status: 404 });
return new Response('Unexpected URL', { status: 500 });
};
const result = await getWingbitsLiveFlight({}, { icao24: 'ae1234' });
assert.ok(result.flight);
assert.equal(result.flight.depIata, 'DXB');
// IATA fallback should NOT have been fetched
assert.ok(!fetchedUrls.some(u => u.includes('/schedule/EK528')), 'should not fetch IATA schedule when ICAO succeeds');
});
it('returns no flight for unknown icao24', async () => {
const result = await getWingbitsLiveFlight({}, { icao24: '' });
assert.equal(result.flight, undefined);
});
it('returns no flight for invalid icao24 format', async () => {
const result = await getWingbitsLiveFlight({}, { icao24: 'ZZZZZZ' });
assert.equal(result.flight, undefined);
});
});
|