mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 18:34:02 +00:00
LocationControls (./ui/location) no longer builds the city and landmark pills or writes the mini status and the search error: it presents the tray and hands it to its publish option, so the entry stays Vue-free. The shell publishes it to a new gev-location store and connects the controls, and the dock renders it and calls chooseCity() and choosePoi(). The landmark row still expands a frame after its pills render. The search field, its toggle and the reset buttons keep their listeners. The location QA harness reads the rendered elements.
106 lines
3.3 KiB
JavaScript
106 lines
3.3 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { NavigationController } from './navigationController.js';
|
|
import { LocationNavigation } from './locationNavigation.js';
|
|
|
|
function input() {
|
|
const classes = new Set(['expanded', 'searching']);
|
|
const attributes = new Map();
|
|
return {
|
|
id: 'location-search',
|
|
value: 'Pariss',
|
|
focused: false,
|
|
selected: false,
|
|
classList: {
|
|
remove: (...names) => names.forEach((name) => classes.delete(name)),
|
|
contains: (name) => classes.has(name),
|
|
},
|
|
focus() {
|
|
this.focused = true;
|
|
},
|
|
blur() {
|
|
this.focused = false;
|
|
},
|
|
select() {
|
|
this.selected = true;
|
|
},
|
|
setAttribute: (name, value) => attributes.set(name, value),
|
|
removeAttribute: (name) => attributes.delete(name),
|
|
getAttribute: (name) => attributes.get(name) ?? null,
|
|
};
|
|
}
|
|
|
|
function settle(searchInput, options) {
|
|
const owner = { _activeLocationSearchGeneration: 4, searchInput };
|
|
NavigationController.prototype._settleLocationSearchUi.call(
|
|
owner,
|
|
4,
|
|
options,
|
|
);
|
|
return owner;
|
|
}
|
|
|
|
test('a search that found nothing keeps its query, the open field and focus', () => {
|
|
const field = input();
|
|
const owner = settle(field, { keepQuery: true });
|
|
assert.equal(owner._activeLocationSearchGeneration, null);
|
|
assert.equal(field.value, 'Pariss');
|
|
assert.equal(field.classList.contains('expanded'), true);
|
|
assert.equal(field.classList.contains('searching'), false);
|
|
assert.equal(field.focused, true);
|
|
assert.equal(field.selected, true);
|
|
});
|
|
|
|
test('a search that arrived still clears and closes the field', () => {
|
|
const field = input();
|
|
field.focused = true;
|
|
settle(field);
|
|
assert.equal(field.value, '');
|
|
assert.equal(field.classList.contains('expanded'), false);
|
|
assert.equal(field.focused, false);
|
|
});
|
|
|
|
function navigation() {
|
|
const field = input();
|
|
// The tray renders the error and the field's aria-invalid from the
|
|
// controls' published view (src/ui/commandDock.test.mjs).
|
|
const errors = [];
|
|
const settled = [];
|
|
const toasts = [];
|
|
const owner = {
|
|
_disposed: false,
|
|
_locationSearch: field,
|
|
_locationControls: { setSearchError: (message) => errors.push(message) },
|
|
_activeLocationSearchGeneration: null,
|
|
_settleLocationSearchUi: (generation, options) =>
|
|
settled.push([generation, options]),
|
|
_showToast: (message) => toasts.push(message),
|
|
_setLocationSearchError:
|
|
LocationNavigation.prototype._setLocationSearchError,
|
|
};
|
|
const handle = (status, type) =>
|
|
LocationNavigation.prototype._handleLocationSearchState.call(
|
|
owner,
|
|
{ status, query: field.value },
|
|
{ type, generation: 7 },
|
|
);
|
|
return { owner, field, errors, settled, toasts, handle };
|
|
}
|
|
|
|
for (const [status, text] of [
|
|
['missing', 'Location not found'],
|
|
['failed', 'Search failed'],
|
|
]) {
|
|
test(`a ${status} search announces a lasting error on the field instead of a toast`, () => {
|
|
const n = navigation();
|
|
n.handle('searching', 'started');
|
|
n.handle(status, status);
|
|
n.handle(status, 'settled');
|
|
assert.match(n.errors.at(-1), new RegExp(`^${text}\\. `));
|
|
assert.deepEqual(n.settled, [[7, { keepQuery: true }]]);
|
|
assert.deepEqual(n.toasts, []);
|
|
n.handle('searching', 'started');
|
|
assert.equal(n.errors.at(-1), null);
|
|
});
|
|
}
|