From 4d3b4ad0e3a943ed179214ff180aef5ea703a897 Mon Sep 17 00:00:00 2001 From: Oleg Drozdovich <44732463+OlegDO@users.noreply.github.com> Date: Wed, 18 Oct 2023 19:02:21 +0400 Subject: [PATCH] feat(endpoint): add view with deleted workflow (#6) --- __tests__/services/endpoint-test.ts | 25 +++++++++++++++++++++++++ src/services/endpoint.ts | 17 ++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/__tests__/services/endpoint-test.ts b/__tests__/services/endpoint-test.ts index 62faa54..4a17384 100644 --- a/__tests__/services/endpoint-test.ts +++ b/__tests__/services/endpoint-test.ts @@ -566,6 +566,17 @@ describe('services/endpoint', () => { expect(result).to.deep.equal({ entity }); }); + it('should run default view handler with query builder and handle has removed: typeorm case', async () => { + const viewWithDefaultHandler = Endpoint.view?.(() => ({ repository })); + + const result = await viewWithDefaultHandler({ query: {}, hasRemoved: true }, endpointOptions); + const [queryBuilder, params] = defaultHandlerStub.firstCall.args; + + expect(queryBuilder).to.be.instanceof(SelectQueryBuilder); + expect(params?.hasRemoved).to.be.ok; + expect(result).to.deep.equal({ entity }); + }); + it('should run default view handler with query builder: query builder case', async () => { handler.resetHistory(); // return query builder from handler @@ -604,6 +615,20 @@ describe('services/endpoint', () => { expect(await waitResult(result)).to.throw(emptyConditionMessage); }); + it('handler - should return view entity with removed: default handler', async () => { + defaultHandlerStub.restore(); + TypeormMock.queryBuilder.getMany.resolves([entity]); + + const qb = repository.createQueryBuilder().where('id = 1'); + const withDeletedSpy = sandbox.spy(qb, 'withDeleted'); + + const result = await Endpoint.defaultHandler.view(qb, { hasRemoved: true }); + + expect(withDeletedSpy).to.be.calledOnce; + expect(TypeormMock.queryBuilder.getMany).to.be.calledOnce; + expect(result).to.deep.equal({ entity }); + }); + it('handler - should return cached result', async () => { defaultHandlerStub.restore(); TypeormMock.queryBuilder.getMany.resolves([entity]); diff --git a/src/services/endpoint.ts b/src/services/endpoint.ts index 3b73a56..ca2528f 100644 --- a/src/services/endpoint.ts +++ b/src/services/endpoint.ts @@ -127,6 +127,7 @@ class ListRequestParams { query?: IJsonQuery; @IsBoolean() + @IsUndefinable() hasRemoved?: boolean; } @@ -147,6 +148,10 @@ class ViewRequestParams { @IsObject() @Type(() => IJsonQueryFilter) query: IJsonQuery; + + @IsBoolean() + @IsUndefinable() + hasRemoved?: boolean; } class ViewOutputParams { @@ -732,7 +737,7 @@ const createDefaultHandler = async ({ */ const viewDefaultHandler = async ( query: SelectQueryBuilder, - { cache = 0 } = {}, + { cache = 0, hasRemoved = false } = {}, ): Promise> => { if (hasEmptyCondition(query)) { throw new BaseException({ @@ -742,6 +747,10 @@ const viewDefaultHandler = async ( }); } + if (hasRemoved) { + query.withDeleted(); + } + if (cache) { query.cache(getCrudCacheKey(query, CACHE_KEYS.view), cache); } @@ -1243,13 +1252,15 @@ class Endpoint { ...queryOptions, }); const result = await handler(typeQuery, params, options); + const { hasRemoved } = params; + const defaultParams = { hasRemoved, cache }; if (result instanceof TypeormJsonQuery) { - return Endpoint.defaultHandler.view(result.toQuery(), { cache }); + return Endpoint.defaultHandler.view(result.toQuery(), defaultParams); } if (result instanceof SelectQueryBuilder) { - return Endpoint.defaultHandler.view(result, { cache }); + return Endpoint.defaultHandler.view(result, defaultParams); } return result;