mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-22 15:06:32 +00:00
5daa2a0311
The server sends accommodation:created and accommodation:updated to the whole trip, the assistant's writes included, but the client listed both as ignored and reloaded stays only after a delete. A stay the assistant, a fellow traveller, a plugin or a booking import added therefore showed in the sidebar, on the map and in the day panel only after a reload. Both events now refresh the stays like the deletes do, in the planner (desktop and phone, which share its hook) and in the day panel. The refresh is bundled per burst, since one assistant step can apply many changes, a newer answer always wins over an older one, and a stay being edited in the day panel that was deleted or moved elsewhere closes its editor instead of letting the form overwrite another stay. A browser test books a stay from a second context and sees it appear in the open planner, on the desktop and on the phone.
53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
import { useTripStore } from '../../../src/store/tripStore';
|
|
import { buildReservation } from '../../helpers/factories';
|
|
import { resetAllStores } from '../../helpers/store';
|
|
|
|
/**
|
|
* Stays live in page-local planner state, so a stay written elsewhere (the
|
|
* assistant, a fellow traveller, a plugin, a booking import) cannot be applied
|
|
* to the store. The handler asks the planner to read them again instead; the
|
|
* planner's useStaysRefresh folds the asks of a burst into one reload.
|
|
*/
|
|
describe('remoteEventHandler > accommodations', () => {
|
|
const refresh = vi.fn();
|
|
|
|
beforeEach(() => {
|
|
resetAllStores();
|
|
refresh.mockClear();
|
|
window.addEventListener('accommodations:refresh', refresh);
|
|
});
|
|
|
|
afterEach(() => {
|
|
window.removeEventListener('accommodations:refresh', refresh);
|
|
});
|
|
|
|
it.each([
|
|
['accommodation:created', { accommodation: { id: 8, trip_id: 1 } }],
|
|
['accommodation:created', {}],
|
|
['accommodation:updated', { accommodation: { id: 8, trip_id: 1 } }],
|
|
['accommodation:deleted', { accommodationId: 8 }],
|
|
])('FE-WSEVT-STAY-001: %s from elsewhere asks the planner once to reload its stays', (type, payload) => {
|
|
const reservations = [buildReservation({ id: 3 })];
|
|
useTripStore.setState({ reservations });
|
|
|
|
useTripStore.getState().handleRemoteEvent({ type, ...payload });
|
|
|
|
expect(refresh).toHaveBeenCalledTimes(1);
|
|
expect(useTripStore.getState().reservations).toBe(reservations);
|
|
});
|
|
|
|
it('FE-WSEVT-STAY-002: a booking change that is no stay leaves the stays alone', () => {
|
|
const reservation = buildReservation({ id: 3 });
|
|
useTripStore.setState({ reservations: [reservation] });
|
|
|
|
useTripStore
|
|
.getState()
|
|
.handleRemoteEvent({ type: 'reservation:updated', reservation: { ...reservation, title: 'Moved' } });
|
|
useTripStore.getState().handleRemoteEvent({ type: 'reservation:deleted', reservationId: 3 });
|
|
|
|
expect(refresh).not.toHaveBeenCalled();
|
|
});
|
|
});
|