From 2e357c53d76325c160e96ec1bb96f1442f2a1300 Mon Sep 17 00:00:00 2001 From: Thiago Ramalho Date: Tue, 23 Jul 2024 18:37:37 -0300 Subject: [PATCH] chore: update cache replace --- .../cache-crud.controller.e2e-spec.ts | 48 ++++++++++++++ .../src/controllers/cache-crud.controller.ts | 65 ++++++++++++++++--- 2 files changed, 103 insertions(+), 10 deletions(-) diff --git a/packages/nestjs-cache/src/controllers/cache-crud.controller.e2e-spec.ts b/packages/nestjs-cache/src/controllers/cache-crud.controller.e2e-spec.ts index e140ed21..046fa813 100644 --- a/packages/nestjs-cache/src/controllers/cache-crud.controller.e2e-spec.ts +++ b/packages/nestjs-cache/src/controllers/cache-crud.controller.e2e-spec.ts @@ -284,6 +284,54 @@ describe('CacheAssignmentController (e2e)', () => { }); }); + it.only('PUT /cache/user replace', async () => { + const payload: CacheCreatableInterface = { + key: 'dashboard-1', + type: 'filter', + data: '{}', + expiresIn: '1d', + assignee: { id: user.id }, + }; + let cacheId = ''; + await supertest(app.getHttpServer()) + .put('/cache/user') + .send(payload) + .expect(200) + .then((res) => { + cacheId = res.body.id; + expect(res.body.key).toBe(payload.key); + expect(res.body.assignee.id).toBe(user.id); + }); + payload.data = '{ "name": "John Doe" }'; + payload.expiresIn = null; + await supertest(app.getHttpServer()) + .put(`/cache/user/${cacheId}`) + .send(payload) + .expect(200) + .then((res) => { + expect(res.body.key).toBe(payload.key); + expect(res.body.data).toBe(payload.data); + expect(res.body.assignee.id).toBe(user.id); + }); + + const url = + `/cache/user/` + + `?filter[0]=key||$eq||${payload.key}` + + `&filter[1]=type||$eq||${payload.type}` + + `&filter[2]=assignee.id||$eq||${payload.assignee.id}`; + // Assuming your endpoint can filter by key and type + await supertest(app.getHttpServer()) + .get(url) + .expect(200) + .then((res) => { + const response = res.body[0]; + assert.strictEqual(response.assignee.id, user.id); + assert.strictEqual(response.key, payload.key); + assert.strictEqual(response.type, payload.type); + assert.strictEqual(response.data, payload.data); + }); + }); + it('DELETE /cache/user/:id', async () => { const userCache = await userCacheFactory .map((userCache) => { diff --git a/packages/nestjs-cache/src/controllers/cache-crud.controller.ts b/packages/nestjs-cache/src/controllers/cache-crud.controller.ts index 3947f708..37a81ea2 100644 --- a/packages/nestjs-cache/src/controllers/cache-crud.controller.ts +++ b/packages/nestjs-cache/src/controllers/cache-crud.controller.ts @@ -1,5 +1,5 @@ -import { Inject, Param } from '@nestjs/common'; -import { ApiTags } from '@nestjs/swagger'; +import { Inject, Param, Put } from '@nestjs/common'; +import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; import { AccessControlCreateOne, AccessControlDeleteOne, @@ -14,6 +14,7 @@ import { CrudDeleteOne, CrudReadMany, CrudReadOne, + CrudReplaceOne, CrudRequest, CrudRequestInterface, CrudUpdateOne, @@ -64,7 +65,7 @@ export class CacheCrudController CacheInterface, CacheCreatableInterface, CacheUpdatableInterface, - never + CacheCreatableInterface > { /** @@ -115,29 +116,33 @@ export class CacheCrudController /** * Create one * - * @param _crudRequest - the CRUD request object + * @param crudRequest - the CRUD request object * @param cacheCreateDto - cache create dto * @param assignment - The cache assignment */ @CrudCreateOne() @AccessControlCreateOne(CacheResource.One) async createOne( - @CrudRequest() _crudRequest: CrudRequestInterface, + @CrudRequest() crudRequest: CrudRequestInterface, @CrudBody() cacheCreateDto: CacheCreateDto, @Param('assignment') assignment: ReferenceAssignment, ) { - const response = await this.cacheService.updateOrCreate( - assignment, - cacheCreateDto, + const expirationDate = getExpirationDate( + cacheCreateDto.expiresIn ?? this.settings.expiresIn, ); - return response; + + // call crud service to create + return this.getCrudService(assignment).createOne(crudRequest, { + ...cacheCreateDto, + expirationDate, + }); } /** * Create one * * @param crudRequest - the CRUD request object - * @param cacheUpdateDto - cache create dto + * @param cacheUpdateDto - cache update dto * @param assignment - The cache assignment */ @CrudUpdateOne() @@ -191,6 +196,46 @@ export class CacheCrudController } } + /** + * Do a Upsert operation for cache + * + * @param crudRequest - the CRUD request object + * @param cacheUpdateDto - cache update dto + * @param assignment - The cache assignment + */ + @Put(':id?') + @ApiOkResponse({ + type: CacheDto, + }) + @CrudReplaceOne() + @AccessControlCreateOne(CacheResource.One) + async replaceOne( + @CrudRequest() crudRequest: CrudRequestInterface, + @CrudBody() cacheUpdateDto: CacheUpdateDto, + @Param('assignment') assignment: ReferenceAssignment, + ) { + let cache; + try { + cache = await this.getOne(crudRequest, assignment); + } catch (error) { + // TODO: find a better aproach + // getOne throws and error if id does not match + } + if (cache && cache?.id) { + const expirationDate = getExpirationDate( + cacheUpdateDto.expiresIn ?? this.settings.expiresIn, + ); + + // call crud service to create + return this.getCrudService(assignment).replaceOne(crudRequest, { + ...cacheUpdateDto, + expirationDate, + }); + } else { + return this.createOne(crudRequest, cacheUpdateDto, assignment); + } + } + /** * Get the entity key for the given assignment. *