mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
style: format satellite and launch provider modules
This commit is contained in:
1 parent
9a4b98700e
commit
290afd808d
6 files changed
+163
-69
No files matched your search
@@ -1,22 +1,48 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { promises as fsp } from 'node:fs';
|
||||
import { celestrakProxy, rocketLaunchesProxy, launchLibraryRequestHeaders, LL2_CACHE_TTL_MS } from 'gods-eye-view/server/providers/space';
|
||||
import { celestrakTleUrl, launchLibraryRecentUrl } from 'gods-eye-view/sources/space';
|
||||
import {
|
||||
celestrakProxy,
|
||||
rocketLaunchesProxy,
|
||||
launchLibraryRequestHeaders,
|
||||
LL2_CACHE_TTL_MS,
|
||||
} from 'gods-eye-view/server/providers/space';
|
||||
import {
|
||||
celestrakTleUrl,
|
||||
launchLibraryRecentUrl,
|
||||
} from 'gods-eye-view/sources/space';
|
||||
import * as compatibility from '../../server/providers/local.js';
|
||||
|
||||
function install(plugin, preview = false) {
|
||||
const routes = new Map();
|
||||
plugin[preview ? 'configurePreviewServer' : 'configureServer']({ middlewares: { use(route, handler) { routes.set(route, handler); } } });
|
||||
plugin[preview ? 'configurePreviewServer' : 'configureServer']({
|
||||
middlewares: {
|
||||
use(route, handler) {
|
||||
routes.set(route, handler);
|
||||
},
|
||||
},
|
||||
});
|
||||
return async (route, url = '/', method = 'GET') => {
|
||||
const res = { headersSent: false, writeHead(status, headers) { Object.assign(this, { status, headers, headersSent: true }); }, end(body) { this.body = body; } };
|
||||
const res = {
|
||||
headersSent: false,
|
||||
writeHead(status, headers) {
|
||||
Object.assign(this, { status, headers, headersSent: true });
|
||||
},
|
||||
end(body) {
|
||||
this.body = body;
|
||||
},
|
||||
};
|
||||
await routes.get(route)({ url, method }, res);
|
||||
return res;
|
||||
};
|
||||
}
|
||||
function isolateDisk(t) {
|
||||
t.mock.method(fsp, 'readFile', async () => { throw Error('no cache'); });
|
||||
t.mock.method(fsp, 'stat', async () => { throw Error('no cache'); });
|
||||
t.mock.method(fsp, 'readFile', async () => {
|
||||
throw Error('no cache');
|
||||
});
|
||||
t.mock.method(fsp, 'stat', async () => {
|
||||
throw Error('no cache');
|
||||
});
|
||||
t.mock.method(fsp, 'mkdir', async () => {});
|
||||
t.mock.method(fsp, 'writeFile', async () => {});
|
||||
}
|
||||
@@ -31,12 +57,20 @@ test('portable requests keep fixed origins, encode group data and preserve the 3
|
||||
const url = launchLibraryRecentUrl(end);
|
||||
assert.equal(url.origin, 'https://ll.thespacedevs.com');
|
||||
assert.equal(url.pathname, '/2.3.0/launches/');
|
||||
assert.deepEqual(Object.fromEntries(url.searchParams), { net__gte: '2026-01-30T12:34:56.000Z', net__lte: '2026-03-01T12:34:56.000Z', limit: '100', mode: 'detailed' });
|
||||
assert.deepEqual(Object.fromEntries(url.searchParams), {
|
||||
net__gte: '2026-01-30T12:34:56.000Z',
|
||||
net__lte: '2026-03-01T12:34:56.000Z',
|
||||
limit: '100',
|
||||
mode: 'detailed',
|
||||
});
|
||||
assert.equal(end.toISOString(), '2026-03-01T12:34:56.000Z');
|
||||
});
|
||||
|
||||
test('compatibility exports retain the same LL2 header helper and TTL', () => {
|
||||
assert.equal(compatibility.launchLibraryRequestHeaders, launchLibraryRequestHeaders);
|
||||
assert.equal(
|
||||
compatibility.launchLibraryRequestHeaders,
|
||||
launchLibraryRequestHeaders,
|
||||
);
|
||||
assert.equal(compatibility.LL2_CACHE_TTL_MS, LL2_CACHE_TTL_MS);
|
||||
});
|
||||
|
||||
@@ -46,8 +80,11 @@ test('exported CelesTrak plugin coalesces refreshes, retains stale TLEs, and rea
|
||||
t.mock.method(Date, 'now', () => now);
|
||||
t.mock.method(console, 'warn', () => {});
|
||||
const tle = 'ISS\n1 25544U fixture\n2 25544 fixture';
|
||||
let calls = 0, release;
|
||||
const gate = new Promise(resolve => { release = resolve; });
|
||||
let calls = 0,
|
||||
release;
|
||||
const gate = new Promise((resolve) => {
|
||||
release = resolve;
|
||||
});
|
||||
t.mock.method(globalThis, 'fetch', async (url) => {
|
||||
calls++;
|
||||
assert.equal(new URL(url).searchParams.get('GROUP'), 'stations');
|
||||
@@ -60,40 +97,52 @@ test('exported CelesTrak plugin coalesces refreshes, retains stale TLEs, and rea
|
||||
const first = request('/api/celestrak', '/stations');
|
||||
const second = request('/api/celestrak', '/stations');
|
||||
release();
|
||||
for(const res of await Promise.all([first, second])) assert.equal(res.body, tle);
|
||||
for (const res of await Promise.all([first, second]))
|
||||
assert.equal(res.body, tle);
|
||||
assert.equal(calls, 1);
|
||||
assert.equal((await request('/api/celestrak', '/stations')).headers['x-tle-cache'], 'HIT');
|
||||
assert.equal(
|
||||
(await request('/api/celestrak', '/stations')).headers['x-tle-cache'],
|
||||
'HIT',
|
||||
);
|
||||
now += 6 * 3600_000;
|
||||
t.mock.method(globalThis, 'fetch', async () => new Response('not a TLE'));
|
||||
const stale = await request('/api/celestrak', '/stations');
|
||||
assert.equal(stale.body, tle);
|
||||
assert.equal(stale.headers['x-tle-cache'], 'STALE-ERROR');
|
||||
t.mock.method(fsp, 'readFile', async () => JSON.stringify({ at: now, body: tle }));
|
||||
t.mock.method(globalThis, 'fetch', async () => { throw Error('fresh disk must prevent fetch'); });
|
||||
t.mock.method(fsp, 'readFile', async () =>
|
||||
JSON.stringify({ at: now, body: tle }),
|
||||
);
|
||||
t.mock.method(globalThis, 'fetch', async () => {
|
||||
throw Error('fresh disk must prevent fetch');
|
||||
});
|
||||
const disk = await install(celestrakProxy())('/api/celestrak', '/stations');
|
||||
assert.equal(disk.headers['x-tle-cache'], 'HIT');
|
||||
assert.equal(disk.body, tle);
|
||||
});
|
||||
|
||||
for(const preview of [false, true]) test(`exported launch plugin preserves optional server auth and cache in ${preview ? 'preview' : 'development'}`, async (t) => {
|
||||
isolateDisk(t);
|
||||
const prior = process.env.LL2_API_TOKEN;
|
||||
t.after(() => { if (prior === undefined) delete process.env.LL2_API_TOKEN; else process.env.LL2_API_TOKEN = prior; });
|
||||
process.env.LL2_API_TOKEN = ' fixture-token ';
|
||||
let calls = 0;
|
||||
t.mock.method(globalThis, 'fetch', async (url, options) => {
|
||||
calls++;
|
||||
assert.equal(url.searchParams.get('limit'), '100');
|
||||
assert.equal(options.headers.Authorization, 'Token fixture-token');
|
||||
return Response.json({ results: [{ id: 'launch-fixture' }] });
|
||||
for (const preview of [false, true])
|
||||
test(`exported launch plugin preserves optional server auth and cache in ${preview ? 'preview' : 'development'}`, async (t) => {
|
||||
isolateDisk(t);
|
||||
const prior = process.env.LL2_API_TOKEN;
|
||||
t.after(() => {
|
||||
if (prior === undefined) delete process.env.LL2_API_TOKEN;
|
||||
else process.env.LL2_API_TOKEN = prior;
|
||||
});
|
||||
process.env.LL2_API_TOKEN = ' fixture-token ';
|
||||
let calls = 0;
|
||||
t.mock.method(globalThis, 'fetch', async (url, options) => {
|
||||
calls++;
|
||||
assert.equal(url.searchParams.get('limit'), '100');
|
||||
assert.equal(options.headers.Authorization, 'Token fixture-token');
|
||||
return Response.json({ results: [{ id: 'launch-fixture' }] });
|
||||
});
|
||||
const request = install(rocketLaunchesProxy(), preview);
|
||||
assert.equal((await request('/api/launches', '/', 'POST')).status, 405);
|
||||
const first = await request('/api/launches');
|
||||
assert.equal(first.headers['X-GEV-Cache'], 'MISS');
|
||||
assert.doesNotMatch(first.body, /fixture-token/);
|
||||
const hit = await request('/api/launches');
|
||||
assert.equal(hit.headers['X-GEV-Cache'], 'HIT');
|
||||
assert.equal(hit.body, first.body);
|
||||
assert.equal(calls, 1);
|
||||
});
|
||||
const request = install(rocketLaunchesProxy(), preview);
|
||||
assert.equal((await request('/api/launches', '/', 'POST')).status, 405);
|
||||
const first = await request('/api/launches');
|
||||
assert.equal(first.headers['X-GEV-Cache'], 'MISS');
|
||||
assert.doesNotMatch(first.body, /fixture-token/);
|
||||
const hit = await request('/api/launches');
|
||||
assert.equal(hit.headers['X-GEV-Cache'], 'HIT');
|
||||
assert.equal(hit.body, first.body);
|
||||
assert.equal(calls, 1);
|
||||
});
|
||||
Reference in new issue
Block a user