From fe881f92758ea7a1587f1548f831d855c8ac7192 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Mon, 20 May 2019 15:57:28 -0700 Subject: [PATCH 1/4] Adding admin delete test case --- test/a02-users.spec.js | 30 +++++++++++++++++++++++++++++- test/utils.js | 21 ++++++++++++++++++++- util/wipe-db.js | 34 ---------------------------------- util/wipe-db.md | 6 ++++++ 4 files changed, 55 insertions(+), 36 deletions(-) delete mode 100644 util/wipe-db.js create mode 100644 util/wipe-db.md diff --git a/test/a02-users.spec.js b/test/a02-users.spec.js index cda8f7d..e656b35 100644 --- a/test/a02-users.spec.js +++ b/test/a02-users.spec.js @@ -20,9 +20,16 @@ describe('Users', () => { password: 'pass2' } const testUser = await testUtils.createUser(userObj) + console.log(`testUser: ${JSON.stringify(testUser, null, 2)}`) context.user2 = testUser.user context.token2 = testUser.token + context.id2 = testUser.user._id + + // Get the JWT used to log in as the admin 'system' user. + const adminJWT = await testUtils.getAdminJWT() + console.log(`adminJWT: ${adminJWT}`) + context.adminJWT = adminJWT }) describe('POST /users', () => { @@ -476,7 +483,7 @@ describe('Users', () => { } }) - it('should delete user', async () => { + it('should delete own user', async () => { const { user: { _id }, token @@ -498,5 +505,26 @@ describe('Users', () => { assert.equal(result.body.success, true) }) + + it('should delete other account when admin', async () => { + const id = context.id2 + const adminJWT = context.adminJWT + + const options = { + method: 'DELETE', + uri: `${LOCALHOST}/users/${id}`, + resolveWithFullResponse: true, + json: true, + headers: { + Accept: 'application/json', + Authorization: `Bearer ${adminJWT}` + } + } + + const result = await rp(options) + console.log(`result: ${util.inspect(result.body)}`) + + assert.equal(result.body.success, true) + }) }) }) diff --git a/test/utils.js b/test/utils.js index 3b3f177..84e14b6 100644 --- a/test/utils.js +++ b/test/utils.js @@ -1,5 +1,6 @@ const mongoose = require('mongoose') const rp = require('request-promise') +const config = require('../config') const LOCALHOST = 'http://localhost:5000' @@ -128,10 +129,28 @@ async function loginAdminUser () { } } +// Retrieve the admin user JWT token from the JSON file it's saved at. +async function getAdminJWT () { + try { + // process.env.KOA_ENV = process.env.KOA_ENV || 'dev' + // console.log(`env: ${process.env.KOA_ENV}`) + + const FILENAME = `../config/system-user-test.json` + const adminUserData = require(FILENAME) + // console.log(`adminUserData: ${JSON.stringify(adminUserData, null, 2)}`) + + return adminUserData.token + } catch (err) { + console.error('Error in test/utils.js/getAdminJWT()') + throw err + } +} + module.exports = { cleanDb, authUser, createUser, loginTestUser, - loginAdminUser + loginAdminUser, + getAdminJWT } diff --git a/util/wipe-db.js b/util/wipe-db.js deleted file mode 100644 index 4340e5d..0000000 --- a/util/wipe-db.js +++ /dev/null @@ -1,34 +0,0 @@ -const mongoose = require('mongoose') - -const config = require('../config') - -// Connect to the Mongo Database. -mongoose.Promise = global.Promise -mongoose.connect(config.database, () => { - // mongoose.connection.db.dropDatabase() -}) - -console.log(`config: ${JSON.stringify(config, null, 2)}`) - -/* -// Wipe the DB. -function cleanDb () { - for (const collection in mongoose.connection.collections) { - if (mongoose.connection.collections.hasOwnProperty(collection)) { - mongoose.connection.collections[collection].remove() - } - } - console.log(`Database wiped.`) -} -cleanDb() -*/ - -mongoose.connection.close() - -console.log(` -Here's how to wipe the db: -1. mongo -2. use p2pvps-server-dev -3. db.dropDatabase() -4. exit -`) diff --git a/util/wipe-db.md b/util/wipe-db.md new file mode 100644 index 0000000..4574ef4 --- /dev/null +++ b/util/wipe-db.md @@ -0,0 +1,6 @@ + +Here's how to wipe the db: +1. mongo +2. use koa-server-dev +3. db.dropDatabase() +4. exit From 91861e657af09e6e9cdb98b3705ea036ff008115 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Mon, 20 May 2019 18:35:02 -0700 Subject: [PATCH 2/4] fix(admin bug): fixed a bug with admin account and tests --- src/lib/admin.js | 20 +++++++++++++++----- test/a01-auth.spec.js | 14 ++------------ test/a02-users.spec.js | 21 +++++++++++++++++---- test/utils.js | 23 ++--------------------- 4 files changed, 36 insertions(+), 42 deletions(-) diff --git a/src/lib/admin.js b/src/lib/admin.js index 752924c..0c5033e 100644 --- a/src/lib/admin.js +++ b/src/lib/admin.js @@ -53,10 +53,17 @@ async function createSystemUser () { // Change the user type to admin user.type = 'admin' - // console.log(`user: ${JSON.stringify(user, null, 2)}`) + console.log(`user: ${JSON.stringify(user, null, 2)}`) // Save the user model. - await user.save() + try { + await user.save() + } catch (err) { + console.error(`Error trying to save admin user: `, err) + } + + console.log(`admin user created: ${JSON.stringify(result.body, null, 2)}`) + console.log(`with password: ${context.password}`) // Write out the system user information to a JSON file that external // applications like the Task Manager and the test scripts can access. @@ -114,9 +121,9 @@ async function deleteExistingSystemUser () { async function loginAdmin () { // console.log(`loginAdmin() running.`) - try { - let existingUser + let existingUser + try { // Read the exising file existingUser = await jsonFiles.readJSON(JSON_PATH) // console.log(`existingUser: ${JSON.stringify(existingUser, null, 2)}`) @@ -137,7 +144,10 @@ async function loginAdmin () { return result } catch (err) { - console.error(`Error in admin.js/loginAdmin().`) + console.error(`Error in admin.js/loginAdmin().`, err) + + console.error(`existingUser: ${JSON.stringify(existingUser, null, 2)}`) + throw err } } diff --git a/test/a01-auth.spec.js b/test/a01-auth.spec.js index 2d5bddf..c5c0c36 100644 --- a/test/a01-auth.spec.js +++ b/test/a01-auth.spec.js @@ -11,19 +11,9 @@ const LOCALHOST = `http://localhost:${config.port}` describe('Auth', () => { before(async () => { - await app.startServer() + utils.cleanDb() // This should be first instruction. - utils.cleanDb() - - /* - authUser(request, (err, { user, token }) => { - if (err) { return done(err) } - - context.user = user - context.token = token - done() - }) - */ + await app.startServer() // This should be second instruction. const userObj = { username: 'test', diff --git a/test/a02-users.spec.js b/test/a02-users.spec.js index e656b35..5ee5fbb 100644 --- a/test/a02-users.spec.js +++ b/test/a02-users.spec.js @@ -2,6 +2,7 @@ const testUtils = require('./utils') const rp = require('request-promise') const assert = require('chai').assert const config = require('../config') +const adminLib = require('../src/lib/admin') const util = require('util') util.inspect.defaultOptions = { depth: 1 } @@ -12,7 +13,7 @@ const context = {} describe('Users', () => { before(async () => { - testUtils.cleanDb() + console.log(`config: ${JSON.stringify(config, null, 2)}`) // Create a second test user. const userObj = { @@ -20,7 +21,7 @@ describe('Users', () => { password: 'pass2' } const testUser = await testUtils.createUser(userObj) - console.log(`testUser: ${JSON.stringify(testUser, null, 2)}`) + console.log(`testUser2: ${JSON.stringify(testUser, null, 2)}`) context.user2 = testUser.user context.token2 = testUser.token @@ -30,6 +31,12 @@ describe('Users', () => { const adminJWT = await testUtils.getAdminJWT() console.log(`adminJWT: ${adminJWT}`) context.adminJWT = adminJWT + + // const admin = await testUtils.loginAdminUser() + // context.adminJWT = admin.token + + // const admin = await adminLib.loginAdmin() + // console.log(`admin: ${JSON.stringify(admin, null, 2)}`) }) describe('POST /users', () => { @@ -81,8 +88,14 @@ describe('Users', () => { context.token = result.body.token assert(result.statusCode === 200, 'Status Code 200 expected.') - assert(result.body.user.username === 'supercoolname', 'Username of test expected') - assert(result.body.user.password === undefined, 'Password expected to be omited') + assert( + result.body.user.username === 'supercoolname', + 'Username of test expected' + ) + assert( + result.body.user.password === undefined, + 'Password expected to be omited' + ) assert.property(result.body, 'token', 'Token property exists.') } catch (err) { console.log( diff --git a/test/utils.js b/test/utils.js index 84e14b6..c0a2852 100644 --- a/test/utils.js +++ b/test/utils.js @@ -13,21 +13,6 @@ function cleanDb () { } } -function authUser (agent, callback) { - agent - .post('/users') - .set('Accept', 'application/json') - .send({ user: { username: 'test', password: 'pass' } }) - .end((err, res) => { - if (err) { return callback(err) } - - callback(null, { - user: res.body.user, - token: res.body.token - }) - }) -} - // This function is used to create new users. // userObj = { // username, @@ -94,10 +79,7 @@ async function loginTestUser () { async function loginAdminUser () { try { - process.env.NODE_ENV = process.env.NODE_ENV || 'dev' - console.log(`env: ${process.env.NODE_ENV}`) - - const FILENAME = `../config/system-user-${process.env.NODE_ENV}.json` + const FILENAME = `../config/system-user-${config.env}.json` const adminUserData = require(FILENAME) console.log(`adminUserData: ${JSON.stringify(adminUserData, null, 2)}`) @@ -135,7 +117,7 @@ async function getAdminJWT () { // process.env.KOA_ENV = process.env.KOA_ENV || 'dev' // console.log(`env: ${process.env.KOA_ENV}`) - const FILENAME = `../config/system-user-test.json` + const FILENAME = `../config/system-user-${config.env}.json` const adminUserData = require(FILENAME) // console.log(`adminUserData: ${JSON.stringify(adminUserData, null, 2)}`) @@ -148,7 +130,6 @@ async function getAdminJWT () { module.exports = { cleanDb, - authUser, createUser, loginTestUser, loginAdminUser, From 2c34e56bc3a9c7502f8b567aba886726c87dd644 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Mon, 20 May 2019 20:24:26 -0700 Subject: [PATCH 3/4] Fixed startup bug with admin in tests --- bin/server.js | 7 ++++++- package.json | 5 +++-- src/lib/admin.js | 2 +- test/a01-auth.spec.js | 2 +- test/utils.js | 4 ++-- util/users/delete-all-test-users.js | 27 ++++++++++++++++++++++++ util/wipe-test-db.js | 32 +++++++++++++++++++++++++++++ 7 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 util/users/delete-all-test-users.js create mode 100644 util/wipe-test-db.js diff --git a/bin/server.js b/bin/server.js index 1f45681..4e9f88b 100644 --- a/bin/server.js +++ b/bin/server.js @@ -1,3 +1,4 @@ +// npm libraries const Koa = require('koa') const bodyParser = require('koa-bodyparser') const convert = require('koa-convert') @@ -8,8 +9,10 @@ const passport = require('koa-passport') const mount = require('koa-mount') const serve = require('koa-static') const cors = require('kcors') + +// Local libraries +const config = require('../config') // this first. const adminLib = require('../src/lib/admin') -const config = require('../config') const errorMiddleware = require('../src/middleware') async function startServer () { @@ -47,6 +50,8 @@ async function startServer () { // MIDDLEWARE END + console.log(`Running server in environment: ${config.env}`) + await app.listen(config.port) console.log(`Server started on ${config.port}`) diff --git a/package.json b/package.json index bc8a23d..50c493c 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,12 @@ "main": "index.js", "scripts": { "start": "node index.js", - "test": "KOA_ENV=test nyc --reporter=text --timeout 15000 ./node_modules/.bin/mocha --exit", + "test": "npm run prep-test && KOA_ENV=test nyc --reporter=text --timeout 15000 ./node_modules/.bin/mocha --exit", "lint": "eslint src/**/*.js", "docs": "./node_modules/.bin/apidoc -i src/ -o docs", "coverage": "nyc report --reporter=text-lcov | coveralls", - "coverage:report": "nyc --reporter=html mocha --exit" + "coverage:report": "nyc --reporter=html mocha --exit", + "prep-test":"node util/users/delete-all-test-users.js" }, "keywords": [ "koa-api-boilerplate", diff --git a/src/lib/admin.js b/src/lib/admin.js index 0c5033e..c052e36 100644 --- a/src/lib/admin.js +++ b/src/lib/admin.js @@ -126,7 +126,7 @@ async function loginAdmin () { try { // Read the exising file existingUser = await jsonFiles.readJSON(JSON_PATH) - // console.log(`existingUser: ${JSON.stringify(existingUser, null, 2)}`) + console.log(`existingUser: ${JSON.stringify(existingUser, null, 2)}`) // Log in as the user. let options = { diff --git a/test/a01-auth.spec.js b/test/a01-auth.spec.js index c5c0c36..e5a9a8c 100644 --- a/test/a01-auth.spec.js +++ b/test/a01-auth.spec.js @@ -11,7 +11,7 @@ const LOCALHOST = `http://localhost:${config.port}` describe('Auth', () => { before(async () => { - utils.cleanDb() // This should be first instruction. + // await utils.cleanDb() // This should be first instruction. await app.startServer() // This should be second instruction. diff --git a/test/utils.js b/test/utils.js index c0a2852..179ecce 100644 --- a/test/utils.js +++ b/test/utils.js @@ -5,10 +5,10 @@ const config = require('../config') const LOCALHOST = 'http://localhost:5000' // Remove all collections from the DB. -function cleanDb () { +async function cleanDb () { for (const collection in mongoose.connection.collections) { if (mongoose.connection.collections.hasOwnProperty(collection)) { - mongoose.connection.collections[collection].deleteMany() + await mongoose.connection.collections[collection].deleteMany() } } } diff --git a/util/users/delete-all-test-users.js b/util/users/delete-all-test-users.js new file mode 100644 index 0000000..99f191e --- /dev/null +++ b/util/users/delete-all-test-users.js @@ -0,0 +1,27 @@ +const mongoose = require('mongoose') + +// Force test environment +process.env.KOA_ENV = 'test' +const config = require('../../config') + +const User = require('../../src/models/users') + +async function deleteUsers () { + // Connect to the Mongo Database. + mongoose.Promise = global.Promise + mongoose.set('useCreateIndex', true) // Stop deprecation warning. + await mongoose.connect(config.database, { useNewUrlParser: true }) + + // 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() + } + + mongoose.connection.close() +} +deleteUsers() diff --git a/util/wipe-test-db.js b/util/wipe-test-db.js new file mode 100644 index 0000000..99f8462 --- /dev/null +++ b/util/wipe-test-db.js @@ -0,0 +1,32 @@ +/* + Utility app to wipe the test database. +*/ + +'use strict' + +const mongoose = require('mongoose') + +// Force test environment +process.env.KOA_ENV = 'test' +const config = require('../config') + +async function cleanDb () { + // Connect to the Mongo Database. + mongoose.Promise = global.Promise + mongoose.set('useCreateIndex', true) // Stop deprecation warning. + await mongoose.connect(config.database, { useNewUrlParser: true }) + + console.log(`mongoose.connection.collections: ${JSON.stringify(mongoose.connection.collections, null, 2)}`) + + for (const collection in mongoose.connection.collections) { + if (mongoose.connection.collections.hasOwnProperty(collection)) { + const thisCollection = mongoose.connection.collections[collection] + console.log(`thisCollection: ${JSON.stringify(thisCollection, null, 2)}`) + + await collection.deleteMany() + } + } + + mongoose.connection.close() +} +cleanDb() From 0f8fe82d50292739313a5ab38490f82f6840bcd6 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Mon, 20 May 2019 20:32:16 -0700 Subject: [PATCH 4/4] Cleaned up console logs in tests --- src/lib/admin.js | 18 +++++++----------- src/middleware/validators.js | 11 ++++++----- test/a02-users.spec.js | 8 ++++---- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/lib/admin.js b/src/lib/admin.js index c052e36..61bb4be 100644 --- a/src/lib/admin.js +++ b/src/lib/admin.js @@ -53,17 +53,13 @@ async function createSystemUser () { // Change the user type to admin user.type = 'admin' - console.log(`user: ${JSON.stringify(user, null, 2)}`) + // console.log(`user: ${JSON.stringify(user, null, 2)}`) // Save the user model. - try { - await user.save() - } catch (err) { - console.error(`Error trying to save admin user: `, err) - } + await user.save() - console.log(`admin user created: ${JSON.stringify(result.body, null, 2)}`) - console.log(`with password: ${context.password}`) + // console.log(`admin user created: ${JSON.stringify(result.body, null, 2)}`) + // console.log(`with password: ${context.password}`) // Write out the system user information to a JSON file that external // applications like the Task Manager and the test scripts can access. @@ -126,7 +122,7 @@ async function loginAdmin () { try { // Read the exising file existingUser = await jsonFiles.readJSON(JSON_PATH) - console.log(`existingUser: ${JSON.stringify(existingUser, null, 2)}`) + // console.log(`existingUser: ${JSON.stringify(existingUser, null, 2)}`) // Log in as the user. let options = { @@ -144,9 +140,9 @@ async function loginAdmin () { return result } catch (err) { - console.error(`Error in admin.js/loginAdmin().`, err) + console.error(`Error in admin.js/loginAdmin().`) - console.error(`existingUser: ${JSON.stringify(existingUser, null, 2)}`) + // console.error(`existingUser: ${JSON.stringify(existingUser, null, 2)}`) throw err } diff --git a/src/middleware/validators.js b/src/middleware/validators.js index ce6d435..8642ba2 100644 --- a/src/middleware/validators.js +++ b/src/middleware/validators.js @@ -102,16 +102,17 @@ async function ensureTargetUserOrAdmin (ctx, next) { // console.log(`ctx.state.user: ${JSON.stringify(ctx.state.user, null, 2)}`) // Ensure the calling user and the target user are the same. if (ctx.state.user._id.toString() !== targetId.toString()) { - console.log(`Calling user and target user do not match!`) - console.log(`Calling user: ${ctx.state.user._id}`) - console.log(`Target user: ${targetId}`) + // console.log(`Calling user and target user do not match!`) + // console.log(`Calling user: ${ctx.state.user._id}`) + // console.log(`Target user: ${targetId}`) // If they don't match, then the calling user better be an admin. if (ctx.state.user.type !== 'admin') { ctx.throw(401, 'not admin') - } else { - console.log(`It's ok. The user is an admin.`) } + // else { + // console.log(`It's ok. The user is an admin.`) + // } } return next() diff --git a/test/a02-users.spec.js b/test/a02-users.spec.js index 5ee5fbb..0fb78e1 100644 --- a/test/a02-users.spec.js +++ b/test/a02-users.spec.js @@ -13,7 +13,7 @@ const context = {} describe('Users', () => { before(async () => { - console.log(`config: ${JSON.stringify(config, null, 2)}`) + // console.log(`config: ${JSON.stringify(config, null, 2)}`) // Create a second test user. const userObj = { @@ -21,7 +21,7 @@ describe('Users', () => { password: 'pass2' } const testUser = await testUtils.createUser(userObj) - console.log(`testUser2: ${JSON.stringify(testUser, null, 2)}`) + // console.log(`testUser2: ${JSON.stringify(testUser, null, 2)}`) context.user2 = testUser.user context.token2 = testUser.token @@ -29,7 +29,7 @@ describe('Users', () => { // Get the JWT used to log in as the admin 'system' user. const adminJWT = await testUtils.getAdminJWT() - console.log(`adminJWT: ${adminJWT}`) + // console.log(`adminJWT: ${adminJWT}`) context.adminJWT = adminJWT // const admin = await testUtils.loginAdminUser() @@ -535,7 +535,7 @@ describe('Users', () => { } const result = await rp(options) - console.log(`result: ${util.inspect(result.body)}`) + // console.log(`result: ${util.inspect(result.body)}`) assert.equal(result.body.success, true) })