From c413ae06dc91ce5c4c86d897ca1951abc10d7d1e Mon Sep 17 00:00:00 2001 From: Ali BARIN Date: Wed, 28 Aug 2024 13:16:16 +0000 Subject: [PATCH] feat: write DELETE /v1/connections/:connectionId --- .../api/v1/connections/delete-connection.js | 11 +++ .../v1/connections/delete-connection.test.js | 77 +++++++++++++++++++ packages/backend/src/helpers/authorization.js | 4 + .../backend/src/routes/api/v1/connections.js | 8 ++ 4 files changed, 100 insertions(+) create mode 100644 packages/backend/src/controllers/api/v1/connections/delete-connection.js create mode 100644 packages/backend/src/controllers/api/v1/connections/delete-connection.test.js diff --git a/packages/backend/src/controllers/api/v1/connections/delete-connection.js b/packages/backend/src/controllers/api/v1/connections/delete-connection.js new file mode 100644 index 00000000..e63e5a79 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/connections/delete-connection.js @@ -0,0 +1,11 @@ +export default async (request, response) => { + await request.currentUser + .$relatedQuery('connections') + .delete() + .findOne({ + id: request.params.connectionId, + }) + .throwIfNotFound(); + + response.status(204).end(); +}; diff --git a/packages/backend/src/controllers/api/v1/connections/delete-connection.test.js b/packages/backend/src/controllers/api/v1/connections/delete-connection.test.js new file mode 100644 index 00000000..bbac5403 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/connections/delete-connection.test.js @@ -0,0 +1,77 @@ +import { describe, it, beforeEach } from 'vitest'; +import request from 'supertest'; +import Crypto from 'crypto'; +import app from '../../../../app.js'; +import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js'; +import { createUser } from '../../../../../test/factories/user.js'; +import { createConnection } from '../../../../../test/factories/connection.js'; +import { createPermission } from '../../../../../test/factories/permission.js'; + +describe('DELETE /api/v1/connections/:connectionId', () => { + let currentUser, currentUserRole, token; + + beforeEach(async () => { + currentUser = await createUser(); + currentUserRole = await currentUser.$relatedQuery('role'); + + await createPermission({ + action: 'delete', + subject: 'Connection', + roleId: currentUserRole.id, + conditions: ['isCreator'], + }); + + await createPermission({ + action: 'update', + subject: 'Connection', + roleId: currentUserRole.id, + conditions: ['isCreator'], + }); + + token = await createAuthTokenByUserId(currentUser.id); + }); + + it('should delete the connection for current user', async () => { + const currentUserConnection = await createConnection({ + userId: currentUser.id, + key: 'deepl', + verified: true, + }); + + await request(app) + .delete(`/api/v1/connections/${currentUserConnection.id}`) + .set('Authorization', token) + .expect(204); + }); + + it(`should return not found for other users' connections`, async () => { + const anotherUser = await createUser(); + + const anotherUserConnection = await createConnection({ + userId: anotherUser.id, + key: 'deepl', + verified: true, + }); + + await request(app) + .post(`/api/v1/connections/${anotherUserConnection.id}`) + .set('Authorization', token) + .expect(404); + }); + + it('should return not found response for not existing connection UUID', async () => { + const notExistingConnectionUUID = Crypto.randomUUID(); + + await request(app) + .delete(`/api/v1/connections/${notExistingConnectionUUID}`) + .set('Authorization', token) + .expect(404); + }); + + it('should return bad request response for invalid UUID', async () => { + await request(app) + .delete('/api/v1/connections/invalidConnectionUUID') + .set('Authorization', token) + .expect(400); + }); +}); diff --git a/packages/backend/src/helpers/authorization.js b/packages/backend/src/helpers/authorization.js index eeee88ef..cc3ab83c 100644 --- a/packages/backend/src/helpers/authorization.js +++ b/packages/backend/src/helpers/authorization.js @@ -71,6 +71,10 @@ const authorizationList = { action: 'update', subject: 'Flow', }, + 'DELETE /api/v1/connections/:connectionId': { + action: 'delete', + subject: 'Connection', + }, }; export const authorizeUser = async (request, response, next) => { diff --git a/packages/backend/src/routes/api/v1/connections.js b/packages/backend/src/routes/api/v1/connections.js index 48e7ea71..5b79fff1 100644 --- a/packages/backend/src/routes/api/v1/connections.js +++ b/packages/backend/src/routes/api/v1/connections.js @@ -4,9 +4,17 @@ import { authorizeUser } from '../../../helpers/authorization.js'; import getFlowsAction from '../../../controllers/api/v1/connections/get-flows.js'; import testConnectionAction from '../../../controllers/api/v1/connections/test-connection.js'; import verifyConnectionAction from '../../../controllers/api/v1/connections/verify-connection.js'; +import deleteConnectionAction from '../../../controllers/api/v1/connections/delete-connection.js'; const router = Router(); +router.delete( + '/:connectionId', + authenticateUser, + authorizeUser, + deleteConnectionAction +); + router.get( '/:connectionId/flows', authenticateUser,