@5minds/node-red-contrib-processcube-tools 1.0.1-feature-050c1a-mfe18hnk → 1.0.1-feature-f506be-mfe3agh6

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.
@@ -1,479 +0,0 @@
1
- const should = require('should');
2
- const helper = require('node-red-node-test-helper');
3
- const {
4
- createMockImap,
5
- createMockMailparser,
6
- createMockNodeRED,
7
- setupModuleMocks,
8
- testConfigs,
9
- testFlows,
10
- testUtils
11
- } = require('../helpers/email-receiver.mocks.js');
12
-
13
- describe('Email Receiver Node - Integration Tests with Helpers', function() {
14
- // Set a reasonable timeout for integration tests
15
- this.timeout(10000);
16
-
17
- let emailReceiverNode;
18
- let cleanupMocks;
19
-
20
- before(function(done) {
21
- // Set up mocks using helper
22
- cleanupMocks = setupModuleMocks();
23
-
24
- // Load the node with mocked dependencies
25
- emailReceiverNode = require('../../email-receiver/email-receiver.js');
26
-
27
- // CRITICAL: Initialize the helper with Node-RED
28
- helper.init(require.resolve('node-red'));
29
- done();
30
- });
31
-
32
- after(function() {
33
- // Clean up mocks using helper cleanup function
34
- if (cleanupMocks) {
35
- cleanupMocks();
36
- }
37
- });
38
-
39
- beforeEach(function(done) {
40
- helper.startServer(done);
41
- });
42
-
43
- afterEach(function(done) {
44
- helper.unload();
45
- helper.stopServer(done);
46
- });
47
-
48
- describe('Node Loading', function() {
49
- it('should load in Node-RED test environment', function(done) {
50
- // ARRANGE: Use test flow from helpers
51
- const flow = [testConfigs.valid];
52
-
53
- // ACT: Load the node in the test helper environment
54
- helper.load(emailReceiverNode, flow, function() {
55
- try {
56
- // ASSERT: Verify the node loaded correctly
57
- const n1 = helper.getNode(testConfigs.valid.id);
58
- should.exist(n1);
59
- n1.should.have.property('name', testConfigs.valid.name);
60
- n1.should.have.property('type', 'email-receiver');
61
- done();
62
- } catch (err) {
63
- done(err);
64
- }
65
- });
66
- });
67
-
68
- it('should load with minimal configuration', function(done) {
69
- // ARRANGE: Use minimal test config from helpers
70
- const flow = [testConfigs.minimal];
71
-
72
- // ACT: Load the node
73
- helper.load(emailReceiverNode, flow, function() {
74
- try {
75
- // ASSERT: Verify the node loaded with minimal config
76
- const n1 = helper.getNode(testConfigs.minimal.id);
77
- should.exist(n1);
78
- n1.should.have.property('type', 'email-receiver');
79
- done();
80
- } catch (err) {
81
- done(err);
82
- }
83
- });
84
- });
85
-
86
- it('should load with string folders configuration', function(done) {
87
- // ARRANGE: Use string folders config from helpers
88
- const flow = [testConfigs.stringFolders];
89
-
90
- // ACT: Load the node
91
- helper.load(emailReceiverNode, flow, function() {
92
- try {
93
- // ASSERT: Verify the node loaded with string folders
94
- const n1 = helper.getNode(testConfigs.stringFolders.id);
95
- should.exist(n1);
96
- n1.should.have.property('name', testConfigs.stringFolders.name);
97
- done();
98
- } catch (err) {
99
- done(err);
100
- }
101
- });
102
- });
103
-
104
- it('should load with array folders configuration', function(done) {
105
- // ARRANGE: Use array folders config from helpers
106
- const flow = [testConfigs.arrayFolders];
107
-
108
- // ACT: Load the node
109
- helper.load(emailReceiverNode, flow, function() {
110
- try {
111
- // ASSERT: Verify the node loaded with array folders
112
- const n1 = helper.getNode(testConfigs.arrayFolders.id);
113
- should.exist(n1);
114
- n1.should.have.property('name', testConfigs.arrayFolders.name);
115
- done();
116
- } catch (err) {
117
- done(err);
118
- }
119
- });
120
- });
121
- });
122
-
123
- describe('Node Connections', function() {
124
- it('should create wired connections correctly', function(done) {
125
- // ARRANGE: Use connected test flow from helpers
126
- const flow = testFlows.connected;
127
-
128
- // ACT: Load nodes and verify connections
129
- helper.load(emailReceiverNode, flow, function() {
130
- try {
131
- const n1 = helper.getNode(testConfigs.valid.id);
132
- const h1 = helper.getNode('h1');
133
-
134
- // ASSERT: Both nodes should exist and be connected
135
- should.exist(n1);
136
- should.exist(h1);
137
- n1.should.have.property('name', testConfigs.valid.name);
138
- h1.should.have.property('type', 'helper');
139
-
140
- done();
141
- } catch (err) {
142
- done(err);
143
- }
144
- });
145
- });
146
-
147
- it('should handle multiple output connections', function(done) {
148
- // ARRANGE: Use multi-output test flow from helpers
149
- const flow = testFlows.multiOutput;
150
-
151
- // ACT: Load nodes
152
- helper.load(emailReceiverNode, flow, function() {
153
- try {
154
- const n1 = helper.getNode(testConfigs.valid.id);
155
- const h1 = helper.getNode('h1');
156
- const h2 = helper.getNode('h2');
157
-
158
- // ASSERT: All nodes should exist
159
- should.exist(n1);
160
- should.exist(h1);
161
- should.exist(h2);
162
- n1.should.have.property('name', testConfigs.valid.name);
163
-
164
- done();
165
- } catch (err) {
166
- done(err);
167
- }
168
- });
169
- });
170
- });
171
-
172
- describe('Message Flow', function() {
173
- it('should handle input without crashing', async function() {
174
- // ARRANGE: Use test flow from helpers
175
- const flow = testFlows.single;
176
-
177
- return new Promise((resolve, reject) => {
178
- helper.load(emailReceiverNode, flow, function() {
179
- try {
180
- const n1 = helper.getNode(testConfigs.valid.id);
181
- should.exist(n1);
182
-
183
- // Send input - this should not crash due to mocked IMAP
184
- n1.receive({ payload: "test input" });
185
-
186
- // ASSERT: If we reach here, the node handled input gracefully
187
- testUtils.wait(500).then(() => {
188
- resolve(); // Success if no errors thrown
189
- });
190
-
191
- } catch (err) {
192
- reject(err);
193
- }
194
- });
195
- });
196
- });
197
-
198
- it('should process messages through connected nodes', function(done) {
199
- // ARRANGE: Use connected test flow from helpers
200
- const flow = testFlows.connected;
201
-
202
- // ACT: Load nodes and set up message listener
203
- helper.load(emailReceiverNode, flow, function() {
204
- try {
205
- const n1 = helper.getNode(testConfigs.valid.id);
206
- const h1 = helper.getNode('h1');
207
-
208
- // Set up listener for messages from email receiver
209
- h1.on("input", function(msg) {
210
- try {
211
- // ASSERT: Should receive a message with expected properties
212
- should.exist(msg);
213
- should.exist(msg.payload);
214
-
215
- // Use helper utility to verify message
216
- testUtils.verifyMessage(msg, {
217
- payload: 'This is a mock email body for testing purposes.'
218
- });
219
-
220
- done();
221
- } catch (err) {
222
- done(err);
223
- }
224
- });
225
-
226
- // Trigger the email receiver
227
- n1.receive({ payload: "trigger" });
228
-
229
- } catch (err) {
230
- done(err);
231
- }
232
- });
233
- });
234
-
235
- it('should handle message timeout gracefully', async function() {
236
- // ARRANGE: Use connected test flow
237
- const flow = testFlows.connected;
238
-
239
- return new Promise((resolve, reject) => {
240
- helper.load(emailReceiverNode, flow, function() {
241
- try {
242
- const n1 = helper.getNode(testConfigs.valid.id);
243
- const h1 = helper.getNode('h1');
244
-
245
- // Use testUtils.waitForMessage with timeout
246
- testUtils.waitForMessage(h1, 1000)
247
- .then((msg) => {
248
- // ASSERT: Should receive message within timeout
249
- should.exist(msg);
250
- resolve();
251
- })
252
- .catch((err) => {
253
- // ASSERT: Should handle timeout appropriately
254
- err.message.should.containEql('Timeout waiting for message');
255
- resolve(); // This is expected behavior for this test
256
- });
257
-
258
- // Trigger the node but don't send a message (to test timeout)
259
- // n1.receive({ payload: "trigger" }); // Commented out to test timeout
260
-
261
- } catch (err) {
262
- reject(err);
263
- }
264
- });
265
- });
266
- });
267
- });
268
-
269
- describe('Configuration Validation', function() {
270
- it('should handle invalid configuration gracefully', function(done) {
271
- // ARRANGE: Use invalid config from helpers
272
- const flow = [testConfigs.invalidConfig];
273
-
274
- // ACT: Load node with invalid config
275
- helper.load(emailReceiverNode, flow, function() {
276
- try {
277
- const n1 = helper.getNode(testConfigs.invalidConfig.id);
278
- should.exist(n1);
279
-
280
- // ASSERT: Node should exist but handle invalid config appropriately
281
- // Send input to trigger validation
282
- n1.receive({ payload: "test" });
283
-
284
- // If we get here without crashing, the validation worked
285
- testUtils.wait(300).then(() => {
286
- done();
287
- });
288
-
289
- } catch (err) {
290
- done(err);
291
- }
292
- });
293
- });
294
-
295
- it('should validate folder configurations properly', async function() {
296
- // ARRANGE: Test different folder configurations
297
- const folderConfigs = [
298
- testConfigs.stringFolders,
299
- testConfigs.arrayFolders
300
- ];
301
-
302
- for (const config of folderConfigs) {
303
- await new Promise((resolve, reject) => {
304
- const flow = [config];
305
-
306
- helper.load(emailReceiverNode, flow, function() {
307
- try {
308
- const n1 = helper.getNode(config.id);
309
-
310
- // ASSERT: Node should load successfully with different folder configs
311
- should.exist(n1);
312
- n1.should.have.property('name', config.name);
313
-
314
- helper.unload();
315
- resolve();
316
- } catch (err) {
317
- reject(err);
318
- }
319
- });
320
- });
321
- }
322
- });
323
- });
324
-
325
- describe('Mock Integration Verification', function() {
326
- it('should work with createMockImap from helpers', function(done) {
327
- // ARRANGE: Create IMAP mock instance directly
328
- const mockImap = createMockImap();
329
- const imapInstance = new mockImap({
330
- host: testConfigs.valid.host,
331
- port: testConfigs.valid.port,
332
- secure: true
333
- });
334
-
335
- // ACT: Test IMAP mock behavior
336
- let readyFired = false;
337
- imapInstance.once('ready', () => {
338
- readyFired = true;
339
-
340
- // Test openBox functionality
341
- imapInstance.openBox('INBOX', false, (err, box) => {
342
- should.not.exist(err);
343
- should.exist(box);
344
- box.should.have.property('messages');
345
-
346
- // ASSERT: Mock IMAP should work as expected
347
- readyFired.should.be.true();
348
- done();
349
- });
350
- });
351
-
352
- imapInstance.connect();
353
- });
354
-
355
- it('should work with createMockMailparser from helpers', async function() {
356
- // ARRANGE: Create mailparser mock instance directly
357
- const mockMailparser = createMockMailparser();
358
-
359
- // ACT: Test mailparser mock behavior
360
- const result = await mockMailparser.simpleParser('test content', {
361
- subject: 'Integration Test Email',
362
- from: 'integration@test.com'
363
- });
364
-
365
- // ASSERT: Mock mailparser should return expected structure
366
- result.should.have.property('subject', 'Integration Test Email');
367
- result.should.have.property('from');
368
- result.from.should.have.property('text', 'integration@test.com');
369
- result.should.have.property('headers');
370
- result.headers.should.be.instanceOf(Map);
371
- });
372
- });
373
-
374
- describe('Node Lifecycle', function() {
375
- it('should clean up properly on unload', async function() {
376
- // ARRANGE: Use test flow from helpers
377
- const flow = testFlows.single;
378
-
379
- return new Promise((resolve, reject) => {
380
- helper.load(emailReceiverNode, flow, function() {
381
- try {
382
- const n1 = helper.getNode(testConfigs.valid.id);
383
- should.exist(n1);
384
-
385
- // Simulate some activity
386
- n1.receive({ payload: "test" });
387
-
388
- // Wait a bit for any async operations
389
- testUtils.wait(100).then(() => {
390
- // ASSERT: Unloading should not throw errors
391
- helper.unload();
392
- resolve();
393
- });
394
-
395
- } catch (err) {
396
- reject(err);
397
- }
398
- });
399
- });
400
- });
401
-
402
- it('should handle multiple load/unload cycles', async function() {
403
- // ARRANGE: Test multiple cycles
404
- const flow = testFlows.single;
405
- const cycles = 3;
406
-
407
- for (let i = 0; i < cycles; i++) {
408
- await new Promise((resolve, reject) => {
409
- helper.load(emailReceiverNode, flow, function() {
410
- try {
411
- const n1 = helper.getNode(testConfigs.valid.id);
412
- should.exist(n1);
413
-
414
- // Quick activity simulation
415
- n1.receive({ payload: `test cycle ${i}` });
416
-
417
- testUtils.wait(50).then(() => {
418
- helper.unload();
419
- resolve();
420
- });
421
- } catch (err) {
422
- reject(err);
423
- }
424
- });
425
- });
426
- }
427
-
428
- // ASSERT: If we complete all cycles without error, lifecycle handling works
429
- // This assertion is implicit in the successful completion of the loop
430
- });
431
- });
432
-
433
- describe('Advanced Flow Testing', function() {
434
- it('should handle complex message flows with multiple helpers', function(done) {
435
- // ARRANGE: Use multi-output flow from helpers
436
- const flow = testFlows.multiOutput;
437
- let receivedMessages = [];
438
-
439
- helper.load(emailReceiverNode, flow, function() {
440
- try {
441
- const n1 = helper.getNode(testConfigs.valid.id);
442
- const h1 = helper.getNode('h1');
443
- const h2 = helper.getNode('h2');
444
-
445
- // Set up listeners for both helper nodes
446
- h1.on("input", function(msg) {
447
- receivedMessages.push({ node: 'h1', msg: msg });
448
- checkCompletion();
449
- });
450
-
451
- h2.on("input", function(msg) {
452
- receivedMessages.push({ node: 'h2', msg: msg });
453
- checkCompletion();
454
- });
455
-
456
- function checkCompletion() {
457
- if (receivedMessages.length >= 2) {
458
- // ASSERT: Both helpers should receive messages
459
- receivedMessages.length.should.equal(2);
460
-
461
- receivedMessages.forEach(item => {
462
- should.exist(item.msg);
463
- should.exist(item.msg.payload);
464
- });
465
-
466
- done();
467
- }
468
- }
469
-
470
- // Trigger the email receiver
471
- n1.receive({ payload: "multi-trigger" });
472
-
473
- } catch (err) {
474
- done(err);
475
- }
476
- });
477
- });
478
- });
479
- });