From f7c87e26db99a5a210895f766b8b5f7230afab95 Mon Sep 17 00:00:00 2001 From: Hiroki Uchikawa Date: Fri, 18 Jan 2019 19:53:15 +0900 Subject: [PATCH] Add test cases for context runtime API --- .../@node-red/runtime/lib/api/context_spec.js | 260 ++++++++++++++---- 1 file changed, 200 insertions(+), 60 deletions(-) diff --git a/test/unit/@node-red/runtime/lib/api/context_spec.js b/test/unit/@node-red/runtime/lib/api/context_spec.js index db604f2a9..bf23e9cc6 100644 --- a/test/unit/@node-red/runtime/lib/api/context_spec.js +++ b/test/unit/@node-red/runtime/lib/api/context_spec.js @@ -19,7 +19,7 @@ var should = require("should"); var sinon = require("sinon"); var NR_TEST_UTILS = require("nr-test-utils"); -var context = NR_TEST_UTILS.require("@node-red/runtime/lib/api/context") +var context = NR_TEST_UTILS.require("@node-red/runtime/lib/api/context"); var mockLog = () => ({ log: sinon.stub(), @@ -29,8 +29,8 @@ var mockLog = () => ({ info: sinon.stub(), metric: sinon.stub(), audit: sinon.stub(), - _: function() { return "abc"} -}) + _: function() { return "abc";} +}); var mockContext = function(contents) { return { @@ -41,51 +41,65 @@ var mockContext = function(contents) { callback(null,undefined); } }, - keys: function(store,callback) { + set: function (key, value, store, callback) { if (contents.hasOwnProperty(store)) { - callback(null,Object.keys(contents[store])); + if (!value) { + delete contents[store][key]; + callback(null); + } + } else { + callback("err store"); + } + }, + keys: function (store, callback) { + if (contents.hasOwnProperty(store)) { + callback(null, Object.keys(contents[store])); } else { callback("err store"); } } - } -} + }; +}; + describe("runtime-api/context", function() { - describe("getValue", function() { - var contexts = { - global: mockContext({ default: {abc:111}, file: {abc:222}}), - flow1: mockContext({ default: {abc:333}, file: {abc:444}}) - } - var nodeContext = mockContext({ default: {abc:555}, file: {abc:666}}) + var globalContext, flowContext, nodeContext, contexts; - beforeEach(function() { - context.init({ - nodes: { - listContextStores: function() { - return { default: 'default', stores: [ 'default', 'file' ] } - }, - getContext: function(id) { - return contexts[id] - }, - getNode: function(id) { - if (id === 'known') { - return { - context: function() { return nodeContext } - } - } else { - return null; - } - } + beforeEach(function() { + globalContext = { default: { abc: 111 }, file: { abc: 222 } }; + flowContext = { default: { abc: 333 }, file: { abc: 444 } }; + nodeContext = { default: { abc: 555 }, file: { abc: 666 } }; + contexts = { + global: mockContext(globalContext), + flow1: mockContext(flowContext) + }; + context.init({ + nodes: { + listContextStores: function() { + return { default: 'default', stores: [ 'default', 'file' ] }; }, - settings: { - functionGlobalContext: { - fgc:1234 - } + getContext: function(id) { + return contexts[id]; }, - log: mockLog() - }) + getNode: function(id) { + if (id === 'known') { + return { + context: function() { return mockContext(nodeContext); } + }; + } else { + return null; + } + } + }, + settings: { + functionGlobalContext: { + fgc:1234 + } + }, + log: mockLog() }); + }); + describe("getValue", function() { it('gets global value of default store', function() { return context.getValue({ scope: 'global', @@ -95,8 +109,9 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','111'); result.should.have.property('format','number'); - }) - }) + }); + }); + it('gets global value of specified store', function() { return context.getValue({ scope: 'global', @@ -106,8 +121,9 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','222'); result.should.have.property('format','number'); - }) - }) + }); + }); + it('gets flow value of default store', function() { return context.getValue({ scope: 'flow', @@ -117,8 +133,9 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','333'); result.should.have.property('format','number'); - }) - }) + }); + }); + it('gets flow value of specified store', function() { return context.getValue({ scope: 'flow', @@ -128,8 +145,9 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','444'); result.should.have.property('format','number'); - }) - }) + }); + }); + it('gets node value of default store', function() { return context.getValue({ scope: 'node', @@ -139,8 +157,9 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','555'); result.should.have.property('format','number'); - }) - }) + }); + }); + it('gets node value of specified store', function() { return context.getValue({ scope: 'node', @@ -150,8 +169,8 @@ describe("runtime-api/context", function() { }).then(function(result) { result.should.have.property('msg','666'); result.should.have.property('format','number'); - }) - }) + }); + }); it('404s for unknown store', function(done) { context.getValue({ @@ -162,12 +181,11 @@ describe("runtime-api/context", function() { }).then(function(result) { done("getValue for unknown store should not resolve"); }).catch(function(err) { - err.should.have.property('code','not_found') + err.should.have.property('code','not_found'); err.should.have.property('status',404); done(); - }) - }) - + }); + }); it('gets all global value properties', function() { return context.getValue({ @@ -180,8 +198,9 @@ describe("runtime-api/context", function() { default: { abc: { msg: '111', format: 'number' } }, file: { abc: { msg: '222', format: 'number' } } }); - }) - }) + }); + }); + it('gets all flow value properties', function() { return context.getValue({ scope: 'flow', @@ -193,8 +212,9 @@ describe("runtime-api/context", function() { default: { abc: { msg: '333', format: 'number' } }, file: { abc: { msg: '444', format: 'number' } } }); - }) - }) + }); + }); + it('gets all node value properties', function() { return context.getValue({ scope: 'node', @@ -206,8 +226,128 @@ describe("runtime-api/context", function() { default: { abc: { msg: '555', format: 'number' } }, file: { abc: { msg: '666', format: 'number' } } }); - }) - }) + }); + }); - }) + it('gets empty object when specified context doesn\'t exist', function() { + return context.getValue({ + scope: 'node', + id: 'non-existent', + store: 'file', + key: 'abc' + }).then(function(result) { + result.should.be.an.Object(); + result.should.be.empty(); + }); + }); + }); + + describe("delete", function () { + it('deletes global value of default store', function () { + return context.delete({ + scope: 'global', + id: undefined, + store: undefined, // use default + key: 'abc' + }).then(function () { + globalContext.should.eql({ + default: {}, file: { abc: 222 } + }); + }); + }); + + it('deletes global value of specified store', function () { + return context.delete({ + scope: 'global', + id: undefined, + store: 'file', + key: 'abc' + }).then(function () { + globalContext.should.eql({ + default: { abc: 111 }, file: {} + }); + }); + }); + + it('deletes flow value of default store', function () { + return context.delete({ + scope: 'flow', + id: 'flow1', + store: undefined, // use default + key: 'abc' + }).then(function () { + flowContext.should.eql({ + default: {}, file: { abc: 444 } + }); + }); + }); + + it('deletes flow value of specified store', function () { + return context.delete({ + scope: 'flow', + id: 'flow1', + store: 'file', + key: 'abc' + }).then(function () { + flowContext.should.eql({ + default: { abc: 333 }, file: {} + }); + }); + }); + + it('deletes node value of default store', function () { + return context.delete({ + scope: 'node', + id: 'known', + store: undefined, // use default + key: 'abc' + }).then(function () { + nodeContext.should.eql({ + default: {}, file: { abc: 666 } + }); + }); + }); + + it('deletes node value of specified store', function () { + return context.delete({ + scope: 'node', + id: 'known', + store: 'file', + key: 'abc' + }).then(function () { + nodeContext.should.eql({ + default: { abc: 555 }, file: {} + }); + }); + }); + + it('does nothing when specified context doesn\'t exist', function() { + return context.delete({ + scope: 'node', + id: 'non-existent', + store: 'file', + key: 'abc' + }).then(function(result) { + should.not.exist(result); + nodeContext.should.eql({ + default: { abc: 555 }, file: { abc: 666 } + }); + }); + }); + + it('404s for unknown store', function (done) { + context.delete({ + scope: 'global', + id: undefined, + store: 'unknown', + key: 'abc' + }).then(function () { + done("delete for unknown store should not resolve"); + }).catch(function (err) { + err.should.have.property('code', 'not_found'); + err.should.have.property('status', 404); + done(); + }); + }); + }); });