@5minds/node-red-contrib-processcube 1.16.0-feature-320605-mfchyhti → 1.16.0-feature-d3ee2b-mfcjbu9w
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -2
- package/test/email-receiver_spec.js +184 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@5minds/node-red-contrib-processcube",
|
|
3
|
-
"version": "1.16.0-feature-
|
|
3
|
+
"version": "1.16.0-feature-d3ee2b-mfcjbu9w",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Node-RED nodes for ProcessCube",
|
|
6
6
|
"scripts": {
|
|
@@ -79,7 +79,6 @@
|
|
|
79
79
|
"dependencies": {
|
|
80
80
|
"@5minds/processcube_engine_client": "^6.1.4",
|
|
81
81
|
"adm-zip": "^0.5.16",
|
|
82
|
-
"chai": "^4.3.4",
|
|
83
82
|
"jwt-decode": "^4.0.0",
|
|
84
83
|
"mailparser": "^3.6.8",
|
|
85
84
|
"node-imap": "^0.9.6"
|
|
@@ -7,35 +7,60 @@ describe('Email Receiver Node', function() {
|
|
|
7
7
|
// Module and mocking setup
|
|
8
8
|
let emailReceiverNode;
|
|
9
9
|
let originalLoad;
|
|
10
|
+
let mockImap;
|
|
11
|
+
let mockMailparser;
|
|
10
12
|
|
|
11
13
|
before(function() {
|
|
12
|
-
// Create mock modules
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
this.
|
|
18
|
-
|
|
19
|
-
this.fetch = function() { return { on: function() {}, once: function() {} }; };
|
|
20
|
-
this.end = function() {};
|
|
21
|
-
this.once = function() {};
|
|
22
|
-
return this;
|
|
23
|
-
},
|
|
24
|
-
'mailparser': {
|
|
25
|
-
simpleParser: function() {
|
|
26
|
-
return Promise.resolve({
|
|
27
|
-
subject: 'test',
|
|
28
|
-
text: 'test body',
|
|
29
|
-
html: '<p>test</p>',
|
|
30
|
-
from: { text: 'test@test.com' },
|
|
31
|
-
date: new Date(),
|
|
32
|
-
headers: new Map(),
|
|
33
|
-
attachments: []
|
|
34
|
-
});
|
|
14
|
+
// Create mock modules with correct behavior
|
|
15
|
+
mockImap = function(config) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
this.connect = () => {
|
|
18
|
+
// Simulate a successful connection by immediately emitting 'ready'
|
|
19
|
+
if (this.events && this.events.ready) {
|
|
20
|
+
this.events.ready();
|
|
35
21
|
}
|
|
22
|
+
};
|
|
23
|
+
this.openBox = (folder, readOnly, callback) => { callback(null, { messages: { total: 1 } }); };
|
|
24
|
+
this.search = (criteria, callback) => { callback(null, [123]); };
|
|
25
|
+
this.fetch = (results, options) => {
|
|
26
|
+
return {
|
|
27
|
+
on: (event, cb) => {
|
|
28
|
+
if (event === 'message') {
|
|
29
|
+
cb({ on: (e, bodyCb) => { if (e === 'body') bodyCb({}); } });
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
once: (event, cb) => {
|
|
33
|
+
if (event === 'end') { cb(); }
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
this.end = () => {};
|
|
38
|
+
this.once = (event, callback) => {
|
|
39
|
+
if (!this.events) this.events = {};
|
|
40
|
+
this.events[event] = callback;
|
|
41
|
+
};
|
|
42
|
+
return this;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
mockMailparser = {
|
|
46
|
+
simpleParser: function() {
|
|
47
|
+
return Promise.resolve({
|
|
48
|
+
subject: 'test',
|
|
49
|
+
text: 'test body',
|
|
50
|
+
html: '<p>test</p>',
|
|
51
|
+
from: { text: 'test@test.com' },
|
|
52
|
+
date: new Date(),
|
|
53
|
+
headers: new Map(),
|
|
54
|
+
attachments: []
|
|
55
|
+
});
|
|
36
56
|
}
|
|
37
57
|
};
|
|
38
58
|
|
|
59
|
+
const mockModules = {
|
|
60
|
+
'node-imap': mockImap,
|
|
61
|
+
'mailparser': mockMailparser
|
|
62
|
+
};
|
|
63
|
+
|
|
39
64
|
// Override require
|
|
40
65
|
const Module = require('module');
|
|
41
66
|
originalLoad = Module._load;
|
|
@@ -165,6 +190,141 @@ describe('Email Receiver Node', function() {
|
|
|
165
190
|
should.exist(nodeInstance);
|
|
166
191
|
nodeInstance.should.have.property('name', 'Test Email Receiver');
|
|
167
192
|
});
|
|
193
|
+
|
|
194
|
+
it('should handle comma-separated folder string', function(done) {
|
|
195
|
+
// ARRANGE: Mock the Node-RED and IMAP environment
|
|
196
|
+
let nodeInstance;
|
|
197
|
+
let inputCallback;
|
|
198
|
+
const mockRED = {
|
|
199
|
+
nodes: {
|
|
200
|
+
createNode: function(node, config) {
|
|
201
|
+
nodeInstance = node;
|
|
202
|
+
node.on = (event, callback) => { if (event === 'input') inputCallback = callback; };
|
|
203
|
+
node.status = () => {};
|
|
204
|
+
node.error = () => {};
|
|
205
|
+
node.send = (msg) => {
|
|
206
|
+
should.exist(msg);
|
|
207
|
+
msg.payload.should.equal('test body');
|
|
208
|
+
done();
|
|
209
|
+
};
|
|
210
|
+
return node;
|
|
211
|
+
},
|
|
212
|
+
registerType: (type, constructor) => {
|
|
213
|
+
new constructor({
|
|
214
|
+
host: "imap.test.com", hostType: "str",
|
|
215
|
+
port: 993, portType: "num",
|
|
216
|
+
user: "test@test.com", userType: "str",
|
|
217
|
+
password: "testpass", passwordType: "str",
|
|
218
|
+
folder: "INBOX, Spam, Sent", folderType: 'str',
|
|
219
|
+
markseen: true, markseenType: 'bool'
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
util: { evaluateNodeProperty: (value) => value },
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// ACT: Register the node, then simulate input
|
|
227
|
+
emailReceiverNode(mockRED);
|
|
228
|
+
inputCallback({});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should handle an array of folders', function(done) {
|
|
232
|
+
// ARRANGE: Mock the Node-RED and IMAP environment
|
|
233
|
+
let nodeInstance;
|
|
234
|
+
let inputCallback;
|
|
235
|
+
const mockRED = {
|
|
236
|
+
nodes: {
|
|
237
|
+
createNode: function(node, config) {
|
|
238
|
+
nodeInstance = node;
|
|
239
|
+
node.on = (event, callback) => { if (event === 'input') inputCallback = callback; };
|
|
240
|
+
node.status = () => {};
|
|
241
|
+
node.error = () => {};
|
|
242
|
+
node.send = (msg) => {
|
|
243
|
+
should.exist(msg);
|
|
244
|
+
msg.payload.should.equal('test body');
|
|
245
|
+
done();
|
|
246
|
+
};
|
|
247
|
+
return node;
|
|
248
|
+
},
|
|
249
|
+
registerType: (type, constructor) => {
|
|
250
|
+
new constructor({
|
|
251
|
+
host: "imap.test.com", hostType: "str",
|
|
252
|
+
port: 993, portType: "num",
|
|
253
|
+
user: "test@test.com", userType: "str",
|
|
254
|
+
password: "testpass", passwordType: "str",
|
|
255
|
+
folder: ["INBOX", "Junk"], folderType: 'json',
|
|
256
|
+
markseen: true, markseenType: 'bool'
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
util: { evaluateNodeProperty: (value) => value },
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// ACT: Register the node, then simulate input
|
|
264
|
+
emailReceiverNode(mockRED);
|
|
265
|
+
inputCallback({});
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('should call node.error for invalid folder type', function(done) {
|
|
269
|
+
// ARRANGE: Mock the node instance to capture errors
|
|
270
|
+
let errorCalled = false;
|
|
271
|
+
const nodeInstance = {
|
|
272
|
+
config: { folder: 123, folderType: 'num' },
|
|
273
|
+
on: (event, callback) => { if (event === 'input') nodeInstance.inputCallback = callback; },
|
|
274
|
+
status: () => {},
|
|
275
|
+
error: (err) => {
|
|
276
|
+
errorCalled = true;
|
|
277
|
+
err.should.containEql('The \'folders\' property must be an array of strings');
|
|
278
|
+
done();
|
|
279
|
+
},
|
|
280
|
+
send: () => {},
|
|
281
|
+
};
|
|
282
|
+
const mockRED = {
|
|
283
|
+
nodes: {
|
|
284
|
+
createNode: (node, config) => Object.assign(node, { on: nodeInstance.on, status: nodeInstance.status, error: nodeInstance.error, send: nodeInstance.send }),
|
|
285
|
+
registerType: (type, constructor) => new constructor(nodeInstance.config),
|
|
286
|
+
},
|
|
287
|
+
util: { evaluateNodeProperty: (value, type) => value },
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
// ACT: Register and instantiate the node, then simulate an input message
|
|
291
|
+
emailReceiverNode(mockRED);
|
|
292
|
+
nodeInstance.inputCallback({});
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('should call node.error for missing config', function(done) {
|
|
296
|
+
// ARRANGE: Mock the node instance to capture errors
|
|
297
|
+
let errorCalled = false;
|
|
298
|
+
let statusCalled = false;
|
|
299
|
+
const nodeInstance = {
|
|
300
|
+
config: {
|
|
301
|
+
host: "imap.test.com", hostType: "str",
|
|
302
|
+
port: 993, portType: "num",
|
|
303
|
+
user: "test@test.com", userType: "str",
|
|
304
|
+
password: "", passwordType: "str",
|
|
305
|
+
folder: "INBOX", folderType: "str"
|
|
306
|
+
},
|
|
307
|
+
on: (event, callback) => { if (event === 'input') nodeInstance.inputCallback = callback; },
|
|
308
|
+
status: (s) => { statusCalled = true; s.fill.should.equal('red'); },
|
|
309
|
+
error: (err) => {
|
|
310
|
+
errorCalled = true;
|
|
311
|
+
err.should.containEql('Missing required IMAP config');
|
|
312
|
+
done();
|
|
313
|
+
},
|
|
314
|
+
send: () => {},
|
|
315
|
+
};
|
|
316
|
+
const mockRED = {
|
|
317
|
+
nodes: {
|
|
318
|
+
createNode: (node, config) => Object.assign(node, { on: nodeInstance.on, status: nodeInstance.status, error: nodeInstance.error, send: nodeInstance.send }),
|
|
319
|
+
registerType: (type, constructor) => new constructor(nodeInstance.config),
|
|
320
|
+
},
|
|
321
|
+
util: { evaluateNodeProperty: (value, type) => value },
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
// ACT: Register and instantiate the node, then simulate an input message
|
|
325
|
+
emailReceiverNode(mockRED);
|
|
326
|
+
nodeInstance.inputCallback({});
|
|
327
|
+
});
|
|
168
328
|
});
|
|
169
329
|
|
|
170
330
|
describe('Integration Tests with Node-RED Helper', function() {
|
|
@@ -314,4 +474,4 @@ describe('Email Receiver Node', function() {
|
|
|
314
474
|
});
|
|
315
475
|
});
|
|
316
476
|
});
|
|
317
|
-
});
|
|
477
|
+
});
|