mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-14 00:01:03 +00:00
feat(collections): edit a saved place's provider ids, website, phone and price (#2646)
The update contract takes google_place_id, google_ftid, osm_id, website, phone, price and currency like saving does, website with the same normalisation and refusal. REST and update_collection_place share it, so an agent can correct a place instead of re-saving it and losing its labels, ratings, position and id. The assistant's change card names the new fields.
This commit is contained in:
@@ -28,6 +28,36 @@ describe('collectionStatusSchema', () => {
|
||||
});
|
||||
|
||||
describe('collectionPlaceUpdateRequestSchema', () => {
|
||||
// #2646: the fields saving takes, with the same checks, so a place is corrected in place.
|
||||
it('takes the provider ids, website, phone and price, and null clears each', () => {
|
||||
const set = {
|
||||
google_place_id: 'ChIJseptime',
|
||||
google_ftid: '0x47e6:0x1b2',
|
||||
osm_id: 'node/42',
|
||||
website: 'https://septime-charonne.fr',
|
||||
phone: '+33 1 43 67 38 29',
|
||||
price: 55,
|
||||
currency: 'EUR',
|
||||
};
|
||||
expect(collectionPlaceUpdateRequestSchema.parse(set)).toEqual(set);
|
||||
const cleared = Object.fromEntries(Object.keys(set).map((key) => [key, null]));
|
||||
expect(collectionPlaceUpdateRequestSchema.parse(cleared)).toEqual(cleared);
|
||||
});
|
||||
|
||||
it('normalises a bare domain as website and refuses a script link, as saving does', () => {
|
||||
expect(collectionPlaceUpdateRequestSchema.parse({ website: 'septime-charonne.fr' }).website).toBe(
|
||||
'https://septime-charonne.fr',
|
||||
);
|
||||
expect(collectionPlaceUpdateRequestSchema.safeParse({ website: 'javascript:alert(1)' }).success).toBe(false);
|
||||
});
|
||||
|
||||
it('leaves the new fields absent when an update does not name them', () => {
|
||||
const parsed = collectionPlaceUpdateRequestSchema.parse({ name: 'Septime' });
|
||||
for (const key of ['google_place_id', 'google_ftid', 'osm_id', 'website', 'phone', 'price', 'currency']) {
|
||||
expect(key in parsed, key).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
// Regression for #1437: an update that omits `status` must NOT inject a default
|
||||
// of 'idea', otherwise the server overwrites the stored status on every edit-save.
|
||||
it('does not inject a status when the field is absent', () => {
|
||||
|
||||
@@ -223,6 +223,16 @@ export const collectionPlaceUpdateRequestSchema = z.object({
|
||||
label_ids: z.array(z.number()).optional(),
|
||||
// Custom thumbnail (#1136): null clears it (falls back to the auto-fetched photo).
|
||||
image_url: placeImageUrlSchema.nullable().optional(),
|
||||
// The fields saving accepts but editing did not (#2646), with the same checks, so
|
||||
// a place can be corrected in place instead of re-saved, which loses its labels,
|
||||
// ratings, position and id. Each one is left alone when absent; null clears it.
|
||||
google_place_id: z.string().nullable().optional(),
|
||||
google_ftid: z.string().nullable().optional(),
|
||||
osm_id: z.string().nullable().optional(),
|
||||
website: placeWebsiteSchema.nullable().optional(),
|
||||
phone: z.string().nullable().optional(),
|
||||
price: z.number().nullable().optional(),
|
||||
currency: z.string().nullable().optional(),
|
||||
});
|
||||
export type CollectionPlaceUpdateRequest = z.infer<typeof collectionPlaceUpdateRequestSchema>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user