diff --git a/packages/backend/src/controllers/api/v1/users/get-user.ee.js b/packages/backend/src/controllers/api/v1/users/get-user.ee.js new file mode 100644 index 00000000..bc0a714f --- /dev/null +++ b/packages/backend/src/controllers/api/v1/users/get-user.ee.js @@ -0,0 +1,13 @@ +import { renderObject } from '../../../../helpers/renderer.js'; +import User from '../../../../models/user.js'; + +export default async (request, response) => { + const user = await User.query() + .withGraphFetched({ + role: true, + }) + .findById(request.params.userId) + .throwIfNotFound(); + + renderObject(response, user); +}; diff --git a/packages/backend/src/controllers/api/v1/users/get-user.ee.test.js b/packages/backend/src/controllers/api/v1/users/get-user.ee.test.js new file mode 100644 index 00000000..0db61f58 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/users/get-user.ee.test.js @@ -0,0 +1,48 @@ +import { vi, describe, it, expect, beforeEach } from 'vitest'; +import request from 'supertest'; +import Crypto from 'crypto'; +import app from '../../../../app.js'; +import { createApiToken } from '../../../../../test/factories/api-token.js'; +import { createUser } from '../../../../../test/factories/user.js'; +import { createRole } from '../../../../../test/factories/role.js'; +import getUserMock from '../../../../../test/mocks/rest/api/v1/users/get-user.js'; +import * as license from '../../../../helpers/license.ee.js'; + +describe('GET /api/v1/users/:userId', () => { + let user, userRole, token; + + beforeEach(async () => { + vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true); + + userRole = await createRole({ name: 'Admin' }); + user = await createUser({ roleId: userRole.id }); + + token = (await createApiToken()).token; + }); + + it('should return specified user info', async () => { + const response = await request(app) + .get(`/api/v1/users/${user.id}`) + .set('x-api-token', token) + .expect(200); + + const expectedPayload = getUserMock(user, userRole); + expect(response.body).toStrictEqual(expectedPayload); + }); + + it('should return not found response for not existing user UUID', async () => { + const notExistingUserUUID = Crypto.randomUUID(); + + await request(app) + .get(`/api/v1/users/${notExistingUserUUID}`) + .set('x-api-token', token) + .expect(404); + }); + + it('should return bad request response for invalid UUID', async () => { + await request(app) + .get('/api/v1/users/invalidUserUUID') + .set('x-api-token', token) + .expect(400); + }); +}); diff --git a/packages/backend/src/routes/api/v1/users.ee.js b/packages/backend/src/routes/api/v1/users.ee.js index 8af2a17f..b4bd45d8 100644 --- a/packages/backend/src/routes/api/v1/users.ee.js +++ b/packages/backend/src/routes/api/v1/users.ee.js @@ -2,11 +2,13 @@ import { Router } from 'express'; import createFlowAction from '../../../controllers/api/v1/users/create-flow.ee.js'; import createFolderAction from '../../../controllers/api/v1/users/create-folder.ee.js'; import getFoldersAction from '../../../controllers/api/v1/users/get-folders.ee.js'; +import getUserAction from '../../../controllers/api/v1/users/get-user.ee.js'; import getUsersAction from '../../../controllers/api/v1/users/get-users.ee.js'; const router = Router(); router.get('/', getUsersAction); +router.get('/:userId', getUserAction); router.post('/:userId/flows', createFlowAction); router.get('/:userId/folders', getFoldersAction); router.post('/:userId/folders', createFolderAction); diff --git a/packages/backend/test/mocks/rest/api/v1/users/get-user.js b/packages/backend/test/mocks/rest/api/v1/users/get-user.js new file mode 100644 index 00000000..fcf40ece --- /dev/null +++ b/packages/backend/test/mocks/rest/api/v1/users/get-user.js @@ -0,0 +1,30 @@ +const getUserMock = (currentUser, role) => { + return { + data: { + createdAt: currentUser.createdAt.getTime(), + email: currentUser.email, + fullName: currentUser.fullName, + id: currentUser.id, + role: { + createdAt: role.createdAt.getTime(), + description: null, + id: role.id, + isAdmin: role.isAdmin, + name: role.name, + updatedAt: role.updatedAt.getTime(), + }, + status: currentUser.status, + trialExpiryDate: currentUser.trialExpiryDate.toISOString(), + updatedAt: currentUser.updatedAt.getTime(), + }, + meta: { + count: 1, + currentPage: null, + isArray: false, + totalPages: null, + type: 'User', + }, + }; +}; + +export default getUserMock; diff --git a/packages/backend/vitest.config.js b/packages/backend/vitest.config.js index d2b193c5..fa3e01ee 100644 --- a/packages/backend/vitest.config.js +++ b/packages/backend/vitest.config.js @@ -29,7 +29,7 @@ export default defineConfig({ thresholds: { autoUpdate: true, statements: 99.42, - branches: 98.36, + branches: 98.37, functions: 99.08, lines: 99.42, },