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() {});