diff --git a/packages/datasource-customizer/src/context/relaxed-wrappers/collection.ts b/packages/datasource-customizer/src/context/relaxed-wrappers/collection.ts index 70e1bef262..b3e5678181 100644 --- a/packages/datasource-customizer/src/context/relaxed-wrappers/collection.ts +++ b/packages/datasource-customizer/src/context/relaxed-wrappers/collection.ts @@ -11,6 +11,7 @@ import { PaginatedFilter, Projection, RecordData, + RecordValidator, Sort, } from '@forestadmin/datasource-toolkit'; @@ -132,6 +133,8 @@ export default class RelaxedCollection< update(filter: TFilter, patch: TPartialSimpleRow): Promise { const filterInstance = this.buildFilter(filter); + RecordValidator.validate(this.collection, patch); + return this.collection.update(this.caller, filterInstance, patch); } diff --git a/packages/datasource-customizer/test/context/wrapper.test.ts b/packages/datasource-customizer/test/context/wrapper.test.ts index 78d20b59e8..8da40ce318 100644 --- a/packages/datasource-customizer/test/context/wrapper.test.ts +++ b/packages/datasource-customizer/test/context/wrapper.test.ts @@ -38,7 +38,13 @@ describe('RelaxedWrappers', () => { beforeEach(() => { caller = factories.caller.build(); - collection = factories.collection.build(); + collection = factories.collection.build({ + schema: { + fields: { + name: factories.columnSchema.build({ columnType: 'String' }), + }, + }, + }); relaxed = new RelatedCollection(collection, caller); }); @@ -154,6 +160,14 @@ describe('RelaxedWrappers', () => { ); }); + test('should validate patch operation before forwarding update', async () => { + await expect(() => + relaxed.update({ segment: 'some_segment' }, { nonexistingField: 'newValue' }), + ).toThrow('Unknown field "nonexistingField"'); + + expect(collection.update).not.toHaveBeenCalled(); + }); + test('should forward delete and transform filter', async () => { await relaxed.delete({ segment: 'some_segment' });