UNPKG

happner

Version:

distributed application engine with evented storage and mesh services

493 lines (350 loc) 11.7 kB
/* RUN: LOG_LEVEL=off mocha test/18-exchange-promises.js */ var Promise = require('bluebird'); var sep = require('path').sep; var spawn = require('child_process').spawn; module.exports = SeeAbove; function SeeAbove() { } SeeAbove.prototype.method1 = function (opts, callback) { if (opts.errorAs == 'callback') return callback(new Error('THIS IS JUST A TEST')); if (opts.errorAs == 'throw') throw new Error('THIS IS JUST A TEST'); opts.number++; callback(null, opts); }; SeeAbove.prototype.method2 = function (opts, callback) { if (opts.errorAs == 'callback') return callback(new Error('THIS IS JUST A TEST')); if (opts.errorAs == 'throw') throw new Error('THIS IS JUST A TEST'); opts.number++; callback(null, opts); }; SeeAbove.prototype.method3 = function ($happn, $origin, opts, callback) { if (opts.errorAs == 'callback') return callback(new Error('THIS IS JUST A TEST')); if (opts.errorAs == 'throw') throw new Error('THIS IS JUST A TEST'); opts.number++; callback(null, opts); }; SeeAbove.prototype.synchronousMethod = function(opts, opts2){ return opts + opts2; }; SeeAbove.prototype.$happner = { config: { 'testComponent': { schema: { methods: { 'methodName1': { alias: 'ancientmoth' }, 'methodName2': { alias: 'ancientmoth' }, 'synchronousMethod': { type: 'sync-promise'//NB - this is how you can wrap a synchronous method with a promise } } } } } }; if (global.TESTING_E9) return; // When 'requiring' the module above, describe('e3a-rest-component', function () { /** * Simon Bishop * @type {expect} */ // Uses unit test 2 modules var expect = require('expect.js'); var Mesh = require('../'); var libFolder = __dirname + sep + 'lib' + sep; //var REMOTE_MESH = 'e2-remote-mesh'; var REMOTE_MESH = 'e3-remote-mesh'; require('benchmarket').start(); after(require('benchmarket').store()); this.timeout(120000); var mesh; var remote; var startRemoteMesh = function(callback){ var timedOut = setTimeout(function(){ callback(new Error('remote mesh start timed out')); },5000); // spawn remote mesh in another process remote = spawn('node', [libFolder + REMOTE_MESH]); remote.stdout.on('data', function (data) { if (data.toString().match(/READY/)) { clearTimeout(timedOut); setTimeout(function(){ callback(); },1000); } }); }; before(function (done) { global.TESTING_E9 = true; //............. startRemoteMesh(function(e){ if (e) return done(e); Mesh.create({ port: 10000, util: { // logger: {} }, modules: { 'testComponent': { path: __filename // ............. } }, components: { 'testComponent': {} }, endpoints:{ 'remoteMesh': { // remote mesh node reconnect:{ max:2000, //we can then wait 10 seconds and should be able to reconnect before the next 10 seconds, retries:100 }, config: { port: 10001, host: 'localhost' } } } }, function (err, instance) { delete global.TESTING_E9; //............. mesh = instance; if (err) return done(err); mesh.exchange.remoteMesh.remoteComponent.remoteFunction('one','two','three', function(err, result){ if (err) return done(err); done(); }); }); }); }); after(function (done) { this.timeout(30000); if (remote) remote.kill(); if (mesh) mesh.stop({reconnect: false}, done); }); var happnUtils = require('../lib/system/utilities'); var mock$Happn = { _mesh:{ utilities:happnUtils, config:{ datalayer:{ secure:false } } }, exchange:{ testComponent:{ method1:function(opts, callback){ opts.number++; callback(null, opts); } } } }; var mock$Origin = { }; var mockResponse = { writeHead:function(code, header){ this.header = {code:code, header:header}; } }; it('tests the rest components __respond method', function(done){ var RestModule = require('../lib/modules/rest/index.js'); var restModule = new RestModule(); var testStage = 'success'; mockResponse.end = function(responseString){ try{ if (testStage == "done") return; var response = JSON.parse(responseString); //TODO: an unexpected GET or POST with a non-json content if (testStage == 'success'){ expect(response.message).to.be("test success response"); expect(response.data.test).to.be("data"); testStage = 'error'; restModule.__respond(mock$Happn, 'test success response', {"test":"data"}, new Error('a test error'), mockResponse); } if (testStage == 'error'){ expect(response.error).to.not.be(null); expect(response.error.message).to.be('a test error'); testStage = "done"; done(); } }catch(e){ done(e); } }; restModule.__respond(mock$Happn, 'test success response', {"test":"data"}, null, mockResponse); }); it('tests the rest components __parseBody method', function(done){ var RestModule = require('../lib/modules/rest/index.js'); var restModule = new RestModule(); var MockRequest = require('./lib/helper_mock_req'); var request = new MockRequest({ method: 'POST', url: '/rest/api', headers: { 'Accept': 'application/json' } }); request.write({ parameters:{ 'opts':{ number:1 } } }); request.end(); mockResponse.end = function(responseString){ var response = JSON.parse(responseString); if (!response.error) return done(new Error('bad response expected error')); done(new Error(response.error)); }; restModule.__parseBody(request, mockResponse, mock$Happn, function(body){ expect(body).to.not.be(null); expect(body).to.not.be(undefined); expect(body.parameters['opts'].number).to.be(1); done(); }); }); it('tests the rest components describe method over the api', function(done){ var restClient = require('restler'); restClient.get('http://localhost:10000/rest/describe').on('complete', function(result){ expect(result.data['/testComponent/method1']).to.not.be(null); expect(result.data['/testComponent/method2']).to.not.be(null); // expect(result.data['/remoteMesh/remoteComponent/remoteFunction'].parameters['one']).to.be('{{one}}'); // expect(result.data['/remoteMesh/remoteComponent/remoteFunction'].parameters['two']).to.be('{{two}}'); // expect(result.data['/remoteMesh/remoteComponent/remoteFunction'].parameters['three']).to.be('{{three}}'); done(); }); }); it('tests the rest components handleRequest method', function(done){ var RestModule = require('../lib/modules/rest/index.js'); var restModule = new RestModule(); restModule.__exchangeDescription = { components:{ testComponent:{ methods:{ method1:{ parameters:[ {name:'opts'}, {name:'callback'} ] } } } } }; var MockRequest = require('./lib/helper_mock_req'); var request = new MockRequest({ method: 'POST', url: '/testComponent/method1', headers: { 'Accept': 'application/json' } }); var operation = { parameters:{ 'opts':{'number':1} } }; request.write(operation); request.end(); mockResponse.end = function(responseString){ var response = JSON.parse(responseString); expect(response.data.number).to.be(2); done(); }; restModule.handleRequest(request, mockResponse, mock$Happn, mock$Origin); }); it('tests posting an operation to a local method', function(done){ var restClient = require('restler'); var operation = { parameters:{ 'opts':{'number':1} } }; restClient.postJson('http://localhost:10000/rest/method/testComponent/method1', operation).on('complete', function(result){ expect(result.data.number).to.be(2); done(); }); }); it('tests posting an operation to a remote method fails', function(done){ var restClient = require('restler'); var operation = { parameters:{ 'one':'one', 'two':'two', 'three':'three' } }; restClient.postJson('http://localhost:10000/rest/method/remoteMesh/remoteComponent/remoteFunction', operation).on('complete', function(result){ expect(result.error).to.not.be(null); expect(result.error.message).to.be('attempt to access remote mesh: remoteMesh'); done(); }); }); it('tests posting an operation to a bad method', function(done){ var restClient = require('restler'); var operation = { parameters:{ 'opts':{'number':1} } }; restClient.postJson('http://localhost:10000/rest/method/blithering_idiot', operation).on('complete', function(result){ expect(result.error.message).to.be('component blithering_idiot does not exist on mesh'); done(); }); }); it('tests posting an operation to the security component fails', function(done){ //TODO login function gives us a token, token is used in body of rest request var restClient = require('restler'); var operation = { parameters:{ 'username':'_ADMIN', 'password':'blah' } }; restClient.postJson('http://localhost:10000/rest/method/security/updateOwnUser', operation).on('complete', function(result){ expect(result.error.number).to.not.be(null); expect(result.error.message).to.be('attempt to access security component over rest'); done(); }); }); it('tests posting an operation an unsecured mesh, with a token works', function(done){ var restClient = require('restler'); var operation = { parameters:{ 'opts':{'number':1} } }; restClient.postJson('http://localhost:10000/rest/method/testComponent/method1?happn_token=' + 'blahblah', operation).on('complete', function(result){ expect(result.data.number).to.be(2); done(); }); }); it('tests posting an operation to a local method, bad uri component', function(done){ var restClient = require('restler'); var operation = { parameters:{ 'opts':{'number':1} } }; restClient.postJson('http://localhost:10000/rest/method/nonexistant/uri', operation).on('complete', function(result){ expect(result.error.message).to.be('component nonexistant does not exist on mesh'); done(); }); }); it('tests posting an operation to a local method, bad uri method', function(done){ var restClient = require('restler'); var operation = { parameters:{ 'opts':{'number':1} } }; restClient.postJson('http://localhost:10000/rest/method/testComponent/nonexistant', operation).on('complete', function(result){ expect(result.error.message).to.be('method nonexistant does not exist on component testComponent'); done(); }); }); require('benchmarket').stop(); });