diff --git a/index.js b/index.js index 4adb883..853efc3 100644 --- a/index.js +++ b/index.js @@ -2,4 +2,5 @@ var helpers = require('./lib/helpers'); exports.describe = helpers.describe; exports.it = helpers.it; exports.beforeEach = helpers.beforeEach; +exports.util = helpers.util; exports.TestDataBuilder = require('./lib/test-data-builder'); diff --git a/lib/helpers.js b/lib/helpers.js index 000cfdc..fe9a5b4 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -1,10 +1,12 @@ var _describe = {}; var _it = {}; var _beforeEach = {}; +var _util = {}; var helpers = exports = module.exports = { describe: _describe, it: _it, - beforeEach: _beforeEach + beforeEach: _beforeEach, + util: _util }; var assert = require('assert'); var request = require('supertest'); @@ -33,11 +35,11 @@ _beforeEach.cleanDatasource = function(dsName) { if (typeof this.app === 'function' && typeof this.app.datasources === 'object' && typeof this.app.datasources[dsName] === 'object') { - this.app.datasources[dsName].automigrate(); + this.app.datasources[dsName].automigrate(done); this.app.datasources[dsName].connector.ids = {}; + } else { + done(); } - - done(); }); } @@ -98,15 +100,16 @@ _beforeEach.givenModel = function(modelName, attrs, optionalHandler) { var test = this; var app = this.app; var model = app.models[modelName]; + + var createFunc = (typeof model.upsert === 'function')? 'upsert':'create'; + assert(model, 'cannot get model of name ' + modelName + ' from app.models'); assert(model.dataSource, 'cannot test model '+ modelName + ' without attached dataSource'); - assert( - typeof model.create === 'function', - modelName + ' does not have a create method' - ); + assert(typeof model[createFunc] === 'function', modelName + + ' does not have a create/upsert method'); - model.create(attrs, function(err, result) { + model[createFunc](attrs, function(err, result) { if(err) { console.error(err.message); if(err.details) console.error(err.details); @@ -123,7 +126,11 @@ _beforeEach.givenModel = function(modelName, attrs, optionalHandler) { } afterEach(function(done) { - this[modelKey].destroy(done); + if (this[modelKey]) { + this[modelKey].destroy(done); + } else { + done(); + } }); } @@ -164,7 +171,7 @@ _beforeEach.givenUserWithRole = function (attrs, role, optionalHandler) { if(err.details) console.error(err.details); return done(err); } - + test.userRoleMapping = result; done(); } @@ -194,7 +201,7 @@ _beforeEach.givenUserWithRole = function (attrs, role, optionalHandler) { _beforeEach.givenLoggedInUser = function(credentials, optionalHandler) { _beforeEach.givenUser(credentials, function(done) { var test = this; - this.app.models[this.userModel].constructor.login(credentials, function(err, token) { + this.app.models[this.userModel].login(credentials, function(err, token) { if(err) { done(err); } else { @@ -217,7 +224,7 @@ _beforeEach.givenLoggedInUser = function(credentials, optionalHandler) { _beforeEach.givenLoggedInUserWithRole = function(credentials, role, optionalHandler){ _beforeEach.givenUserWithRole(credentials, role, function(done) { var test = this; - this.app.models[this.userModel].constructor.login(credentials, function(err, token) { + this.app.models[this.userModel].login(credentials, function(err, token) { if(err) { done(err); } else { @@ -328,7 +335,7 @@ _describe.whenCalledByUserWithRole = function (credentials, role, verb, url, dat describe('when called by logged in user with role ' + role, function () { _beforeEach.givenLoggedInUserWithRole(credentials, role); _describe.whenCalledRemotely(verb, url, data, cb); - }); + }); } _describe.whenCalledAnonymously = function(verb, url, data, cb) { @@ -340,7 +347,7 @@ _describe.whenCalledAnonymously = function(verb, url, data, cb) { _describe.whenCalledUnauthenticated = function(verb, url, data, cb) { describe('when called with unauthenticated token', function () { - _beforeEach.givenAnAnonymousToken(); + _beforeEach.givenAnUnauthenticatedToken(); _describe.whenCalledRemotely(verb, url, data, cb); }); } @@ -356,6 +363,14 @@ _it.shouldBeAllowed = function() { _it.shouldBeDenied = function() { it('should not be allowed', function() { + assert(this.res); + var expectedStatus = 401; + expect(this.res.statusCode).to.equal(expectedStatus); + }); +} + +_it.shouldBeForbidden = function() { + it('should be forbidden', function() { assert(this.res); var expectedStatus = this.aclErrorStatus || this.app && this.app.get('aclErrorStatus') || @@ -409,7 +424,7 @@ function(credentials, verb, url, data) { _it.shouldBeDeniedWhenCalledByUser = function(credentials, verb, url) { _describe.whenCalledByUser(credentials, verb, url, function() { - _it.shouldBeDenied(); + _it.shouldBeForbidden(); }); } @@ -423,6 +438,26 @@ function(credentials, role, verb, url, data) { _it.shouldBeDeniedWhenCalledByUserWithRole = function(credentials, role, verb, url) { _describe.whenCalledByUserWithRole(credentials, role, verb, url, function() { - _it.shouldBeDenied(); + _it.shouldBeForbidden(); }); } + +_util.dumpHttpRequest = +function(logger, tag, req) { + logger('[' + tag + '] Request: \nheaders: %j\n', req._headers); +} + +_util.dumpHttpResponse = +function(logger, tag, res) { + logger('[' + tag + '] Response: \nstatus: %s\nmessage: %s\nheaders: %j\nbody: %j', + res.statusCode, + res.statusMessage, + res.headers, + res.body); +} + +_util.dumpHttpContext = +function(logger, tag, ctx) { + this.dumpHttpRequest(logger, tag, ctx.req); + this.dumpHttpResponse(logger, tag, ctx.res); +} diff --git a/package.json b/package.json index 83666e6..169baf2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "loopback-testing", - "version": "1.2.0", + "version": "1.2.3", "description": "Utilities for testing LoopBack applications", "main": "index.js", "scripts": { @@ -8,7 +8,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/strongloop/loopback-testing" + "url": "https://github.com/tscoder/loopback-testing" }, "author": "Ritchie Martori", "dependencies": { @@ -22,6 +22,6 @@ }, "license": { "name": "Dual MIT/StrongLoop", - "url": "https://github.com/strongloop/loopback-testing/blob/master/LICENSE" + "url": "https://github.com/tscoder/loopback-testing/blob/master/LICENSE" } }