From 8843b3e2b067b064c741f8b00593c240f720563f Mon Sep 17 00:00:00 2001 From: Daniel Gonzalez Date: Wed, 28 May 2025 20:52:25 -0400 Subject: [PATCH] Separate e2e tests --- package.json | 1 + test/e2e/automated/a01-auth.rest-e2e.js | 5 -- test/e2e/automated/a02-users.rest-e2e.js | 96 ++++++++---------------- test/e2e/automated/a09-admin.rest-e2e.js | 1 + test/utils/test-utils.js | 65 +++++++++++----- 5 files changed, 80 insertions(+), 88 deletions(-) diff --git a/package.json b/package.json index 67d05dc..123b04a 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "test:all": "export SVC_ENV=test && c8 --reporter=text mocha --exit --timeout 15000 --recursive test/unit test/e2e/automated/", "test:unit": "export SVC_ENV=test && c8 --reporter=text mocha --exit --timeout 15000 --recursive test/unit/", "test:e2e:auto": "export SVC_ENV=test && mocha --exit --timeout 15000 test/e2e/automated/", + "start:e2e:server": "export SVC_ENV=test && node index.js", "test:temp": "export SVC_ENV=test && mocha --exit --timeout 15000 -g '#rate-limit' test/unit/json-rpc/", "lint": "standard --env mocha --fix", "docs": "./node_modules/.bin/apidoc -i src/ -o docs", diff --git a/test/e2e/automated/a01-auth.rest-e2e.js b/test/e2e/automated/a01-auth.rest-e2e.js index 1965c5c..88f3f22 100644 --- a/test/e2e/automated/a01-auth.rest-e2e.js +++ b/test/e2e/automated/a01-auth.rest-e2e.js @@ -15,8 +15,6 @@ import axios from 'axios' import config from '../../../config/index.js' // import Server from '../../../bin/server.js' import testUtils from '../../utils/test-utils.js' -import AdminLib from '../../../src/adapters/admin.js' -const adminLib = new AdminLib() // const request = supertest.agent(app.listen()) const context = {} @@ -39,9 +37,6 @@ if (!config.noMongo) { // Delete all previous users in the database. await testUtils.deleteAllUsers() - // Create a new admin user. - await adminLib.createSystemUser() - const userObj = { email: 'test@test.com', password: 'pass', diff --git a/test/e2e/automated/a02-users.rest-e2e.js b/test/e2e/automated/a02-users.rest-e2e.js index 2af1eb1..222664a 100644 --- a/test/e2e/automated/a02-users.rest-e2e.js +++ b/test/e2e/automated/a02-users.rest-e2e.js @@ -5,16 +5,11 @@ import axios from 'axios' import sinon from 'sinon' import util from 'util' -import UserController from '../../../src/controllers/rest-api/users/controller.js' -import Adapters from '../../../src/adapters/index.js' -import UseCases from '../../../src/use-cases/index.js' util.inspect.defaultOptions = { depth: 1 } const LOCALHOST = `http://localhost:${config.port}` const context = {} -const adapters = new Adapters() -let uut let sandbox // const mockContext = require('../../unit/mocks/ctx-mock').context @@ -50,9 +45,6 @@ if (!config.noMongo) { }) beforeEach(() => { - const useCases = new UseCases({ adapters }) - uut = new UserController({ adapters, useCases }) - sandbox = sinon.createSandbox() }) @@ -191,41 +183,46 @@ if (!config.noMongo) { assert(false, 'Unexpected result') } catch (err) { + console.log(err) assert(err.response.status === 401, 'Error code 401 expected.') } }) it('admin can create a user when DISABLE_NEW_ACCOUNTS is true', async () => { - process.env.DISABLE_NEW_ACCOUNTS = true - const options = { - method: 'post', - url: `${LOCALHOST}/users`, - headers: { - Authorization: `Bearer ${context.adminJWT}` - }, - data: { - user: { - email: 'fromAdmin@test.com', - password: 'supersecretpassword', - name: 'test3' + try { + process.env.DISABLE_NEW_ACCOUNTS = true + const options = { + method: 'post', + url: `${LOCALHOST}/users`, + headers: { + Authorization: `Bearer ${context.adminJWT}` + }, + data: { + user: { + email: 'fromAdmin@test.com', + password: 'supersecretpassword', + name: 'test3' + } } } + const result = await axios(options) + + context.user = result.data.user + context.token = result.data.token + + assert(result.status === 200, 'Status Code 200 expected.') + assert( + result.data.user.email === 'fromAdmin@test.com', + 'Email of test expected' + ) + assert( + result.data.user.password === undefined, + 'Password expected to be omited' + ) + assert.property(result.data, 'token', 'Token property exists.') + assert.equal(result.data.user.type, 'user') + } catch (error) { + assert.fail('Unexpected code path') } - const result = await axios(options) - - context.user = result.data.user - context.token = result.data.token - - assert(result.status === 200, 'Status Code 200 expected.') - assert( - result.data.user.email === 'fromAdmin@test.com', - 'Email of test expected' - ) - assert( - result.data.user.password === undefined, - 'Password expected to be omited' - ) - assert.property(result.data, 'token', 'Token property exists.') - assert.equal(result.data.user.type, 'user') }) }) @@ -321,33 +318,6 @@ if (!config.noMongo) { assert.hasAnyKeys(users[0], ['type', '_id', 'email']) assert.isNumber(users.length) }) - - it('should return a 422 http status if biz-logic throws an error', async () => { - try { - const { token } = context - - // Force an error - sandbox - .stub(uut.useCases.user, 'getAllUsers') - .rejects(new Error('test error')) - - const options = { - method: 'GET', - url: `${LOCALHOST}/users`, - headers: { - Accept: 'application/json', - Authorization: `Bearer ${token}` - } - } - await axios(options) - - assert.fail('Unexpected code path!') - } catch (err) { - // console.log(err) - assert.equal(err.response.status, 422) - assert.equal(err.response.data, 'test error') - } - }) }) describe('GET /users/:id', () => { diff --git a/test/e2e/automated/a09-admin.rest-e2e.js b/test/e2e/automated/a09-admin.rest-e2e.js index 6c43def..ec31e0f 100644 --- a/test/e2e/automated/a09-admin.rest-e2e.js +++ b/test/e2e/automated/a09-admin.rest-e2e.js @@ -84,6 +84,7 @@ describe('Admin', () => { } sandbox.stub(uut.User, 'findOne').resolves(fakeUser) + sandbox.stub(uut.jsonFiles, 'writeJSON').resolves(true) const result = await uut.createSystemUser() assert.property(result, 'email') diff --git a/test/utils/test-utils.js b/test/utils/test-utils.js index 0afbbd5..6ee0e45 100644 --- a/test/utils/test-utils.js +++ b/test/utils/test-utils.js @@ -8,7 +8,6 @@ import axios from 'axios' // Local libraries import config from '../../config/index.js' -import User from '../../src/adapters/localdb/models/users.js' import JsonFiles from '../../src/adapters/json-files.js' // Hack to get __dirname back. @@ -33,24 +32,6 @@ async function cleanDb () { } } -// Delete all users in the database. This ensures there is no previous state -// to confuse tests. -async function deleteAllUsers () { - try { - // Get all the users in the DB. - const users = await User.find({}, '-password') - // console.log(`users: ${JSON.stringify(users, null, 2)}`) - - // Delete each user. - for (let i = 0; i < users.length; i++) { - const thisUser = users[i] - await thisUser.remove() - } - } catch (err) { - console.error('Error in test-utils.js/deleteAllUsers(): ', err) - } -} - // This function is used to create new users. // userObj = { // username, @@ -170,12 +151,56 @@ async function getAdminJWT () { throw err } } +// Fetches all users from the database. +async function getAllUsers () { + try { + const adminJWT = await getAdminJWT() + const options = { + method: 'GET', + url: `${LOCALHOST}/users`, + headers: { + Authorization: `Bearer ${adminJWT}` + } + } + const result = await axios(options) + return result.data.users + } catch (err) { + console.error('Error in test/utils.js/getAllUsers()', err) + throw err + } +} +// Deletes all users from the database. +async function deleteAllUsers () { + try { + const allUsers = await getAllUsers() + const adminJWT = await getAdminJWT() + for (let i = 0; i < allUsers.length; i++) { + const user = allUsers[i] + // Skip the admin user. + if (user.type === 'admin') { + continue + } + const options = { + method: 'DELETE', + url: `${LOCALHOST}/users/${user._id}`, + headers: { + Authorization: `Bearer ${adminJWT}` + } + } + await axios(options) + } + } catch (err) { + console.error('Error in test/utils.js/deleteAllUsers()', err) + throw err + } +} export default { cleanDb, createUser, loginTestUser, loginAdminUser, getAdminJWT, - deleteAllUsers + deleteAllUsers, + getAllUsers }