Socket
Socket
Sign inDemoInstall

kinvey-flex-sdk

Package Overview
Dependencies
Maintainers
2
Versions
54
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

kinvey-flex-sdk - npm Package Compare versions

Comparing version 3.2.1 to 3.3.0-alpha.1

test/unit/lib/mocks/loggerMock.js

4

CHANGELOG.md
## Changelog
### 3.3.0
* Added new onInsertMulti data event for handling insertion of Arrays
* Added support for arrays in dataStore.save()
### 3.2.1
* When making requests to Kinvey, use original requests computed API version rather than relying on the header API Version.

@@ -5,0 +9,0 @@ * Change default API version to 3 when making requests to Kinvey and no API version is present

@@ -31,2 +31,9 @@ /**

function getPublicConnectionErrorMsg(receiverMsg) {
if (receiverMsg === 'Connection ended by client.') {
return 'Flex Service request timed out.';
}
return 'Unexpected network issue.';
}
class Flex {

@@ -88,2 +95,9 @@ constructor(opt, cb) {

const complete = (task) => {
const errorMsg = completionCallback(null, task);
if (errorMsg && options.type === 'tcp') {
this.logger.error(`Unable to send response for taskId ${task.taskId}: ${getPublicConnectionErrorMsg(errorMsg)}`);
}
};
if (this.sharedSecret != null

@@ -103,3 +117,3 @@ && task.taskType !== 'serviceDiscovery'

task.response.continue = false;
return completionCallback(null, task);
return complete(task);
}

@@ -118,3 +132,3 @@

task.response.continue = false;
return completionCallback(null, task);
return complete(task);
}

@@ -134,7 +148,7 @@

};
return completionCallback(null, task);
return complete(task);
}
return this[task.taskType].process(task, this.moduleGenerator.generate(task), (taskWithError, task) => {
completionCallback(null, taskWithError || task);
complete(taskWithError || task);
});

@@ -141,0 +155,0 @@ });

14

lib/service/auth.js

@@ -15,2 +15,3 @@ /**

const logger = require('./logger');
const notImplementedHandler = require('./notImplementedHandler');

@@ -20,2 +21,6 @@

function logAlreadyResponded(handlerName) {
logger.error(`Invoked done() or next() more than once to the same FlexAuth request in handler "${handlerName}"`);
}
function getHandlers() {

@@ -46,4 +51,5 @@ return [...authFunctions.keys()];

function authCompletionHandler(task, callback) {
let responseCallback = callback;
function completionHandler(token) {
const responseCallback = callback;
const result = task.response;

@@ -134,3 +140,4 @@

result.continue = false;
return responseCallback(null, task);
responseCallback(null, task);
responseCallback = logAlreadyResponded.bind(null, task.taskName);
},

@@ -145,3 +152,4 @@ done() {

result.continue = false;
return responseCallback(null, task);
responseCallback(null, task);
responseCallback = logAlreadyResponded.bind(null, task.taskName);
}

@@ -148,0 +156,0 @@ };

@@ -22,2 +22,3 @@ /**

'onInsert',
'onInsertMany',
'onDeleteById',

@@ -60,2 +61,6 @@ 'onDeleteAll',

onInsertMany(functionToExecute) {
this.register('onInsertMany', functionToExecute);
}
onDeleteById(functionToExecute) {

@@ -163,3 +168,7 @@ this.register('onDeleteById', functionToExecute);

if (task.method === 'POST') {
dataOp = 'onInsert';
if (Array.isArray(task.request.body)) {
dataOp = 'onInsertMany';
} else {
dataOp = 'onInsert';
}
} else if (task.method === 'PUT') {

@@ -166,0 +175,0 @@ dataOp = 'onUpdate';

@@ -15,8 +15,24 @@ /**

const logger = require('./logger');
function isFunctionHandler(taskType) {
return taskType === 'businessLogic' || taskType === 'functions';
}
function logAlreadyResponded(task) {
let message = 'Invoked done() or next() more than once to the same Flex ';
if (isFunctionHandler(task.taskType)) {
message += `Functions request to "${task.taskName}"`;
} else {
message += `Data handler ${task.request.method} for ${task.request.serviceObjectName}`;
}
logger.error(message);
}
function createCompletionHandler(task, requestBody, cb) {
const callback = !cb && typeof requestBody === 'function' ? requestBody : cb;
const updateRequestBody = typeof requestBody === 'function' ? {} : requestBody;
let responseCallback = callback;
function completionHandler(body) {
let responseCallback = callback;
const result = {};

@@ -153,4 +169,3 @@

responseCallback(null, task);
responseCallback = () => null;
return responseCallback;
responseCallback = logAlreadyResponded.bind(null, task);
},

@@ -176,4 +191,3 @@ next() {

responseCallback(null, task);
responseCallback = () => null;
return responseCallback;
responseCallback = logAlreadyResponded.bind(null, task);
}

@@ -180,0 +194,0 @@ };

@@ -47,4 +47,3 @@ /**

const requestOptions = this._buildAppdataRequest(collectionName);
if (entity._id) {
if (!Array.isArray(entity) && entity._id) {
requestOptions.method = 'PUT';

@@ -51,0 +50,0 @@ requestOptions.url += entity._id;

{
"name": "kinvey-flex-sdk",
"version": "3.2.1",
"version": "3.3.0-alpha.1",
"description": "SDK for creating Kinvey Flex Services",

@@ -20,3 +20,3 @@ "engines": {

"bson": "0.4.23",
"kinvey-code-task-runner": "2.3.1",
"kinvey-code-task-runner": "2.4.0",
"kinvey-datalink-errors": "0.3.2",

@@ -35,3 +35,3 @@ "moment": "2.22.2",

"should": "13.2.3",
"sinon": "7.1.1",
"sinon": "7.2.7",
"test-console": "1.1.0",

@@ -38,0 +38,0 @@ "uuid": "3.3.2"

@@ -15,5 +15,9 @@ /**

const auth = require('../../../lib/service/auth');
const should = require('should');
const sinon = require('sinon');
const proxyquire = require('proxyquire');
const loggerMock = require('./mocks/loggerMock');
const auth = proxyquire('../../../lib/service/auth', { './logger': loggerMock });
function quickRandom() {

@@ -133,2 +137,3 @@ return Math.floor((Math.random() * (1000 - 1)) + 1);

afterEach((done) => {
loggerMock.error.resetHistory();
auth.clearAll();

@@ -188,3 +193,2 @@ return done();

});
it('should return a 401 server_error', (done) => {

@@ -262,3 +266,33 @@ const taskName = quickRandom();

});
['next', 'done'].forEach((method1) => {
['next', 'done'].forEach((method2) => {
it(`should log a message when attempting to respond more than once, by calling ${method1}() and then ${method2}()`, (done) => {
const taskName = quickRandom();
const task = sampleTask(taskName);
auth.register(taskName, (context, complete) => {
complete({ foo: 'bar' }).ok()[method1]();
setTimeout(() => {
complete({ foo: 'not bar' }).ok()[method2]();
}, 0);
});
const processCallbackSpy = sinon.spy((err, result) => {
should.not.exist(err);
result.response.statusCode.should.eql(200);
result.response.body.should.eql({ token: { foo: 'bar' }, authenticated: true });
result.response.continue.should.eql(false);
});
loggerMock.error = sinon.spy((message) => {
message.should.eql(`Invoked done() or next() more than once to the same FlexAuth request in handler "${taskName}"`);
processCallbackSpy.calledOnce.should.eql(true);
done();
});
auth.process(task, null, processCallbackSpy);
});
});
});
});
});

@@ -15,5 +15,10 @@ /**

const data = require('../../../lib/service/data');
const should = require('should');
const sinon = require('sinon');
const proxyquire = require('proxyquire');
const loggerMock = require('./mocks/loggerMock');
const completionHandler = proxyquire('../../../lib/service/kinveyCompletionHandler', { './logger': loggerMock });
const data = proxyquire('../../../lib/service/data', { './kinveyCompletionHandler': completionHandler });
const serviceObjectName = 'myServiceObject';

@@ -42,2 +47,3 @@

afterEach((done) => {
loggerMock.error.resetHistory();
data.clearAll();

@@ -52,2 +58,7 @@ return done();

});
it('can register insertMany ', (done) => {
data.serviceObject(serviceObjectName).onInsertMany(() => done());
const fn = data.serviceObject(serviceObjectName).resolve('onInsertMany');
return fn();
});
it('can register a deleteAll', (done) => {

@@ -195,2 +206,15 @@ data.serviceObject(serviceObjectName).onDeleteAll(() => done());

});
it('can explicitly set an array body', (done) => {
const task = sampleTask();
task.request.body = [];
data.serviceObject(serviceObjectName).onInsertMany((context, complete) => complete()
.setBody([{ foo: 'bar' }])
.ok()
.done());
return data.process(task, {}, (err, result) => {
should.not.exist(err);
result.response.body.should.eql([{ foo: 'bar' }]);
done();
});
});
it('can process an insert', (done) => {

@@ -214,2 +238,31 @@ const task = sampleTask();

});
it('can process insertMany with an empty array body', (done) => {
const task = sampleTask();
task.request.body = [];
data.serviceObject(serviceObjectName).onInsertMany((context) => {
context.body.should.eql([]);
return done();
});
return data.process(task, {}, () => {});
});
it('can process insertMany with an array body', (done) => {
const task = sampleTask();
task.request.body = [{ foo: 'bar' }, { foo2: 'bar2' }];
data.serviceObject(serviceObjectName).onInsertMany((context) => {
context.body.should.eql(task.request.body);
return done();
});
return data.process(task, {}, () => {});
});
it('can process insertMany and include request, complete, and modules', (done) => {
const task = sampleTask();
task.request.body = [];
data.serviceObject(serviceObjectName).onInsertMany((context, complete, modules) => {
context.should.be.an.Object();
complete.should.be.a.Function();
modules.should.be.an.Object();
return done();
});
return data.process(task, {}, () => {});
});
it('can process an update', (done) => {

@@ -493,2 +546,5 @@ const task = sampleTask();

describe('completion handlers', () => {
afterEach(() => {
loggerMock.error.resetHistory();
});
it('should return a successful response', (done) => {

@@ -660,3 +716,34 @@ const task = sampleTask();

});
['next', 'done'].forEach((method1) => {
['next', 'done'].forEach((method2) => {
it(`should log a message when attempting to respond more than once, by calling ${method1}() and then ${method2}()`, (done) => {
const task = sampleTask();
data.serviceObject(serviceObjectName).onInsert((context, complete) => {
complete({ foo: 'bar' }).ok()[method1]();
setTimeout(() => {
complete({ foo: 'not bar' }).ok()[method2]();
}, 0);
});
const processCallbackSpy = sinon.spy((err, result) => {
should.not.exist(err);
result.response.statusCode.should.eql(200);
result.response.body.should.eql({
foo: 'bar'
});
result.response.continue.should.eql(method1 === 'next');
});
loggerMock.error = sinon.spy((message) => {
const { method, serviceObjectName } = task.request;
message.should.eql(`Invoked done() or next() more than once to the same Flex Data handler ${method} for ${serviceObjectName}`);
processCallbackSpy.calledOnce.should.eql(true);
done();
});
data.process(task, {}, processCallbackSpy);
});
});
});
});
});

@@ -26,7 +26,16 @@ /**

let sdk = null;
before((done) => {
sdk = proxyquire('../../../lib/flex', { 'kinvey-code-task-runner': mockTaskReceiver });
return done();
before(() => {
this.loggerMock = { error: sinon.spy() };
sdk = proxyquire('../../../lib/flex', {
'kinvey-code-task-runner': mockTaskReceiver,
'./service/logger': this.loggerMock
});
});
it('can create a new service', done =>
beforeEach(() => {
this.loggerMock.error = sinon.spy();
});
it('can create a new service', (done) => {
sdk.service((err, flex) => {

@@ -41,4 +50,5 @@ should.not.exist(err);

flex.version.should.eql(flexPackageJson.version);
return done();
}));
done();
});
});

@@ -412,2 +422,94 @@ it('should set the type to http by default', (done) => {

});
it('should log a timeout error, if receiver returns a client disconnect error', (done) => {
process.env.SDK_RECEIVER = 'tcp';
sdk.service((err, sdk) => {
const task = {
taskId: `some id ${Math.random()}`,
appMetadata: {
_id: '12345',
appsecret: 'appsecret',
mastersecret: 'mastersecret',
pushService: undefined,
restrictions: {
level: 'starter'
},
API_version: 3,
name: 'DevApp',
platform: null
},
taskType: 'functions',
taskName: 'foo',
hookType: 'customEndpoint',
method: 'GET',
request: {
method: 'GET',
headers: {},
body: {}
},
response: {
headers: {}
}
};
sdk.functions.register('foo', (context, complete) => {
complete().ok().done();
});
mockTaskReceiver.taskReceived()(task, (err, result) => {
return 'Connection ended by client.';
});
this.loggerMock.error.calledOnce.should.eql(true);
this.loggerMock.error.firstCall.args.length.should.eql(1);
this.loggerMock.error.firstCall.args[0].should.eql(`Unable to send response for taskId ${task.taskId}: Flex Service request timed out.`);
done();
});
});
it('should log an unknown network error, if receiver returns an error which isn\'t a client disconnect', (done) => {
process.env.SDK_RECEIVER = 'tcp';
sdk.service((err, sdk) => {
const task = {
taskId: `some id ${Math.random()}`,
appMetadata: {
_id: '12345',
appsecret: 'appsecret',
mastersecret: 'mastersecret',
pushService: undefined,
restrictions: {
level: 'starter'
},
API_version: 3,
name: 'DevApp',
platform: null
},
taskType: 'functions',
taskName: 'foo',
hookType: 'customEndpoint',
method: 'GET',
request: {
method: 'GET',
headers: {},
body: {}
},
response: {
headers: {}
}
};
sdk.functions.register('foo', (context, complete) => {
complete().ok().done();
});
mockTaskReceiver.taskReceived()(task, (err, result) => {
return `Any other message ${Math.random()}`;
});
this.loggerMock.error.calledOnce.should.eql(true);
this.loggerMock.error.firstCall.args.length.should.eql(1);
this.loggerMock.error.firstCall.args[0].should.eql(`Unable to send response for taskId ${task.taskId}: Unexpected network issue.`);
done();
});
});
});

@@ -15,5 +15,10 @@ /**

const functions = require('../../../lib/service/functions');
const should = require('should');
const sinon = require('sinon');
const proxyquire = require('proxyquire');
const loggerMock = require('./mocks/loggerMock');
const completionHandler = proxyquire('../../../lib/service/kinveyCompletionHandler', { './logger': loggerMock });
const functions = proxyquire('../../../lib/service/functions', { './kinveyCompletionHandler': completionHandler });
const testTaskName = 'myTaskName';

@@ -213,2 +218,3 @@

afterEach((done) => {
loggerMock.error.resetHistory();
functions.clearAll();

@@ -673,3 +679,33 @@ return done();

});
['next', 'done'].forEach((method1) => {
['next', 'done'].forEach((method2) => {
it(`should log a message when attempting to respond more than once, by calling ${method1}() and then ${method2}()`, (done) => {
const taskName = quickRandom();
const task = sampleTask(taskName);
functions.register(taskName, (context, complete) => {
complete({ baz: 'bar' }).ok()[method1]();
setTimeout(() => {
complete({ baz: 'not bar' }).ok()[method2]();
}, 0);
});
const processCallbackSpy = sinon.spy((err, result) => {
should.not.exist(err);
result.response.statusCode.should.eql(200);
const expectedBody = method1 === 'next' ? result.request.body : result.response.body;
expectedBody.should.eql({ baz: 'bar' });
result.response.continue.should.eql(method1 === 'next');
});
loggerMock.error = sinon.spy((message) => {
message.should.eql(`Invoked done() or next() more than once to the same Flex Functions request to "${task.taskName}"`);
done();
});
functions.process(task, null, processCallbackSpy);
});
});
});
});
});

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc