@capriza/connector-controller
Advanced tools
Comparing version 1.0.72 to 1.0.73
@@ -397,8 +397,8 @@ /** | ||
async mapUserIds(data, options) { | ||
var res = this.connector.mapUserIds({ ids : data.ids }, options); | ||
var res = await this.connector.mapUserIds({ ids : data.payload.ids }, options); | ||
if (!(res instanceof Array)) | ||
return options.logger.error(`mapUserIds: Invalid response from connector: ${res}`); | ||
await axios.post(`${this.apiUrl}/connectors/createUserMapping`, res, { headers : this.requestHeaders }); | ||
await axios.post(`${this.apiUrl}/connectors/usermapping`, res, { headers : this.requestHeaders }); | ||
} | ||
}); |
@@ -10,3 +10,13 @@ var Syncher = require ("./syncher.js"); | ||
this.BL = require(process.cwd()); | ||
this.BL.settings = this.BL.settings || {} | ||
try { | ||
this.BL.dataTransformer = require(`${process.cwd()}/resources/transformer.js`); | ||
if(typeof this.BL.dataTransformer === "object") { | ||
let jsltTemplate = this.BL.dataTransformer; | ||
this.BL.dataTransformer = ((approval) => jslt.transform(approval, jsltTemplate)); | ||
} | ||
} catch (err) { | ||
this.logger.log(`transformer.js is not exists`); | ||
this.BL.dataTransformer = identityTransform; | ||
} | ||
this.BL.settings = this.BL.settings || {}; | ||
this.signatureList = []; | ||
@@ -34,23 +44,22 @@ this.validateBL(); | ||
throw new Error (`'getApproval' method is missing in the BL Connector (selfValidation: ${this.BL.settings.selfValidation}, disableMiniSync: ${this.BL.settings.disableMiniSync})`); | ||
} | ||
_addApprovalData(approval, logger) { | ||
if (approval.error) return approval; | ||
if (this.config.schemaTransformer) { | ||
try { | ||
approval = jslt.transform(approval, this.config.schemaTransformer); | ||
} catch(ex) { | ||
logger.error(`Exception with transforming approval. ex=${ex}`); | ||
approval.error = "TransformException"; | ||
return approval; | ||
} | ||
} | ||
if (approval.error) return approval; | ||
approval.metadata = { | ||
fingerprints : this._createApprovalFingerprints(approval) | ||
}; | ||
approval.systemUserId = approval.private.approver; //(todo) should be: hashFunction(approval.private.approver) | ||
try { | ||
approval = this.BL.dataTransformer(approval); | ||
} catch (ex) { | ||
logger.error(`Exception with transforming approval. ex=${ex}`); | ||
approval.error = "TransformException"; | ||
return approval; | ||
} | ||
approval.metadata = { | ||
fingerprints : this._createApprovalFingerprints(approval) | ||
}; | ||
approval.systemUserId = approval.private.approver; //(todo) should be: hashFunction(approval.private.approver) | ||
approval.systemApprovalId = approval.private.id; | ||
return approval; | ||
return approval; | ||
} | ||
@@ -63,8 +72,8 @@ | ||
if (actionFingerprint) { | ||
try { | ||
fingerprints.action = hashFunction(jslt.transform(approval, actionFingerprint)) | ||
} catch(ex) { | ||
logger.error(`Error creating approval fingerprint action: ${(ex && ex.message) ? ex.message : ex}`); | ||
} | ||
} | ||
try { | ||
fingerprints.action = hashFunction(jslt.transform(approval, actionFingerprint)) | ||
} catch(ex) { | ||
logger.error(`Error creating approval fingerprint action: ${(ex && ex.message) ? ex.message : ex}`); | ||
} | ||
} | ||
@@ -165,2 +174,7 @@ return fingerprints; | ||
this.config = context.config.controllerConfig; | ||
// for backward compatibility | ||
if (this.config.schemaTransformer) { | ||
this.BL.dataTransformer = ((approval) => jslt.transform(approval, this.config.schemaTransformer)); | ||
} | ||
return this.BL.init({config: context.config.blConfig, logger: this.getBLLogger(this.logger)}); | ||
@@ -188,3 +202,4 @@ } | ||
if (!approvalsChunk.partialSync) sendApprovals = sendApprovals.concat(syncher.calcRemoved()); | ||
logger.info(syncher.stats, "Sync statistics"); | ||
logger.info(syncher.stats, "Sync statistics"); | ||
syncher.destroy(); | ||
} | ||
@@ -197,10 +212,15 @@ | ||
var fetchRes = this.BL.fetch({ signatureList, logger : blLogger, fetchType : action.syncType }, (err, approvalsChunk, hasMore) => { | ||
if (err) return reject(err); | ||
processChunk(approvalsChunk, hasMore); | ||
}); | ||
if (fetchRes && typeof fetchRes.then == "function") | ||
fetchRes.then(processChunk, reject); | ||
}); | ||
function failedFetch(err) { | ||
syncher.destroy(); | ||
reject(err); | ||
}; | ||
var fetchRes = this.BL.fetch({ signatureList, logger : blLogger, fetchType : action.syncType }, (err, approvalsChunk, hasMore) => { | ||
if (err) return failedFetch(err); | ||
processChunk(approvalsChunk, hasMore); | ||
}); | ||
if (fetchRes && typeof fetchRes.then == "function") | ||
fetchRes.then(processChunk).catch(failedFetch); | ||
}); | ||
} | ||
@@ -236,7 +256,7 @@ async approve (data, options) { | ||
} | ||
async mapUserIds(data, options){ | ||
async mapUserIds(data, options){ | ||
var logger = options.logger.child({component: "connector-controller"}); | ||
var blLogger = this.getBLLogger(logger); | ||
logger.info(`Mapping users: ${data.ids}`); | ||
logger.info(`Mapping users: ${JSON.stringify(data.ids)}`); | ||
try { | ||
@@ -247,2 +267,3 @@ var res = await this.BL.mapUserIds(data, {logger : blLogger}); | ||
} | ||
return res; | ||
} catch (ex) { | ||
@@ -255,1 +276,5 @@ var error = new Error(`Could not map users. ` + (ex.message || ex)); | ||
} | ||
function identityTransform(a) { | ||
return a; | ||
} |
@@ -12,61 +12,92 @@ /** | ||
var synchers = []; | ||
const MAX_SYNCERS = 5; | ||
module.exports = class Syncher { | ||
constructor(signatureList) { | ||
this._signatureList = signatureList; | ||
this._signatureMap = Object.create(null); | ||
this._newApprovalsMap = Object.create(null); | ||
for (var i = 0; i < signatureList.length; ++i) | ||
this._signatureMap[signatureList[i].private.id] = signatureList[i]; | ||
this.stats = { added : 0, updated : 0, removed : 0, error : 0 }; | ||
} | ||
syncChunk(approvals) { | ||
var resApprovals = []; | ||
approvals.forEach(curApproval => { | ||
this._newApprovalsMap[curApproval.private.id] = 1; | ||
var oldApproval = this._signatureMap[curApproval.private.id] | ||
if (curApproval.error) { | ||
++this.stats.error; | ||
} else if (curApproval.deleted) { | ||
if (oldApproval) { | ||
++this.stats.removed; | ||
resApprovals.push({id: oldApproval.id, syncver: oldApproval.syncver, deleted: true}); | ||
} | ||
} else if (!oldApproval) { | ||
++this.stats.added; | ||
resApprovals.push(curApproval); | ||
} else if (curApproval.private.approver != oldApproval.private.approver) { | ||
// In case the approval was found but changed owner, we need to remove it and create a new one, and not update the existing one. | ||
++this.stats.added; | ||
++this.stats.removed; | ||
resApprovals.push({id: oldApproval.id, syncver: oldApproval.syncver, deleted: true}); | ||
resApprovals.push(curApproval); | ||
} else if (!oldApproval.metadata || !oldApproval.metadata.fingerprints || | ||
oldApproval.metadata.fingerprints.sync != curApproval.metadata.fingerprints.sync || | ||
oldApproval.metadata.fingerprints.action != curApproval.metadata.fingerprints.action) { | ||
++this.stats.updated; | ||
resApprovals.push(Object.assign({}, oldApproval, curApproval)); | ||
} | ||
}); | ||
var stats = this.stats; | ||
stats.errorRate = stats.error / ((stats.added + stats.updated + stats.error) || 1); | ||
return resApprovals; | ||
} | ||
calcRemoved() { | ||
var removed = this._signatureList | ||
.filter(oldApproval => !this._newApprovalsMap[oldApproval.private.id]) | ||
.map(a => ({id: a.id, syncver: a.syncver, deleted: true})); | ||
var stats = this.stats; | ||
stats.removed += removed.length; | ||
stats.errorRate = stats.error / ((stats.added + stats.updated + stats.error) || 1); | ||
return removed; | ||
} | ||
static sync(signatureList, approvals) { | ||
var syncher = new Syncher(signatureList); | ||
return syncher.syncChunk(approvals).concat(syncher.calcRemoved()); | ||
} | ||
constructor(signatureList) { | ||
this._signatureList = signatureList; | ||
this._signatureMap = Object.create(null); | ||
this._newApprovalsMap = Object.create(null); | ||
this._removedApprovals = Object.create(null); | ||
for (var i = 0; i < signatureList.length; ++i) | ||
this._signatureMap[signatureList[i].private.id] = signatureList[i]; | ||
this.stats = { added : 0, updated : 0, removed : 0, error : 0 }; | ||
if(synchers.length >= MAX_SYNCERS) synchers.shift(); | ||
synchers.push(this); | ||
} | ||
destroy() { | ||
synchers = synchers.filter(syncher => syncher !== this); | ||
} | ||
syncChunk(approvals) { | ||
var resApprovals = []; | ||
approvals.forEach(curApproval => { | ||
var id = curApproval.private && curApproval.private.id; | ||
if(id) this._newApprovalsMap[id] = 1; | ||
if (this._removedApprovals[id]) return; | ||
var oldApproval = this._signatureMap[id]; | ||
if (curApproval.error) { | ||
++this.stats.error; | ||
} else if (curApproval.deleted) { | ||
if (oldApproval) { | ||
++this.stats.removed; | ||
resApprovals.push({id: oldApproval.id, syncver: oldApproval.syncver, deleted: true}); | ||
this._syncSynchersRemovedApproval(oldApproval.private.id); | ||
} | ||
} else if (!oldApproval) { | ||
++this.stats.added; | ||
resApprovals.push(curApproval); | ||
} else if (curApproval.private.approver != oldApproval.private.approver) { | ||
// In case the approval was found but changed owner, we need to remove it and create a new one, and not update the existing one. | ||
++this.stats.added; | ||
++this.stats.removed; | ||
resApprovals.push({id: oldApproval.id, syncver: oldApproval.syncver, deleted: true}); | ||
resApprovals.push(curApproval); | ||
} else if (!oldApproval.metadata || !oldApproval.metadata.fingerprints || | ||
oldApproval.metadata.fingerprints.sync != curApproval.metadata.fingerprints.sync || | ||
oldApproval.metadata.fingerprints.action != curApproval.metadata.fingerprints.action) { | ||
++this.stats.updated; | ||
resApprovals.push(Object.assign({}, oldApproval, curApproval)); | ||
} | ||
}); | ||
var stats = this.stats; | ||
stats.errorRate = stats.error / ((stats.added + stats.updated + stats.error) || 1); | ||
return resApprovals; | ||
} | ||
calcRemoved() { | ||
var removedIdsList = []; | ||
var removed = this._signatureList | ||
.filter(oldApproval => !this._newApprovalsMap[oldApproval.private.id]) | ||
.map(a => { | ||
removedIdsList.push(a.private.id); | ||
return {id: a.id, syncver: a.syncver, deleted: true}; | ||
}); | ||
var stats = this.stats; | ||
stats.removed += removed.length; | ||
stats.errorRate = stats.error / ((stats.added + stats.updated + stats.error) || 1); | ||
if(synchers.length > 1) removedIdsList.forEach(r => this._syncSynchersRemovedApproval(r)); | ||
return removed; | ||
} | ||
_syncSynchersRemovedApproval(removedApprovalId) { | ||
synchers.forEach(syncher => { | ||
if(syncher !== this) syncher._removedApprovals[removedApprovalId] = true; | ||
}); | ||
} | ||
static sync(signatureList, approvals) { | ||
var syncher = new Syncher(signatureList); | ||
var res = syncher.syncChunk(approvals).concat(syncher.calcRemoved()); | ||
syncher.destroy(); | ||
return res; | ||
} | ||
}; |
{ | ||
"name": "@capriza/connector-controller", | ||
"version": "1.0.72", | ||
"version": "1.0.73", | ||
"description": "Capriza connectors controller", | ||
"main": "index.js", | ||
"directories": { | ||
"test": "test" | ||
}, | ||
"files": [ | ||
"lib", | ||
"outpost", | ||
"test", | ||
"index.js", | ||
"start.js" | ||
], | ||
"scripts": { | ||
@@ -13,8 +17,16 @@ "test": "./node_modules/.bin/mocha --exit --reporter spec", | ||
}, | ||
"author": "Doron Oded", | ||
"author": { | ||
"name": "Capriza", | ||
"email": "connecteam@capriza.com", | ||
"url": "https://www.capriza.com/" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/capriza/connector-sdk" | ||
}, | ||
"dependencies": { | ||
"jslt": "^0.1.0", | ||
"async-exit-hook": "2.0.1", | ||
"axios": "0.17.1", | ||
"deepmerge": "2.0.1", | ||
"jslt": "^0.1.0", | ||
"logrotator": "1.1.0", | ||
@@ -27,3 +39,4 @@ "minimist": "1.2.0", | ||
"proxying-agent": "^2.2.0", | ||
"syswide-cas": "^5.0.0" | ||
"syswide-cas": "^5.0.0", | ||
"ws": "^5.1.1" | ||
}, | ||
@@ -30,0 +43,0 @@ "devDependencies": { |
@@ -24,3 +24,3 @@ var chai = require('chai'); | ||
}; | ||
describe ("approve / reject", function (){ | ||
describe ("SDK Tasks", function (){ | ||
beforeEach (function (){ | ||
@@ -32,2 +32,5 @@ var newApproval = {private: {id: "approval1", approver: "approver1"}}; | ||
settings: {}, | ||
fetch(){ | ||
return Promise.resolve([newApproval]); | ||
}, | ||
getApproval(){ | ||
@@ -59,2 +62,5 @@ return newApproval; | ||
}, | ||
async sync () { | ||
return Connector.prototype.sync.apply(this, arguments); | ||
}, | ||
async getApproval () { | ||
@@ -72,4 +78,236 @@ return Connector.prototype.getApproval.apply (this, arguments); | ||
it ("~1 should fail on bad validation (the approval has changed)", function (done){ | ||
it ("~1 sync task - should add 1 approvals", function (done) { | ||
connector.signatureList = []; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
approvals[0].should.deep.include({private: {approver: "approver1", id: "approval1"}}); | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~2 sync task - fetch return same approval as store in the backend - should add 0 approvals", function (done) { | ||
var backendApproval = {private: {id: "approval1", approver: "approver1"}}; | ||
connector._addApprovalData(backendApproval); | ||
connector.signatureList = [backendApproval]; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
expect(approvals.length).to.equal(0); | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~3 sync task - fetch return new approval - should add 1 approval and remove 1 approval", function (done) { | ||
var backendApproval = {private: {id: "approval2", approver: "approver2"}}; | ||
connector._addApprovalData(backendApproval); | ||
backendApproval.id = "caprizaId1"; | ||
connector.signatureList = [backendApproval]; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
approvals[0].should.deep.include({private: {approver: "approver1", id: "approval1"}}); | ||
approvals[1].should.deep.include({id: "caprizaId1", deleted: true}); | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~4 sync task - fetch return empty list - should remove 1 approval", function (done) { | ||
var backendApproval = {private: {id: "approval1", approver: "approver1"}}; | ||
connector._addApprovalData(backendApproval); | ||
backendApproval.id = "caprizaId1"; | ||
connector.signatureList = [backendApproval]; | ||
connector.BL.fetch = function () { | ||
return Promise.resolve([]) | ||
}; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
approvals[0].should.deep.include({id: "caprizaId1", deleted: true}); | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~5 sync task - fetch return empty list - should remove 0 approval instead of 1 due to partial sync", function (done) { | ||
var backendApproval = {private: {id: "approval1", approver: "approver1"}}; | ||
connector._addApprovalData(backendApproval); | ||
connector.signatureList = [backendApproval]; | ||
connector.BL.fetch = function () { | ||
return Promise.resolve({approvals: [], partialSync: true}); | ||
}; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
expect(approvals.length).to.equal(0); | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~6 sync task - fetch return updated approval - should update 1 approval", function (done) { | ||
var backendApproval = {private: {id: "approval1", approver: "approver1"}, a: "1"}; | ||
connector._addApprovalData(backendApproval); | ||
connector.signatureList = [backendApproval]; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
approvals[0].should.deep.include({private: {approver: "approver1", id: "approval1"}, a: "1"}); | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~7 sync task - fetch return new and updated approval - should update 1, add 1, remove 0 due to partial sync", function (done) { | ||
var backendApproval = {private: {id: "approval1", approver: "approver1"}, a: "1"}; | ||
var backendApproval2 = {private: {id: "approval2", approver: "approver2"}, a: "2"}; | ||
connector._addApprovalData(backendApproval); | ||
connector._addApprovalData(backendApproval2); | ||
connector.signatureList = [backendApproval, backendApproval2]; | ||
connector.BL.fetch = function () { | ||
var updatedApproval = {private: {id: "approval1", approver: "approver1"}, a: "a"}; | ||
var newApproval = {private: {id: "approval3", approver: "approver3"}, a: "3"}; | ||
return Promise.resolve({approvals: [updatedApproval, newApproval], partialSync: true}) | ||
}; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
approvals[0].should.deep.include({private: {approver: "approver1", id: "approval1"}, a: "a"}); | ||
approvals[1].should.deep.include({private: {approver: "approver3", id: "approval3"}, a: "3"}); | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~8 sync task - using callback - should add one approval, one chunk", function (done) { | ||
connector.signatureList = []; | ||
connector.BL.fetch = function ({}, callback) { | ||
var newApproval = {private: {id: "approval1", approver: "approver1"}}; | ||
callback(null, [newApproval], false); | ||
}; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
approvals[0].should.deep.include({private: {approver: "approver1", id: "approval1"}}); | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~9 sync task - using callback - should add two approvals, two chunk", function (done) { | ||
connector.signatureList = []; | ||
connector.BL.fetch = function ({}, callback) { | ||
var newApproval = {private: {id: "approval1", approver: "approver1"}}; | ||
callback(null, [newApproval], false); | ||
var newApproval2 = {private: {id: "approval2", approver: "approver2"}}; | ||
callback(null, [newApproval2], true); | ||
}; | ||
let times = 0; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
if(times==0) { | ||
approvals[0].should.deep.include({private: {approver: "approver1", id: "approval1"}}); | ||
times++; | ||
} else { | ||
approvals[0].should.deep.include({private: {approver: "approver2", id: "approval2"}}); | ||
} | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~10 sync task - using callback - should add one approval, and NOT remove one because of partialSync", function (done) { | ||
var backendApproval = {private: {id: "approval1", approver: "approver1"}, a: "1"}; | ||
connector._addApprovalData(backendApproval); | ||
connector.signatureList = [backendApproval]; | ||
connector.BL.fetch = function ({}, callback) { | ||
var newApproval2 = {private: {id: "approval2", approver: "approver2"}}; | ||
callback(null, {approvals: [newApproval2], partialSync: true}, false); | ||
}; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
approvals[0].should.deep.include({private: {approver: "approver2", id: "approval2"}}); | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~11 sync task - using callback - should add 1 approval, and remove 1", function (done) { | ||
var backendApproval = {private: {id: "approval1", approver: "approver1"}, a: "1"}; | ||
connector._addApprovalData(backendApproval); | ||
backendApproval.id = "caprizaId1"; | ||
connector.signatureList = [backendApproval]; | ||
connector.BL.fetch = function ({}, callback) { | ||
var newApproval2 = {private: {id: "approval2", approver: "approver2"}}; | ||
callback(null, [newApproval2], false); | ||
}; | ||
let action = { | ||
logger: logger, | ||
send: function (approvals) { | ||
approvals[0].should.deep.include({private: {approver: "approver2", id: "approval2"}}); | ||
approvals[1].should.deep.include({id: "caprizaId1", deleted: true}); | ||
} | ||
}; | ||
connector.sync(action).then(() => { | ||
done(); | ||
}); | ||
}); | ||
it ("~12 sync task - using callback - throw error", function (done) { | ||
connector.signatureList = []; | ||
connector.BL.fetch = function ({}, callback) { | ||
callback("simulated error", [], false); | ||
}; | ||
let action = { | ||
logger: logger, | ||
}; | ||
connector.sync(action).then(res => { | ||
}).catch(err => { | ||
expect(err).to.equal("simulated error"); | ||
done(); | ||
}); | ||
}); | ||
it ("~13 approve task - should fail on bad validation (the approval has changed)", function (done){ | ||
var backendApproval = {private: {id: "approval1", approver: "approver1", a: "a"}}; | ||
@@ -89,3 +327,3 @@ connector._addApprovalData(backendApproval); | ||
it ("~2 should return the approval as deleted once approved (assuming not returned again by getApproval)", function (done) { | ||
it ("~14 approve task - should return the approval as deleted once approved (assuming not returned again by getApproval)", function (done) { | ||
var approval = {private: {id: "approval1", approver: "approver1"}}; | ||
@@ -102,5 +340,6 @@ connector._addApprovalData(approval); | ||
it ("~3 should remove not exists approval from the backend (after approve)", function (done){ | ||
it ("~15 approve task - should remove not exists approval from the backend (after approve)", function (done){ | ||
var backendApproval = {private: {id: "approval1", approver: "approver1", a: "a"}, metadata: {fingerprints: {sync: "a"}}}; | ||
connector._addApprovalData(backendApproval); | ||
backendApproval.id = "caprizaId1"; | ||
connector.signatureList = [backendApproval]; | ||
@@ -114,4 +353,3 @@ connector.BL.getApproval = function () { | ||
.catch (err => { | ||
err.should.have.property('details', "Approval was not returned from the connector"); | ||
expect(err.approvalSyncResult.length).to.equal(1); | ||
err.approvalSyncResult[0].should.deep.include ({id: "caprizaId1",syncver:undefined, deleted: true}); | ||
done(); | ||
@@ -142,5 +380,5 @@ }); | ||
connector.config = { | ||
"actionFingerprint": { | ||
"id": "{{approval.id}}" | ||
} | ||
"actionFingerprint": { | ||
"id": "{{approval.id}}" | ||
} | ||
}; | ||
@@ -167,2 +405,25 @@ }); | ||
describe ("When actionFingerprint is not configured", function (){ | ||
beforeEach (function (){ | ||
connector.config = {}; | ||
}); | ||
it ("~5 return same hash", function (){ | ||
var obj = {approval: {id: "caprizaId1", requester: "Roie Uziel", private: {id: "approval1"}}}; | ||
var h1 = connector._createApprovalFingerprints(obj); | ||
expect(h1.sync).to.equal(connector._createApprovalFingerprints(obj).sync); | ||
}); | ||
it ("~6 return different hash if object was changed", function (){ | ||
var obj = {approval: {id: "caprizaId1", requester: "Roie Uziel", private: {id: "approval1"}}}; | ||
var h1 = connector._createApprovalFingerprints(obj); | ||
obj.approval.requester = "John Doe"; | ||
expect(h1.sync).not.to.equal(connector._createApprovalFingerprints(obj).sync); | ||
}); | ||
}); | ||
}); | ||
@@ -169,0 +430,0 @@ |
@@ -260,3 +260,6 @@ var validate = require('@capriza/schemas').validate; | ||
} | ||
}).listen(PORT); | ||
}); | ||
var WS = require("ws"); | ||
new WS.Server({server: server}).on("connection", () => { logger.info("BLTester connected")}); | ||
server.listen(PORT); | ||
@@ -263,0 +266,0 @@ server.timeout = 15 * 60 * 1000; |
var should = require('chai').should(); | ||
var syncher = require ("../lib/syncher.js"); | ||
var hash = require ("object-hash"); | ||
var chai = require('chai'); | ||
var expect = chai.expect; | ||
var Logger = require ("../lib/log").Logger; | ||
@@ -142,2 +144,86 @@ var loggerFactory = new Logger("console"); | ||
}); | ||
it("~9 prevent adding removed approval. using calcRemoved", function () { | ||
var mockApprovals = [ | ||
{ id: "aa-aa-12", private: { id: 1, approver : "approver" }, metadata: { fingerprints: { sync: "111", action: "aaa" } } }, | ||
]; | ||
var expected = [ | ||
{ id: "aa-aa-12", syncver: undefined, deleted: true } | ||
]; | ||
var syncher1 = new syncher([]); | ||
syncher.sync(mockApprovals, []).should.have.deep.members(expected); | ||
expect(syncher1.syncChunk(mockApprovals).length).to.equal(0); | ||
syncher1.destroy(); | ||
}); | ||
it("~10 prevent adding removed approval where approval marked as deleted", function () { | ||
var mockApprovals = [ | ||
{ id: "aa-aa-12", private: { id: 1, approver : "approver" }, metadata: { fingerprints: { sync: "111", action: "aaa" } } }, | ||
]; | ||
var expected = [ | ||
{ id: "aa-aa-12", syncver: undefined, deleted: true } | ||
]; | ||
var syncher1 = new syncher([]); | ||
var syncher2 = new syncher(mockApprovals); | ||
syncher2.syncChunk([{ deleted: this, id: 1, private: { id: 1, approver : "approver" }, metadata: { fingerprints: { sync: "111", action: "aaa" }}}]).should.have.deep.members(expected); | ||
expect(syncher1.syncChunk(mockApprovals).length).to.equal(0); | ||
syncher1.destroy(); | ||
syncher2.destroy(); | ||
}); | ||
it("~11 check max synchers should be 5 and make a change in the first - should not impact", function () { | ||
var mockApprovals = [ | ||
{ id: "aa-aa-12", private: { id: 1, approver : "approver" }, metadata: { fingerprints: { sync: "111", action: "aaa" } } }, | ||
]; | ||
var expected = [ | ||
{ id: "aa-aa-12", syncver: undefined, deleted: true } | ||
]; | ||
var syncher1 = new syncher([]); | ||
var syncher2 = new syncher([]); | ||
var syncher3 = new syncher([]); | ||
var syncher4 = new syncher([]); | ||
var syncher5 = new syncher([]); | ||
var syncher6 = new syncher([]); | ||
syncher.sync(mockApprovals, []).should.have.deep.members(expected); | ||
expect(syncher1.syncChunk(mockApprovals).length).to.equal(1); | ||
syncher1.destroy(); | ||
syncher2.destroy(); | ||
syncher3.destroy(); | ||
syncher4.destroy(); | ||
syncher5.destroy(); | ||
syncher6.destroy(); | ||
}); | ||
it("~12 check max synchers should be 5 and make a change in the last - should impact", function () { | ||
var mockApprovals = [ | ||
{ id: "aa-aa-12", private: { id: 1, approver : "approver" }, metadata: { fingerprints: { sync: "111", action: "aaa" } } }, | ||
]; | ||
var expected = [ | ||
{ id: "aa-aa-12", syncver: undefined, deleted: true } | ||
]; | ||
var syncher1 = new syncher([]); | ||
var syncher2 = new syncher([]); | ||
var syncher3 = new syncher([]); | ||
var syncher4 = new syncher([]); | ||
var syncher5 = new syncher([]); | ||
var syncher6 = new syncher([]); | ||
syncher.sync(mockApprovals, []).should.have.deep.members(expected); | ||
expect(syncher6.syncChunk(mockApprovals).length).to.equal(0); | ||
syncher1.destroy(); | ||
syncher2.destroy(); | ||
syncher3.destroy(); | ||
syncher4.destroy(); | ||
syncher5.destroy(); | ||
syncher6.destroy(); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
1915
120466
13
23
+ Addedws@^5.1.1
+ Addedasync-limiter@1.0.1(transitive)
+ Addedws@5.2.4(transitive)