diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js index 9994d5000..0d8ba103f 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js @@ -218,11 +218,11 @@ RED.sidebar.context = (function() { var obj = $(propRow.children()[0]); obj.text(k); var tools = $(''); - + const urlSafeK = encodeURIComponent(k) var refreshItem = $('').appendTo(tools).on("click", function(e) { e.preventDefault(); e.stopPropagation(); - $.getJSON(baseUrl+"/"+k+"?store="+v.store, function(data) { + $.getJSON(baseUrl+"/"+urlSafeK+"?store="+v.store, function(data) { if (data.msg !== payload || data.format !== format) { payload = data.msg; format = data.format; @@ -258,11 +258,12 @@ RED.sidebar.context = (function() { $('').appendTo(bg).on("click", function(e) { e.preventDefault(); popover.close(); + const urlSafeK = encodeURIComponent(k) $.ajax({ - url: baseUrl+"/"+k+"?store="+v.store, + url: baseUrl+"/"+urlSafeK+"?store="+v.store, type: "DELETE" }).done(function(data,textStatus,xhr) { - $.getJSON(baseUrl+"/"+k+"?store="+v.store, function(data) { + $.getJSON(baseUrl+"/"+urlSafeK+"?store="+v.store, function(data) { if (data.format === 'undefined') { propRow.remove(); if (container.children().length === 0) { diff --git a/test/unit/@node-red/editor-api/lib/admin/context_spec.js b/test/unit/@node-red/editor-api/lib/admin/context_spec.js index 8f3dbba55..7075d616e 100644 --- a/test/unit/@node-red/editor-api/lib/admin/context_spec.js +++ b/test/unit/@node-red/editor-api/lib/admin/context_spec.js @@ -126,6 +126,26 @@ describe("api/admin/context", function () { }); }); + it('should call context.getValue to get a node context value - url unsafe keyname', function (done) { + stub.returns(Promise.resolve(nContext)); + request(app) + .get('/context/node/5678/foo%23123?store=file') + .set('Accept', 'application/json') + .expect(200) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'node'); + stub.args[0][0].should.have.property('id', '5678'); + stub.args[0][0].should.have.property('key', 'foo#123'); + stub.args[0][0].should.have.property('store', 'file'); + var body = res.body; + body.should.eql(nContext); + done(); + }); + }); it('should handle error which context.getValue causes', function (done) { var stubbedResult = Promise.reject('error'); stubbedResult.catch(function() {}); @@ -214,6 +234,24 @@ describe("api/admin/context", function () { }); }); + it('should call context.delete to delete a node context - url unsafe keyname', function (done) { + stub.returns(Promise.resolve()); + request(app) + .delete('/context/node/5678/foo%23123?store=file') + .expect(204) + .end(function (err, res) { + if (err) { + return done(err); + } + stub.args[0][0].should.have.property('user', undefined); + stub.args[0][0].should.have.property('scope', 'node'); + stub.args[0][0].should.have.property('id', '5678'); + stub.args[0][0].should.have.property('key', 'foo#123'); + stub.args[0][0].should.have.property('store', 'file'); + done(); + }); + }); + it('should handle error which context.delete causes', function (done) { var stubbedResult = Promise.reject('error'); stubbedResult.catch(function() {});