mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
317 lines
11 KiB
JavaScript
317 lines
11 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { readFileSync } from 'node:fs';
|
|
import vm from 'node:vm';
|
|
import { createGoogleTokenSource } from './maps/googleTokens.js';
|
|
import {
|
|
loadPhotorealisticTileset,
|
|
selectMapStartupRoute,
|
|
} from './mapStartup.js';
|
|
|
|
function fakeCesium(outcomes = []) {
|
|
const calls = [];
|
|
const next = () => {
|
|
const outcome = outcomes.shift();
|
|
if (outcome instanceof Error) throw outcome;
|
|
return outcome;
|
|
};
|
|
return {
|
|
calls,
|
|
Ion: { defaultAccessToken: undefined },
|
|
GoogleMaps: {
|
|
defaultApiKey: undefined,
|
|
mapTilesApiEndpoint: 'https://tile.googleapis.com/',
|
|
getDefaultCredit: () => undefined,
|
|
},
|
|
Resource: class {
|
|
constructor(options) {
|
|
Object.assign(this, options);
|
|
}
|
|
},
|
|
async createGooglePhotorealistic3DTileset(options) {
|
|
calls.push({ options, googleKey: options.key });
|
|
return next();
|
|
},
|
|
IonResource: {
|
|
async fromAssetId(assetId, options) {
|
|
return { assetId, ...options };
|
|
},
|
|
},
|
|
Cesium3DTileset: {
|
|
async fromUrl(resource, options) {
|
|
calls.push({
|
|
options,
|
|
resource,
|
|
ionToken: resource.accessToken,
|
|
assetId: resource.assetId,
|
|
});
|
|
return next();
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
async function standaloneStartup(Cesium, credentials, fetchImpl) {
|
|
// Exercise the actual assembly; replace browser-only imports at its scene seam.
|
|
const source = readFileSync(
|
|
new URL('./standalone/application.js', import.meta.url),
|
|
'utf8',
|
|
)
|
|
// Imports may span lines (`import {\n a,\n b,\n} from '…';`).
|
|
.replace(/^import [^;]*;\n/gm, '')
|
|
.replace(/^export /gm, '');
|
|
const context = vm.createContext({
|
|
document: {
|
|
getElementById: () => ({ querySelector: () => ({}) }),
|
|
},
|
|
resolveLocale: () => 'en',
|
|
setLocale() {},
|
|
getLocale: () => 'en',
|
|
onLocaleChange: () => () => {},
|
|
mountApplicationViews() {},
|
|
applyDocumentLanguage() {},
|
|
applyDocumentTranslations() {},
|
|
CITY_POIS: [],
|
|
createApplication: (options) => options,
|
|
createStandalonePlaceSearch: () => ({}),
|
|
createStandaloneCatalog: () => ({}),
|
|
createGoogleTokenSource: () => createGoogleTokenSource({ fetchImpl }),
|
|
selectMapStartupRoute,
|
|
// The real scene forwards these credentials to this same loader.
|
|
createStandaloneScene: async (options) => ({
|
|
...(await loadPhotorealisticTileset(Cesium, options)),
|
|
operations: {},
|
|
}),
|
|
});
|
|
vm.runInContext(source, context);
|
|
const app = context.createStandaloneApplication(credentials);
|
|
// The application passes each constructor its signal and defer(cleanup).
|
|
return app.createScene({ signal: new AbortController().signal, defer() {} });
|
|
}
|
|
|
|
test('standalone falls back to ion when the server token route is unavailable', async () => {
|
|
const tileset = { id: 'ion' };
|
|
const Cesium = fakeCesium([tileset]);
|
|
const requests = [];
|
|
const result = await standaloneStartup(
|
|
Cesium,
|
|
{ cesiumToken: 'ion-fixture' },
|
|
async (url) => {
|
|
requests.push(url);
|
|
return { ok: false };
|
|
},
|
|
);
|
|
assert.equal(result.route, 'google-ion');
|
|
assert.equal(result.tileset, tileset);
|
|
assert.deepEqual(requests, ['/api/google/tiles-token']);
|
|
assert.equal(result.errors.length, 1);
|
|
assert.equal(Cesium.calls[0].assetId, 2275207);
|
|
});
|
|
|
|
test('standalone uses server tokens without a browser key and preserves keyless fallback', async () => {
|
|
const tileset = { id: 'server-token' };
|
|
const Cesium = fakeCesium([tileset]);
|
|
const requests = [];
|
|
const result = await standaloneStartup(Cesium, {}, async (url) => {
|
|
requests.push(url);
|
|
return {
|
|
ok: true,
|
|
json: async () => ({
|
|
accessToken: 'server-fixture',
|
|
expiresAt: Date.now() + 120_000,
|
|
}),
|
|
};
|
|
});
|
|
assert.equal(result.route, 'google-token');
|
|
assert.equal(result.tileset, tileset);
|
|
assert.deepEqual(requests, ['/api/google/tiles-token']);
|
|
assert.equal(
|
|
Cesium.calls[0].resource.headers.Authorization,
|
|
'Bearer server-fixture',
|
|
);
|
|
assert.deepEqual(result.errors, []);
|
|
const fallback = await standaloneStartup(fakeCesium(), {}, async () => ({
|
|
status: 204,
|
|
}));
|
|
assert.equal(fallback.route, 'osm');
|
|
assert.equal(fallback.tileset, null);
|
|
});
|
|
|
|
test('map startup route reflects the best configured provider', () => {
|
|
assert.equal(
|
|
selectMapStartupRoute({ googleApiKey: 'google', cesiumToken: 'ion' }),
|
|
'google-direct',
|
|
);
|
|
assert.equal(selectMapStartupRoute({ cesiumToken: 'ion' }), 'google-ion');
|
|
assert.equal(selectMapStartupRoute(), 'osm');
|
|
});
|
|
|
|
test('no credentials skip photoreal loading and preserve keyless startup', async () => {
|
|
const Cesium = fakeCesium();
|
|
const result = await loadPhotorealisticTileset(Cesium);
|
|
assert.equal(result.tileset, null);
|
|
assert.equal(result.route, 'osm');
|
|
assert.equal(Cesium.calls.length, 0);
|
|
});
|
|
|
|
test('a direct Google key is preferred', async () => {
|
|
const tileset = { id: 'direct' };
|
|
const Cesium = fakeCesium([tileset]);
|
|
let tokenRequests = 0;
|
|
const result = await standaloneStartup(
|
|
Cesium,
|
|
{
|
|
googleApiKey: 'google-secret',
|
|
cesiumToken: 'ion-secret',
|
|
},
|
|
async () => {
|
|
tokenRequests++;
|
|
return { status: 204 };
|
|
},
|
|
);
|
|
assert.equal(result.tileset, tileset);
|
|
assert.equal(result.route, 'google-direct');
|
|
assert.equal(Cesium.calls[0].googleKey, 'google-secret');
|
|
assert.equal(tokenRequests, 0);
|
|
});
|
|
|
|
test('an ion-only setup loads the hosted Google 3D asset', async () => {
|
|
const tileset = { id: 'ion' };
|
|
const Cesium = fakeCesium([tileset]);
|
|
const result = await loadPhotorealisticTileset(Cesium, {
|
|
cesiumToken: 'ion-secret',
|
|
});
|
|
assert.equal(result.tileset, tileset);
|
|
assert.equal(result.route, 'google-ion');
|
|
assert.equal(Cesium.calls.length, 1);
|
|
assert.equal(Cesium.calls[0].googleKey, undefined);
|
|
assert.equal(Cesium.calls[0].ionToken, 'ion-secret');
|
|
assert.equal(Cesium.Ion.defaultAccessToken, undefined);
|
|
assert.equal(Cesium.calls[0].assetId, 2275207);
|
|
assert.equal(Cesium.calls[0].options.enableCollision, true);
|
|
});
|
|
|
|
test('a failed direct request retries through ion before falling back', async () => {
|
|
const tileset = { id: 'ion-fallback' };
|
|
const Cesium = fakeCesium([new Error('direct denied'), tileset]);
|
|
const result = await loadPhotorealisticTileset(Cesium, {
|
|
googleApiKey: 'google-secret',
|
|
cesiumToken: 'ion-secret',
|
|
});
|
|
assert.equal(result.tileset, tileset);
|
|
assert.equal(result.route, 'google-ion');
|
|
assert.equal(result.errors.length, 1);
|
|
assert.equal(Cesium.calls[0].googleKey, 'google-secret');
|
|
assert.equal(Cesium.calls[1].googleKey, undefined);
|
|
assert.equal(Cesium.calls.length, 2);
|
|
});
|
|
|
|
test('a failed direct-only request does not consume an implicit Cesium token', async () => {
|
|
const Cesium = fakeCesium([new Error('direct denied')]);
|
|
const result = await loadPhotorealisticTileset(Cesium, {
|
|
googleApiKey: 'google-secret',
|
|
});
|
|
assert.equal(result.tileset, null);
|
|
assert.equal(result.route, 'osm');
|
|
assert.equal(result.errors.length, 1);
|
|
assert.equal(Cesium.calls.length, 1);
|
|
assert.equal(Cesium.calls[0].googleKey, 'google-secret');
|
|
assert.equal(Cesium.GoogleMaps.defaultApiKey, undefined);
|
|
});
|
|
|
|
test('failed direct and ion requests preserve the keyless OSM fallback', async () => {
|
|
const Cesium = fakeCesium([
|
|
new Error('direct denied'),
|
|
new Error('ion denied'),
|
|
]);
|
|
const result = await loadPhotorealisticTileset(Cesium, {
|
|
googleApiKey: 'google-secret',
|
|
cesiumToken: 'ion-secret',
|
|
});
|
|
assert.equal(result.tileset, null);
|
|
assert.equal(result.route, 'osm');
|
|
assert.equal(result.errors.length, 2);
|
|
assert.equal(Cesium.calls.length, 2);
|
|
assert.equal(Cesium.GoogleMaps.defaultApiKey, undefined);
|
|
});
|
|
|
|
test('independent source configurations never mutate shared SDK credentials', async () => {
|
|
const Cesium = fakeCesium([{ id: 'a' }, { id: 'b' }]);
|
|
Cesium.Ion.defaultAccessToken = 'untouched-ion';
|
|
Cesium.GoogleMaps.defaultApiKey = 'untouched-google';
|
|
await Promise.all([
|
|
loadPhotorealisticTileset(Cesium, { googleApiKey: 'source-a' }),
|
|
loadPhotorealisticTileset(Cesium, { cesiumToken: 'source-b' }),
|
|
]);
|
|
assert.equal(Cesium.calls[0].googleKey, 'source-a');
|
|
assert.equal(Cesium.calls[1].ionToken, 'source-b');
|
|
assert.equal(Cesium.Ion.defaultAccessToken, 'untouched-ion');
|
|
assert.equal(Cesium.GoogleMaps.defaultApiKey, 'untouched-google');
|
|
});
|
|
|
|
function tokenSource(...issued) {
|
|
const requests = [];
|
|
return {
|
|
requests,
|
|
async token(options = {}) {
|
|
requests.push(options);
|
|
return issued.shift() ?? null;
|
|
},
|
|
};
|
|
}
|
|
|
|
test('without a key, server tokens load Google 3D directly', async () => {
|
|
const tileset = { id: 'token' };
|
|
const Cesium = fakeCesium([tileset]);
|
|
const result = await loadPhotorealisticTileset(Cesium, {
|
|
googleTokens: tokenSource('short-lived'),
|
|
cesiumToken: 'ion-secret',
|
|
});
|
|
assert.equal(result.tileset, tileset);
|
|
assert.equal(result.route, 'google-token');
|
|
const { resource, options } = Cesium.calls[0];
|
|
assert.equal(
|
|
resource.url,
|
|
'https://tile.googleapis.com/v1/3dtiles/root.json',
|
|
);
|
|
assert.equal(resource.headers.Authorization, 'Bearer short-lived');
|
|
assert.equal(resource.queryParameters, undefined);
|
|
assert.equal(options.enableCollision, true);
|
|
});
|
|
|
|
test('a tile refused for an expired token retries once with a renewed one', async () => {
|
|
const Cesium = fakeCesium([{ id: 'token' }]);
|
|
const tokens = tokenSource('first', 'second');
|
|
await loadPhotorealisticTileset(Cesium, { googleTokens: tokens });
|
|
const { resource } = Cesium.calls[0];
|
|
const tile = { headers: { ...resource.headers } };
|
|
assert.equal(await resource.retryCallback(tile, { statusCode: 401 }), true);
|
|
assert.equal(tile.headers.Authorization, 'Bearer second');
|
|
assert.deepEqual(tokens.requests.at(-1), { replacing: 'first' });
|
|
assert.equal(resource.retryAttempts, 1);
|
|
assert.equal(await resource.retryCallback(tile, { statusCode: 500 }), false);
|
|
});
|
|
|
|
test('a key takes precedence over server tokens', async () => {
|
|
const Cesium = fakeCesium([{ id: 'direct' }]);
|
|
const tokens = tokenSource('short-lived');
|
|
const result = await loadPhotorealisticTileset(Cesium, {
|
|
googleApiKey: 'google-secret',
|
|
googleTokens: tokens,
|
|
});
|
|
assert.equal(result.route, 'google-direct');
|
|
assert.equal(tokens.requests.length, 0);
|
|
});
|
|
|
|
test('a server without tokens falls back to ion', async () => {
|
|
const tileset = { id: 'ion' };
|
|
const Cesium = fakeCesium([tileset]);
|
|
const result = await loadPhotorealisticTileset(Cesium, {
|
|
googleTokens: tokenSource(),
|
|
cesiumToken: 'ion-secret',
|
|
});
|
|
assert.equal(result.route, 'google-ion');
|
|
assert.equal(result.errors.length, 1);
|
|
assert.equal(Cesium.calls.length, 1);
|
|
});
|