From 268a7aadab75e7b9bd4a966b56b08071c303e945 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Mon, 12 Jul 2021 18:10:26 -0700 Subject: [PATCH] Increased unit test coverage to 100% for REST auth endpoint --- src/controllers/rest-api/auth/controller.js | 4 +- src/controllers/rest-api/auth/index.js | 30 +++++-- src/controllers/rest-api/auth/router.js | 51 ----------- .../auth/auth.rest.controller.unit.js | 90 +++++++++++++++++++ .../rest-api/auth/auth.rest.router.unit.js | 78 ++++++++++++++++ 5 files changed, 195 insertions(+), 58 deletions(-) delete mode 100644 src/controllers/rest-api/auth/router.js create mode 100644 test/unit/controllers/rest-api/auth/auth.rest.controller.unit.js create mode 100644 test/unit/controllers/rest-api/auth/auth.rest.router.unit.js diff --git a/src/controllers/rest-api/auth/controller.js b/src/controllers/rest-api/auth/controller.js index 5c5f140..a542b79 100644 --- a/src/controllers/rest-api/auth/controller.js +++ b/src/controllers/rest-api/auth/controller.js @@ -9,13 +9,13 @@ class AuthRESTController { this.adapters = localConfig.adapters if (!this.adapters) { throw new Error( - 'Instance of Adapters library required when instantiating PostEntry REST Controller.' + 'Instance of Adapters library required when instantiating Auth REST Controller.' ) } this.useCases = localConfig.useCases if (!this.useCases) { throw new Error( - 'Instance of Use Cases library required when instantiating PostEntry REST Controller.' + 'Instance of Use Cases library required when instantiating Auth REST Controller.' ) } diff --git a/src/controllers/rest-api/auth/index.js b/src/controllers/rest-api/auth/index.js index 0ea355a..71da067 100644 --- a/src/controllers/rest-api/auth/index.js +++ b/src/controllers/rest-api/auth/index.js @@ -2,9 +2,13 @@ REST API library for auth route. */ -const AuthRESTRouter = require('./router') +// Public npm libraries. +const Router = require('koa-router') -class AuthRESTController { +// Local libraries. +const AuthRESTController = require('./controller') + +class AuthRouter { constructor (localConfig = {}) { // Dependency Injection. this.adapters = localConfig.adapters @@ -20,12 +24,28 @@ class AuthRESTController { ) } - this.authRESTRouter = new AuthRESTRouter(localConfig) + // Encapsulate dependencies. + this.authRESTController = new AuthRESTController(localConfig) + + // Instantiate the router and set the base route. + const baseUrl = '/auth' + this.router = new Router({ prefix: baseUrl }) } attach (app) { - this.authRESTRouter.attachControllers(app) + if (!app) { + throw new Error( + 'Must pass app object when attached REST API controllers.' + ) + } + + // Define the routes and attach the controller. + this.router.post('/', this.authRESTController.authUser) + + // Attach the Controller routes to the Koa app. + app.use(this.router.routes()) + app.use(this.router.allowedMethods()) } } -module.exports = AuthRESTController +module.exports = AuthRouter diff --git a/src/controllers/rest-api/auth/router.js b/src/controllers/rest-api/auth/router.js deleted file mode 100644 index 6320ebd..0000000 --- a/src/controllers/rest-api/auth/router.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - REST Router for the /auth route. -*/ - -// Public npm libraries. -const Router = require('koa-router') - -// Local libraries. -const AuthRESTController = require('./controller') - -class AuthRESTRouter { - constructor (localConfig = {}) { - // Dependency Injection. - this.adapters = localConfig.adapters - if (!this.adapters) { - throw new Error( - 'Instance of Adapters library required when instantiating PostEntry REST Controller.' - ) - } - this.useCases = localConfig.useCases - if (!this.useCases) { - throw new Error( - 'Instance of Use Cases library required when instantiating PostEntry REST Controller.' - ) - } - - // Encapsulate dependencies. - this.authRESTController = new AuthRESTController(localConfig) - - // Instantiate the router and set the base route. - const baseUrl = '/auth' - this.router = new Router({ prefix: baseUrl }) - } - - attachControllers (app) { - if (!app) { - throw new Error( - 'Must pass app object when attached REST API controllers.' - ) - } - - // Define the routes and attach the controller. - this.router.post('/', this.authRESTController.authUser) - - // Attach the Controller routes to the Koa app. - app.use(this.router.routes()) - app.use(this.router.allowedMethods()) - } -} - -module.exports = AuthRESTRouter diff --git a/test/unit/controllers/rest-api/auth/auth.rest.controller.unit.js b/test/unit/controllers/rest-api/auth/auth.rest.controller.unit.js new file mode 100644 index 0000000..454269c --- /dev/null +++ b/test/unit/controllers/rest-api/auth/auth.rest.controller.unit.js @@ -0,0 +1,90 @@ +/* + Unit tests for the REST API handler for the /users endpoints. +*/ + +// Public npm libraries +const assert = require('chai').assert +const sinon = require('sinon') + +// Local support libraries +const adapters = require('../../../mocks/adapters') +const UseCasesMock = require('../../../mocks/use-cases') +// const app = require('../../../mocks/app-mock') + +const AuthRESTController = require('../../../../../src/controllers/rest-api/auth/controller') +let uut +let sandbox +let ctx + +const mockContext = require('../../../../unit/mocks/ctx-mock').context + +describe('#Auth-REST-Router', () => { + // const testUser = {} + + beforeEach(() => { + const useCases = new UseCasesMock() + uut = new AuthRESTController({ adapters, useCases }) + + sandbox = sinon.createSandbox() + + // Mock the context object. + ctx = mockContext() + }) + + afterEach(() => sandbox.restore()) + + describe('#constructor', () => { + it('should throw an error if adapters are not passed in', () => { + try { + uut = new AuthRESTController() + + assert.fail('Unexpected code path') + } catch (err) { + assert.include( + err.message, + 'Instance of Adapters library required when instantiating Auth REST Controller.' + ) + } + }) + + it('should throw an error if useCases are not passed in', () => { + try { + uut = new AuthRESTController({ adapters }) + + assert.fail('Unexpected code path') + } catch (err) { + assert.include( + err.message, + 'Instance of Use Cases library required when instantiating Auth REST Controller.' + ) + } + }) + }) + + describe('#authUser', () => { + it('should authorize a user', async () => { + // Mock dependencies + const user = { + toJSON: () => { + return { password: 'password' } + }, + generateToken: () => {} + } + sandbox.stub(uut.passport, 'authUser').resolves(user) + + await uut.authUser(ctx) + }) + + it('should catch and throw an error', async () => { + try { + // Force an error + sandbox.stub(uut.passport, 'authUser').rejects('test error') + + await uut.authUser(ctx) + } catch (err) { + // console.log('err: ', err) + assert.include(err.message, 'Unauthorized') + } + }) + }) +}) diff --git a/test/unit/controllers/rest-api/auth/auth.rest.router.unit.js b/test/unit/controllers/rest-api/auth/auth.rest.router.unit.js new file mode 100644 index 0000000..86325e1 --- /dev/null +++ b/test/unit/controllers/rest-api/auth/auth.rest.router.unit.js @@ -0,0 +1,78 @@ +/* + Unit tests for the REST API handler for the /users endpoints. +*/ + +// Public npm libraries +const assert = require('chai').assert +const sinon = require('sinon') + +// Local support libraries +const adapters = require('../../../mocks/adapters') +const UseCasesMock = require('../../../mocks/use-cases') +// const app = require('../../../mocks/app-mock') + +const AuthRouter = require('../../../../../src/controllers/rest-api/auth') +let uut +let sandbox +// let ctx + +// const mockContext = require('../../../../unit/mocks/ctx-mock').context + +describe('#Auth-REST-Router', () => { + // const testUser = {} + + beforeEach(() => { + const useCases = new UseCasesMock() + uut = new AuthRouter({ adapters, useCases }) + + sandbox = sinon.createSandbox() + + // Mock the context object. + // ctx = mockContext() + }) + + afterEach(() => sandbox.restore()) + + describe('#constructor', () => { + it('should throw an error if adapters are not passed in', () => { + try { + uut = new AuthRouter() + + assert.fail('Unexpected code path') + } catch (err) { + assert.include( + err.message, + 'Instance of Adapters library required when instantiating PostEntry REST Controller.' + ) + } + }) + + it('should throw an error if useCases are not passed in', () => { + try { + uut = new AuthRouter({ adapters }) + + assert.fail('Unexpected code path') + } catch (err) { + assert.include( + err.message, + 'Instance of Use Cases library required when instantiating PostEntry REST Controller.' + ) + } + }) + }) + + describe('#attach', () => { + it('should throw an error if app is not passed in.', () => { + try { + uut.attach() + + assert.fail('Unexpected code path') + } catch (err) { + assert.include( + err.message, + 'Must pass app object when attached REST API controllers.' + ) + } + }) + }) +})