diff --git a/packages/repository-tests/src/crud/create-retrieve.suite.ts b/packages/repository-tests/src/crud/create-retrieve.suite.ts index 7ec364f8b6d6..6334fd0af4d4 100644 --- a/packages/repository-tests/src/crud/create-retrieve.suite.ts +++ b/packages/repository-tests/src/crud/create-retrieve.suite.ts @@ -87,7 +87,7 @@ export function createRetrieveSuite( it('retrieves an instance of a model from its foreign key value', async () => { const pens = await repo.create({name: 'Pens', categoryId: 1}); const pencils = await repo.create({name: 'Pencils', categoryId: 2}); - const products = await findByForeignKeys(repo, 'categoryId', [1]); + const products = await findByForeignKeys(repo, 'categoryId', 1); expect(products).deepEqual([pens]); expect(products).to.not.containDeep(pencils); }); diff --git a/packages/repository/src/__tests__/unit/repositories/relation.helpers.unit.ts b/packages/repository/src/__tests__/unit/repositories/relation.helpers.unit.ts index 216b3f7ff397..fa8cd92ee4ab 100644 --- a/packages/repository/src/__tests__/unit/repositories/relation.helpers.unit.ts +++ b/packages/repository/src/__tests__/unit/repositories/relation.helpers.unit.ts @@ -21,25 +21,39 @@ describe('findByForeignKeys', () => { it('returns an empty array when no instances have the foreign key value', async () => { await productRepo.create({id: 1, name: 'product', categoryId: 1}); - const products = await findByForeignKeys(productRepo, 'categoryId', [2]); + const products = await findByForeignKeys(productRepo, 'categoryId', 2); + expect(products).to.be.empty(); + }); + + it('returns an empty array when no instances have the foreign key values', async () => { + await productRepo.create({id: 1, name: 'product', categoryId: 1}); + const products = await findByForeignKeys(productRepo, 'categoryId', [2, 3]); expect(products).to.be.empty(); }); it('returns all instances that have the foreign key value', async () => { const pens = await productRepo.create({name: 'pens', categoryId: 1}); const pencils = await productRepo.create({name: 'pencils', categoryId: 1}); - const products = await findByForeignKeys(productRepo, 'categoryId', [1]); + const products = await findByForeignKeys(productRepo, 'categoryId', 1); expect(products).to.deepEqual([pens, pencils]); }); it('does not include instances with different foreign key values', async () => { const pens = await productRepo.create({name: 'pens', categoryId: 1}); const pencils = await productRepo.create({name: 'pencils', categoryId: 2}); - const products = await findByForeignKeys(productRepo, 'categoryId', [1]); + const products = await findByForeignKeys(productRepo, 'categoryId', 1); expect(products).to.deepEqual([pens]); expect(products).to.not.containDeep(pencils); }); + it('includes instances when there is one value in the array of foreign key values', async () => { + const pens = await productRepo.create({name: 'pens', categoryId: 1}); + const pencils = await productRepo.create({name: 'pencils', categoryId: 2}); + const products = await findByForeignKeys(productRepo, 'categoryId', [2]); + expect(products).to.deepEqual([pencils]); + expect(products).to.not.containDeep(pens); + }); + it('returns all instances that have any of multiple foreign key values', async () => { const pens = await productRepo.create({name: 'pens', categoryId: 1}); const pencils = await productRepo.create({name: 'pencils', categoryId: 2}); @@ -61,6 +75,20 @@ describe('findByForeignKeys', () => { expect(errorMessage).to.eql('scope is not supported'); }); + it('does not throw an error if scope is passed in and is undefined or empty', async () => { + let products = await findByForeignKeys( + productRepo, + 'categoryId', + [1], + undefined, + {}, + ); + expect(products).to.be.empty(); + + products = await findByForeignKeys(productRepo, 'categoryId', 1, {}, {}); + expect(products).to.be.empty(); + }); + /******************* HELPERS *******************/ @model() diff --git a/packages/repository/src/relations/relation.helpers.ts b/packages/repository/src/relations/relation.helpers.ts index 921c27570d19..e15aaf90a3ba 100644 --- a/packages/repository/src/relations/relation.helpers.ts +++ b/packages/repository/src/relations/relation.helpers.ts @@ -11,19 +11,18 @@ import {Entity, EntityCrudRepository, Filter, Options, Where} from '..'; * * @param targetRepository - The target repository where the model instances are found * @param fkName - Name of the foreign key - * @param fkValues - Array of the values of the foreign keys to be included + * @param fkValues - One value or array of values of the foreign keys to be included * @param scope - Additional scope constraints (not currently supported) * @param options - Options for the operations */ export async function findByForeignKeys< Target extends Entity, - TargetID, TargetRelations extends object, - ForeignKey + ForeignKey extends StringKeyOf >( - targetRepository: EntityCrudRepository, - fkName: StringKeyOf, - fkValues: ForeignKey[], + targetRepository: EntityCrudRepository, + fkName: ForeignKey, + fkValues: Target[ForeignKey][] | Target[ForeignKey], scope?: Filter, options?: Options, ): Promise<(Target & TargetRelations)[]> { @@ -33,9 +32,13 @@ export async function findByForeignKeys< throw new Error('scope is not supported'); } - const where = ({ - [fkName]: fkValues.length === 1 ? fkValues[0] : {inq: fkValues}, - } as unknown) as Where; + const value = Array.isArray(fkValues) + ? fkValues.length === 1 + ? fkValues[0] + : {inq: fkValues} + : fkValues; + + const where = ({[fkName]: value} as unknown) as Where; const targetFilter = {where}; return targetRepository.find(targetFilter, options);