Skip to content

Commit

Permalink
feat(typegoose): Implement setRelations to set many references
Browse files Browse the repository at this point in the history
  • Loading branch information
doug-martin committed Apr 13, 2021
1 parent 3dc8a84 commit 4ec5fe0
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,75 @@ describe('TypegooseQueryService', () => {
});
});

describe('#setRelations', () => {
it('set all relations on the entity', async () => {
const entity = TEST_ENTITIES[0];
const queryService = moduleRef.get(TestEntityService);
const relationIds = TEST_REFERENCES.slice(3, 6).map((r) => r._id);
const queryResult = await queryService.setRelations(
'testReferences',
entity._id.toHexString(),
relationIds.map((id) => id.toHexString()),
);
expect(queryResult).toEqual(
expect.objectContaining({
_id: entity._id,
testReferences: expect.arrayContaining(relationIds),
}),
);

const relations = await queryService.queryRelations(TestReference, 'testReferences', entity, {});
expect(relations.map((r) => r._id)).toEqual(relationIds);
});

it('should remove all relations if the relationIds is empty', async () => {
const entity = TEST_ENTITIES[0];
const queryService = moduleRef.get(TestEntityService);
const queryResult = await queryService.setRelations('testReferences', entity._id.toHexString(), []);
expect(queryResult).toEqual(
expect.objectContaining({
_id: entity._id,
testReferences: expect.arrayContaining([]),
}),
);

const relations = await queryService.queryRelations(TestReference, 'testReferences', entity, {});
expect(relations.map((r) => r._id)).toEqual([]);
});

describe('with modify options', () => {
it('should throw an error if the entity is not found with the id and provided filter', async () => {
const entity = TEST_ENTITIES[0];
const queryService = moduleRef.get(TestEntityService);
return expect(
queryService.setRelations(
'testReferences',
entity._id.toHexString(),
TEST_REFERENCES.slice(3, 6).map((r) => r._id.toHexString()),
{
filter: { stringType: { eq: TEST_ENTITIES[1].stringType } },
},
),
).rejects.toThrow(`Unable to find TestEntity with id: ${String(entity._id)}`);
});

it('should throw an error if the relations are not found with the relationIds and provided filter', async () => {
const entity = TEST_ENTITIES[0];
const queryService = moduleRef.get(TestEntityService);
return expect(
queryService.setRelations<TestReference>(
'testReferences',
entity._id.toHexString(),
TEST_REFERENCES.slice(3, 6).map((r) => r._id.toHexString()),
{
relationFilter: { referenceName: { like: '%-one' } },
},
),
).rejects.toThrow('Unable to find all testReferences to set on TestEntity');
});
});
});

describe('#setRelation', () => {
it('call select and return the result', async () => {
const entity = TEST_REFERENCES[0];
Expand Down
19 changes: 19 additions & 0 deletions packages/query-typegoose/src/services/reference-query.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,25 @@ export abstract class ReferenceQueryService<Entity extends Base> {
return entity;
}

async setRelations<Relation>(
relationName: string,
id: string,
relationIds: (string | number)[],
opts?: ModifyRelationOptions<Entity, Relation>,
): Promise<DocumentType<Entity>> {
this.checkForReference('AddRelations', relationName, false);
const refCount = await this.getRefCount(relationName, relationIds, opts?.relationFilter);
if (relationIds.length !== refCount) {
throw new Error(`Unable to find all ${relationName} to set on ${this.Model.modelName}`);
}
const entity = await this.findAndUpdate(
id,
opts?.filter as Filter<Entity>,
{ [relationName]: relationIds } as UpdateQuery<DocumentType<Entity>>,
);
return entity;
}

async setRelation<Relation>(
relationName: string,
id: string | number,
Expand Down

0 comments on commit 4ec5fe0

Please sign in to comment.