feat(admin): Increased code coverage of lib/admin.js

This commit is contained in:
Daniel Gonzalez
2020-11-22 18:43:01 -04:00
parent 7067b56c7f
commit d9172dd4f6
4 changed files with 246 additions and 109 deletions
+4 -1
View File
@@ -12,7 +12,10 @@ const cors = require('kcors')
// Local libraries
const config = require('../config') // this first.
const adminLib = require('../src/lib/admin')
const AdminLib = require('../src/lib/admin')
const adminLib = new AdminLib()
const errorMiddleware = require('../src/middleware')
const wlogger = require('../src/lib/wlogger')
+108 -96
View File
@@ -23,125 +23,137 @@ const JSON_PATH = `${__dirname}/../../config/${JSON_FILE}`
const LOCALHOST = `http://localhost:${config.port}`
const context = {}
// Create the first user in the system. A 'admin' level system user that is
// used by the Listing Manager and test scripts, in order access private API
// functions.
async function createSystemUser () {
// Create the system user.
try {
context.password = _randomString(20)
let _this
class Admin {
constructor () {
this.axios = axios
this.User = User
this.config = config
this.jsonFiles = jsonFiles
this.context = context
const options = {
method: 'POST',
url: `${LOCALHOST}/users`,
data: {
user: {
email: 'system@system.com',
password: context.password
_this = this
}
// Create the first user in the system. A 'admin' level system user that is
// used by the Listing Manager and test scripts, in order access private API
// functions.
async createSystemUser () {
// Create the system user.
try {
context.password = _this._randomString(20)
const options = {
method: 'POST',
url: `${LOCALHOST}/users`,
data: {
user: {
email: 'system@system.com',
password: context.password
}
}
}
}
const result = await axios(options)
const result = await _this.axios.request(options)
context.email = result.data.user.email
context.id = result.data.user._id
context.token = result.data.token
context.email = result.data.user.email
context.id = result.data.user._id
context.token = result.data.token
// Get the mongoDB entry
const user = await _this.User.findById(context.id)
// Get the mongoDB entry
const user = await User.findById(context.id)
// Change the user type to admin
user.type = 'admin'
// console.log(`user created: ${JSON.stringify(user, null, 2)}`)
// Change the user type to admin
user.type = 'admin'
// console.log(`user: ${JSON.stringify(user, null, 2)}`)
// Save the user model.
await user.save()
// Save the user model.
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.
// Write out the system user information to a JSON file that external
// applications like the Task Manager and the test scripts can access.
await jsonFiles.writeJSON(context, JSON_PATH)
await jsonFiles.writeJSON(context, JSON_PATH)
return context
} catch (err) {
// Handle existing system user.
if (err.response.status === 422) {
try {
return context
} catch (err) {
// Handle existing system user.
if (err.response.status === 422) {
try {
// Delete the existing user
await deleteExistingSystemUser()
await _this.deleteExistingSystemUser()
// Call this function again.
return createSystemUser()
} catch (err2) {
console.error('Error in admin.js/createSystemUser() while trying generate new system user.')
// Call this function again.
return _this.createSystemUser()
} catch (err2) {
console.error('Error in admin.js/createSystemUser() while trying generate new system user.')
// process.end(1)
throw err2
}
} else {
console.log('Error in admin.js/createSystemUser: ')
// process.end(1)
throw err2
throw err
}
} else {
console.log('Error in admin.js/createSystemUser: ' + JSON.stringify(err, null, 2))
// process.end(1)
}
}
async deleteExistingSystemUser () {
try {
mongoose.Promise = global.Promise
mongoose.set('useCreateIndex', true) // Stop deprecation warning.
await mongoose.connect(config.database, { useNewUrlParser: true, useUnifiedTopology: true })
await _this.User.deleteOne({ email: 'system@system.com' })
} catch (err) {
console.log('Error in admin.js/deleteExistingSystemUser()')
throw err
}
}
}
async function deleteExistingSystemUser () {
try {
mongoose.Promise = global.Promise
mongoose.set('useCreateIndex', true) // Stop deprecation warning.
async loginAdmin () {
// console.log(`loginAdmin() running.`)
let existingUser
await mongoose.connect(config.database, { useNewUrlParser: true, useUnifiedTopology: true })
try {
// Read the exising file
existingUser = await _this.jsonFiles.readJSON(JSON_PATH)
// console.log(`existingUser: ${JSON.stringify(existingUser, null, 2)}`)
await User.deleteOne({ email: 'system@system.com' })
} catch (err) {
console.log('Error in admin.js/deleteExistingSystemUser()')
throw err
}
}
async function loginAdmin () {
// console.log(`loginAdmin() running.`)
let existingUser
try {
// Read the exising file
existingUser = await jsonFiles.readJSON(JSON_PATH)
// console.log(`existingUser: ${JSON.stringify(existingUser, null, 2)}`)
// Log in as the user.
const options = {
method: 'POST',
url: `${LOCALHOST}/auth`,
data: {
email: 'system@system.com',
password: existingUser.password
// Log in as the user.
const options = {
method: 'POST',
url: `${LOCALHOST}/auth`,
headers: {
Accept: 'application/json'
},
data: {
email: 'system@system.com',
password: existingUser.password
}
}
const result = await _this.axios.request(options)
// console.log(`result1: ${JSON.stringify(result, null, 2)}`)
return result
} catch (err) {
console.error('Error in admin.js/loginAdmin().')
// console.error(`existingUser: ${JSON.stringify(existingUser, null, 2)}`)
throw err
}
const result = await axios(options)
// console.log(`result1: ${JSON.stringify(result, null, 2)}`)
}
return result
} catch (err) {
console.error('Error in admin.js/loginAdmin().')
// console.error(`existingUser: ${JSON.stringify(existingUser, null, 2)}`)
throw err
_randomString (length) {
var text = ''
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length))
}
return text
}
}
function _randomString (length) {
var text = ''
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length))
}
return text
}
module.exports = {
createSystemUser,
loginAdmin
}
module.exports = Admin
+18 -12
View File
@@ -1,17 +1,24 @@
const assert = require('chai').assert
const PassportLib = require('../src/lib/passport')
describe('#passport.js', () => {
let passportLib
const sinon = require('sinon')
beforeEach(async () => {
passportLib = new PassportLib()
let uut
let sandbox
describe('#passport.js', () => {
beforeEach(() => {
uut = new PassportLib()
sandbox = sinon.createSandbox()
})
afterEach(() => sandbox.restore())
describe('authUser()', () => {
it('should throw error if ctx is not provided', async () => {
try {
await passportLib.authUser()
await uut.authUser()
assert(false, 'Unexpected result')
} catch (err) {
assert.include(err.message, 'ctx is required')
@@ -20,17 +27,16 @@ describe('#passport.js', () => {
it('Should throw error if the passport library fails', async () => {
try {
// This is a mock to handle the callback error
// when the passport library fails or throws error
const error = new Error('cant auth user')
const user = null
const authMock = (value, callback) => {
callback(error, user)
}
passportLib.passport.authenticate = authMock
// Mock calls
// https://sinonjs.org/releases/latest/stubs/
// About yields
sandbox.stub(uut.passport, 'authenticate').yields(error, user)
const ctx = {}
await passportLib.authUser(ctx)
await uut.authUser(ctx)
assert(false, 'Unexpected result')
} catch (err) {
assert.include(err.message, 'cant auth user')
+116
View File
@@ -0,0 +1,116 @@
const assert = require('chai').assert
const Admin = require('../src/lib/admin')
const sinon = require('sinon')
const util = require('util')
util.inspect.defaultOptions = { depth: 1 }
let sandbox
let uut
describe('Admin', () => {
beforeEach(() => {
uut = new Admin()
sandbox = sinon.createSandbox()
})
afterEach(() => sandbox.restore())
describe('loginAdmin()', () => {
it('should logind admin', async () => {
try {
const error = new Error('test error')
error.response = {
status: 422
}
// sandbox.stub(uut.axios, 'request').onFirstCall().throws(error)
const result = await uut.loginAdmin()
const user = result.data.user
assert.property(user, '_id')
assert.property(user, 'email')
assert.property(user, 'type')
assert.isString(user._id)
assert.isString(user.email)
assert.isString(user.type)
assert.equal(user.type, 'admin')
} catch (err) {
assert(false, 'Unexpected result')
}
})
it('should handle axios error', async () => {
try {
// Returns an erroneous password to force
// an auth error
sandbox
.stub(uut.jsonFiles, 'readJSON').resolves({ password: 'wrong' })
await uut.loginAdmin()
assert(false, 'Unexpected result')
} catch (err) {
assert.equal(err.response.status, 401)
assert.include(err.response.data, 'Unauthorized')
}
})
})
describe('createSystemUser()', () => {
it('should create admin', async () => {
try {
const result = await uut.createSystemUser()
assert.property(result, 'email')
assert.property(result, 'password')
assert.property(result, 'id')
assert.property(result, 'token')
} catch (err) {
assert(false, 'Unexpected result')
}
})
it('should handle axios error', async () => {
try {
const error1 = new Error('test error')
error1.response = {
status: 422
}
const error2 = new Error('test error')
error1.response = {
status: 500
}
// The loginAdmin() function in some use cases is recursive
// after handling the 422 error, it gets called again
sandbox
.stub(uut.axios, 'request')
.onFirstCall()
.throws(error1)
.onSecondCall()
.throws(error2)
await uut.createSystemUser()
assert(false, 'Unexpected result')
} catch (err) {
assert.include(err.message, 'test error')
}
})
it('should handle errors when remove user', async () => {
try {
const error1 = new Error('test error')
error1.response = {
status: 422
}
sandbox
.stub(uut.axios, 'request').throws(error1)
sandbox
.stub(uut.User, 'deleteOne').throws(new Error('test error'))
await uut.createSystemUser()
assert(false, 'Unexpected result')
} catch (err) {
assert.include(err.message, 'test error')
}
})
})
})