UNPKG

box-view-api

Version:

Box View API, node.js client library

343 lines (320 loc) 11 kB
// Sets up a *global* framework for testing. // // This is included in the mocha.opts file as a --require, // so that individual test specs don't have to explicitly require the framework. var _ = require('underscore'); var chai = require('chai'); expect = chai.expect; var boxViewResponses = require('./boxViewResponses'); var boxViewDetails = (function(){ // if the boxViewDetails.js exists, use the values in that // otherwise use default (dummy) ones. try { return require('./boxViewDetails'); } catch (e) { return null; } })() || { validApiKey: 'replace-with-a-valid-api-key', dummyApiKey: 'leave-this-dummy-api-key-alone' }; var DocumentAPI = require('index').DocumentAPI; var document = new DocumentAPI(boxViewDetails.validApiKey); function checkProps(objFn, props, strict) { it('should be an object', (function (_ofn) { return function () { expect(_ofn()).to.be.an('object'); }; })(objFn)); function checkPropType(getter, name, type, value) { it('should have a property called "' + name + '"', (function (_ofn, _pn, _t) { return function () { expect(_ofn()).to.have.a.property(_pn); }; })(getter, name, type)); describe('.'+name, function() { it('should be of type "' + type + '"', (function (_ofn, _pn, _t) { return function () { if (_t.indexOf('?') === 0) { _t = _t.substring(1); if (_ofn()[_pn] === null) { // it's ok for something to be null if it's type string starts with a '?' return; } } expect(_ofn()[_pn]).to.be.a(_t); }; })(getter, name, type)); if (value) { it('should be equal to "' + value + '"', (function (_ofn, _pn, _v) { return function () { expect(_ofn()[_pn]).to.equal(_v); }; })(getter, name, value)); } }); // it('.' + name + ' should be of type "' + type + '"', (function (_ofn, _pn, _t) { // return function () { // if (_t.indexOf('?') === 0) { // _t = _t.substring(1); // if (_ofn()[_pn] === null) { // // it's ok for something to be null if it's type string starts with a '?' // return; // } // } // expect(_ofn()[_pn]).to.be.a(_t); // }; // })(getter, name, type)); } for (var p in props) { if (typeof props[p] === 'object') { it('should have a property called "' + p + '", which is an object with more properties', (function (_ofn, _pn, _po) { return function () { expect(_ofn()).to.have.a.property(_pn); expect(_ofn()[_pn]).to.be.an('object'); }; })(objFn, p, props[p])); describe('.' + p, (function (_ofn, _pn, _po) { return function () { checkProps(function () { return _ofn()[_pn]; }, _po, strict); }; })(objFn, p, props[p])); } else { switch (props[p]) { case 'object': case 'string': case 'boolean': case 'number': case 'array': case 'function': case '?object': case '?string': checkPropType(objFn, p, props[p]); break; case 'undefined': it('should not have a property called "' + p + '"', (function (_ofn, _pn, _t) { return function () { expect(_ofn()).to.not.have.a.property(_pn); }; })(objFn, p, props[p])); break; default: if (props[p].indexOf('$') === 0) { checkPropType(objFn, p, 'string', props[p].substr(1)); } else { it('should have a property called "' + p + '"', (function (_ofn, _pn, _t) { return function () { expect(_ofn()).to.have.a.property(_pn); }; })(objFn, p, props[p])); it('.' + p + ' should be of type "' + props[p] + '"', (function (_ofn, _pn, _t) { return function () { expect(_ofn()[_pn]).to.be.an.instanceOf(_t); }; })(objFn, p, props[p])); } break; } } } var keys; if (strict) { keys = Object.keys(props); if (keys && keys.length > 0) { it('should have no other properties', function () { expect(objFn()).to.have.keys(keys); }); } else { it('should have no properties', function() { expect(Object.keys(objFn()).length).to.equal(0); }); } } } var tempUuid = { uuids: [], add: function(uuid) { tempUuid.uuids.push(uuid); }, remove: function(uuid) { var i; while((i = tempUuid.uuids.indexOf(uuid)) >= 0 ) { tempUuid.uuids.splice(i, 1); } }, purge: function (cb, failed) { failed = failed || []; cb = cb || function(){}; if (tempUuid.uuids && tempUuid.uuids.length > 0) { document.remove(tempUuid.uuids[0], function(e, r, b) { if (b === false || b.error) { failed.push(tempUuid.uuids[0]); } tempUuid.remove(tempUuid.uuids[0]); tempUuid.purge(cb, failed); }); } else { cb(null, failed); } }, fromUrl: function(url, name, cb) { cb = cb || function(){}; document.uploadUrl(url, name, function(e, r, b) { if (!e && b && b.uuid) { tempUuid.add(b.uuid); } cb(e, r, b); }); }, fromFile: function(filepath, cb) { cb = cb || function(){}; document.uploadFile(filepath, function(e, r, b) { if (!e && b && b.uuid) { tempUuid.add(b.uuid); } cb(e, r, b); }); }, waitFor: function(id, cb) { cb = cb || function(){}; document.poll(id, cb); } }; function commonChecks(it, e, r, b) { it('should get a truthy response', function() { framework.assert(r(), 'Expected response to be truthy, not: '+r()); }); it('should have truthy response headers', function() { framework.assert(r().headers, 'Expected response headers to be truthy, not: '+r().headers); }); it('should have a truthy response body', function() { framework.assert(b(), 'Expected body to be truthy, not: '+b()); }); it('should get a falsey error', function () { framework.assert(!e(), 'Expected error to be falsey, not: ' + e()); }); } function statusCodeChecks(it, statusCode) { return function (e, r, b) { it('should get a ' + statusCode + ' response code', function () { framework.assert(r().statusCode === statusCode, 'Expected status code to be ' + statusCode + ', not ' + r().statusCode); }); commonChecks(it, e, r, b); }; } function contentTypeChecks(e, r, b, mimeType, invert) { mimeType = mimeType || 'application/json'; if (invert) { it('should have a content-type response header which is not '+mimeType, function () { var contentType = r().headers['content-type']; framework.assert((typeof contentType === 'string') && contentType.toLowerCase().indexOf(mimeType) < 0, 'Expected content type not to be '+mimeType); }); } else { it('should have a content-type response header of '+ mimeType, function () { var contentType = r().headers['content-type']; framework.assert((typeof contentType === 'string') && contentType.toLowerCase().indexOf(mimeType) >= 0, 'Expected content type to be ' + mimeType + ', not: ' + contentType); }); } } function jsonContentTypeChecks(e, r, b, notJson) { return contentTypeChecks(e, r, b, 'application/json', notJson); } function instanceMethodTests(getInstance, method, goodParams, badParams) { var index; for (index = 0; index < goodParams.length; index++) { it('should not throw an error when called with ' + goodParams[index].name, (function (i) { return function () { getInstance()[method].apply(getInstance(), goodParams[i].args); }; })(index)); } for (index = 0; index < badParams.length; index++) { it('should throw an error when called with ' + badParams[index].name, (function (i) { return function () { framework.throwsError(function () { getInstance()[method].apply(getInstance(), badParams[i].args); }); }; })(index)); } } framework = module.exports = { assert: require('assert'), url: require('url'), path: require('path'), qs: require('querystring'), inspect: require('util').inspect, exec: require('child_process').exec, fsUtils: require('index').fsUtils, throwsError: function(fn, message) { if (typeof fn !== 'function') { throw new Error('Invalid use of framework: Expected a function to be supplied'); } message = message || 'Expected an error to be thrown'; var err; try { fn(); } catch (e) { err = e; } framework.assert(err, message); }, isArray: _.isArray, tempUuid: tempUuid, tempFile: function(fname) { return framework.path.resolve('test/results', fname); }, timeouts: { poll: 40000, response: 5000 }, statusCodeChecks: statusCodeChecks, contentTypeChecks: contentTypeChecks, jsonContentTypeChecks: jsonContentTypeChecks, restTests: function() { return { _200Checks: statusCodeChecks(it, 200), _201Checks: statusCodeChecks(it, 201), _202Checks: statusCodeChecks(it, 202), _204Checks: statusCodeChecks(it, 204), _400Checks: statusCodeChecks(it, 400), _404Checks: statusCodeChecks(it, 404), _JsonContentChecks: function(e, r, b, notJson) { if (notJson) { it('should have a content-type response header which is not application/json', function() { var contentType = r().headers['content-type']; framework.assert((typeof contentType === 'string') && contentType.toLowerCase().indexOf('application/json') < 0, 'Expected content type not to be application/json'); }); } else { it('should have a content-type response header of application/json', function() { var contentType = r().headers['content-type']; framework.assert((typeof contentType === 'string') && contentType.toLowerCase().indexOf('application/json') >= 0, 'Expected content type to be application/json, not: '+contentType); }); } } }; }, values: { invalidParamList: [ { name: 'undefined', value: undefined }, { name: 'null', value: null }, { name: 'number', value: 1 }, { name: 'boolean, true', value: true }, { name: 'boolean, false', value: false }, { name: 'object', value: {} }, { name: 'function', value: function (){} }, { name: 'empty array', value: [] }, { name: 'empty string', value: '' } ] }, instanceMethodTests: instanceMethodTests, checkProps: checkProps, boxView: boxViewDetails, boxViewResponses: boxViewResponses };