mirror of
https://github.com/jason5ng32/MyIP.git
synced 2026-11-04 18:23:27 +00:00
The backend downloaded every missing dataset before listening, so a first boot (or a newly added dataset) refused every request for a minute or more. Snapshots already on disk now load before the listener opens and missing ones download behind it. Meanwhile only routes reading still-missing data answer 503 (never edge-cached): /api/maxmind, /api/asn-connectivity and /api/service-status. An ASN Profile section whose data is still loading answers 'error' on its own, and the connectivity graph client doesn't cache a 503, so both recover once the data lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
87 lines
3.0 KiB
JavaScript
87 lines
3.0 KiB
JavaScript
// Tests for common/offline-data.js — the boot window, the per-route 503
|
|
// gate and the per-part isStillLoading probe.
|
|
|
|
import assert from 'node:assert/strict';
|
|
import { describe, it } from 'node:test';
|
|
|
|
import { runOfflineBootstrap, requireOfflineData, isStillLoading } from '../common/offline-data.js';
|
|
|
|
const makeRes = () => ({
|
|
statusCode: null,
|
|
body: null,
|
|
headers: {},
|
|
setHeader(name, value) { this.headers[name] = value; },
|
|
status(code) { this.statusCode = code; return this; },
|
|
json(payload) { this.body = payload; return this; },
|
|
});
|
|
|
|
// Run a gate once; true when it passed the request on.
|
|
const passes = (gate) => {
|
|
let passed = false;
|
|
const res = makeRes();
|
|
gate({ query: {} }, res, () => { passed = true; });
|
|
return { passed, res };
|
|
};
|
|
|
|
// Hold the boot window open while `fn` runs, then close it.
|
|
const duringBoot = async (fn) => {
|
|
let release;
|
|
const boot = runOfflineBootstrap([() => new Promise((resolve) => { release = resolve; })]);
|
|
try {
|
|
await fn();
|
|
} finally {
|
|
release();
|
|
await boot;
|
|
}
|
|
};
|
|
|
|
const ready = () => true;
|
|
const missing = () => false;
|
|
|
|
describe('requireOfflineData', () => {
|
|
it('passes everything outside the boot window, missing data included', () => {
|
|
assert.equal(passes(requireOfflineData([missing])).passed, true);
|
|
});
|
|
|
|
it('answers 503 + Retry-After during boot while a dataset is missing', async () => {
|
|
await duringBoot(() => {
|
|
const { passed, res } = passes(requireOfflineData([ready, missing]));
|
|
assert.equal(passed, false);
|
|
assert.equal(res.statusCode, 503);
|
|
assert.equal(res.headers['Retry-After'], '30');
|
|
assert.deepEqual(res.body, { error: 'Offline data is loading' });
|
|
});
|
|
});
|
|
|
|
it('passes during boot once every dataset the route reads is loaded', async () => {
|
|
await duringBoot(() => {
|
|
assert.equal(passes(requireOfflineData([ready, ready])).passed, true);
|
|
assert.equal(passes(requireOfflineData([])).passed, true);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('isStillLoading', () => {
|
|
it('is true only inside the boot window, for unready data', async () => {
|
|
assert.equal(isStillLoading(missing), false, 'after boot a miss is a failed download');
|
|
await duringBoot(() => {
|
|
assert.equal(isStillLoading(ready, missing), true);
|
|
assert.equal(isStillLoading(ready), false);
|
|
assert.equal(isStillLoading(), false);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('runOfflineBootstrap', () => {
|
|
it('closes the window after every step settles, a throwing one included', async () => {
|
|
const gate = requireOfflineData([missing]);
|
|
let duringSteps;
|
|
await runOfflineBootstrap([
|
|
async () => { throw new Error('download failed'); },
|
|
async () => { duringSteps = passes(gate).passed; },
|
|
]);
|
|
assert.equal(duringSteps, false);
|
|
assert.equal(passes(gate).passed, true);
|
|
});
|
|
});
|