mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 05:26:47 +00:00
refactor(planner): share the trip sheet wiring between desktop and phone
The phone trip sheet host wrote out by hand three pieces of planner wiring the desktop planner already had. useBookingExpenseEditor now holds the expense editor both planners open over the trip: the booking request state, the receipt fallback, the base currency, the current user and the save that reloads the budget. TripPlannerPage and MTripSheets both read it. applyTripCoverUpdate patches a new trip cover into the store for the trip form on both sides. The transport editor and the transit route change moved into openTransportEditorWith and changeTransitRouteWith, which take the planner's setters. usePlannerDialogs builds openTransportEditor and changeTransitRoute on them, and the phone sheet calls the same helpers on the planner it receives. There are no differences between the two views to keep as options.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { vi } from 'vitest';
|
||||
import type { TripPlanner, MTripShellApi } from '../../src/mobile/screens/trip/MTripShell';
|
||||
import type { Reservation } from '../../src/types';
|
||||
import { changeTransitRouteWith, openTransportEditorWith } from '../../src/pages/tripPlanner/transportEditorOpeners';
|
||||
import { buildTrip } from './factories';
|
||||
|
||||
/**
|
||||
@@ -299,6 +301,10 @@ export function buildPlanner(overrides: Partial<TripPlanner> = {}): TripPlanner
|
||||
handleSaveReservation: vi.fn(),
|
||||
handleSaveTransport: vi.fn(),
|
||||
handleDeleteReservation: vi.fn(),
|
||||
// The planner's two ways into the transport editor, run on the setter spies above
|
||||
// the way usePlannerDialogs runs them on its state.
|
||||
openTransportEditor: vi.fn((r: Reservation) => openTransportEditorWith(planner, r)),
|
||||
changeTransitRoute: vi.fn((r: Reservation) => changeTransitRouteWith(planner, r)),
|
||||
|
||||
selectedPlace: null,
|
||||
dayOrderMap: new Map<number, number>(),
|
||||
@@ -309,7 +315,8 @@ export function buildPlanner(overrides: Partial<TripPlanner> = {}): TripPlanner
|
||||
splashDone: true,
|
||||
};
|
||||
|
||||
return { ...base, ...overrides } as unknown as TripPlanner;
|
||||
const planner = { ...base, ...overrides } as unknown as TripPlanner;
|
||||
return planner;
|
||||
}
|
||||
|
||||
export function buildShell(overrides: Partial<MTripShellApi> = {}): MTripShellApi {
|
||||
|
||||
@@ -13,7 +13,7 @@ import { buildPlanner, buildShell } from '../../../helpers/mobileTrip'
|
||||
import { resetAllStores, seedStore } from '../../../helpers/store'
|
||||
import { fireEvent, render, screen, waitFor, within } from '../../../helpers/render'
|
||||
|
||||
// FE-MOB-SHOST-001 to FE-MOB-SHOST-029, FE-MOB-SHOST-032 and FE-MOB-SHOST-033 (030 and 031 live in MTripSheets.members.test.tsx)
|
||||
// FE-MOB-SHOST-001 to FE-MOB-SHOST-029 and FE-MOB-SHOST-032 to FE-MOB-SHOST-034 (030 and 031 live in MTripSheets.members.test.tsx)
|
||||
//
|
||||
// Every child sheet is stubbed: this file is about the host — which sheet is
|
||||
// mounted for which shell.sheet id, and how the host's own callbacks wire the
|
||||
@@ -160,18 +160,20 @@ vi.mock('../../../../src/components/Trips/TripMembersModal', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('../../../../src/components/Planner/TransitJourneyModal', () => ({
|
||||
default: ({ reservation, canEdit, onClose, onSave, onDelete, onChangeRoute }: {
|
||||
default: ({ reservation, canEdit, onClose, onSave, onDelete, onChangeRoute, onEditDetails }: {
|
||||
reservation: Reservation
|
||||
canEdit: boolean
|
||||
onClose: () => void
|
||||
onSave: (fields: Record<string, unknown>) => Promise<void>
|
||||
onDelete: () => Promise<void>
|
||||
onChangeRoute: () => void
|
||||
onEditDetails: () => void
|
||||
}) => (
|
||||
<div data-testid="stub-transit" data-title={reservation.title} data-canedit={String(canEdit)}>
|
||||
<button type="button" onClick={() => void onSave({ title: 'Renamed' })}>save transit</button>
|
||||
<button type="button" onClick={() => void onDelete()}>delete transit</button>
|
||||
<button type="button" onClick={onChangeRoute}>change route</button>
|
||||
<button type="button" onClick={onEditDetails}>edit details</button>
|
||||
<button type="button" onClick={onClose}>close transit</button>
|
||||
</div>
|
||||
),
|
||||
@@ -373,6 +375,16 @@ describe('MTripSheets', () => {
|
||||
expect(planner.setTransportModalDayId).toHaveBeenCalledWith(null)
|
||||
})
|
||||
|
||||
it('FE-MOB-SHOST-034: editing the details opens the transport editor on the newer store copy', () => {
|
||||
const fresh = { ...JOURNEY, title: 'Tokyo → Kyoto (saved)' } as Reservation
|
||||
const { planner } = renderHost({ transitJourney: JOURNEY, reservations: [fresh] })
|
||||
fireEvent.click(screen.getByText('edit details'))
|
||||
expect(planner.openTransportEditor).toHaveBeenCalledWith(fresh)
|
||||
expect(planner.setEditingTransport).toHaveBeenCalledWith(fresh)
|
||||
expect(planner.setTransportModalAutomated).toHaveBeenCalledWith(false)
|
||||
expect(planner.setShowTransportModal).toHaveBeenCalledWith(true)
|
||||
})
|
||||
|
||||
it('FE-MOB-SHOST-020: a booking opens the expense editor for its linked item and closes again', () => {
|
||||
renderHost()
|
||||
expect(screen.queryByTestId('stub-cost')).not.toBeInTheDocument()
|
||||
|
||||
Reference in New Issue
Block a user