Rework entry types: merge hotel into stay, transport with modes, auto-transport
- Type set is now activity/stay/transport/flight/rental/note; hotel, travel and immigration are removed with idempotent startup data migrations (hotel->stay, travel->transport, immigration->activity with flag prefix) - Transport entries carry an optional mode (train/bus/ferry/taxi/drive/other) that drives the chip/map icon; route stops expose transport_mode - Creating a stay auto-creates a bridging transport to its neighbouring stays unless a transport/flight already covers the gap (one-shot) - Summary: transports count replaces hotels/travelLegs
This commit is contained in:
+19
-7
@@ -270,7 +270,7 @@ test('entry CRUD and full-row shape', async () => {
|
||||
const entry = create.body.entry;
|
||||
assert.deepEqual(
|
||||
Object.keys(entry).sort(),
|
||||
['date', 'end_date', 'details', 'end_time', 'id', 'lat', 'lng', 'location_name', 'paid_by', 'participants', 'price', 'rental', 'segments', 'sort_order', 'split_mode', 'start_time', 'title', 'trip_id', 'type'].sort()
|
||||
['date', 'end_date', 'details', 'end_time', 'id', 'lat', 'lng', 'location_name', 'paid_by', 'participants', 'price', 'rental', 'segments', 'sort_order', 'split_mode', 'start_time', 'title', 'transport_mode', 'trip_id', 'type'].sort()
|
||||
);
|
||||
assert.equal(entry.end_date, null);
|
||||
assert.equal(entry.details, '');
|
||||
@@ -321,6 +321,17 @@ test('entry validation: type, title, lat/lng pairing and ranges', async () => {
|
||||
assert.equal(ok.status, 201);
|
||||
});
|
||||
|
||||
test('legacy entry types (hotel, travel, immigration) are rejected', async () => {
|
||||
const { agent } = await createAccount();
|
||||
const trip = await makeTrip(agent);
|
||||
const base = `/api/trips/${trip.id}/entries`;
|
||||
|
||||
for (const type of ['hotel', 'travel', 'immigration']) {
|
||||
const res = await agent.post(base).send({ date: '2026-08-01', type, title: 'x' });
|
||||
assert.equal(res.status, 400, `expected ${type} to be rejected`);
|
||||
}
|
||||
});
|
||||
|
||||
test('non-member cannot add or view entries', async () => {
|
||||
const owner = await createAccount();
|
||||
const guest = await createAccount();
|
||||
@@ -348,13 +359,13 @@ test('route computes legs, totalKm and summary counts', async () => {
|
||||
});
|
||||
// Chiang Mai
|
||||
await agent.post(`/api/trips/${trip.id}/entries`).send({
|
||||
date: '2026-08-01', type: 'hotel', title: 'Hotel CNX', sort_order: 1,
|
||||
date: '2026-08-01', type: 'stay', title: 'Hotel CNX', sort_order: 1,
|
||||
location_name: 'Chiang Mai', lat: 18.7883, lng: 98.9853,
|
||||
});
|
||||
// A second flight + hotel + activities + a travel leg (no coords) to exercise counts
|
||||
// A second flight + stay + activities + a transport leg (no coords) to exercise counts
|
||||
await agent.post(`/api/trips/${trip.id}/entries`).send({ date: '2026-08-02', type: 'flight', title: 'F2' });
|
||||
await agent.post(`/api/trips/${trip.id}/entries`).send({ date: '2026-08-02', type: 'hotel', title: 'H2' });
|
||||
await agent.post(`/api/trips/${trip.id}/entries`).send({ date: '2026-08-02', type: 'travel', title: 'Drive' });
|
||||
await agent.post(`/api/trips/${trip.id}/entries`).send({ date: '2026-08-02', type: 'stay', title: 'H2' });
|
||||
await agent.post(`/api/trips/${trip.id}/entries`).send({ date: '2026-08-02', type: 'transport', title: 'Drive' });
|
||||
await agent.post(`/api/trips/${trip.id}/entries`).send({ date: '2026-08-03', type: 'activity', title: 'A1' });
|
||||
await agent.post(`/api/trips/${trip.id}/entries`).send({ date: '2026-08-03', type: 'activity', title: 'A2' });
|
||||
|
||||
@@ -371,8 +382,9 @@ test('route computes legs, totalKm and summary counts', async () => {
|
||||
assert.equal(s.days, 10);
|
||||
assert.equal(s.nights, 9);
|
||||
assert.equal(s.flights, 2);
|
||||
assert.equal(s.hotels, 2);
|
||||
assert.equal(s.travelLegs, 1);
|
||||
assert.equal(s.transports, 1);
|
||||
assert.equal(s.hotels, undefined);
|
||||
assert.equal(s.travelLegs, undefined);
|
||||
assert.equal(s.activities, 2);
|
||||
assert.deepEqual(s.locations, ['Bangkok', 'Chiang Mai']);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user