mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-13 06:42:23 +00:00
Ignore a late image or error from a street-level provider the user switched away from
This commit is contained in:
1 parent
f7cd6797ec
commit
299a5943a0
2 files changed
+100
-2
No files matched your search
@@ -0,0 +1,91 @@
|
|||||||
|
// Edge cases from docs/migration/planet-separation/layers.md (street-level):
|
||||||
|
// without a paid source, a late answer from a provider the user switched away
|
||||||
|
// from is ignored and the lit provider keeps the panel.
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
import * as Cesium from 'cesium';
|
||||||
|
import { createStreetLevelLayer } from './index.js';
|
||||||
|
import {
|
||||||
|
fakeCesiumViewer,
|
||||||
|
fakeStreetLevelProvider as fakeProvider,
|
||||||
|
} from '../../testSupport/streetLevelFakes.mjs';
|
||||||
|
|
||||||
|
const settle = () => new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
|
|
||||||
|
function deferred() {
|
||||||
|
let resolve;
|
||||||
|
const promise = new Promise((done) => (resolve = done));
|
||||||
|
return { promise, resolve };
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Two keyless providers; the first answers its nearest lookup on demand. */
|
||||||
|
async function twoProviders(t) {
|
||||||
|
const saved = globalThis.document;
|
||||||
|
const drawing = new Proxy({}, { get: () => () => ({ addColorStop() {} }) });
|
||||||
|
globalThis.document = Object.assign(new EventTarget(), {
|
||||||
|
createElement: () => ({ getContext: () => drawing }),
|
||||||
|
});
|
||||||
|
t.mock.method(
|
||||||
|
Cesium.GroundPolylinePrimitive,
|
||||||
|
'initializeTerrainHeights',
|
||||||
|
async () => {},
|
||||||
|
);
|
||||||
|
const lookups = [];
|
||||||
|
const previous = fakeProvider({
|
||||||
|
nearestImage: (point, { signal } = {}) => {
|
||||||
|
const answer = deferred();
|
||||||
|
lookups.push({ point, signal, answer });
|
||||||
|
return answer.promise;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const lit = fakeProvider({
|
||||||
|
id: 'panoramax',
|
||||||
|
pickPrefix: 'pmx:',
|
||||||
|
nearestImage: async () => 'pmx-1',
|
||||||
|
});
|
||||||
|
const viewer = fakeCesiumViewer();
|
||||||
|
const layer = createStreetLevelLayer({ providers: [previous, lit] });
|
||||||
|
layer.init(viewer);
|
||||||
|
layer.enable(viewer);
|
||||||
|
layer.attachViewerHost({});
|
||||||
|
t.after(() => {
|
||||||
|
layer.destroy();
|
||||||
|
globalThis.document = saved;
|
||||||
|
});
|
||||||
|
await settle();
|
||||||
|
return { layer, previous, lit, lookups };
|
||||||
|
}
|
||||||
|
|
||||||
|
test('edge:street-level: a late nearest answer from the previous provider is ignored', async (t) => {
|
||||||
|
const { layer, previous, lit, lookups } = await twoProviders(t);
|
||||||
|
const stale = layer.openNearest({ lat: 38.58, lon: -121.49 });
|
||||||
|
await settle();
|
||||||
|
layer.setProviderEnabled('panoramax', true);
|
||||||
|
assert.equal(await layer.openNearest({ lat: 38.58, lon: -121.49 }), true);
|
||||||
|
lookups[0].answer.resolve('mly-late');
|
||||||
|
assert.equal(await stale, false);
|
||||||
|
await settle();
|
||||||
|
assert.deepEqual(previous.calls.open, []);
|
||||||
|
assert.deepEqual(lit.calls.open, ['pmx-1']);
|
||||||
|
const { street } = layer.getUIState();
|
||||||
|
assert.equal(street.providerId, 'panoramax');
|
||||||
|
assert.equal(street.error, null);
|
||||||
|
assert.equal(street.loading, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('edge:street-level: a switched-off provider cannot open an image or post an error late', async (t) => {
|
||||||
|
const { layer, previous, lit } = await twoProviders(t);
|
||||||
|
const late = previous.context().actions;
|
||||||
|
layer.setProviderEnabled('panoramax', true);
|
||||||
|
assert.equal(await layer.openNearest({ lat: 1, lon: 2 }), true);
|
||||||
|
// The darkened provider's own work (a sequence step, a cone it had queued)
|
||||||
|
// finishes after the switch.
|
||||||
|
assert.equal(await late.openImage('mly-late'), false);
|
||||||
|
late.reportError('Sequence images unavailable');
|
||||||
|
await settle();
|
||||||
|
assert.deepEqual(previous.calls.open, []);
|
||||||
|
assert.deepEqual(lit.calls.open, ['pmx-1']);
|
||||||
|
const { street } = layer.getUIState();
|
||||||
|
assert.equal(street.providerId, 'panoramax');
|
||||||
|
assert.equal(street.error, null);
|
||||||
|
});
|
||||||
@@ -100,9 +100,14 @@ export function createStreetLevelLayer({
|
|||||||
waitingForView: () => waitingForView,
|
waitingForView: () => waitingForView,
|
||||||
notify,
|
notify,
|
||||||
actions: {
|
actions: {
|
||||||
/** `{frame: false}` opens it without moving the camera. */
|
/**
|
||||||
|
* `{frame: false}` opens it without moving the camera. A provider
|
||||||
|
* switched off (or a layer turned off) answers late: ignored.
|
||||||
|
*/
|
||||||
openImage: (imageId, options) =>
|
openImage: (imageId, options) =>
|
||||||
openImage(entry.def.id, imageId, options),
|
state.enabled && entry.on
|
||||||
|
? openImage(entry.def.id, imageId, options)
|
||||||
|
: Promise.resolve(false),
|
||||||
/** This provider's image nearest a point the user picked on the map. */
|
/** This provider's image nearest a point the user picked on the map. */
|
||||||
openNearest: (point) =>
|
openNearest: (point) =>
|
||||||
layer.openNearest(point, {
|
layer.openNearest(point, {
|
||||||
@@ -115,6 +120,8 @@ export function createStreetLevelLayer({
|
|||||||
*/
|
*/
|
||||||
reportError: (message) => {
|
reportError: (message) => {
|
||||||
if (message) {
|
if (message) {
|
||||||
|
// Another source owns the panel now; its late failure is not news.
|
||||||
|
if (!state.enabled || !entry.on) return;
|
||||||
state.street.error = entry.reportedError = message;
|
state.street.error = entry.reportedError = message;
|
||||||
} else {
|
} else {
|
||||||
if (!entry.reportedError) return;
|
if (!entry.reportedError) return;
|
||||||
|
|||||||
Reference in new issue
Block a user