diff --git a/packages/backend/src/controllers/api/v1/users/get-users.ee.js b/packages/backend/src/controllers/api/v1/users/get-users.ee.js new file mode 100644 index 00000000..750f5181 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/users/get-users.ee.js @@ -0,0 +1,15 @@ +import paginateRest from '../../../../helpers/pagination.js'; +import { renderObject } from '../../../../helpers/renderer.js'; +import User from '../../../../models/user.js'; + +export default async (request, response) => { + const usersQuery = User.query() + .withGraphFetched({ + role: true, + }) + .orderBy('full_name', 'asc'); + + const users = await paginateRest(usersQuery, request.query.page); + + renderObject(response, users); +}; diff --git a/packages/backend/src/controllers/api/v1/users/get-users.ee.test.js b/packages/backend/src/controllers/api/v1/users/get-users.ee.test.js new file mode 100644 index 00000000..98893dc4 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/users/get-users.ee.test.js @@ -0,0 +1,48 @@ +import request from 'supertest'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { createApiToken } from '../../../../../test/factories/api-token.js'; +import { createRole } from '../../../../../test/factories/role.js'; +import { createUser } from '../../../../../test/factories/user.js'; +import getUsersMock from '../../../../../test/mocks/rest/internal/api/v1/admin/users/get-users.js'; +import app from '../../../../app.js'; +import * as license from '../../../../helpers/license.ee.js'; + +describe('GET /api/v1/users', () => { + let userOne, userOneRole, userTwo, userTwoRole, token; + + beforeEach(async () => { + vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true); + + userOneRole = await createRole({ name: 'Admin' }); + + userOne = await createUser({ + roleId: userOneRole.id, + fullName: 'User 1', + }); + + userTwoRole = await createRole({ + name: 'Another user role', + }); + + userTwo = await createUser({ + roleId: userTwoRole.id, + fullName: 'User 2', + }); + + token = (await createApiToken()).token; + }); + + it('should return users data', async () => { + const response = await request(app) + .get('/api/v1/users') + .set('x-api-token', token) + .expect(200); + + const expectedResponsePayload = await getUsersMock( + [userOne, userTwo], + [userOneRole, userTwoRole] + ); + + expect(response.body).toStrictEqual(expectedResponsePayload); + }); +}); diff --git a/packages/backend/src/routes/api/v1/users.ee.js b/packages/backend/src/routes/api/v1/users.ee.js index 0bf2fd7e..8af2a17f 100644 --- a/packages/backend/src/routes/api/v1/users.ee.js +++ b/packages/backend/src/routes/api/v1/users.ee.js @@ -1,10 +1,12 @@ import { Router } from 'express'; -import getFoldersAction from '../../../controllers/api/v1/users/get-folders.ee.js'; -import createFolderAction from '../../../controllers/api/v1/users/create-folder.ee.js'; 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 getUsersAction from '../../../controllers/api/v1/users/get-users.ee.js'; const router = Router(); +router.get('/', getUsersAction); 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-users.js b/packages/backend/test/mocks/rest/api/v1/users/get-users.js new file mode 100644 index 00000000..7daff409 --- /dev/null +++ b/packages/backend/test/mocks/rest/api/v1/users/get-users.js @@ -0,0 +1,38 @@ +const getUsersMock = async (users, roles) => { + const data = users.map((user) => { + const role = roles.find((r) => r.id === user.roleId); + + return { + createdAt: user.createdAt.getTime(), + email: user.email, + fullName: user.fullName, + id: user.id, + role: role + ? { + createdAt: role.createdAt.getTime(), + description: role.description, + id: role.id, + isAdmin: role.isAdmin, + name: role.name, + updatedAt: role.updatedAt.getTime(), + } + : null, + status: user.status, + trialExpiryDate: user.trialExpiryDate.toISOString(), + updatedAt: user.updatedAt.getTime(), + }; + }); + + return { + data: data, + meta: { + count: data.length, + currentPage: 1, + isArray: true, + totalPages: 1, + type: 'User', + }, + }; +}; + +export default getUsersMock; diff --git a/packages/backend/vitest.config.js b/packages/backend/vitest.config.js index c48685c3..d2b193c5 100644 --- a/packages/backend/vitest.config.js +++ b/packages/backend/vitest.config.js @@ -30,7 +30,7 @@ export default defineConfig({ autoUpdate: true, statements: 99.42, branches: 98.36, - functions: 99.07, + functions: 99.08, lines: 99.42, }, },