From 3d2c578094b59493ce1dedc6d0ff4eaf95635f41 Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Fri, 25 Apr 2025 15:39:51 +0000 Subject: [PATCH] feat(api): add delete user invitation endpoint --- .../delete-user-invitation.ee.js | 12 +++++ .../delete-user-invitation.ee.test.js | 50 +++++++++++++++++++ .../src/routes/api/v1/user-invitations.ee.js | 2 + packages/backend/test/factories/user.js | 1 + packages/backend/vitest.config.js | 6 +-- 5 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 packages/backend/src/controllers/api/v1/user-invitations/delete-user-invitation.ee.js create mode 100644 packages/backend/src/controllers/api/v1/user-invitations/delete-user-invitation.ee.test.js diff --git a/packages/backend/src/controllers/api/v1/user-invitations/delete-user-invitation.ee.js b/packages/backend/src/controllers/api/v1/user-invitations/delete-user-invitation.ee.js new file mode 100644 index 00000000..197092d2 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/user-invitations/delete-user-invitation.ee.js @@ -0,0 +1,12 @@ +import User from '../../../../models/user.js'; + +export default async (request, response) => { + const user = await User.query() + .findById(request.params.userId) + .where({ status: 'invited' }) + .throwIfNotFound(); + + await user.$query().delete(); + + response.status(204).end(); +}; diff --git a/packages/backend/src/controllers/api/v1/user-invitations/delete-user-invitation.ee.test.js b/packages/backend/src/controllers/api/v1/user-invitations/delete-user-invitation.ee.test.js new file mode 100644 index 00000000..be9e15d3 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/user-invitations/delete-user-invitation.ee.test.js @@ -0,0 +1,50 @@ +import Crypto from 'crypto'; +import request from 'supertest'; +import { beforeEach, describe, it, vi } from 'vitest'; +import { createApiToken } from '../../../../../test/factories/api-token.js'; +import { createUser } from '../../../../../test/factories/user.js'; +import app from '../../../../app.js'; +import * as license from '../../../../helpers/license.ee.js'; + +describe('DELETE /api/v1/user-invitations/:userId', () => { + let token; + + beforeEach(async () => { + vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true); + + token = (await createApiToken()).token; + }); + + it('should soft delete user invitation and respond with no content', async () => { + const user = await createUser({ status: 'invited' }); + + await request(app) + .delete(`/api/v1/user-invitations/${user.id}`) + .set('x-api-token', token) + .expect(204); + }); + it('should return not found response for active user', async () => { + const user = await createUser(); + + await request(app) + .delete(`/api/v1/user-invitations/${user.id}`) + .set('x-api-token', token) + .expect(404); + }); + + it('should return not found response for not existing user UUID', async () => { + const notExistingUserUUID = Crypto.randomUUID(); + + await request(app) + .delete(`/api/v1/user-invitations/${notExistingUserUUID}`) + .set('x-api-token', token) + .expect(404); + }); + + it('should return bad request response for invalid UUID', async () => { + await request(app) + .delete('/api/v1/user-invitations/invalidUserUUID') + .set('x-api-token', token) + .expect(400); + }); +}); diff --git a/packages/backend/src/routes/api/v1/user-invitations.ee.js b/packages/backend/src/routes/api/v1/user-invitations.ee.js index d5dd151e..ea14eab5 100644 --- a/packages/backend/src/routes/api/v1/user-invitations.ee.js +++ b/packages/backend/src/routes/api/v1/user-invitations.ee.js @@ -1,8 +1,10 @@ import { Router } from 'express'; import getUserInvitationsAction from '../../../controllers/api/v1/user-invitations/get-user-invitations.ee.js'; +import deleteUserInvitationAction from '../../../controllers/api/v1/user-invitations/delete-user-invitation.ee.js'; const router = Router(); router.get('/', getUserInvitationsAction); +router.delete('/:userId', deleteUserInvitationAction); export default router; diff --git a/packages/backend/test/factories/user.js b/packages/backend/test/factories/user.js index 117939d9..5ec8ed90 100644 --- a/packages/backend/test/factories/user.js +++ b/packages/backend/test/factories/user.js @@ -7,6 +7,7 @@ export const createUser = async (params = {}) => { params.fullName = params?.fullName || faker.person.fullName(); params.email = params?.email || faker.internet.email(); params.password = params?.password || faker.internet.password(); + params.status = params?.status || 'active'; const user = await User.query().insertAndFetch(params); diff --git a/packages/backend/vitest.config.js b/packages/backend/vitest.config.js index 397c36bd..b201f322 100644 --- a/packages/backend/vitest.config.js +++ b/packages/backend/vitest.config.js @@ -28,10 +28,10 @@ export default defineConfig({ ], thresholds: { autoUpdate: true, - statements: 99.43, - branches: 98.4, + statements: 99.44, + branches: 98.41, functions: 99.09, - lines: 99.43, + lines: 99.44, }, }, },