@5minds/node-red-contrib-processcube-tools 1.0.1-feature-48c9c8-mff7tax3 → 1.0.1-feature-4d41c0-mff7tr8d

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