Skip to content

Commit

Permalink
Merge pull request #54 from Steve-Mcl/add-setFlows
Browse files Browse the repository at this point in the history
add `setFlows` so that node being tested can modify flows
  • Loading branch information
knolleary committed Jun 21, 2022
2 parents 229c5fb + 547980c commit a04dc2c
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 14 deletions.
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,44 @@ Loads a flow then starts the flow. This function has the following arguments:
* testNode: (object|array of objects) Module object of a node to be tested returned by require function. This node will be registered, and can be used in testFlows.
* testFlow: (array of objects) Flow data to test a node. If you want to use flow data exported from Node-RED editor, export the flow to the clipboard and paste the content into your test scripts.
* testCredentials: (object) Optional node credentials.
* cb: (function) Function to call back when testFlows has been started.
* cb: (function) Function to call back when testFlows has been started (not required when called wih `await`)

### setFlows(testFlow, type, testCredentials, cb)

Updates the currently loaded flow. This function has the following arguments:

* testFlow: (array of objects) Flow data to test a node. If you want to use flow data exported from Node-RED editor, export the flow to the clipboard and paste the content into your test scripts.
* type: (string) Flow data to test a node. If you want to use flow data exported from Node-RED editor, export the flow to the clipboard and paste the content into your test scripts.
* testCredentials: (object) Optional node credentials.
* cb: (function) Function to call back when testFlows has been loaded (not required when called wih `await`)

#### Example

```js
it('should modify the flow then lower case of payload', async function () {
const flow = [
{ id: "n2", type: "helper" }
]
await helper.load(lowerNode, flow)
const newFlow = [...flow]
newFlow.push( { id: "n1", type: "lower-case", name: "lower-case", wires:[['n2']] },)
await helper.setFlows(newFlow, "nodes") //update flows
const n1 = helper.getNode('n1')
n1.should.have.a.property('name', 'lower-case')
await new Promise((resolve, reject) => {
const n2 = helper.getNode('n2')
n2.on('input', function (msg) {
try {
msg.should.have.property('payload', 'hello');
resolve()
} catch (err) {
reject(err);
}
});
n1.receive({ payload: 'HELLO' });
});
});
```

### unload()

Expand Down
24 changes: 24 additions & 0 deletions examples/lower-case_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,28 @@ describe('lower-case Node', function () {
n1.receive({ payload: "UpperCase" });
});
});
it('should modify the flow then lower case of payload', async function () {
const flow = [
{ id: "n2", type: "helper" }
]
await helper.load(lowerNode, flow)

const newFlow = [...flow]
newFlow.push( { id: "n1", type: "lower-case", name: "lower-case", wires:[['n2']] },)
await helper.setFlows(newFlow)
const n1 = helper.getNode('n1')
n1.should.have.a.property('name', 'lower-case')
await new Promise((resolve, reject) => {
const n2 = helper.getNode('n2')
n2.on('input', function (msg) {
try {
msg.should.have.property('payload', 'hello');
resolve()
} catch (err) {
reject(err);
}
});
n1.receive({ payload: 'HELLO' });
});
});
});
57 changes: 52 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,19 @@ class NodeTestHelper extends EventEmitter {
});



if (typeof testCredentials === 'function') {
cb = testCredentials;
testCredentials = {};
}

var storage = {
const conf = {flows:testFlow,credentials:testCredentials|| {}}
const storage = {
conf: conf,
getFlows: function () {
return Promise.resolve({flows:testFlow,credentials:testCredentials});
return Promise.resolve(conf);
},
saveFlows: function(conf) {
storage.conf = conf;
return Promise.resolve();
}
};
// this._settings.logging = {console:{level:'off'}};
Expand Down Expand Up @@ -281,7 +285,7 @@ class NodeTestHelper extends EventEmitter {
unload() {
// TODO: any other state to remove between tests?
this._redNodes.clearRegistry();
this._logSpy.restore();
this._logSpy && this._logSpy.restore();
this._sandbox.restore();

// internal API
Expand All @@ -302,6 +306,49 @@ class NodeTestHelper extends EventEmitter {
return this._redNodes.stopFlows();
}

/**
* Update flows
* @param {object|object[]} testFlow Flow data to test a node
* @param {"full"|"flows"|"nodes"} type The type of deploy mode "full", "flows" or "nodes" (defaults to "full")
* @param {object} [testCredentials] Optional node credentials
* @param {function} [cb] Optional callback (not required when called with await)
* @returns {Promise}
*/
setFlows(testFlow, type, testCredentials, cb) {
const helper = this;
if (typeof testCredentials === 'string' ) {
cb = testCredentials;
testCredentials = {};
}
if(!type || typeof type != "string") {
type = "full"
}
async function waitStarted() {
return new Promise((resolve, reject) => {
let timeover = setTimeout(() => {
if (timeover) {
timeover = null
reject(Error("timeout waiting event"))
}
}, 300);
function hander() {
clearTimeout(timeover)
helper._events.off('flows:started', hander)
if (timeover) {
timeover = null
resolve()
}
}
helper._events.on('flows:started', hander); // call resolve when its done
});
}
return this._redNodes.setFlows(testFlow, testCredentials || {}, type)
.then(waitStarted)
.then(() => {
if(cb) cb();
});
}

request() {
return request(this._httpAdmin);
}
Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-red-node-test-helper",
"version": "0.2.7",
"version": "0.3.0",
"description": "A test framework for Node-RED nodes",
"main": "index.js",
"scripts": {
Expand All @@ -13,18 +13,18 @@
"url": "https://github.com/node-red/node-red-node-test-helper.git"
},
"dependencies": {
"express": "4.17.1",
"body-parser": "1.19.0",
"body-parser": "1.20.0",
"express": "4.18.1",
"read-pkg-up": "7.0.1",
"semver": "7.3.4",
"semver": "7.3.7",
"should": "^13.2.3",
"should-sinon": "0.0.6",
"sinon": "9.2.4",
"sinon": "11.1.2",
"stoppable": "1.1.0",
"supertest": "4.0.2"
"supertest": "6.2.3"
},
"devDependencies": {
"mocha": "~7.1.2"
"mocha": "9.2.2"
},
"contributors": [
{
Expand All @@ -46,6 +46,6 @@
"node-red"
],
"engines": {
"node": ">=8"
"node": ">=14"
}
}

0 comments on commit a04dc2c

Please sign in to comment.