fix(tours): hold the new code to the server's warning baseline

A stop's link to a tour is checked for all its points at once, and the
tests read the values they assert on without non-null assertions.
This commit is contained in:
Maurice
2026-10-19 16:35:57 +02:00
parent 827e682684
commit c5c88691bc
3 changed files with 21 additions and 17 deletions
+9 -7
View File
@@ -603,13 +603,15 @@ export class ToursService {
const ids = waypoints.flatMap((point) => (point.linked_place_id ? [point.linked_place_id] : []));
if (ids.length === 0) return waypoints;
const linkable = await this.waypointsRepo.linkablePlaceIds(tripId, ids);
for (const id of ids) {
if (!linkable.has(id) && (await this.toursRepo.findInTrip(tripId, id))) {
throw new DomainError(400, 'A waypoint cannot stand for a tour', {
code: 'waypoint_links_a_tour',
details: { code: 'waypoint_links_a_tour' },
});
}
// A place that cannot be linked may be a tour of this trip, which a stop never stands for.
const tours = await Promise.all(
ids.filter((id) => !linkable.has(id)).map((id) => this.toursRepo.findInTrip(tripId, id)),
);
if (tours.some(Boolean)) {
throw new DomainError(400, 'A waypoint cannot stand for a tour', {
code: 'waypoint_links_a_tour',
details: { code: 'waypoint_links_a_tour' },
});
}
return waypoints.map((point) =>
point.linked_place_id && !linkable.has(point.linked_place_id) ? { ...point, linked_place_id: null } : point,
+10 -8
View File
@@ -576,7 +576,8 @@ describe('Tours planned e2e (real guards + temp SQLite)', () => {
const preview = await request(server).get(`/api/tours/library/${placeId}`).set('Cookie', sessionCookie(OWNER));
expect(preview.body.line).toHaveLength(400);
expect(preview.body.line[0]).toEqual([47, 11]);
expect(preview.body.line[399]).toEqual([long[1199]![0], long[1199]![1]]);
const last = long[long.length - 1] ?? [];
expect(preview.body.line[399]).toEqual([last[0], last[1]]);
});
it('takes a tour over as an independent tour of this trip, remembering where it came from', async () => {
@@ -728,17 +729,18 @@ describe('Tours planned e2e (real guards + temp SQLite)', () => {
.set('Cookie', sessionCookie(OUTSIDER))
.send(body);
expect(outsider.status).toBe(404);
for (const bad of [
const bad = [
{ ...body, categories: ['fuel'] },
{ ...body, corridor_m: 9000 },
{ ...body, line: [[47, 11]] },
{ ...body, add: 1 },
]) {
expect(
(await request(server).post('/api/trips/5/tours/poi-search').set('Cookie', sessionCookie(OWNER)).send(bad))
.status,
).toBe(400);
}
];
const refused = await Promise.all(
bad.map((sent) =>
request(server).post('/api/trips/5/tours/poi-search').set('Cookie', sessionCookie(OWNER)).send(sent),
),
);
expect(refused.map((res) => res.status)).toEqual([400, 400, 400, 400]);
expect((await request(server).post('/api/trips/5/tours/poi-search').send(body)).status).toBe(401);
});
});
@@ -301,7 +301,7 @@ describe('buildTourGpx (PR1-06A)', () => {
[47.3, 11.3, 650],
]),
),
)!;
) ?? '';
expect(XMLValidator.validate(gpx)).toBe(true);
const doc = parser.parse(gpx).gpx;
expect(doc.metadata).toMatchObject({
@@ -327,7 +327,7 @@ describe('buildTourGpx (PR1-06A)', () => {
description: ' ',
website: null,
stops: [],
})!;
}) ?? '';
const doc = parser.parse(gpx).gpx;
expect(doc.metadata).toEqual({ name: 'Grat <Ost>' });
expect(doc.trk.desc).toBeUndefined();