mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge branch 'master' of https://github.com/node-red/node-red
This commit is contained in:
commit
6321b21a1a
@ -193,7 +193,8 @@ module.exports = function(grunt) {
|
|||||||
"packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.0.1.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.0.1.min.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-ui.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-ui.min.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery.ui.touch-punch.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery.ui.touch-punch.min.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/vendor/marked/marked.min.js",
|
"node_modules/marked/marked.min.js",
|
||||||
|
"node_modules/dompurify/dist/purify.min.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js",
|
||||||
"packages/node_modules/@node-red/editor-client/src/vendor/i18next/i18next.min.js",
|
"packages/node_modules/@node-red/editor-client/src/vendor/i18next/i18next.min.js",
|
||||||
"node_modules/jsonata/jsonata-es5.min.js",
|
"node_modules/jsonata/jsonata-es5.min.js",
|
||||||
|
@ -41,13 +41,13 @@
|
|||||||
"fs-extra": "8.1.0",
|
"fs-extra": "8.1.0",
|
||||||
"fs.notify": "0.0.4",
|
"fs.notify": "0.0.4",
|
||||||
"hash-sum": "2.0.0",
|
"hash-sum": "2.0.0",
|
||||||
"https-proxy-agent": "2.2.4",
|
"https-proxy-agent": "5.0.0",
|
||||||
"i18next": "15.1.2",
|
"i18next": "15.1.2",
|
||||||
"iconv-lite": "0.5.0",
|
"iconv-lite": "0.5.0",
|
||||||
"is-utf8": "0.2.1",
|
"is-utf8": "0.2.1",
|
||||||
"js-yaml": "3.13.1",
|
"js-yaml": "3.13.1",
|
||||||
"json-stringify-safe": "5.0.1",
|
"json-stringify-safe": "5.0.1",
|
||||||
"jsonata": "1.8.0",
|
"jsonata": "1.8.1",
|
||||||
"media-typer": "1.1.0",
|
"media-typer": "1.1.0",
|
||||||
"memorystore": "1.6.1",
|
"memorystore": "1.6.1",
|
||||||
"mime": "2.4.4",
|
"mime": "2.4.4",
|
||||||
@ -75,6 +75,8 @@
|
|||||||
"bcrypt": "3.0.6"
|
"bcrypt": "3.0.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"marked": "0.8.0",
|
||||||
|
"dompurify": "2.0.8",
|
||||||
"grunt": "~1.0.4",
|
"grunt": "~1.0.4",
|
||||||
"grunt-chmod": "~1.1.1",
|
"grunt-chmod": "~1.1.1",
|
||||||
"grunt-cli": "~1.3.2",
|
"grunt-cli": "~1.3.2",
|
||||||
|
@ -100,7 +100,10 @@ function login(req,res) {
|
|||||||
}
|
}
|
||||||
} else if (mergedAdminAuth.type === "strategy") {
|
} else if (mergedAdminAuth.type === "strategy") {
|
||||||
|
|
||||||
var urlPrefix = (settings.httpAdminRoot==='/')?"":settings.httpAdminRoot;
|
var urlPrefix = (settings.httpAdminRoot||"").replace(/\/$/,"");
|
||||||
|
if (urlPrefix.length > 0) {
|
||||||
|
urlPrefix += "/";
|
||||||
|
}
|
||||||
response = {
|
response = {
|
||||||
"type":"strategy",
|
"type":"strategy",
|
||||||
"prompts":[{type:"button",label:mergedAdminAuth.strategy.label, url: urlPrefix + "auth/strategy"}]
|
"prompts":[{type:"button",label:mergedAdminAuth.strategy.label, url: urlPrefix + "auth/strategy"}]
|
||||||
|
@ -431,7 +431,7 @@ var RED = (function() {
|
|||||||
'<img width="50px" src="red/images/node-red-icon.svg" />'+
|
'<img width="50px" src="red/images/node-red-icon.svg" />'+
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
RED.sidebar.info.set(aboutHeader+marked(data));
|
RED.sidebar.info.set(aboutHeader+RED.utils.renderMarkdown(data));
|
||||||
RED.sidebar.info.show();
|
RED.sidebar.info.show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@
|
|||||||
var f = $(this).val();
|
var f = $(this).val();
|
||||||
var args = RED._('jsonata:'+f+".args",{defaultValue:''});
|
var args = RED._('jsonata:'+f+".args",{defaultValue:''});
|
||||||
var title = "<h5>"+f+"("+args+")</h5>";
|
var title = "<h5>"+f+"("+args+")</h5>";
|
||||||
var body = marked(RED._('jsonata:'+f+'.desc',{defaultValue:''}));
|
var body = RED.utils.renderMarkdown(RED._('jsonata:'+f+'.desc',{defaultValue:''}));
|
||||||
$("#red-ui-editor-type-expression-help").html(title+"<p>"+body+"</p>");
|
$("#red-ui-editor-type-expression-help").html(title+"<p>"+body+"</p>");
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -107,7 +107,7 @@
|
|||||||
clearTimeout(changeTimer);
|
clearTimeout(changeTimer);
|
||||||
changeTimer = setTimeout(function() {
|
changeTimer = setTimeout(function() {
|
||||||
var currentScrollTop = $(".red-ui-editor-type-markdown-panel-preview").scrollTop();
|
var currentScrollTop = $(".red-ui-editor-type-markdown-panel-preview").scrollTop();
|
||||||
$(".red-ui-editor-type-markdown-panel-preview").html(marked(expressionEditor.getValue()));
|
$(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
|
||||||
$(".red-ui-editor-type-markdown-panel-preview").scrollTop(currentScrollTop);
|
$(".red-ui-editor-type-markdown-panel-preview").scrollTop(currentScrollTop);
|
||||||
},200);
|
},200);
|
||||||
})
|
})
|
||||||
@ -116,7 +116,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
$(".red-ui-editor-type-markdown-panel-preview").html(marked(expressionEditor.getValue()));
|
$(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
|
||||||
}
|
}
|
||||||
panels = RED.panels.create({
|
panels = RED.panels.create({
|
||||||
id:"red-ui-editor-type-markdown-panels",
|
id:"red-ui-editor-type-markdown-panels",
|
||||||
|
@ -269,7 +269,7 @@ RED.palette = (function() {
|
|||||||
RED.view.focus();
|
RED.view.focus();
|
||||||
var helpText;
|
var helpText;
|
||||||
if (nt.indexOf("subflow:") === 0) {
|
if (nt.indexOf("subflow:") === 0) {
|
||||||
helpText = marked(RED.nodes.subflow(nt.substring(8)).info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
helpText = RED.utils.renderMarkdown(RED.nodes.subflow(nt.substring(8)).info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||||
} else {
|
} else {
|
||||||
helpText = $("script[data-help-name='"+d.attr("data-palette-type")+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
helpText = $("script[data-help-name='"+d.attr("data-palette-type")+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||||
}
|
}
|
||||||
@ -370,7 +370,7 @@ RED.palette = (function() {
|
|||||||
RED.workspaces.show(nt.substring(8));
|
RED.workspaces.show(nt.substring(8));
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
nodeInfo = marked(def.info||"");
|
nodeInfo = RED.utils.renderMarkdown(def.info||"");
|
||||||
}
|
}
|
||||||
setLabel(nt,d,label,nodeInfo);
|
setLabel(nt,d,label,nodeInfo);
|
||||||
|
|
||||||
@ -440,7 +440,7 @@ RED.palette = (function() {
|
|||||||
} else if (portOutput.length !== 0 && sf.out.length === 0) {
|
} else if (portOutput.length !== 0 && sf.out.length === 0) {
|
||||||
portOutput.remove();
|
portOutput.remove();
|
||||||
}
|
}
|
||||||
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,marked(sf.info||""));
|
setLabel(sf.type+":"+sf.id,paletteNode,sf.name,RED.utils.renderMarkdown(sf.info||""));
|
||||||
setIcon(paletteNode,sf);
|
setIcon(paletteNode,sf);
|
||||||
|
|
||||||
var currentCategory = paletteNode.data('category');
|
var currentCategory = paletteNode.data('category');
|
||||||
|
@ -158,7 +158,7 @@ RED.projects.settings = (function() {
|
|||||||
container.empty();
|
container.empty();
|
||||||
var desc;
|
var desc;
|
||||||
if (activeProject.description) {
|
if (activeProject.description) {
|
||||||
desc = marked(activeProject.description);
|
desc = RED.utils.renderMarkdown(activeProject.description);
|
||||||
} else {
|
} else {
|
||||||
desc = '<span class="red-ui-help-info-none">' + RED._("sidebar.project.noDescriptionAvailable") + '</span>';
|
desc = '<span class="red-ui-help-info-none">' + RED._("sidebar.project.noDescriptionAvailable") + '</span>';
|
||||||
}
|
}
|
||||||
|
@ -15,17 +15,6 @@
|
|||||||
**/
|
**/
|
||||||
RED.sidebar.info = (function() {
|
RED.sidebar.info = (function() {
|
||||||
|
|
||||||
marked.setOptions({
|
|
||||||
renderer: new marked.Renderer(),
|
|
||||||
gfm: true,
|
|
||||||
tables: true,
|
|
||||||
breaks: false,
|
|
||||||
pedantic: false,
|
|
||||||
sanitize: true,
|
|
||||||
smartLists: true,
|
|
||||||
smartypants: false
|
|
||||||
});
|
|
||||||
|
|
||||||
var content;
|
var content;
|
||||||
var sections;
|
var sections;
|
||||||
var propertiesSection;
|
var propertiesSection;
|
||||||
@ -314,7 +303,7 @@ RED.sidebar.info = (function() {
|
|||||||
if (subflowNode && node.type !== "subflow") {
|
if (subflowNode && node.type !== "subflow") {
|
||||||
// Selected a subflow instance node.
|
// Selected a subflow instance node.
|
||||||
// - The subflow template info goes into help
|
// - The subflow template info goes into help
|
||||||
helpText = (marked(subflowNode.info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'));
|
helpText = (RED.utils.renderMarkdown(subflowNode.info||"")||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>'));
|
||||||
} else {
|
} else {
|
||||||
helpText = $("script[data-help-name='"+node.type+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
helpText = $("script[data-help-name='"+node.type+"']").html()||('<span class="red-ui-help-info-none">'+RED._("sidebar.info.none")+'</span>');
|
||||||
}
|
}
|
||||||
@ -326,10 +315,10 @@ RED.sidebar.info = (function() {
|
|||||||
if (node._def && node._def.info) {
|
if (node._def && node._def.info) {
|
||||||
var info = node._def.info;
|
var info = node._def.info;
|
||||||
var textInfo = (typeof info === "function" ? info.call(node) : info);
|
var textInfo = (typeof info === "function" ? info.call(node) : info);
|
||||||
infoText = infoText + marked(textInfo);
|
infoText = infoText + RED.utils.renderMarkdown(textInfo);
|
||||||
}
|
}
|
||||||
if (node.info) {
|
if (node.info) {
|
||||||
infoText = infoText + marked(node.info || "")
|
infoText = infoText + RED.utils.renderMarkdown(node.info || "")
|
||||||
}
|
}
|
||||||
setInfoText(infoText, infoSection.content);
|
setInfoText(infoText, infoSection.content);
|
||||||
|
|
||||||
|
@ -16,6 +16,28 @@
|
|||||||
|
|
||||||
RED.utils = (function() {
|
RED.utils = (function() {
|
||||||
|
|
||||||
|
window._marked = window.marked;
|
||||||
|
window.marked = function(txt) {
|
||||||
|
console.warn("Use of 'marked()' is deprecated. Use RED.utils.renderMarkdown() instead");
|
||||||
|
return renderMarkdown(txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
_marked.setOptions({
|
||||||
|
renderer: new _marked.Renderer(),
|
||||||
|
gfm: true,
|
||||||
|
tables: true,
|
||||||
|
breaks: false,
|
||||||
|
pedantic: false,
|
||||||
|
smartLists: true,
|
||||||
|
smartypants: false
|
||||||
|
});
|
||||||
|
|
||||||
|
function renderMarkdown(txt) {
|
||||||
|
var rendered = _marked(txt);
|
||||||
|
var cleaned = DOMPurify.sanitize(rendered, {SAFE_FOR_JQUERY: true})
|
||||||
|
return cleaned;
|
||||||
|
}
|
||||||
|
|
||||||
function formatString(str) {
|
function formatString(str) {
|
||||||
return str.replace(/\r?\n/g,"↵").replace(/\t/g,"→");
|
return str.replace(/\r?\n/g,"↵").replace(/\t/g,"→");
|
||||||
}
|
}
|
||||||
@ -1053,6 +1075,7 @@ RED.utils = (function() {
|
|||||||
decodeObject: decodeObject,
|
decodeObject: decodeObject,
|
||||||
parseContextKey: parseContextKey,
|
parseContextKey: parseContextKey,
|
||||||
createIconElement: createIconElement,
|
createIconElement: createIconElement,
|
||||||
sanitize: sanitize
|
sanitize: sanitize,
|
||||||
|
renderMarkdown: renderMarkdown
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
var length = str.length;
|
var length = str.length;
|
||||||
var start = 0;
|
var start = 0;
|
||||||
var inString = false;
|
var inString = false;
|
||||||
|
var inRegex = false;
|
||||||
var inBox = false;
|
var inBox = false;
|
||||||
var quoteChar;
|
var quoteChar;
|
||||||
var list = [];
|
var list = [];
|
||||||
@ -24,8 +25,13 @@
|
|||||||
}
|
}
|
||||||
for (var i=0;i<length;i++) {
|
for (var i=0;i<length;i++) {
|
||||||
var c = str[i];
|
var c = str[i];
|
||||||
if (!inString) {
|
if (!inString && !inRegex) {
|
||||||
if (c === "'" || c === '"') {
|
if (c === "/") {
|
||||||
|
inRegex = true;
|
||||||
|
frame = {type:"regex",pos:i};
|
||||||
|
list.push(frame);
|
||||||
|
stack.push(frame);
|
||||||
|
} else if (c === "'" || c === '"') {
|
||||||
inString = true;
|
inString = true;
|
||||||
quoteChar = c;
|
quoteChar = c;
|
||||||
frame = {type:"string",pos:i};
|
frame = {type:"string",pos:i};
|
||||||
@ -37,6 +43,9 @@
|
|||||||
} else if (c === ",") {
|
} else if (c === ",") {
|
||||||
frame = {type:",",pos:i};
|
frame = {type:",",pos:i};
|
||||||
list.push(frame);
|
list.push(frame);
|
||||||
|
} else if (c === "&") {
|
||||||
|
frame = {type:"&",pos:i};
|
||||||
|
list.push(frame);
|
||||||
} else if (/[\(\[\{]/.test(c)) {
|
} else if (/[\(\[\{]/.test(c)) {
|
||||||
frame = {type:"open-block",char:c,pos:i};
|
frame = {type:"open-block",char:c,pos:i};
|
||||||
list.push(frame);
|
list.push(frame);
|
||||||
@ -44,7 +53,8 @@
|
|||||||
} else if (/[\}\)\]]/.test(c)) {
|
} else if (/[\}\)\]]/.test(c)) {
|
||||||
var oldFrame = stack.pop();
|
var oldFrame = stack.pop();
|
||||||
if (matchingBrackets[oldFrame.char] !== c) {
|
if (matchingBrackets[oldFrame.char] !== c) {
|
||||||
//console.log("Stack frame mismatch",c,"at",i,"expected",matchingBrackets[oldFrame.char],"from",oldFrame.pos);
|
// console.log("Stack frame mismatch",c,"at",i,"expected",matchingBrackets[oldFrame.char],"from",oldFrame.pos);
|
||||||
|
// console.log(list);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
//console.log("Closing",c,"at",i,"compare",oldFrame.type,oldFrame.pos);
|
//console.log("Closing",c,"at",i,"compare",oldFrame.type,oldFrame.pos);
|
||||||
@ -53,19 +63,32 @@
|
|||||||
list.push(frame);
|
list.push(frame);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (c === "\\") {
|
||||||
|
// an escaped char - stay in current mode and skip the next char
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (inString) {
|
||||||
if (c === quoteChar) {
|
if (c === quoteChar) {
|
||||||
// Next char must be a ]
|
// Next char must be a ]
|
||||||
inString = false;
|
inString = false;
|
||||||
stack.pop();
|
var f = stack.pop();
|
||||||
|
f.end = i;
|
||||||
|
}
|
||||||
|
} else if (inRegex) {
|
||||||
|
if (c === "/") {
|
||||||
|
inRegex = false;
|
||||||
|
var f = stack.pop();
|
||||||
|
f.end = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log("list",list);
|
||||||
|
|
||||||
}
|
|
||||||
// console.log(stack);
|
|
||||||
var result = str;
|
var result = str;
|
||||||
var indent = 0;
|
var indent = 0;
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
var pre,post,indented;
|
var pre,post,indented,hasNewline;
|
||||||
var longStack = [];
|
var longStack = [];
|
||||||
list.forEach(function(f) {
|
list.forEach(function(f) {
|
||||||
if (f.type === ";" || f.type === ",") {
|
if (f.type === ";" || f.type === ",") {
|
||||||
@ -73,30 +96,52 @@
|
|||||||
pre = result.substring(0,offset+f.pos+1);
|
pre = result.substring(0,offset+f.pos+1);
|
||||||
post = result.substring(offset+f.pos+1);
|
post = result.substring(offset+f.pos+1);
|
||||||
indented = indentLine(post,indent);
|
indented = indentLine(post,indent);
|
||||||
result = pre+"\n"+indented;
|
hasNewline = /\n$/.test(pre);
|
||||||
offset += indented.length-post.length+1;
|
// console.log("A§"+pre+"§\n§"+indented+"§",hasNewline);
|
||||||
|
result = pre+(hasNewline?"":"\n")+indented;
|
||||||
|
offset += indented.length-post.length+(hasNewline?0:1);
|
||||||
}
|
}
|
||||||
|
} else if (f.type === "&") {
|
||||||
|
pre = result.substring(0,offset+f.pos+1);
|
||||||
|
var lastLineBreak = pre.lastIndexOf("\n");
|
||||||
|
var lineLength = pre.length - lastLineBreak;
|
||||||
|
if (lineLength > 70) {
|
||||||
|
post = result.substring(offset+f.pos+1);
|
||||||
|
if (!/^\n/.test(post)) {
|
||||||
|
indented = indentLine(post,indent);
|
||||||
|
hasNewline = /\n$/.test(pre);
|
||||||
|
result = pre+(hasNewline?"":"\n")+indented;
|
||||||
|
offset += indented.length-post.length+(hasNewline?0:1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (f.type === "open-block") {
|
} else if (f.type === "open-block") {
|
||||||
if (f.width > 30) {
|
if (f.width > 40) {
|
||||||
longStack.push(true);
|
longStack.push(true);
|
||||||
indent += 4;
|
indent += 4;
|
||||||
pre = result.substring(0,offset+f.pos+1);
|
pre = result.substring(0,offset+f.pos+1);
|
||||||
post = result.substring(offset+f.pos+1);
|
post = result.substring(offset+f.pos+1);
|
||||||
|
hasNewline = /\n$/.test(pre);
|
||||||
indented = indentLine(post,indent);
|
indented = indentLine(post,indent);
|
||||||
result = pre+"\n"+indented;
|
result = pre+(hasNewline?"":"\n")+indented;
|
||||||
offset += indented.length-post.length+1;
|
offset += indented.length-post.length+(hasNewline?0:1);
|
||||||
} else {
|
} else {
|
||||||
longStack.push(false);
|
longStack.push(false);
|
||||||
}
|
}
|
||||||
} else if (f.type === "close-block") {
|
} else if (f.type === "close-block") {
|
||||||
if (f.width > 30) {
|
if (f.width > 40) {
|
||||||
indent -= 4;
|
indent -= 4;
|
||||||
pre = result.substring(0,offset+f.pos);
|
pre = result.substring(0,offset+f.pos);
|
||||||
post = result.substring(offset+f.pos);
|
post = result.substring(offset+f.pos);
|
||||||
indented = indentLine(post,indent);
|
indented = indentLine(post,indent);
|
||||||
|
hasNewline = /\n *$/.test(pre);
|
||||||
|
if (hasNewline) {
|
||||||
|
result = pre + post;
|
||||||
|
} else {
|
||||||
result = pre+"\n"+indented;
|
result = pre+"\n"+indented;
|
||||||
offset += indented.length-post.length+1;
|
offset += indented.length-post.length+1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
longStack.pop();
|
longStack.pop();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -28,6 +28,11 @@ ace.define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/m
|
|||||||
}, "identifier");
|
}, "identifier");
|
||||||
this.$rules = {
|
this.$rules = {
|
||||||
"start" : [
|
"start" : [
|
||||||
|
{
|
||||||
|
token: "string.regexp",
|
||||||
|
regex: "\\/",
|
||||||
|
next: "regex"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
token : "string",
|
token : "string",
|
||||||
regex : "'(?=.)",
|
regex : "'(?=.)",
|
||||||
@ -46,7 +51,8 @@ ace.define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/m
|
|||||||
token : "constant.numeric", // float
|
token : "constant.numeric", // float
|
||||||
regex : /[+-]?\d[\d_]*(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/
|
regex : /[+-]?\d[\d_]*(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/
|
||||||
},
|
},
|
||||||
{ token: "keyword",
|
{
|
||||||
|
token: "keyword",
|
||||||
regex: /λ/
|
regex: /λ/
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -86,7 +92,8 @@ ace.define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/m
|
|||||||
token : "string",
|
token : "string",
|
||||||
regex : '"|$',
|
regex : '"|$',
|
||||||
next : "start"
|
next : "start"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
defaultToken: "string"
|
defaultToken: "string"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -95,9 +102,24 @@ ace.define("ace/mode/jsonata",["require","exports","module","ace/lib/oop","ace/m
|
|||||||
token : "string",
|
token : "string",
|
||||||
regex : "'|$",
|
regex : "'|$",
|
||||||
next : "start"
|
next : "start"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
defaultToken: "string"
|
defaultToken: "string"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"regex" : [
|
||||||
|
{
|
||||||
|
token: "string.regexp",
|
||||||
|
regex: "\\\\/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
token: "string.regexp",
|
||||||
|
regex: "/[sxngimy]*",
|
||||||
|
next: "start"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
defaultToken: "string.regexp"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
File diff suppressed because one or more lines are too long
@ -27,7 +27,7 @@
|
|||||||
"fs-extra": "8.1.0",
|
"fs-extra": "8.1.0",
|
||||||
"fs.notify": "0.0.4",
|
"fs.notify": "0.0.4",
|
||||||
"hash-sum": "2.0.0",
|
"hash-sum": "2.0.0",
|
||||||
"https-proxy-agent": "2.2.4",
|
"https-proxy-agent": "5.0.0",
|
||||||
"is-utf8": "0.2.1",
|
"is-utf8": "0.2.1",
|
||||||
"js-yaml": "3.13.1",
|
"js-yaml": "3.13.1",
|
||||||
"media-typer": "1.1.0",
|
"media-typer": "1.1.0",
|
||||||
|
@ -57,6 +57,8 @@ var api = module.exports = {
|
|||||||
* Sets the current flow configuration
|
* Sets the current flow configuration
|
||||||
* @param {Object} opts
|
* @param {Object} opts
|
||||||
* @param {User} opts.user - the user calling the api
|
* @param {User} opts.user - the user calling the api
|
||||||
|
* @param {Object} opts.flows - the flow configuration: `{flows: [..], credentials: {}}`
|
||||||
|
* @param {Object} opts.deploymentType - the type of deployment - "full", "nodes", "flows", "reload"
|
||||||
* @param {Object} opts.req - the request to log (optional)
|
* @param {Object} opts.req - the request to log (optional)
|
||||||
* @return {Promise<Flows>} - the active flow configuration
|
* @return {Promise<Flows>} - the active flow configuration
|
||||||
* @memberof @node-red/runtime_flows
|
* @memberof @node-red/runtime_flows
|
||||||
@ -83,7 +85,7 @@ var api = module.exports = {
|
|||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apiPromise = runtime.nodes.setFlows(flows.flows,deploymentType);
|
apiPromise = runtime.nodes.setFlows(flows.flows,flows.credentials,deploymentType);
|
||||||
}
|
}
|
||||||
apiPromise.then(function(flowId) {
|
apiPromise.then(function(flowId) {
|
||||||
return resolve({rev:flowId});
|
return resolve({rev:flowId});
|
||||||
|
@ -106,15 +106,20 @@ function load(forceStart) {
|
|||||||
// This is a force reload from the API - disable safeMode
|
// This is a force reload from the API - disable safeMode
|
||||||
delete settings.safeMode;
|
delete settings.safeMode;
|
||||||
}
|
}
|
||||||
return setFlows(null,"load",false,forceStart);
|
return setFlows(null,null,"load",false,forceStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _config - new node array configuration
|
* _config - new node array configuration
|
||||||
|
* _credentials - new credentials configuration (optional)
|
||||||
* type - full/nodes/flows/load (default full)
|
* type - full/nodes/flows/load (default full)
|
||||||
* muteLog - don't emit the standard log messages (used for individual flow api)
|
* muteLog - don't emit the standard log messages (used for individual flow api)
|
||||||
*/
|
*/
|
||||||
function setFlows(_config,type,muteLog,forceStart) {
|
function setFlows(_config,_credentials,type,muteLog,forceStart) {
|
||||||
|
if (typeof _credentials === "string") {
|
||||||
|
type = _credentials;
|
||||||
|
_credentials = null;
|
||||||
|
}
|
||||||
type = type||"full";
|
type = type||"full";
|
||||||
if (settings.safeMode) {
|
if (settings.safeMode) {
|
||||||
if (type !== "load") {
|
if (type !== "load") {
|
||||||
@ -155,16 +160,27 @@ function setFlows(_config,type,muteLog,forceStart) {
|
|||||||
delete newFlowConfig.allNodes[id].credentials;
|
delete newFlowConfig.allNodes[id].credentials;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var credsDirty;
|
||||||
|
|
||||||
|
if (_credentials) {
|
||||||
|
// A full set of credentials have been provided. Use those instead
|
||||||
|
configSavePromise = credentials.load(_credentials);
|
||||||
|
credsDirty = true;
|
||||||
|
} else {
|
||||||
// Allow the credential store to remove anything no longer needed
|
// Allow the credential store to remove anything no longer needed
|
||||||
credentials.clean(config);
|
credentials.clean(config);
|
||||||
|
|
||||||
// Remember whether credentials need saving or not
|
// Remember whether credentials need saving or not
|
||||||
var credsDirty = credentials.dirty();
|
var credsDirty = credentials.dirty();
|
||||||
|
|
||||||
|
configSavePromise = Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
// Get the latest credentials and ask storage to save them (if needed)
|
// Get the latest credentials and ask storage to save them (if needed)
|
||||||
// as well as the new flow configuration.
|
// as well as the new flow configuration.
|
||||||
configSavePromise = credentials.export().then(function(creds) {
|
configSavePromise = configSavePromise.then(function() {
|
||||||
|
return credentials.export()
|
||||||
|
}).then(function(creds) {
|
||||||
var saveConfig = {
|
var saveConfig = {
|
||||||
flows: config,
|
flows: config,
|
||||||
credentialsDirty:credsDirty,
|
credentialsDirty:credsDirty,
|
||||||
@ -515,7 +531,7 @@ function addFlow(flow) {
|
|||||||
var newConfig = clone(activeConfig.flows);
|
var newConfig = clone(activeConfig.flows);
|
||||||
newConfig = newConfig.concat(nodes);
|
newConfig = newConfig.concat(nodes);
|
||||||
|
|
||||||
return setFlows(newConfig,'flows',true).then(function() {
|
return setFlows(newConfig,null,'flows',true).then(function() {
|
||||||
log.info(log._("nodes.flows.added-flow",{label:(flow.label?flow.label+" ":"")+"["+flow.id+"]"}));
|
log.info(log._("nodes.flows.added-flow",{label:(flow.label?flow.label+" ":"")+"["+flow.id+"]"}));
|
||||||
return flow.id;
|
return flow.id;
|
||||||
});
|
});
|
||||||
@ -646,7 +662,7 @@ function updateFlow(id,newFlow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
newConfig = newConfig.concat(nodes);
|
newConfig = newConfig.concat(nodes);
|
||||||
return setFlows(newConfig,'flows',true).then(function() {
|
return setFlows(newConfig,null,'flows',true).then(function() {
|
||||||
log.info(log._("nodes.flows.updated-flow",{label:(label?label+" ":"")+"["+id+"]"}));
|
log.info(log._("nodes.flows.updated-flow",{label:(label?label+" ":"")+"["+id+"]"}));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -668,7 +684,7 @@ function removeFlow(id) {
|
|||||||
return node.z !== id && node.id !== id;
|
return node.z !== id && node.id !== id;
|
||||||
});
|
});
|
||||||
|
|
||||||
return setFlows(newConfig,'flows',true).then(function() {
|
return setFlows(newConfig,null,'flows',true).then(function() {
|
||||||
log.info(log._("nodes.flows.removed-flow",{label:(flow.label?flow.label+" ":"")+"["+flow.id+"]"}));
|
log.info(log._("nodes.flows.removed-flow",{label:(flow.label?flow.label+" ":"")+"["+flow.id+"]"}));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
"clone": "2.1.2",
|
"clone": "2.1.2",
|
||||||
"i18next": "15.1.2",
|
"i18next": "15.1.2",
|
||||||
"json-stringify-safe": "5.0.1",
|
"json-stringify-safe": "5.0.1",
|
||||||
"jsonata": "1.8.0",
|
"jsonata": "1.8.1",
|
||||||
"when": "3.7.8"
|
"when": "3.7.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,22 +15,29 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
var idMap = {
|
var idMap = {
|
||||||
// input
|
// common
|
||||||
"inject": ".red-ui-palette-node[data-palette-type='inject']",
|
"inject": ".red-ui-palette-node[data-palette-type='inject']",
|
||||||
"httpIn": ".red-ui-palette-node[data-palette-type='http in']",
|
|
||||||
"mqttIn": ".red-ui-palette-node[data-palette-type='mqtt in']",
|
|
||||||
// output
|
|
||||||
"debug": ".red-ui-palette-node[data-palette-type='debug']",
|
"debug": ".red-ui-palette-node[data-palette-type='debug']",
|
||||||
"httpResponse": ".red-ui-palette-node[data-palette-type='http response']",
|
|
||||||
"mqttOut": ".red-ui-palette-node[data-palette-type='mqtt out']",
|
|
||||||
// function
|
// function
|
||||||
"function": ".red-ui-palette-node[data-palette-type='function']",
|
"function": ".red-ui-palette-node[data-palette-type='function']",
|
||||||
"template": ".red-ui-palette-node[data-palette-type='template']",
|
|
||||||
"change": ".red-ui-palette-node[data-palette-type='change']",
|
"change": ".red-ui-palette-node[data-palette-type='change']",
|
||||||
"range": ".red-ui-palette-node[data-palette-type='range']",
|
"range": ".red-ui-palette-node[data-palette-type='range']",
|
||||||
|
"template": ".red-ui-palette-node[data-palette-type='template']",
|
||||||
|
// network
|
||||||
|
"mqttIn": ".red-ui-palette-node[data-palette-type='mqtt in']",
|
||||||
|
"mqttOut": ".red-ui-palette-node[data-palette-type='mqtt out']",
|
||||||
|
"httpIn": ".red-ui-palette-node[data-palette-type='http in']",
|
||||||
|
"httpResponse": ".red-ui-palette-node[data-palette-type='http response']",
|
||||||
"httpRequest": ".red-ui-palette-node[data-palette-type='http request']",
|
"httpRequest": ".red-ui-palette-node[data-palette-type='http request']",
|
||||||
|
// sequence
|
||||||
|
"join": ".red-ui-palette-node[data-palette-type='join']",
|
||||||
|
"split": ".red-ui-palette-node[data-palette-type='split']",
|
||||||
|
// parser
|
||||||
|
"csv": ".red-ui-palette-node[data-palette-type='csv']",
|
||||||
"html": ".red-ui-palette-node[data-palette-type='html']",
|
"html": ".red-ui-palette-node[data-palette-type='html']",
|
||||||
"json": ".red-ui-palette-node[data-palette-type='json']",
|
"json": ".red-ui-palette-node[data-palette-type='json']",
|
||||||
|
"xml": ".red-ui-palette-node[data-palette-type='xml']",
|
||||||
|
"yaml": ".red-ui-palette-node[data-palette-type='yaml']",
|
||||||
// storage
|
// storage
|
||||||
"fileIn": ".red-ui-palette-node[data-palette-type='file in']",
|
"fileIn": ".red-ui-palette-node[data-palette-type='file in']",
|
||||||
};
|
};
|
||||||
|
@ -42,7 +42,7 @@ function addNode(type, x, y) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
browser.waitForVisible('#red-ui-palette-search');
|
browser.waitForVisible('#red-ui-palette-search');
|
||||||
browser.setValue('//*[@id="red-ui-palette-search"]/div/input', type.replace(/([A-Z])/g,' $1').toLowerCase());
|
browser.setValue('//*[@id="red-ui-palette-search"]/div/form/input', type.replace(/([A-Z])/g, ' $1').toLowerCase());
|
||||||
browser.pause(300);
|
browser.pause(300);
|
||||||
browser.waitForVisible(palette.getId(type));
|
browser.waitForVisible(palette.getId(type));
|
||||||
browser.moveToObject(palette.getId(type));
|
browser.moveToObject(palette.getId(type));
|
||||||
@ -66,8 +66,8 @@ function deleteAllNodes() {
|
|||||||
|
|
||||||
function deploy() {
|
function deploy() {
|
||||||
browser.call(function () {
|
browser.call(function () {
|
||||||
return when.promise(function(resolve, reject) {
|
return when.promise(function (resolve, reject) {
|
||||||
events.on("runtime-event", function(event) {
|
events.on("runtime-event", function (event) {
|
||||||
if (event.id === 'runtime-deploy') {
|
if (event.id === 'runtime-deploy') {
|
||||||
events.removeListener("runtime-event", arguments.callee);
|
events.removeListener("runtime-event", arguments.callee);
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
var util = require("util");
|
var util = require('util');
|
||||||
|
|
||||||
var nodePage = require("../../node_page");
|
var nodePage = require('../../node_page');
|
||||||
|
|
||||||
function changeNode(id) {
|
function changeNode(id) {
|
||||||
nodePage.call(this, id);
|
nodePage.call(this, id);
|
||||||
@ -85,7 +85,7 @@ changeNode.prototype.ruleMove = function (p, to, index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
changeNode.prototype.addRule = function () {
|
changeNode.prototype.addRule = function () {
|
||||||
browser.clickWithWait('//*[@id="dialog-form"]/div[3]/div/a');
|
browser.clickWithWait('//*[@id="dialog-form"]/div[5]/div/a');
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = changeNode;
|
module.exports = changeNode;
|
||||||
|
51
test/editor/pageobjects/nodes/core/parsers/70-CSV_page.js
Normal file
51
test/editor/pageobjects/nodes/core/parsers/70-CSV_page.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var util = require('util');
|
||||||
|
|
||||||
|
var nodePage = require('../../node_page');
|
||||||
|
|
||||||
|
function csvNode(id) {
|
||||||
|
nodePage.call(this, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(csvNode, nodePage);
|
||||||
|
|
||||||
|
csvNode.prototype.setColumns = function (columns) {
|
||||||
|
browser.setValue('#node-input-temp', columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
csvNode.prototype.setSkipLines = function (skip) {
|
||||||
|
browser.setValue('#node-input-skip', skip);
|
||||||
|
}
|
||||||
|
|
||||||
|
csvNode.prototype.setFirstRow4Names = function (checkbox) {
|
||||||
|
if (browser.isSelected('#node-input-hdrin') !== checkbox) {
|
||||||
|
browser.click('#node-input-hdrin');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
csvNode.prototype.setOutput = function (output) {
|
||||||
|
browser.selectWithWait('#node-input-multi', output);
|
||||||
|
}
|
||||||
|
|
||||||
|
csvNode.prototype.setIncludeRow = function (checkbox) {
|
||||||
|
if (browser.isSelected('#node-input-hdrout') !== checkbox) {
|
||||||
|
browser.click('#node-input-hdrout');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = csvNode;
|
@ -14,9 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
var util = require("util");
|
var util = require('util');
|
||||||
|
|
||||||
var nodePage = require("../../node_page");
|
var nodePage = require('../../node_page');
|
||||||
|
|
||||||
function htmlNode(id) {
|
function htmlNode(id) {
|
||||||
nodePage.call(this, id);
|
nodePage.call(this, id);
|
||||||
@ -24,7 +24,7 @@ function htmlNode(id) {
|
|||||||
|
|
||||||
util.inherits(htmlNode, nodePage);
|
util.inherits(htmlNode, nodePage);
|
||||||
|
|
||||||
htmlNode.prototype.setSelector = function(tag) {
|
htmlNode.prototype.setSelector = function (tag) {
|
||||||
browser.setValue('#node-input-tag', tag);
|
browser.setValue('#node-input-tag', tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
var util = require("util");
|
var util = require('util');
|
||||||
|
|
||||||
var nodePage = require("../../node_page");
|
var nodePage = require('../../node_page');
|
||||||
|
|
||||||
function jsonNode(id) {
|
function jsonNode(id) {
|
||||||
nodePage.call(this, id);
|
nodePage.call(this, id);
|
||||||
@ -28,8 +28,8 @@ jsonNode.prototype.setAction = function (action) {
|
|||||||
browser.setValue('node-input-action', action);
|
browser.setValue('node-input-action', action);
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonNode.prototype.setProperty = function(property) {
|
jsonNode.prototype.setProperty = function (property) {
|
||||||
browser.setValue('//*[@id="dialog-form"]/div[2]/div/div/input', property);
|
browser.setValue('//*[@id="dialog-form"]/div[4]/div/div[1]/input', property);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = jsonNode;
|
module.exports = jsonNode;
|
||||||
|
35
test/editor/pageobjects/nodes/core/parsers/70-XML_page.js
Normal file
35
test/editor/pageobjects/nodes/core/parsers/70-XML_page.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var util = require('util');
|
||||||
|
|
||||||
|
var nodePage = require('../../node_page');
|
||||||
|
|
||||||
|
function xmlNode(id) {
|
||||||
|
nodePage.call(this, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(xmlNode, nodePage);
|
||||||
|
|
||||||
|
xmlNode.prototype.setAction = function (action) {
|
||||||
|
browser.setValue('node-input-action', action);
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlNode.prototype.setProperty = function (property) {
|
||||||
|
browser.setValue('//*[@id="dialog-form"]/div[3]/div/div[1]/input', property);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = xmlNode;
|
35
test/editor/pageobjects/nodes/core/parsers/70-YAML_page.js
Normal file
35
test/editor/pageobjects/nodes/core/parsers/70-YAML_page.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var util = require('util');
|
||||||
|
|
||||||
|
var nodePage = require('../../node_page');
|
||||||
|
|
||||||
|
function yamlNode(id) {
|
||||||
|
nodePage.call(this, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(yamlNode, nodePage);
|
||||||
|
|
||||||
|
yamlNode.prototype.setAction = function (action) {
|
||||||
|
browser.setValue('node-input-action', action);
|
||||||
|
}
|
||||||
|
|
||||||
|
yamlNode.prototype.setProperty = function (property) {
|
||||||
|
browser.setValue('//*[@id="dialog-form"]/div[3]/div/div[1]/input', property);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = yamlNode;
|
35
test/editor/pageobjects/nodes/core/sequence/17-split_page.js
Normal file
35
test/editor/pageobjects/nodes/core/sequence/17-split_page.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var util = require('util');
|
||||||
|
|
||||||
|
var nodePage = require('../../node_page');
|
||||||
|
|
||||||
|
function joinNode(id) {
|
||||||
|
nodePage.call(this, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(joinNode, nodePage);
|
||||||
|
|
||||||
|
module.exports = joinNode;
|
||||||
|
|
||||||
|
function joinNode(id) {
|
||||||
|
nodePage.call(this, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(joinNode, nodePage);
|
||||||
|
|
||||||
|
module.exports = joinNode;
|
@ -25,8 +25,13 @@ var mqttOutNode = require('./core/network/10-mqttout_page');
|
|||||||
var httpInNode = require('./core/network/21-httpin_page');
|
var httpInNode = require('./core/network/21-httpin_page');
|
||||||
var httpResponseNode = require('./core/network/21-httpresponse_page');
|
var httpResponseNode = require('./core/network/21-httpresponse_page');
|
||||||
var httpRequestNode = require('./core/network/21-httprequest_page');
|
var httpRequestNode = require('./core/network/21-httprequest_page');
|
||||||
|
var splitNode = require('./core/sequence/17-split_page');
|
||||||
|
var joinNode = require('./core/sequence/17-split_page');
|
||||||
|
var csvNode = require('./core/parsers/70-CSV_page');
|
||||||
var htmlNode = require('./core/parsers/70-HTML_page');
|
var htmlNode = require('./core/parsers/70-HTML_page');
|
||||||
var jsonNode = require('./core/parsers/70-JSON_page');
|
var jsonNode = require('./core/parsers/70-JSON_page');
|
||||||
|
var xmlNode = require('./core/parsers/70-XML_page');
|
||||||
|
var yamlNode = require('./core/parsers/70-YAML_page');
|
||||||
var fileInNode = require('./core/storage/10-filein_page');
|
var fileInNode = require('./core/storage/10-filein_page');
|
||||||
|
|
||||||
var nodeCatalog = {
|
var nodeCatalog = {
|
||||||
@ -44,9 +49,15 @@ var nodeCatalog = {
|
|||||||
"httpIn": httpInNode,
|
"httpIn": httpInNode,
|
||||||
"httpResponse": httpResponseNode,
|
"httpResponse": httpResponseNode,
|
||||||
"httpRequest": httpRequestNode,
|
"httpRequest": httpRequestNode,
|
||||||
|
// sequence
|
||||||
|
"split": splitNode,
|
||||||
|
"join": joinNode,
|
||||||
// parser
|
// parser
|
||||||
|
"csv": csvNode,
|
||||||
"html": htmlNode,
|
"html": htmlNode,
|
||||||
"json": jsonNode,
|
"json": jsonNode,
|
||||||
|
"xml": xmlNode,
|
||||||
|
"yaml": yamlNode,
|
||||||
// storage
|
// storage
|
||||||
"fileIn": fileInNode
|
"fileIn": fileInNode
|
||||||
};
|
};
|
||||||
|
364
test/editor/specs/scenario/cookbook_dataformats_uispec.js
Normal file
364
test/editor/specs/scenario/cookbook_dataformats_uispec.js
Normal file
@ -0,0 +1,364 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var when = require('when');
|
||||||
|
var should = require('should');
|
||||||
|
var fs = require('fs-extra');
|
||||||
|
|
||||||
|
var helper = require('../../editor_helper');
|
||||||
|
var debugTab = require('../../pageobjects/editor/debugTab_page');
|
||||||
|
var workspace = require('../../pageobjects/editor/workspace_page');
|
||||||
|
var specUtil = require('../../pageobjects/util/spec_util_page');
|
||||||
|
|
||||||
|
var httpNodeRoot = '/api';
|
||||||
|
|
||||||
|
// https://cookbook.nodered.org/
|
||||||
|
describe('cookbook', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
workspace.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
before(function () {
|
||||||
|
helper.startServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function () {
|
||||||
|
helper.stopServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('working with data formats', function () {
|
||||||
|
it('convert to/from JSON', function () {
|
||||||
|
var injectNode1 = workspace.addNode('inject');
|
||||||
|
var jsonNode1 = workspace.addNode('json');
|
||||||
|
var debugNode1 = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode1.edit();
|
||||||
|
injectNode1.setPayload('str', '{"a":1}');
|
||||||
|
injectNode1.clickOk();
|
||||||
|
|
||||||
|
jsonNode1.edit();
|
||||||
|
jsonNode1.setProperty('payload');
|
||||||
|
jsonNode1.clickOk();
|
||||||
|
|
||||||
|
injectNode1.connect(jsonNode1);
|
||||||
|
jsonNode1.connect(debugNode1);
|
||||||
|
|
||||||
|
var injectNode2 = workspace.addNode('inject');
|
||||||
|
var jsonNode2 = workspace.addNode('json');
|
||||||
|
var debugNode2 = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode2.edit();
|
||||||
|
injectNode2.setPayload('json', '{"a":1}');
|
||||||
|
injectNode2.clickOk();
|
||||||
|
|
||||||
|
jsonNode2.edit();
|
||||||
|
jsonNode2.setProperty('payload');
|
||||||
|
jsonNode2.clickOk();
|
||||||
|
|
||||||
|
injectNode2.connect(jsonNode2);
|
||||||
|
jsonNode2.connect(debugNode2);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode1.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('1');
|
||||||
|
debugTab.clearMessage();
|
||||||
|
injectNode2.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('"{"a":1}"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('convert to/from XML', function () {
|
||||||
|
var injectNode1 = workspace.addNode('inject', 0);
|
||||||
|
var templateNode1 = workspace.addNode('template', 200);
|
||||||
|
var xmlNode1 = workspace.addNode('xml', 400);
|
||||||
|
var debugNode1 = workspace.addNode('debug', 600);
|
||||||
|
|
||||||
|
injectNode1.edit();
|
||||||
|
injectNode1.setPayload('str', '{"a":1}');
|
||||||
|
injectNode1.clickOk();
|
||||||
|
|
||||||
|
templateNode1.edit();
|
||||||
|
templateNode1.setFormat('text');
|
||||||
|
templateNode1.setSyntax('plain');
|
||||||
|
templateNode1.setTemplate('<note priority="high">'
|
||||||
|
+ ' <to>Nick</to>'
|
||||||
|
+ ' <from>Dave</from>'
|
||||||
|
+ ' <heading>Reminder</heading>'
|
||||||
|
+ ' <body>Update the website</body>'
|
||||||
|
+ '</note>');
|
||||||
|
templateNode1.clickOk();
|
||||||
|
|
||||||
|
xmlNode1.edit();
|
||||||
|
xmlNode1.setProperty('payload');
|
||||||
|
xmlNode1.clickOk();
|
||||||
|
|
||||||
|
injectNode1.connect(templateNode1);
|
||||||
|
templateNode1.connect(xmlNode1);
|
||||||
|
xmlNode1.connect(debugNode1);
|
||||||
|
|
||||||
|
var injectNode2 = workspace.addNode('inject');
|
||||||
|
var xmlNode2 = workspace.addNode('xml');
|
||||||
|
var debugNode2 = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode2.edit();
|
||||||
|
injectNode2.setPayload('json', '{'
|
||||||
|
+ ' "note": {'
|
||||||
|
+ ' "$": { "priority": "high" },'
|
||||||
|
+ ' "to": [ "Nick" ],'
|
||||||
|
+ ' "from": [ "Dave" ],'
|
||||||
|
+ ' "heading": [ "Reminder" ],'
|
||||||
|
+ ' "body": [ "Update the website" ]'
|
||||||
|
+ ' }'
|
||||||
|
+ '}');
|
||||||
|
injectNode2.clickOk();
|
||||||
|
|
||||||
|
xmlNode2.edit();
|
||||||
|
xmlNode2.setProperty('payload');
|
||||||
|
xmlNode2.clickOk();
|
||||||
|
|
||||||
|
injectNode2.connect(xmlNode2);
|
||||||
|
xmlNode2.connect(debugNode2);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode1.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('object');
|
||||||
|
debugTab.clearMessage();
|
||||||
|
injectNode2.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('"<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
|
||||||
|
+ '<note priority="high">'
|
||||||
|
+ '<to>Nick</to>'
|
||||||
|
+ '<from>Dave</from>'
|
||||||
|
+ '<heading>Reminder</heading>'
|
||||||
|
+ '<body>Update the website</body>'
|
||||||
|
+ '</note>"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('convert to/from YAML', function () {
|
||||||
|
var injectNode1 = workspace.addNode('inject', 0);
|
||||||
|
var templateNode1 = workspace.addNode('template', 200);
|
||||||
|
var yamlNode1 = workspace.addNode('yaml', 400);
|
||||||
|
var debugNode1 = workspace.addNode('debug', 600);
|
||||||
|
|
||||||
|
injectNode1.edit();
|
||||||
|
injectNode1.setPayload('str', '{"a":1}');
|
||||||
|
injectNode1.clickOk();
|
||||||
|
|
||||||
|
templateNode1.edit();
|
||||||
|
templateNode1.setFormat('yaml');
|
||||||
|
templateNode1.setSyntax('plain');
|
||||||
|
templateNode1.setTemplate('a: 1\n'
|
||||||
|
+ 'b:\n'
|
||||||
|
+ ' - 1\n'
|
||||||
|
+ '- 2\n'
|
||||||
|
+ '- 3');
|
||||||
|
templateNode1.clickOk();
|
||||||
|
|
||||||
|
yamlNode1.edit();
|
||||||
|
yamlNode1.setProperty('payload');
|
||||||
|
yamlNode1.clickOk();
|
||||||
|
|
||||||
|
injectNode1.connect(templateNode1);
|
||||||
|
templateNode1.connect(yamlNode1);
|
||||||
|
yamlNode1.connect(debugNode1);
|
||||||
|
|
||||||
|
var injectNode2 = workspace.addNode('inject');
|
||||||
|
var yamlNode2 = workspace.addNode('yaml');
|
||||||
|
var debugNode2 = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode2.edit();
|
||||||
|
injectNode2.setPayload('json', '{"a":1, "b":[1,2,3]}');
|
||||||
|
injectNode2.clickOk();
|
||||||
|
|
||||||
|
yamlNode2.edit();
|
||||||
|
yamlNode2.setProperty('payload');
|
||||||
|
yamlNode2.clickOk();
|
||||||
|
|
||||||
|
injectNode2.connect(yamlNode2);
|
||||||
|
yamlNode2.connect(debugNode2);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode1.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql([ '1', 'array[3]' ]);
|
||||||
|
debugTab.clearMessage();
|
||||||
|
injectNode2.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('"a: 1↵b:↵ - 1↵ - 2↵ - 3↵"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('generate CSV output', function () {
|
||||||
|
var injectNode1 = workspace.addNode('inject', 0);
|
||||||
|
var changeNode1 = workspace.addNode('change', 200);
|
||||||
|
var csvNode1 = workspace.addNode('csv', 400);
|
||||||
|
var debugNode1 = workspace.addNode('debug', 600);
|
||||||
|
|
||||||
|
changeNode1.edit();
|
||||||
|
changeNode1.ruleSet('payload', 'msg', '{'
|
||||||
|
+ ' "a": $floor(100*$random()),'
|
||||||
|
+ ' "b": $floor(100*$random()),'
|
||||||
|
+ ' "c": $floor(100*$random())'
|
||||||
|
+ '}', 'jsonata');
|
||||||
|
changeNode1.clickOk();
|
||||||
|
|
||||||
|
csvNode1.edit();
|
||||||
|
csvNode1.setColumns('a,b,c');
|
||||||
|
csvNode1.clickOk();
|
||||||
|
|
||||||
|
injectNode1.connect(changeNode1);
|
||||||
|
changeNode1.connect(csvNode1);
|
||||||
|
csvNode1.connect(debugNode1);
|
||||||
|
|
||||||
|
var injectNode2 = workspace.addNode('inject', 0, 80);
|
||||||
|
var changeNode2 = workspace.addNode('change', 200, 80);
|
||||||
|
var csvNode2 = workspace.addNode('csv', 400, 80);
|
||||||
|
var debugNode2 = workspace.addNode('debug', 600, 80);
|
||||||
|
|
||||||
|
changeNode2.edit();
|
||||||
|
changeNode2.ruleSet('payload', 'msg', '['
|
||||||
|
+ ' {'
|
||||||
|
+ ' "a": $floor(100*$random()),'
|
||||||
|
+ ' "b": $floor(100*$random()),'
|
||||||
|
+ ' "c": $floor(100*$random())'
|
||||||
|
+ ' }, {'
|
||||||
|
+ ' "a": $floor(100*$random()),'
|
||||||
|
+ ' "b": $floor(100*$random()),'
|
||||||
|
+ ' "c": $floor(100*$random())'
|
||||||
|
+ ' }, {'
|
||||||
|
+ ' "a": $floor(100*$random()),'
|
||||||
|
+ ' "b": $floor(100*$random()),'
|
||||||
|
+ ' "c": $floor(100*$random())'
|
||||||
|
+ ' }, {'
|
||||||
|
+ ' "a": $floor(100*$random()),'
|
||||||
|
+ ' "b": $floor(100*$random()),'
|
||||||
|
+ ' "c": $floor(100*$random())'
|
||||||
|
+ ' }'
|
||||||
|
+ ']', 'jsonata');
|
||||||
|
changeNode2.clickOk();
|
||||||
|
|
||||||
|
csvNode2.edit();
|
||||||
|
csvNode2.setColumns('a,b,c');
|
||||||
|
csvNode2.setIncludeRow(true);
|
||||||
|
csvNode2.clickOk();
|
||||||
|
|
||||||
|
injectNode2.connect(changeNode2);
|
||||||
|
changeNode2.connect(csvNode2);
|
||||||
|
csvNode2.connect(debugNode2);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode1.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.match(/^"([1-9]?[0-9],){2}[1-9]?[0-9]↵"$/);
|
||||||
|
debugTab.clearMessage();
|
||||||
|
injectNode2.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.match(/^"a,b,c↵(([1-9]?[0-9],){2}[1-9]?[0-9]↵){4}"$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parse CSV input', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var templateNode = workspace.addNode('template');
|
||||||
|
var csvNode = workspace.addNode('csv');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
templateNode.edit();
|
||||||
|
templateNode.setFormat('handlebars');
|
||||||
|
templateNode.setSyntax('mustache');
|
||||||
|
templateNode.setTemplate('# This is some random data\n'
|
||||||
|
+ 'a,b,c\n'
|
||||||
|
+ '80,18,2\n'
|
||||||
|
+ '52,36,10\n'
|
||||||
|
+ '91,18,61\n'
|
||||||
|
+ '32,47,65');
|
||||||
|
templateNode.clickOk();
|
||||||
|
|
||||||
|
csvNode.edit();
|
||||||
|
csvNode.setSkipLines(1);
|
||||||
|
csvNode.setFirstRow4Names(true);
|
||||||
|
csvNode.setOutput('mult');
|
||||||
|
csvNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(templateNode);
|
||||||
|
templateNode.connect(csvNode);
|
||||||
|
csvNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql([ 'object', 'object', 'object', 'object' ]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('simple GET request', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var httpRequestNode = workspace.addNode('httpRequest');
|
||||||
|
var htmlNode = workspace.addNode('html');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
httpRequestNode.edit();
|
||||||
|
httpRequestNode.setMethod('GET');
|
||||||
|
httpRequestNode.setUrl('https://nodered.org');
|
||||||
|
httpRequestNode.clickOk();
|
||||||
|
|
||||||
|
htmlNode.edit();
|
||||||
|
htmlNode.setSelector('.node-red-latest-version');
|
||||||
|
htmlNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(httpRequestNode);
|
||||||
|
httpRequestNode.connect(htmlNode);
|
||||||
|
htmlNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.match(/^"v[0-9]+\.[0-9]+\.[0-9]"$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('split text into one message per line', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var templateNode = workspace.addNode('template');
|
||||||
|
var splitNode = workspace.addNode('split');
|
||||||
|
var changeNode = workspace.addNode('change');
|
||||||
|
var joinNode = workspace.addNode('join');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
templateNode.edit();
|
||||||
|
templateNode.setFormat('handlebars');
|
||||||
|
templateNode.setSyntax('mustache');
|
||||||
|
templateNode.setTemplate('one\ntwo\nthree\nfour\nfive');
|
||||||
|
templateNode.clickOk();
|
||||||
|
|
||||||
|
changeNode.edit();
|
||||||
|
changeNode.ruleSet('payload', 'msg', '(parts.index+1) & ": " & payload', 'jsonata');
|
||||||
|
changeNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(templateNode);
|
||||||
|
templateNode.connect(splitNode);
|
||||||
|
splitNode.connect(changeNode);
|
||||||
|
changeNode.connect(joinNode);
|
||||||
|
joinNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('"1: one↵2: two↵3: three↵4: four↵5: five"');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
81
test/editor/specs/scenario/cookbook_flowcontrol_uispec.js
Normal file
81
test/editor/specs/scenario/cookbook_flowcontrol_uispec.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var when = require('when');
|
||||||
|
var should = require('should');
|
||||||
|
var fs = require('fs-extra');
|
||||||
|
|
||||||
|
var helper = require('../../editor_helper');
|
||||||
|
var debugTab = require('../../pageobjects/editor/debugTab_page');
|
||||||
|
var workspace = require('../../pageobjects/editor/workspace_page');
|
||||||
|
var specUtil = require('../../pageobjects/util/spec_util_page');
|
||||||
|
|
||||||
|
var httpNodeRoot = '/api';
|
||||||
|
|
||||||
|
// https://cookbook.nodered.org/
|
||||||
|
describe('cookbook', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
workspace.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
before(function () {
|
||||||
|
helper.startServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function () {
|
||||||
|
helper.stopServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('flow control', function () {
|
||||||
|
it('trigger a flow whenever Node-RED starts', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode.edit();
|
||||||
|
injectNode.setPayload('str', 'Started!');
|
||||||
|
injectNode.setOnce(true);
|
||||||
|
injectNode.clickOk();
|
||||||
|
injectNode.connect(debugNode);
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
workspace.deploy();
|
||||||
|
debugTab.getMessage().should.eql('"Started!"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('trigger a flow at regular intervals', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode.edit();
|
||||||
|
injectNode.setRepeat('interval');
|
||||||
|
injectNode.setRepeatInterval(1);
|
||||||
|
injectNode.clickOk();
|
||||||
|
injectNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
specUtil.pause(1000);
|
||||||
|
var t1 = Number(debugTab.getMessage(1));
|
||||||
|
t1.should.within(1500000000000, 3000000000000);
|
||||||
|
specUtil.pause(1000);
|
||||||
|
debugTab.getMessage(2).should.within(t1 + 900, 3000000000000);
|
||||||
|
});
|
||||||
|
|
||||||
|
// skip this case since it needs up to one minite.
|
||||||
|
it.skip('trigger a flow at a specific time');
|
||||||
|
});
|
||||||
|
});
|
@ -23,16 +23,16 @@ var workspace = require('../../pageobjects/editor/workspace_page');
|
|||||||
var httpNodeRoot = "/api";
|
var httpNodeRoot = "/api";
|
||||||
|
|
||||||
// https://cookbook.nodered.org/
|
// https://cookbook.nodered.org/
|
||||||
describe('cookbook', function() {
|
describe('cookbook', function () {
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
workspace.init();
|
workspace.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
before(function() {
|
before(function () {
|
||||||
helper.startServer();
|
helper.startServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function() {
|
after(function () {
|
||||||
helper.stopServer();
|
helper.stopServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ describe('cookbook', function() {
|
|||||||
debugTab.getMessage().indexOf('Text file').should.not.eql(-1);
|
debugTab.getMessage().indexOf('Text file').should.not.eql(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('post raw data to a flow', function() {
|
it('post raw data to a flow', function () {
|
||||||
var httpInNode = workspace.addNode("httpIn");
|
var httpInNode = workspace.addNode("httpIn");
|
||||||
var templateNode = workspace.addNode("template");
|
var templateNode = workspace.addNode("template");
|
||||||
var httpResponseNode = workspace.addNode("httpResponse");
|
var httpResponseNode = workspace.addNode("httpResponse");
|
||||||
@ -383,7 +383,7 @@ describe('cookbook', function() {
|
|||||||
var httpRequestNode = workspace.addNode("httpRequest");
|
var httpRequestNode = workspace.addNode("httpRequest");
|
||||||
var debugNode = workspace.addNode("debug");
|
var debugNode = workspace.addNode("debug");
|
||||||
|
|
||||||
injectNode.edit()
|
injectNode.edit();
|
||||||
injectNode.setPayload("str", "Nick");
|
injectNode.setPayload("str", "Nick");
|
||||||
injectNode.clickOk();
|
injectNode.clickOk();
|
||||||
|
|
||||||
@ -427,7 +427,7 @@ describe('cookbook', function() {
|
|||||||
var httpRequestNode = workspace.addNode("httpRequest");
|
var httpRequestNode = workspace.addNode("httpRequest");
|
||||||
var debugNode = workspace.addNode("debug");
|
var debugNode = workspace.addNode("debug");
|
||||||
|
|
||||||
injectNode.edit()
|
injectNode.edit();
|
||||||
injectNode.setPayload("str", "name=Nick");
|
injectNode.setPayload("str", "name=Nick");
|
||||||
injectNode.clickOk();
|
injectNode.clickOk();
|
||||||
|
|
||||||
@ -451,7 +451,7 @@ describe('cookbook', function() {
|
|||||||
debugTab.getMessage().indexOf('Hello Nick!').should.not.eql(-1);
|
debugTab.getMessage().indexOf('Hello Nick!').should.not.eql(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('post JSON data to a flow', function() {
|
it('post JSON data to a flow', function () {
|
||||||
var httpInNode = workspace.addNode("httpIn");
|
var httpInNode = workspace.addNode("httpIn");
|
||||||
var templateNode = workspace.addNode("template");
|
var templateNode = workspace.addNode("template");
|
||||||
var httpResponseNode = workspace.addNode("httpResponse");
|
var httpResponseNode = workspace.addNode("httpResponse");
|
||||||
@ -476,7 +476,7 @@ describe('cookbook', function() {
|
|||||||
var httpRequestNode = workspace.addNode("httpRequest");
|
var httpRequestNode = workspace.addNode("httpRequest");
|
||||||
var debugNode = workspace.addNode("debug");
|
var debugNode = workspace.addNode("debug");
|
||||||
|
|
||||||
injectNode.edit()
|
injectNode.edit();
|
||||||
injectNode.setPayload("json", '{"name":"Nick"}');
|
injectNode.setPayload("json", '{"name":"Nick"}');
|
||||||
injectNode.clickOk();
|
injectNode.clickOk();
|
||||||
|
|
300
test/editor/specs/scenario/cookbook_httprequests_uispec.js
Normal file
300
test/editor/specs/scenario/cookbook_httprequests_uispec.js
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var when = require('when');
|
||||||
|
var should = require('should');
|
||||||
|
var fs = require('fs-extra');
|
||||||
|
|
||||||
|
var helper = require('../../editor_helper');
|
||||||
|
var debugTab = require('../../pageobjects/editor/debugTab_page');
|
||||||
|
var workspace = require('../../pageobjects/editor/workspace_page');
|
||||||
|
var specUtil = require('../../pageobjects/util/spec_util_page');
|
||||||
|
|
||||||
|
var httpNodeRoot = '/api';
|
||||||
|
|
||||||
|
// https://cookbook.nodered.org/
|
||||||
|
describe('cookbook', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
workspace.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
before(function () {
|
||||||
|
helper.startServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function () {
|
||||||
|
helper.stopServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('HTTP requests', function () {
|
||||||
|
it('simple get request', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var httpRequestNode = workspace.addNode('httpRequest');
|
||||||
|
var htmlNode = workspace.addNode('html');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
httpRequestNode.edit();
|
||||||
|
httpRequestNode.setMethod('GET');
|
||||||
|
httpRequestNode.setUrl(helper.url());
|
||||||
|
httpRequestNode.clickOk();
|
||||||
|
|
||||||
|
htmlNode.edit();
|
||||||
|
htmlNode.setSelector('title');
|
||||||
|
htmlNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(httpRequestNode);
|
||||||
|
httpRequestNode.connect(htmlNode);
|
||||||
|
htmlNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('"Node-RED"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('set the URL of a request', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var changeNode = workspace.addNode('change');
|
||||||
|
var httpRequestNode = workspace.addNode('httpRequest');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode.edit();
|
||||||
|
injectNode.setPayload('str', helper.url());
|
||||||
|
injectNode.clickOk();
|
||||||
|
|
||||||
|
changeNode.edit();
|
||||||
|
changeNode.ruleSet('url', 'msg', 'payload', 'msg');
|
||||||
|
changeNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(changeNode);
|
||||||
|
changeNode.connect(httpRequestNode);
|
||||||
|
httpRequestNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.containEql('<title>Node-RED</title>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('set the URL of a request using a template', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var changeNode = workspace.addNode('change');
|
||||||
|
var httpRequestNode = workspace.addNode('httpRequest');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode.edit();
|
||||||
|
injectNode.setPayload('str', 'settings');
|
||||||
|
injectNode.clickOk();
|
||||||
|
|
||||||
|
changeNode.edit();
|
||||||
|
changeNode.ruleSet('query', 'msg', 'payload', 'msg');
|
||||||
|
changeNode.clickOk();
|
||||||
|
|
||||||
|
httpRequestNode.edit();
|
||||||
|
httpRequestNode.setUrl(helper.url() + '/{{{query}}}');
|
||||||
|
httpRequestNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(changeNode);
|
||||||
|
changeNode.connect(httpRequestNode);
|
||||||
|
httpRequestNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.containEql('httpNodeRoot');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('set the query string parameters', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var changeNode = workspace.addNode('change');
|
||||||
|
var httpRequestNode = workspace.addNode('httpRequest');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode.edit();
|
||||||
|
injectNode.setPayload('str', 'Nick');
|
||||||
|
injectNode.clickOk();
|
||||||
|
|
||||||
|
changeNode.edit();
|
||||||
|
changeNode.ruleSet('query', 'msg', 'payload', 'msg');
|
||||||
|
changeNode.clickOk();
|
||||||
|
|
||||||
|
httpRequestNode.edit();
|
||||||
|
httpRequestNode.setUrl(helper.url() + httpNodeRoot + '/set-query?q={{{query}}}');
|
||||||
|
httpRequestNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(changeNode);
|
||||||
|
changeNode.connect(httpRequestNode);
|
||||||
|
httpRequestNode.connect(debugNode);
|
||||||
|
|
||||||
|
// The code for confirmation starts from here.
|
||||||
|
var httpInNode = workspace.addNode('httpIn', 0, 200);
|
||||||
|
var templateNode = workspace.addNode('template');
|
||||||
|
var httpResponseNode = workspace.addNode('httpResponse');
|
||||||
|
|
||||||
|
httpInNode.edit();
|
||||||
|
httpInNode.setMethod('get');
|
||||||
|
httpInNode.setUrl('/set-query');
|
||||||
|
httpInNode.clickOk();
|
||||||
|
|
||||||
|
templateNode.edit();
|
||||||
|
templateNode.setSyntax('mustache');
|
||||||
|
templateNode.setFormat('handlebars');
|
||||||
|
templateNode.setTemplate('Hello {{req.query.q}}');
|
||||||
|
templateNode.clickOk();
|
||||||
|
|
||||||
|
httpInNode.connect(templateNode);
|
||||||
|
templateNode.connect(httpResponseNode);
|
||||||
|
// The code for confirmation ends here.
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('"Hello Nick"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get a parsed JSON response', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var changeNodeSetPost = workspace.addNode('change');
|
||||||
|
var httpRequestNode = workspace.addNode('httpRequest');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode.edit();
|
||||||
|
injectNode.setPayload('str', 'json-response');
|
||||||
|
injectNode.clickOk();
|
||||||
|
|
||||||
|
changeNodeSetPost.edit();
|
||||||
|
changeNodeSetPost.ruleSet('post', 'msg', 'payload', 'msg');
|
||||||
|
changeNodeSetPost.clickOk();
|
||||||
|
|
||||||
|
httpRequestNode.edit();
|
||||||
|
httpRequestNode.setMethod('GET');
|
||||||
|
var url = helper.url() + httpNodeRoot + '/{{post}}';
|
||||||
|
httpRequestNode.setUrl(url);
|
||||||
|
httpRequestNode.setReturn('obj');
|
||||||
|
httpRequestNode.clickOk();
|
||||||
|
|
||||||
|
debugNode.edit();
|
||||||
|
debugNode.setOutput('.title');
|
||||||
|
debugNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(changeNodeSetPost);
|
||||||
|
changeNodeSetPost.connect(httpRequestNode);
|
||||||
|
httpRequestNode.connect(debugNode);
|
||||||
|
|
||||||
|
// The code for confirmation starts from here.
|
||||||
|
var httpInNode = workspace.addNode('httpIn', 0, 200);
|
||||||
|
var templateNode = workspace.addNode('template');
|
||||||
|
var changeNodeSetHeader = workspace.addNode('change');
|
||||||
|
var httpResponseNode = workspace.addNode('httpResponse');
|
||||||
|
|
||||||
|
httpInNode.edit();
|
||||||
|
httpInNode.setMethod('get');
|
||||||
|
httpInNode.setUrl('/json-response');
|
||||||
|
httpInNode.clickOk();
|
||||||
|
|
||||||
|
templateNode.edit();
|
||||||
|
templateNode.setSyntax('mustache');
|
||||||
|
templateNode.setFormat('handlebars');
|
||||||
|
templateNode.setTemplate('{"title": "Hello"}');
|
||||||
|
templateNode.clickOk();
|
||||||
|
|
||||||
|
changeNodeSetHeader.edit();
|
||||||
|
changeNodeSetHeader.ruleSet('headers', 'msg', '{"content-type":"application/json"}', 'json');
|
||||||
|
changeNodeSetHeader.clickOk();
|
||||||
|
|
||||||
|
httpInNode.connect(templateNode);
|
||||||
|
templateNode.connect(changeNodeSetHeader);
|
||||||
|
changeNodeSetHeader.connect(httpResponseNode);
|
||||||
|
// The code for confirmation ends here.
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('"Hello"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get a binary response', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var httpRequestNode = workspace.addNode('httpRequest');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
httpRequestNode.edit();
|
||||||
|
httpRequestNode.setMethod('GET');
|
||||||
|
httpRequestNode.setUrl(helper.url() + '/settings');
|
||||||
|
httpRequestNode.setReturn('bin');
|
||||||
|
httpRequestNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(httpRequestNode);
|
||||||
|
httpRequestNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
|
||||||
|
debugTab.getMessage().should.eql(['123', '34', '104', '116', '116', '112', '78', '111', '100', '101']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('set a request header', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var functionNode = workspace.addNode('function');
|
||||||
|
var httpRequestNode = workspace.addNode('httpRequest');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
functionNode.edit();
|
||||||
|
functionNode.setFunction('msg.payload = "data to post";\nreturn msg;');
|
||||||
|
functionNode.clickOk();
|
||||||
|
|
||||||
|
httpRequestNode.edit();
|
||||||
|
httpRequestNode.setMethod('POST');
|
||||||
|
var url = helper.url() + httpNodeRoot + '/set-header';
|
||||||
|
httpRequestNode.setUrl(url);
|
||||||
|
httpRequestNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(functionNode);
|
||||||
|
functionNode.connect(httpRequestNode);
|
||||||
|
httpRequestNode.connect(debugNode);
|
||||||
|
|
||||||
|
// The code for confirmation starts from here.
|
||||||
|
var httpInNode = workspace.addNode('httpIn', 0, 200);
|
||||||
|
var templateNode = workspace.addNode('template');
|
||||||
|
var httpResponseNode = workspace.addNode('httpResponse');
|
||||||
|
|
||||||
|
httpInNode.edit();
|
||||||
|
httpInNode.setMethod('post');
|
||||||
|
httpInNode.setUrl('/set-header');
|
||||||
|
httpInNode.clickOk();
|
||||||
|
|
||||||
|
templateNode.edit();
|
||||||
|
templateNode.setSyntax('mustache');
|
||||||
|
templateNode.setFormat('handlebars');
|
||||||
|
templateNode.setTemplate('{{ payload }}');
|
||||||
|
templateNode.clickOk();
|
||||||
|
|
||||||
|
httpInNode.connect(templateNode);
|
||||||
|
templateNode.connect(httpResponseNode);
|
||||||
|
// The code for confirmation ends here.
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('"data to post"');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
142
test/editor/specs/scenario/cookbook_messages_uispec.js
Normal file
142
test/editor/specs/scenario/cookbook_messages_uispec.js
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/**
|
||||||
|
* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var when = require('when');
|
||||||
|
var should = require('should');
|
||||||
|
var fs = require('fs-extra');
|
||||||
|
|
||||||
|
var helper = require('../../editor_helper');
|
||||||
|
var debugTab = require('../../pageobjects/editor/debugTab_page');
|
||||||
|
var workspace = require('../../pageobjects/editor/workspace_page');
|
||||||
|
var specUtil = require('../../pageobjects/util/spec_util_page');
|
||||||
|
|
||||||
|
var httpNodeRoot = '/api';
|
||||||
|
|
||||||
|
// https://cookbook.nodered.org/
|
||||||
|
describe('cookbook', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
workspace.init();
|
||||||
|
});
|
||||||
|
|
||||||
|
before(function () {
|
||||||
|
helper.startServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function () {
|
||||||
|
helper.stopServer();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('messages', function () {
|
||||||
|
it('set a message property to a fixed value', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var changeNode = workspace.addNode('change');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
changeNode.edit();
|
||||||
|
changeNode.ruleSet('payload', 'msg', 'Hello World!');
|
||||||
|
changeNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(changeNode);
|
||||||
|
changeNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('"Hello World!"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('delete a message property', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var changeNode = workspace.addNode('change');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
changeNode.edit();
|
||||||
|
changeNode.ruleDelete();
|
||||||
|
changeNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(changeNode);
|
||||||
|
changeNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('undefined');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('move a message property', function () {
|
||||||
|
var injectNode = workspace.addNode('inject');
|
||||||
|
var changeNode = workspace.addNode('change');
|
||||||
|
var debugNode = workspace.addNode('debug');
|
||||||
|
|
||||||
|
injectNode.edit();
|
||||||
|
injectNode.setTopic('Hello');
|
||||||
|
injectNode.clickOk();
|
||||||
|
|
||||||
|
changeNode.edit();
|
||||||
|
changeNode.ruleMove('topic', 'payload');
|
||||||
|
changeNode.clickOk();
|
||||||
|
|
||||||
|
injectNode.connect(changeNode);
|
||||||
|
changeNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode.clickLeftButton();
|
||||||
|
debugTab.getMessage().should.eql('"Hello"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('map a property between different numeric ranges', function () {
|
||||||
|
var injectNode1 = workspace.addNode('inject');
|
||||||
|
var injectNode2 = workspace.addNode('inject', 0, 100);
|
||||||
|
var injectNode3 = workspace.addNode('inject', 0, 200);
|
||||||
|
var rangeNode = workspace.addNode('range', 200, 100);
|
||||||
|
var debugNode = workspace.addNode('debug', 400);
|
||||||
|
|
||||||
|
injectNode1.edit();
|
||||||
|
injectNode1.setPayload('num', 0);
|
||||||
|
injectNode1.clickOk();
|
||||||
|
injectNode2.edit();
|
||||||
|
injectNode2.setPayload('num', 512);
|
||||||
|
injectNode2.clickOk();
|
||||||
|
injectNode3.edit();
|
||||||
|
injectNode3.setPayload('num', 1023);
|
||||||
|
injectNode3.clickOk();
|
||||||
|
|
||||||
|
rangeNode.edit();
|
||||||
|
rangeNode.setAction('clamp');
|
||||||
|
rangeNode.setRange(0, 1023, 0, 5);
|
||||||
|
rangeNode.clickOk();
|
||||||
|
|
||||||
|
injectNode1.connect(rangeNode);
|
||||||
|
injectNode2.connect(rangeNode);
|
||||||
|
injectNode3.connect(rangeNode);
|
||||||
|
rangeNode.connect(debugNode);
|
||||||
|
|
||||||
|
workspace.deploy();
|
||||||
|
|
||||||
|
debugTab.open();
|
||||||
|
injectNode1.clickLeftButton();
|
||||||
|
debugTab.getMessage(1).should.eql('0');
|
||||||
|
injectNode2.clickLeftButton();
|
||||||
|
debugTab.getMessage(2).should.eql('2.5024437927663734');
|
||||||
|
injectNode3.clickLeftButton();
|
||||||
|
debugTab.getMessage(3).should.eql('5');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,441 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright JS Foundation and other contributors, http://js.foundation
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
**/
|
|
||||||
|
|
||||||
var when = require('when');
|
|
||||||
var should = require("should");
|
|
||||||
var fs = require('fs-extra');
|
|
||||||
|
|
||||||
var helper = require("../../editor_helper");
|
|
||||||
var debugTab = require('../../pageobjects/editor/debugTab_page');
|
|
||||||
var workspace = require('../../pageobjects/editor/workspace_page');
|
|
||||||
var specUtil = require('../../pageobjects/util/spec_util_page');
|
|
||||||
|
|
||||||
var httpNodeRoot = "/api";
|
|
||||||
|
|
||||||
// https://cookbook.nodered.org/
|
|
||||||
describe('cookbook', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
workspace.init();
|
|
||||||
});
|
|
||||||
|
|
||||||
before(function() {
|
|
||||||
helper.startServer();
|
|
||||||
});
|
|
||||||
|
|
||||||
after(function() {
|
|
||||||
helper.stopServer();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('messages', function() {
|
|
||||||
it('set a message property to a fixed value', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var changeNode = workspace.addNode("change");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
changeNode.edit();
|
|
||||||
changeNode.ruleSet("payload", "msg", "Hello World!");
|
|
||||||
changeNode.clickOk();
|
|
||||||
|
|
||||||
injectNode.connect(changeNode);
|
|
||||||
changeNode.connect(debugNode);
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
|
|
||||||
debugTab.open();
|
|
||||||
injectNode.clickLeftButton();
|
|
||||||
debugTab.getMessage().should.eql('"Hello World!"');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('delete a message property', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var changeNode = workspace.addNode("change");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
changeNode.edit();
|
|
||||||
changeNode.ruleDelete();
|
|
||||||
changeNode.clickOk();
|
|
||||||
|
|
||||||
injectNode.connect(changeNode);
|
|
||||||
changeNode.connect(debugNode);
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
|
|
||||||
debugTab.open();
|
|
||||||
injectNode.clickLeftButton();
|
|
||||||
debugTab.getMessage().should.eql("undefined");
|
|
||||||
});
|
|
||||||
|
|
||||||
it('move a message property', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var changeNode = workspace.addNode("change");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
injectNode.edit();
|
|
||||||
injectNode.setTopic("Hello");
|
|
||||||
injectNode.clickOk();
|
|
||||||
|
|
||||||
changeNode.edit();
|
|
||||||
changeNode.ruleMove("topic", "payload");
|
|
||||||
changeNode.clickOk();
|
|
||||||
|
|
||||||
injectNode.connect(changeNode);
|
|
||||||
changeNode.connect(debugNode);
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
|
|
||||||
debugTab.open();
|
|
||||||
injectNode.clickLeftButton();
|
|
||||||
debugTab.getMessage().should.eql('"Hello"');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('map a property between different numeric ranges', function() {
|
|
||||||
var injectNode1 = workspace.addNode("inject");
|
|
||||||
var injectNode2 = workspace.addNode("inject", 0, 100);
|
|
||||||
var injectNode3 = workspace.addNode("inject", 0, 200);
|
|
||||||
var rangeNode = workspace.addNode("range", 200, 100);
|
|
||||||
var debugNode = workspace.addNode("debug", 400);
|
|
||||||
|
|
||||||
injectNode1.edit();
|
|
||||||
injectNode1.setPayload("num", 0);
|
|
||||||
injectNode1.clickOk();
|
|
||||||
injectNode2.edit();
|
|
||||||
injectNode2.setPayload("num", 512);
|
|
||||||
injectNode2.clickOk();
|
|
||||||
injectNode3.edit();
|
|
||||||
injectNode3.setPayload("num", 1023);
|
|
||||||
injectNode3.clickOk();
|
|
||||||
|
|
||||||
rangeNode.edit();
|
|
||||||
rangeNode.setAction("clamp");
|
|
||||||
rangeNode.setRange(0, 1023, 0, 5);
|
|
||||||
rangeNode.clickOk();
|
|
||||||
|
|
||||||
injectNode1.connect(rangeNode);
|
|
||||||
injectNode2.connect(rangeNode);
|
|
||||||
injectNode3.connect(rangeNode);
|
|
||||||
rangeNode.connect(debugNode);
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
|
|
||||||
debugTab.open();
|
|
||||||
injectNode1.clickLeftButton();
|
|
||||||
debugTab.getMessage(1).should.eql('0');
|
|
||||||
injectNode2.clickLeftButton();
|
|
||||||
debugTab.getMessage(2).should.eql('2.5024437927663734');
|
|
||||||
injectNode3.clickLeftButton();
|
|
||||||
debugTab.getMessage(3).should.eql('5');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('flow control', function() {
|
|
||||||
it('trigger a flow whenever Node-RED starts', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
injectNode.edit();
|
|
||||||
injectNode.setPayload("str", "Started!")
|
|
||||||
injectNode.setOnce(true);
|
|
||||||
injectNode.clickOk();
|
|
||||||
injectNode.connect(debugNode);
|
|
||||||
|
|
||||||
debugTab.open();
|
|
||||||
workspace.deploy();
|
|
||||||
debugTab.getMessage().should.eql('"Started!"');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('trigger a flow at regular intervals', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
injectNode.edit();
|
|
||||||
injectNode.setRepeat("interval");
|
|
||||||
injectNode.setRepeatInterval(1);
|
|
||||||
injectNode.clickOk();
|
|
||||||
injectNode.connect(debugNode);
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
|
|
||||||
debugTab.open();
|
|
||||||
specUtil.pause(1000);
|
|
||||||
var t1 = Number(debugTab.getMessage(1));
|
|
||||||
t1.should.within(1500000000000, 3000000000000);
|
|
||||||
specUtil.pause(1000);
|
|
||||||
debugTab.getMessage(2).should.within(t1 + 900, 3000000000000);
|
|
||||||
});
|
|
||||||
|
|
||||||
// skip this case since it needs up to one minite.
|
|
||||||
it.skip('trigger a flow at a specific time');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('HTTP requests', function() {
|
|
||||||
it('simple get request', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var httpRequetNode = workspace.addNode("httpRequest");
|
|
||||||
var htmlNode = workspace.addNode("html");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
httpRequetNode.edit();
|
|
||||||
httpRequetNode.setMethod("GET");
|
|
||||||
httpRequetNode.setUrl(helper.url());
|
|
||||||
httpRequetNode.clickOk();
|
|
||||||
|
|
||||||
htmlNode.edit();
|
|
||||||
htmlNode.setSelector("title");
|
|
||||||
htmlNode.clickOk();
|
|
||||||
|
|
||||||
injectNode.connect(httpRequetNode);
|
|
||||||
httpRequetNode.connect(htmlNode);
|
|
||||||
htmlNode.connect(debugNode);
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
|
|
||||||
debugTab.open();
|
|
||||||
injectNode.clickLeftButton();
|
|
||||||
debugTab.getMessage().should.eql('"Node-RED"');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('set the URL of a request', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var changeNode = workspace.addNode("change");
|
|
||||||
var httpRequetNode = workspace.addNode("httpRequest");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
injectNode.edit();
|
|
||||||
injectNode.setPayload("str", helper.url());
|
|
||||||
injectNode.clickOk();
|
|
||||||
|
|
||||||
changeNode.edit();
|
|
||||||
changeNode.ruleSet("url", "msg", "payload", "msg");
|
|
||||||
changeNode.clickOk();
|
|
||||||
|
|
||||||
injectNode.connect(changeNode);
|
|
||||||
changeNode.connect(httpRequetNode);
|
|
||||||
httpRequetNode.connect(debugNode);
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
|
|
||||||
debugTab.open();
|
|
||||||
injectNode.clickLeftButton();
|
|
||||||
debugTab.getMessage().should.containEql('<title>Node-RED</title>');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('set the URL of a request using a template', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var changeNode = workspace.addNode("change");
|
|
||||||
var httpRequetNode = workspace.addNode("httpRequest");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
injectNode.edit();
|
|
||||||
injectNode.setPayload("str", 'settings');
|
|
||||||
injectNode.clickOk();
|
|
||||||
|
|
||||||
changeNode.edit();
|
|
||||||
changeNode.ruleSet("query", "msg", "payload", "msg");
|
|
||||||
changeNode.clickOk();
|
|
||||||
|
|
||||||
httpRequetNode.edit();
|
|
||||||
httpRequetNode.setUrl(helper.url() + "/{{{query}}}");
|
|
||||||
httpRequetNode.clickOk();
|
|
||||||
|
|
||||||
injectNode.connect(changeNode);
|
|
||||||
changeNode.connect(httpRequetNode);
|
|
||||||
httpRequetNode.connect(debugNode);
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
|
|
||||||
debugTab.open();
|
|
||||||
injectNode.clickLeftButton();
|
|
||||||
debugTab.getMessage().should.containEql('httpNodeRoot');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('set the query string parameters', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var changeNode = workspace.addNode("change");
|
|
||||||
var httpRequetNode = workspace.addNode("httpRequest");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
injectNode.edit();
|
|
||||||
injectNode.setPayload("str", 'Nick');
|
|
||||||
injectNode.clickOk();
|
|
||||||
|
|
||||||
changeNode.edit();
|
|
||||||
changeNode.ruleSet("query", "msg", "payload", "msg");
|
|
||||||
changeNode.clickOk();
|
|
||||||
|
|
||||||
httpRequetNode.edit();
|
|
||||||
httpRequetNode.setUrl(helper.url() + httpNodeRoot + '/set-query?q={{{query}}}');
|
|
||||||
httpRequetNode.clickOk();
|
|
||||||
|
|
||||||
injectNode.connect(changeNode);
|
|
||||||
changeNode.connect(httpRequetNode);
|
|
||||||
httpRequetNode.connect(debugNode);
|
|
||||||
|
|
||||||
// The code for confirmation starts from here.
|
|
||||||
var httpInNode = workspace.addNode("httpIn", 0, 200);
|
|
||||||
var templateNode = workspace.addNode("template");
|
|
||||||
var httpResponseNode = workspace.addNode("httpResponse");
|
|
||||||
|
|
||||||
httpInNode.edit();
|
|
||||||
httpInNode.setMethod("get");
|
|
||||||
httpInNode.setUrl("/set-query");
|
|
||||||
httpInNode.clickOk();
|
|
||||||
|
|
||||||
templateNode.edit();
|
|
||||||
templateNode.setSyntax("mustache");
|
|
||||||
templateNode.setFormat("handlebars");
|
|
||||||
templateNode.setTemplate("Hello {{req.query.q}}");
|
|
||||||
templateNode.clickOk();
|
|
||||||
|
|
||||||
httpInNode.connect(templateNode);
|
|
||||||
templateNode.connect(httpResponseNode);
|
|
||||||
// The code for confirmation ends here.
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
debugTab.open();
|
|
||||||
injectNode.clickLeftButton();
|
|
||||||
debugTab.getMessage().should.eql('"Hello Nick"');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('get a parsed JSON response', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var changeNodeSetPost = workspace.addNode("change");
|
|
||||||
var httpRequetNode = workspace.addNode("httpRequest");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
injectNode.edit();
|
|
||||||
injectNode.setPayload("str", "json-response");
|
|
||||||
injectNode.clickOk();
|
|
||||||
|
|
||||||
changeNodeSetPost.edit();
|
|
||||||
changeNodeSetPost.ruleSet("post", "msg", "payload", "msg");
|
|
||||||
changeNodeSetPost.clickOk();
|
|
||||||
|
|
||||||
httpRequetNode.edit();
|
|
||||||
httpRequetNode.setMethod("GET");
|
|
||||||
var url = helper.url() + httpNodeRoot + "/{{post}}";
|
|
||||||
httpRequetNode.setUrl(url);
|
|
||||||
httpRequetNode.setReturn("obj");
|
|
||||||
httpRequetNode.clickOk();
|
|
||||||
|
|
||||||
debugNode.edit();
|
|
||||||
debugNode.setOutput(".title");
|
|
||||||
debugNode.clickOk();
|
|
||||||
|
|
||||||
injectNode.connect(changeNodeSetPost);
|
|
||||||
changeNodeSetPost.connect(httpRequetNode);
|
|
||||||
httpRequetNode.connect(debugNode);
|
|
||||||
|
|
||||||
// The code for confirmation starts from here.
|
|
||||||
var httpInNode = workspace.addNode("httpIn", 0, 200);
|
|
||||||
var templateNode = workspace.addNode("template");
|
|
||||||
var changeNodeSetHeader = workspace.addNode("change");
|
|
||||||
var httpResponseNode = workspace.addNode("httpResponse");
|
|
||||||
|
|
||||||
httpInNode.edit();
|
|
||||||
httpInNode.setMethod("get");
|
|
||||||
httpInNode.setUrl("/json-response");
|
|
||||||
httpInNode.clickOk();
|
|
||||||
|
|
||||||
templateNode.edit();
|
|
||||||
templateNode.setSyntax("mustache");
|
|
||||||
templateNode.setFormat("handlebars");
|
|
||||||
templateNode.setTemplate('{"title": "Hello"}');
|
|
||||||
templateNode.clickOk();
|
|
||||||
|
|
||||||
changeNodeSetHeader.edit();
|
|
||||||
changeNodeSetHeader.ruleSet("headers", "msg", '{"content-type":"application/json"}', "json");
|
|
||||||
changeNodeSetHeader.clickOk();
|
|
||||||
|
|
||||||
httpInNode.connect(templateNode);
|
|
||||||
templateNode.connect(changeNodeSetHeader);
|
|
||||||
changeNodeSetHeader.connect(httpResponseNode);
|
|
||||||
// The code for confirmation ends here.
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
debugTab.open();
|
|
||||||
injectNode.clickLeftButton();
|
|
||||||
debugTab.getMessage().should.eql('"Hello"');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('get a binary response', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var httpRequetNode = workspace.addNode("httpRequest");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
httpRequetNode.edit();
|
|
||||||
httpRequetNode.setMethod("GET");
|
|
||||||
httpRequetNode.setUrl(helper.url() + "/settings");
|
|
||||||
httpRequetNode.setReturn("bin");
|
|
||||||
httpRequetNode.clickOk();
|
|
||||||
|
|
||||||
injectNode.connect(httpRequetNode);
|
|
||||||
httpRequetNode.connect(debugNode);
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
|
|
||||||
debugTab.open();
|
|
||||||
injectNode.clickLeftButton();
|
|
||||||
|
|
||||||
debugTab.getMessage().should.eql(['123', '34', '104', '116', '116', '112', '78', '111', '100', '101']);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('set a request header', function() {
|
|
||||||
var injectNode = workspace.addNode("inject");
|
|
||||||
var functionNode = workspace.addNode("function");
|
|
||||||
var httpRequetNode = workspace.addNode("httpRequest");
|
|
||||||
var debugNode = workspace.addNode("debug");
|
|
||||||
|
|
||||||
functionNode.edit();
|
|
||||||
functionNode.setFunction('msg.payload = "data to post";\nreturn msg;');
|
|
||||||
functionNode.clickOk();
|
|
||||||
|
|
||||||
httpRequetNode.edit();
|
|
||||||
httpRequetNode.setMethod("POST");
|
|
||||||
var url = helper.url() + httpNodeRoot + "/set-header";
|
|
||||||
httpRequetNode.setUrl(url);
|
|
||||||
httpRequetNode.clickOk();
|
|
||||||
|
|
||||||
injectNode.connect(functionNode);
|
|
||||||
functionNode.connect(httpRequetNode);
|
|
||||||
httpRequetNode.connect(debugNode);
|
|
||||||
|
|
||||||
// The code for confirmation starts from here.
|
|
||||||
var httpInNode = workspace.addNode("httpIn", 0, 200);
|
|
||||||
var templateNode = workspace.addNode("template");
|
|
||||||
var httpResponseNode = workspace.addNode("httpResponse");
|
|
||||||
|
|
||||||
httpInNode.edit();
|
|
||||||
httpInNode.setMethod("post");
|
|
||||||
httpInNode.setUrl("/set-header");
|
|
||||||
httpInNode.clickOk();
|
|
||||||
|
|
||||||
templateNode.edit();
|
|
||||||
templateNode.setSyntax("mustache");
|
|
||||||
templateNode.setFormat("handlebars");
|
|
||||||
templateNode.setTemplate("{{ payload }}");
|
|
||||||
templateNode.clickOk();
|
|
||||||
|
|
||||||
httpInNode.connect(templateNode);
|
|
||||||
templateNode.connect(httpResponseNode);
|
|
||||||
// The code for confirmation ends here.
|
|
||||||
|
|
||||||
workspace.deploy();
|
|
||||||
debugTab.open();
|
|
||||||
injectNode.clickLeftButton();
|
|
||||||
debugTab.getMessage().should.eql('"data to post"');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -53,7 +53,7 @@ describe("runtime-api/flows", function() {
|
|||||||
var loadFlows;
|
var loadFlows;
|
||||||
var reloadError = false;
|
var reloadError = false;
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
setFlows = sinon.spy(function(flows,type) {
|
setFlows = sinon.spy(function(flows,credentials,type) {
|
||||||
if (flows[0] === "error") {
|
if (flows[0] === "error") {
|
||||||
var err = new Error("error");
|
var err = new Error("error");
|
||||||
err.code = "error";
|
err.code = "error";
|
||||||
@ -91,7 +91,19 @@ describe("runtime-api/flows", function() {
|
|||||||
result.should.eql({rev:"newRev"});
|
result.should.eql({rev:"newRev"});
|
||||||
setFlows.called.should.be.true();
|
setFlows.called.should.be.true();
|
||||||
setFlows.lastCall.args[0].should.eql([4,5,6]);
|
setFlows.lastCall.args[0].should.eql([4,5,6]);
|
||||||
setFlows.lastCall.args[1].should.eql("full");
|
setFlows.lastCall.args[2].should.eql("full");
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
it("includes credentials when part of the request", function(done) {
|
||||||
|
flows.setFlows({
|
||||||
|
flows: {flows:[4,5,6], credentials: {$:"creds"}},
|
||||||
|
}).then(function(result) {
|
||||||
|
result.should.eql({rev:"newRev"});
|
||||||
|
setFlows.called.should.be.true();
|
||||||
|
setFlows.lastCall.args[0].should.eql([4,5,6]);
|
||||||
|
setFlows.lastCall.args[1].should.eql({$:"creds"});
|
||||||
|
setFlows.lastCall.args[2].should.eql("full");
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
@ -103,7 +115,7 @@ describe("runtime-api/flows", function() {
|
|||||||
result.should.eql({rev:"newRev"});
|
result.should.eql({rev:"newRev"});
|
||||||
setFlows.called.should.be.true();
|
setFlows.called.should.be.true();
|
||||||
setFlows.lastCall.args[0].should.eql([4,5,6]);
|
setFlows.lastCall.args[0].should.eql([4,5,6]);
|
||||||
setFlows.lastCall.args[1].should.eql("nodes");
|
setFlows.lastCall.args[2].should.eql("nodes");
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
@ -125,7 +137,7 @@ describe("runtime-api/flows", function() {
|
|||||||
result.should.eql({rev:"newRev"});
|
result.should.eql({rev:"newRev"});
|
||||||
setFlows.called.should.be.true();
|
setFlows.called.should.be.true();
|
||||||
setFlows.lastCall.args[0].should.eql([4,5,6]);
|
setFlows.lastCall.args[0].should.eql([4,5,6]);
|
||||||
setFlows.lastCall.args[1].should.eql("nodes");
|
setFlows.lastCall.args[2].should.eql("nodes");
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
@ -67,7 +67,10 @@ describe('flows/index', function() {
|
|||||||
});
|
});
|
||||||
return when.resolve();
|
return when.resolve();
|
||||||
});
|
});
|
||||||
credentialsLoad = sinon.stub(credentials,"load",function() {
|
credentialsLoad = sinon.stub(credentials,"load",function(creds) {
|
||||||
|
if (creds && creds.hasOwnProperty("$") && creds['$'] === "fail") {
|
||||||
|
return when.reject("creds error");
|
||||||
|
}
|
||||||
return when.resolve();
|
return when.resolve();
|
||||||
});
|
});
|
||||||
flowCreate = sinon.stub(Flow,"create",function(parent, global, flow) {
|
flowCreate = sinon.stub(Flow,"create",function(parent, global, flow) {
|
||||||
@ -177,6 +180,23 @@ describe('flows/index', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('sets the full flow including credentials', function(done) {
|
||||||
|
var originalConfig = [
|
||||||
|
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]},
|
||||||
|
{id:"t1",type:"tab"}
|
||||||
|
];
|
||||||
|
var credentials = {"t1-1":{"a":1}};
|
||||||
|
|
||||||
|
flows.init({log:mockLog, settings:{},storage:storage});
|
||||||
|
flows.setFlows(originalConfig,credentials).then(function() {
|
||||||
|
credentialsClean.called.should.be.false();
|
||||||
|
credentialsLoad.called.should.be.true();
|
||||||
|
credentialsLoad.lastCall.args[0].should.eql(credentials);
|
||||||
|
flows.getFlows().flows.should.eql(originalConfig);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('updates existing flows with partial deployment - nodes', function(done) {
|
it('updates existing flows with partial deployment - nodes', function(done) {
|
||||||
var originalConfig = [
|
var originalConfig = [
|
||||||
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]},
|
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]},
|
||||||
@ -235,6 +255,20 @@ describe('flows/index', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns error if it cannot decrypt credentials', function(done) {
|
||||||
|
var originalConfig = [
|
||||||
|
{id:"t1-1",x:10,y:10,z:"t1",type:"test",wires:[]},
|
||||||
|
{id:"t1",type:"tab"}
|
||||||
|
];
|
||||||
|
var credentials = {"$":"fail"};
|
||||||
|
|
||||||
|
flows.init({log:mockLog, settings:{},storage:storage});
|
||||||
|
flows.setFlows(originalConfig,credentials).then(function() {
|
||||||
|
done("Unexpected success when credentials couldn't be decrypted")
|
||||||
|
}).catch(function(err) {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#load', function() {
|
describe('#load', function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user