diff --git a/packages/core/__tests__/services/assembler-query.service.spec.ts b/packages/core/__tests__/services/assembler-query.service.spec.ts index db0352a68..dc1718f4a 100644 --- a/packages/core/__tests__/services/assembler-query.service.spec.ts +++ b/packages/core/__tests__/services/assembler-query.service.spec.ts @@ -362,6 +362,33 @@ describe('AssemblerQueryService', () => { }); }); + describe('setRelations', () => { + it('should transform the results for a single entity', () => { + const mockQueryService = mock>(); + const assemblerService = new AssemblerQueryService(new TestAssembler(), instance(mockQueryService)); + when(mockQueryService.setRelations('test', 1, deepEqual([2]), undefined)).thenResolve({ + bar: 'baz', + }); + + return expect(assemblerService.setRelations('test', 1, [2])).resolves.toEqual({ foo: 'baz' }); + }); + it('should transform the options and results for a single entity', () => { + const mockQueryService = mock>(); + const assemblerService = new AssemblerQueryService(new TestAssembler(), instance(mockQueryService)); + when( + mockQueryService.setRelations('test', 1, deepEqual([2]), objectContaining({ filter: { bar: { eq: 'bar' } } })), + ).thenResolve({ + bar: 'baz', + }); + + return expect( + assemblerService.setRelations('test', 1, [2], { + filter: { foo: { eq: 'bar' } }, + }), + ).resolves.toEqual({ foo: 'baz' }); + }); + }); + describe('removeRelations', () => { it('should transform the results for a single entity', () => { const mockQueryService = mock>(); diff --git a/packages/core/__tests__/services/noop-query.service.spec.ts b/packages/core/__tests__/services/noop-query.service.spec.ts index c8545cd52..c58999a1f 100644 --- a/packages/core/__tests__/services/noop-query.service.spec.ts +++ b/packages/core/__tests__/services/noop-query.service.spec.ts @@ -12,22 +12,31 @@ describe('NoOpQueryService', () => { DeepPartial, DeepPartial >(); + it('should throw a NotImplementedException when calling addRelations', () => expect(instance.addRelations('test', 1, [1, 2, 3])).rejects.toThrow('addRelations is not implemented')); + it('should throw a NotImplementedException when calling createMany', () => expect(instance.createMany([{ foo: 'bar' }])).rejects.toThrow('createMany is not implemented')); + it('should throw a NotImplementedException when calling createOne', () => expect(instance.createOne({ foo: 'bar' })).rejects.toThrow('createOne is not implemented')); + it('should throw a NotImplementedException when calling deleteMany', () => expect(instance.deleteMany({ foo: { eq: 'bar' } })).rejects.toThrow('deleteMany is not implemented')); + it('should throw a NotImplementedException when calling deleteOne', () => expect(instance.deleteOne(1)).rejects.toThrow('deleteOne is not implemented')); + it('should throw a NotImplementedException when calling findById', () => expect(instance.findById(1)).rejects.toThrow('findById is not implemented')); + it('should throw a NotImplementedException when calling findRelation', () => expect(instance.findRelation(TestType, 'test', new TestType())).rejects.toThrow('findRelation is not implemented')); + it('should throw a NotImplementedException when calling getById', () => expect(instance.getById(1)).rejects.toThrow('getById is not implemented')); + it('should throw a NotImplementedException when calling query', () => expect(instance.query({})).rejects.toThrow('query is not implemented')); @@ -36,22 +45,32 @@ describe('NoOpQueryService', () => { it('should throw a NotImplementedException when calling count', () => expect(instance.count({})).rejects.toThrow('count is not implemented')); + it('should throw a NotImplementedException when calling queryRelations', () => expect(instance.queryRelations(TestType, 'test', new TestType(), {})).rejects.toThrow( 'queryRelations is not implemented', )); + it('should throw a NotImplementedException when calling countRelations', () => expect(instance.countRelations(TestType, 'test', new TestType(), {})).rejects.toThrow( 'countRelations is not implemented', )); + it('should throw a NotImplementedException when calling removeRelation', () => expect(instance.removeRelation('test', 1, 2)).rejects.toThrow('removeRelation is not implemented')); + it('should throw a NotImplementedException when calling removeRelations', () => expect(instance.removeRelations('test', 1, [1, 2, 3])).rejects.toThrow('removeRelations is not implemented')); + it('should throw a NotImplementedException when calling setRelation', () => expect(instance.setRelation('test', 1, 1)).rejects.toThrow('setRelation is not implemented')); + + it('should throw a NotImplementedException when calling setRelations', () => + expect(instance.setRelations('test', 1, [1])).rejects.toThrow('setRelations is not implemented')); + it('should throw a NotImplementedException when calling updateMany', () => expect(instance.updateMany({ foo: 'bar' }, {})).rejects.toThrow('updateMany is not implemented')); + it('should throw a NotImplementedException when calling updateOne', () => expect(instance.updateOne(1, { foo: 'bar' })).rejects.toThrow('updateOne is not implemented')); diff --git a/packages/core/__tests__/services/proxy-query.service.spec.ts b/packages/core/__tests__/services/proxy-query.service.spec.ts index a6888612c..270269128 100644 --- a/packages/core/__tests__/services/proxy-query.service.spec.ts +++ b/packages/core/__tests__/services/proxy-query.service.spec.ts @@ -169,6 +169,14 @@ describe('ProxyQueryService', () => { when(mockQueryService.setRelation(relationName, id, relationId, undefined)).thenResolve(result); return expect(queryService.setRelation(relationName, id, relationId)).resolves.toBe(result); }); + it('should proxy to the underlying service when calling setRelations', () => { + const relationName = 'test'; + const id = 1; + const relationIds = [2]; + const result = { foo: 'bar' }; + when(mockQueryService.setRelations(relationName, id, relationIds, undefined)).thenResolve(result); + return expect(queryService.setRelations(relationName, id, relationIds)).resolves.toBe(result); + }); it('should proxy to the underlying service when calling updateMany', () => { const update = { foo: 'bar' }; const filter = {}; diff --git a/packages/core/__tests__/services/relation-query.service.spec.ts b/packages/core/__tests__/services/relation-query.service.spec.ts index c9e3137b2..f0e492b64 100644 --- a/packages/core/__tests__/services/relation-query.service.spec.ts +++ b/packages/core/__tests__/services/relation-query.service.spec.ts @@ -261,4 +261,14 @@ describe('RelationQueryService', () => { return expect(queryService.setRelation(relationName, id, relationId)).resolves.toBe(result); }); }); + describe('#setRelations', () => { + it('should proxy to the underlying service when calling setRelations', () => { + const relationName = 'test'; + const id = 1; + const relationIds = [2]; + const result = { foo: 'bar' }; + when(mockQueryService.setRelations(relationName, id, relationIds, undefined)).thenResolve(result); + return expect(queryService.setRelations(relationName, id, relationIds)).resolves.toBe(result); + }); + }); }); diff --git a/packages/core/src/services/assembler-query.service.ts b/packages/core/src/services/assembler-query.service.ts index b096ebb92..d4159cd01 100644 --- a/packages/core/src/services/assembler-query.service.ts +++ b/packages/core/src/services/assembler-query.service.ts @@ -227,6 +227,17 @@ export class AssemblerQueryService, CE = DeepP ); } + setRelations( + relationName: string, + id: string | number, + relationIds: (string | number)[], + opts?: ModifyRelationOptions, + ): Promise { + return this.assembler.convertAsyncToDTO( + this.queryService.setRelations(relationName, id, relationIds, this.convertModifyRelationsOptions(opts)), + ); + } + setRelation( relationName: string, id: string | number, diff --git a/packages/core/src/services/noop-query.service.ts b/packages/core/src/services/noop-query.service.ts index f697f29f5..392d21f09 100644 --- a/packages/core/src/services/noop-query.service.ts +++ b/packages/core/src/services/noop-query.service.ts @@ -160,6 +160,15 @@ export class NoOpQueryService, U = DeepPartial> i return Promise.reject(new NotImplementedException('removeRelations is not implemented')); } + setRelations( + relationName: string, + id: string | number, + relationId: (string | number)[], + opts?: ModifyRelationOptions, + ): Promise { + return Promise.reject(new NotImplementedException('setRelations is not implemented')); + } + setRelation( relationName: string, id: string | number, diff --git a/packages/core/src/services/proxy-query.service.ts b/packages/core/src/services/proxy-query.service.ts index bcfc0d61a..ad168e757 100644 --- a/packages/core/src/services/proxy-query.service.ts +++ b/packages/core/src/services/proxy-query.service.ts @@ -45,6 +45,15 @@ export class ProxyQueryService, U = DeepPartial> return this.proxied.removeRelations(relationName, id, relationIds, opts); } + setRelations( + relationName: string, + id: string | number, + relationIds: (string | number)[], + opts?: ModifyRelationOptions, + ): Promise { + return this.proxied.setRelations(relationName, id, relationIds, opts); + } + setRelation( relationName: string, id: string | number, diff --git a/packages/core/src/services/query.service.ts b/packages/core/src/services/query.service.ts index 5af6d06ba..7ad665644 100644 --- a/packages/core/src/services/query.service.ts +++ b/packages/core/src/services/query.service.ts @@ -156,6 +156,22 @@ export interface QueryService, U = DeepPartial> { opts?: ModifyRelationOptions, ): Promise; + /** + * Set the relations on the dto. + * + * @param relationName - The name of the relation to query for. + * @param id - The id of the dto to set the relation on. + * @param relationIds - The ids of the relation to set on the dto. If the array is empty the relations will be + * removed. + * @param opts - Additional options. + */ + setRelations( + relationName: string, + id: string | number, + relationIds: (string | number)[], + opts?: ModifyRelationOptions, + ): Promise; + /** * Set the relation on the dto. *