@5minds/node-red-contrib-processcube-tools 1.2.0-develop-d19f89-mg68thdf → 1.2.0-develop-59ef22-mg9d9ja5
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/.mocharc.json +5 -0
- package/package.json +26 -10
- package/src/custom-node-template/custom-node-template.html.template +45 -0
- package/src/custom-node-template/custom-node-template.ts.template +69 -0
- package/src/email-receiver/email-receiver.ts +439 -0
- package/src/email-sender/email-sender.ts +210 -0
- package/{processcube-html-to-text/processcube-html-to-text.html → src/html-to-text/html-to-text.html} +3 -3
- package/src/html-to-text/html-to-text.ts +53 -0
- package/src/index.ts +12 -0
- package/src/interfaces/EmailReceiverMessage.ts +22 -0
- package/src/interfaces/EmailSenderNodeProperties.ts +37 -0
- package/src/interfaces/FetchState.ts +9 -0
- package/src/interfaces/ImapConnectionConfig.ts +14 -0
- package/src/test/framework/advanced-test-patterns.ts +224 -0
- package/src/test/framework/generic-node-test-suite.ts +58 -0
- package/src/test/framework/index.ts +17 -0
- package/src/test/framework/integration-assertions.ts +67 -0
- package/src/test/framework/integration-scenario-builder.ts +77 -0
- package/src/test/framework/integration-test-runner.ts +101 -0
- package/src/test/framework/node-assertions.ts +63 -0
- package/src/test/framework/node-test-runner.ts +260 -0
- package/src/test/framework/test-scenario-builder.ts +74 -0
- package/src/test/framework/types.ts +61 -0
- package/src/test/helpers/email-receiver-test-configs.ts +67 -0
- package/src/test/helpers/email-receiver-test-flows.ts +16 -0
- package/src/test/helpers/email-sender-test-configs.ts +123 -0
- package/src/test/helpers/email-sender-test-flows.ts +16 -0
- package/src/test/integration/email-receiver.integration.test.ts +41 -0
- package/src/test/integration/email-sender.integration.test.ts +129 -0
- package/src/test/interfaces/email-data.ts +10 -0
- package/src/test/interfaces/email-receiver-config.ts +12 -0
- package/src/test/interfaces/email-sender-config.ts +26 -0
- package/src/test/interfaces/imap-config.ts +9 -0
- package/src/test/interfaces/imap-mailbox.ts +5 -0
- package/src/test/interfaces/mail-options.ts +20 -0
- package/src/test/interfaces/parsed-email.ts +11 -0
- package/src/test/interfaces/send-mail-result.ts +7 -0
- package/src/test/mocks/imap-mock.ts +147 -0
- package/src/test/mocks/mailparser-mock.ts +82 -0
- package/src/test/mocks/nodemailer-mock.ts +118 -0
- package/src/test/unit/email-receiver.unit.test.ts +471 -0
- package/src/test/unit/email-sender.unit.test.ts +550 -0
- package/tsconfig.json +23 -0
- package/email-receiver/email-receiver.js +0 -304
- package/email-sender/email-sender.js +0 -178
- package/examples/.gitkeep +0 -0
- package/processcube-html-to-text/processcube-html-to-text.js +0 -22
- package/test/helpers/email-receiver.mocks.js +0 -447
- package/test/helpers/email-sender.mocks.js +0 -368
- package/test/integration/email-receiver.integration.test.js +0 -515
- package/test/integration/email-sender.integration.test.js +0 -239
- package/test/unit/email-receiver.unit.test.js +0 -304
- package/test/unit/email-sender.unit.test.js +0 -570
- /package/{email-receiver → src/email-receiver}/email-receiver.html +0 -0
- /package/{email-sender → src/email-sender}/email-sender.html +0 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
import { expect } from 'chai';
|
|
2
|
+
import emailReceiverNode from '../../email-receiver/email-receiver';
|
|
3
|
+
import { EmailReceiverTestConfigs } from '../helpers/email-receiver-test-configs';
|
|
4
|
+
|
|
5
|
+
import { MockImap } from '../mocks/imap-mock';
|
|
6
|
+
import { createMockMailparser } from '../mocks/mailparser-mock';
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
TestScenarioBuilder,
|
|
10
|
+
NodeTestRunner,
|
|
11
|
+
NodeAssertions,
|
|
12
|
+
createNodeTestSuite,
|
|
13
|
+
type TestScenario,
|
|
14
|
+
type MockNodeREDOptions,
|
|
15
|
+
SecurityTestBuilder,
|
|
16
|
+
EdgeCaseTestBuilder,
|
|
17
|
+
ErrorResilienceTestBuilder,
|
|
18
|
+
} from '../framework';
|
|
19
|
+
|
|
20
|
+
describe('E-Mail Receiver Node - Unit Tests', function () {
|
|
21
|
+
// ========================================================================
|
|
22
|
+
// USE GENERIC TEST SUITE FOR BASIC FUNCTIONALITY
|
|
23
|
+
// ========================================================================
|
|
24
|
+
|
|
25
|
+
createNodeTestSuite('Email Receiver', emailReceiverNode, EmailReceiverTestConfigs);
|
|
26
|
+
|
|
27
|
+
// ========================================================================
|
|
28
|
+
// SPECIFIC EMAIL RECEIVER TESTS
|
|
29
|
+
// ========================================================================
|
|
30
|
+
|
|
31
|
+
describe('Email Receiver Specific Tests', function () {
|
|
32
|
+
describe('Configuration Validation', function () {
|
|
33
|
+
const configTests = new TestScenarioBuilder()
|
|
34
|
+
.addValidScenario('valid configuration', EmailReceiverTestConfigs.valid)
|
|
35
|
+
.addValidScenario('minimal configuration', EmailReceiverTestConfigs.minimal)
|
|
36
|
+
.addValidScenario('array folders configuration', EmailReceiverTestConfigs.arrayFolders)
|
|
37
|
+
.addErrorScenario(
|
|
38
|
+
'invalid folder type',
|
|
39
|
+
EmailReceiverTestConfigs.invalidFolderType,
|
|
40
|
+
"The 'folders' property must be an array of strings.",
|
|
41
|
+
)
|
|
42
|
+
.addErrorScenario(
|
|
43
|
+
'missing required config',
|
|
44
|
+
EmailReceiverTestConfigs.invalidConfig,
|
|
45
|
+
'Missing required IMAP config',
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
configTests.getScenarios().forEach((scenario) => {
|
|
49
|
+
it(`should handle ${scenario.name}`, async function () {
|
|
50
|
+
const context = await NodeTestRunner.runScenario(emailReceiverNode, scenario);
|
|
51
|
+
|
|
52
|
+
// Verify node was created
|
|
53
|
+
expect(context.nodeInstance).to.exist;
|
|
54
|
+
|
|
55
|
+
// Check specific expectations
|
|
56
|
+
if (scenario.expectedError) {
|
|
57
|
+
NodeAssertions.expectError(context, scenario.expectedError);
|
|
58
|
+
} else {
|
|
59
|
+
NodeAssertions.expectNoErrors(context);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Verify node properties
|
|
63
|
+
if (scenario.config.name) {
|
|
64
|
+
NodeAssertions.expectNodeProperty(context, 'name', scenario.config.name);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (scenario.config.id) {
|
|
68
|
+
NodeAssertions.expectNodeProperty(context, 'id', scenario.config.id);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe('IMAP Connection Handling', function () {
|
|
75
|
+
it('should establish connection successfully till the end', async function () {
|
|
76
|
+
this.timeout(15000);
|
|
77
|
+
const mockDependencies = {
|
|
78
|
+
ImapClient: MockImap,
|
|
79
|
+
mailParser: createMockMailparser(),
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const mockOptions: MockNodeREDOptions = {
|
|
83
|
+
dependencies: mockDependencies,
|
|
84
|
+
statusHandler: function (status: any) {
|
|
85
|
+
console.log('📊 Status received:', JSON.stringify(status, null, 2));
|
|
86
|
+
},
|
|
87
|
+
errorHandler: function (err: any) {
|
|
88
|
+
console.log('❌ Error received:', err);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const scenario: TestScenario = {
|
|
93
|
+
name: 'successful connection',
|
|
94
|
+
config: EmailReceiverTestConfigs.valid,
|
|
95
|
+
input: { payload: 'test' },
|
|
96
|
+
expectedStatus: { fill: 'green', shape: 'dot', text: 'IMAP connection ended.' },
|
|
97
|
+
timeout: 10000,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const context = await NodeTestRunner.runScenario(emailReceiverNode, scenario, mockOptions);
|
|
101
|
+
|
|
102
|
+
// Should have received a green status
|
|
103
|
+
const finalStatus = context.statuses.pop(); // Get the last status update
|
|
104
|
+
expect(finalStatus.fill).to.equal('green', 'IMAP connection ended.');
|
|
105
|
+
expect(finalStatus.text).to.include(
|
|
106
|
+
'IMAP connection ended.',
|
|
107
|
+
'Final status text should indicate completion',
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should establish connection successfully to show mails received', async function () {
|
|
112
|
+
this.timeout(15000);
|
|
113
|
+
const mockDependencies = {
|
|
114
|
+
ImapClient: MockImap,
|
|
115
|
+
mailParser: createMockMailparser(),
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const mockOptions: MockNodeREDOptions = {
|
|
119
|
+
dependencies: mockDependencies,
|
|
120
|
+
statusHandler: function (status: any) {
|
|
121
|
+
console.log('📊 Status received:', JSON.stringify(status, null, 2));
|
|
122
|
+
},
|
|
123
|
+
errorHandler: function (err: any) {
|
|
124
|
+
console.log('❌ Error received:', err);
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const scenario: TestScenario = {
|
|
129
|
+
name: 'successful connection',
|
|
130
|
+
config: EmailReceiverTestConfigs.valid,
|
|
131
|
+
input: { payload: 'test' },
|
|
132
|
+
expectedStatus: { fill: 'green', shape: 'dot', text: 'Done, fetched 5 mails from INBOX.' },
|
|
133
|
+
timeout: 10000,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const context = await NodeTestRunner.runScenario(emailReceiverNode, scenario, mockOptions);
|
|
137
|
+
const doneStatus = context.statuses.find((s) => s.text?.includes('Done, fetched'));
|
|
138
|
+
|
|
139
|
+
// Should have received a green status
|
|
140
|
+
expect(doneStatus).to.exist;
|
|
141
|
+
expect(doneStatus.fill).to.equal('green', 'Done, fetched 5 mails from INBOX.');
|
|
142
|
+
expect(doneStatus.text).to.include(
|
|
143
|
+
'Done, fetched',
|
|
144
|
+
'Final status text should indicate completion and fetched mails',
|
|
145
|
+
);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should handle connection failures gracefully', async function () {
|
|
149
|
+
const mockDependencies = {
|
|
150
|
+
ImapClient: MockImap,
|
|
151
|
+
mailParser: createMockMailparser(),
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const mockOptions: MockNodeREDOptions = {
|
|
155
|
+
dependencies: mockDependencies,
|
|
156
|
+
statusHandler: function (status: any) {
|
|
157
|
+
console.log('📊 Status received:', JSON.stringify(status, null, 2));
|
|
158
|
+
},
|
|
159
|
+
errorHandler: function (err: any) {
|
|
160
|
+
console.log('❌ Error received:', err);
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const scenario: TestScenario = {
|
|
165
|
+
name: 'connection failure',
|
|
166
|
+
config: EmailReceiverTestConfigs.invalidConfig,
|
|
167
|
+
input: { payload: 'test' },
|
|
168
|
+
expectedStatus: { fill: 'red', shape: 'ring', text: 'config error' },
|
|
169
|
+
expectedError: 'Missing required IMAP config: host, password. Aborting.',
|
|
170
|
+
timeout: 5000,
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const context = await NodeTestRunner.runScenario(emailReceiverNode, scenario, mockOptions);
|
|
174
|
+
|
|
175
|
+
// Should have either error or red status (or both)
|
|
176
|
+
const hasError = context.errors.length > 0;
|
|
177
|
+
const hasRedStatus = context.statuses.some((s) => s.fill === 'red');
|
|
178
|
+
|
|
179
|
+
expect(hasError || hasRedStatus, 'Should have error or red status for connection failure').to.be.true;
|
|
180
|
+
|
|
181
|
+
if (hasRedStatus) {
|
|
182
|
+
const redStatus = context.statuses.find((s) => s.fill === 'red');
|
|
183
|
+
expect(redStatus!.text).to.include('error');
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
describe('Email Processing', function () {
|
|
189
|
+
const processingTests = new TestScenarioBuilder()
|
|
190
|
+
.addCustomScenario({
|
|
191
|
+
name: 'single email fetch',
|
|
192
|
+
config: EmailReceiverTestConfigs.valid,
|
|
193
|
+
input: { payload: 'fetch' },
|
|
194
|
+
timeout: 5000,
|
|
195
|
+
})
|
|
196
|
+
.addCustomScenario({
|
|
197
|
+
name: 'multiple folders processing',
|
|
198
|
+
config: EmailReceiverTestConfigs.arrayFolders,
|
|
199
|
+
input: { payload: 'fetch' },
|
|
200
|
+
timeout: 5000,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
processingTests.getScenarios().forEach((scenario) => {
|
|
204
|
+
it(`should handle ${scenario.name}`, async function () {
|
|
205
|
+
const context = await NodeTestRunner.runScenario(emailReceiverNode, scenario);
|
|
206
|
+
|
|
207
|
+
// Node should be created without errors
|
|
208
|
+
expect(context.nodeInstance).to.exist;
|
|
209
|
+
NodeAssertions.expectNoErrors(context);
|
|
210
|
+
|
|
211
|
+
// For now, just verify the node processes input without crashing
|
|
212
|
+
// You can add more specific email processing assertions here
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe('Error Recovery', function () {
|
|
218
|
+
it('should recover from temporary connection issues', async function () {
|
|
219
|
+
// This test would verify that the node can recover from network issues
|
|
220
|
+
// Implementation depends on your specific error recovery logic
|
|
221
|
+
const scenario: TestScenario = {
|
|
222
|
+
name: 'error recovery',
|
|
223
|
+
config: EmailReceiverTestConfigs.valid,
|
|
224
|
+
input: { payload: 'test' },
|
|
225
|
+
timeout: 3000,
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const context = await NodeTestRunner.runScenario(emailReceiverNode, scenario);
|
|
229
|
+
expect(context.nodeInstance).to.exist;
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// ========================================================================
|
|
235
|
+
// EMAIL-SPECIFIC ERROR RESILIENCE TESTS
|
|
236
|
+
// ========================================================================
|
|
237
|
+
|
|
238
|
+
describe('Email Error Resilience', function () {
|
|
239
|
+
const resilience = new ErrorResilienceTestBuilder()
|
|
240
|
+
.addNetworkErrorScenario('IMAP connection', EmailReceiverTestConfigs.valid)
|
|
241
|
+
.addMalformedInputScenario('email message processing', EmailReceiverTestConfigs.valid)
|
|
242
|
+
.addRapidFireScenario('email burst handling', EmailReceiverTestConfigs.valid, 50);
|
|
243
|
+
|
|
244
|
+
resilience.getScenarios().forEach((scenario) => {
|
|
245
|
+
it(`should handle ${scenario.name}`, async function () {
|
|
246
|
+
const context = await NodeTestRunner.runScenario(emailReceiverNode, scenario);
|
|
247
|
+
|
|
248
|
+
// Node should exist and handle errors gracefully
|
|
249
|
+
expect(context.nodeInstance).to.exist;
|
|
250
|
+
|
|
251
|
+
// Should either process successfully or handle errors appropriately
|
|
252
|
+
const hasGracefulHandling =
|
|
253
|
+
context.errors.length === 0 ||
|
|
254
|
+
context.statuses.some((s) => s.fill === 'red') ||
|
|
255
|
+
context.errors.some((e) => typeof e === 'string');
|
|
256
|
+
|
|
257
|
+
expect(hasGracefulHandling, 'Should handle errors gracefully').to.be.true;
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// ========================================================================
|
|
263
|
+
// EMAIL-SPECIFIC EDGE CASES
|
|
264
|
+
// ========================================================================
|
|
265
|
+
|
|
266
|
+
describe('Email Edge Cases', function () {
|
|
267
|
+
const edgeCases = new EdgeCaseTestBuilder()
|
|
268
|
+
.addEmptyDataScenarios('empty email data', EmailReceiverTestConfigs.valid)
|
|
269
|
+
.addSpecialCharacterScenarios('special characters in emails', EmailReceiverTestConfigs.valid)
|
|
270
|
+
.addLargeDataScenarios('large email attachments', EmailReceiverTestConfigs.valid);
|
|
271
|
+
|
|
272
|
+
// Add email-specific edge cases
|
|
273
|
+
const emailSpecificCases = new TestScenarioBuilder()
|
|
274
|
+
.addCustomScenario({
|
|
275
|
+
name: 'very long subject line',
|
|
276
|
+
config: EmailReceiverTestConfigs.valid,
|
|
277
|
+
input: {
|
|
278
|
+
payload: 'fetch',
|
|
279
|
+
subject: 'a'.repeat(1000), // Very long subject
|
|
280
|
+
},
|
|
281
|
+
})
|
|
282
|
+
.addCustomScenario({
|
|
283
|
+
name: 'multiple folder processing',
|
|
284
|
+
config: {
|
|
285
|
+
...EmailReceiverTestConfigs.valid,
|
|
286
|
+
folders: Array.from({ length: 50 }, (_, i) => `FOLDER${i}`),
|
|
287
|
+
},
|
|
288
|
+
input: { payload: 'fetch' },
|
|
289
|
+
})
|
|
290
|
+
.addCustomScenario({
|
|
291
|
+
name: 'special email characters',
|
|
292
|
+
config: EmailReceiverTestConfigs.valid,
|
|
293
|
+
input: {
|
|
294
|
+
payload: 'fetch',
|
|
295
|
+
from: 'tëst@exämple.com',
|
|
296
|
+
subject: '📧 Émails with spéciál chars! 🌟',
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
[...edgeCases.getScenarios(), ...emailSpecificCases.getScenarios()].forEach((scenario) => {
|
|
301
|
+
it(`should handle ${scenario.name}`, async function () {
|
|
302
|
+
const context = await NodeTestRunner.runScenario(emailReceiverNode, scenario);
|
|
303
|
+
expect(context.nodeInstance).to.exist;
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// ========================================================================
|
|
309
|
+
// SECURITY TESTS FOR EMAIL PROCESSING
|
|
310
|
+
// ========================================================================
|
|
311
|
+
|
|
312
|
+
describe('Email Security', function () {
|
|
313
|
+
const security = new SecurityTestBuilder()
|
|
314
|
+
.addInjectionTestScenarios('email content injection', EmailReceiverTestConfigs.valid)
|
|
315
|
+
.addOversizedPayloadScenarios('large email payload', EmailReceiverTestConfigs.valid);
|
|
316
|
+
|
|
317
|
+
// Email-specific security tests
|
|
318
|
+
const emailSecurity = new TestScenarioBuilder()
|
|
319
|
+
.addCustomScenario({
|
|
320
|
+
name: 'malicious email headers',
|
|
321
|
+
config: EmailReceiverTestConfigs.valid,
|
|
322
|
+
input: {
|
|
323
|
+
payload: 'fetch',
|
|
324
|
+
headers: {
|
|
325
|
+
'X-Malicious': '<script>alert("xss")</script>',
|
|
326
|
+
'X-Injection': "'; DROP TABLE emails; --",
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
})
|
|
330
|
+
.addCustomScenario({
|
|
331
|
+
name: 'suspicious attachment handling',
|
|
332
|
+
config: EmailReceiverTestConfigs.valid,
|
|
333
|
+
input: {
|
|
334
|
+
payload: 'fetch',
|
|
335
|
+
attachments: [
|
|
336
|
+
{ filename: '../../../../../../etc/passwd' },
|
|
337
|
+
{ filename: 'virus.exe.txt' },
|
|
338
|
+
{ filename: '<script>evil.js</script>' },
|
|
339
|
+
],
|
|
340
|
+
},
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
[...security.getScenarios(), ...emailSecurity.getScenarios()].forEach((scenario) => {
|
|
344
|
+
it(`should resist ${scenario.name}`, async function () {
|
|
345
|
+
const context = await NodeTestRunner.runScenario(emailReceiverNode, scenario);
|
|
346
|
+
|
|
347
|
+
// Node should exist and not crash
|
|
348
|
+
expect(context.nodeInstance).to.exist;
|
|
349
|
+
|
|
350
|
+
// Should handle security threats gracefully
|
|
351
|
+
const handledSecurely =
|
|
352
|
+
context.errors.length === 0 || context.errors.some((e) => typeof e === 'string');
|
|
353
|
+
|
|
354
|
+
expect(handledSecurely, 'Should handle security threats gracefully').to.be.true;
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// ========================================================================
|
|
360
|
+
// DATA-DRIVEN TESTS FOR EMAIL SCENARIOS
|
|
361
|
+
// ========================================================================
|
|
362
|
+
|
|
363
|
+
describe('Email Receiver Data driven tests', function () {
|
|
364
|
+
const mockDependencies = {
|
|
365
|
+
ImapClient: MockImap,
|
|
366
|
+
mailParser: createMockMailparser(),
|
|
367
|
+
};
|
|
368
|
+
const mockOptions: MockNodeREDOptions = {
|
|
369
|
+
dependencies: mockDependencies,
|
|
370
|
+
statusHandler: function (status: any) {
|
|
371
|
+
console.log('📊 Status:', JSON.stringify(status, null, 2));
|
|
372
|
+
},
|
|
373
|
+
errorHandler: function (err: any) {
|
|
374
|
+
console.log('❌ Error:', err);
|
|
375
|
+
console.log('❌ Error stack:', new Error().stack); // See when error occurs
|
|
376
|
+
},
|
|
377
|
+
onHandler: function (event: string, callback: Function) {
|
|
378
|
+
console.log(`🎯 Event registered: ${event}`);
|
|
379
|
+
if (event === 'input') {
|
|
380
|
+
(this as any).inputCallback = callback;
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
const DataDrivenTests = [
|
|
386
|
+
{
|
|
387
|
+
name: 'fetch INBOX emails',
|
|
388
|
+
config: {
|
|
389
|
+
...EmailReceiverTestConfigs.valid,
|
|
390
|
+
folder: 'INBOX',
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
name: 'fetch SENT emails',
|
|
395
|
+
config: {
|
|
396
|
+
...EmailReceiverTestConfigs.valid,
|
|
397
|
+
folder: 'SENT',
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
name: 'invalid email receiver',
|
|
402
|
+
config: {
|
|
403
|
+
...EmailReceiverTestConfigs.valid,
|
|
404
|
+
folder: 'INBOX',
|
|
405
|
+
host: '',
|
|
406
|
+
},
|
|
407
|
+
expectedStatus: { fill: 'red' },
|
|
408
|
+
expectedError: /invalid|unknown|missing/i,
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
name: 'empty folder name',
|
|
412
|
+
config: {
|
|
413
|
+
...EmailReceiverTestConfigs.valid,
|
|
414
|
+
folder: '',
|
|
415
|
+
},
|
|
416
|
+
expectedStatus: { fill: 'red' },
|
|
417
|
+
expectedError: /folders|empty|invalid/i,
|
|
418
|
+
timeout: 2000,
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
name: 'numeric folder name',
|
|
422
|
+
config: {
|
|
423
|
+
...EmailReceiverTestConfigs.valid,
|
|
424
|
+
folder: 123,
|
|
425
|
+
},
|
|
426
|
+
expectedStatus: { fill: 'red' },
|
|
427
|
+
expectedError: /folder|string|type/i,
|
|
428
|
+
timeout: 2000,
|
|
429
|
+
},
|
|
430
|
+
];
|
|
431
|
+
|
|
432
|
+
DataDrivenTests.forEach((testCase) => {
|
|
433
|
+
it(`Email Processing Scenarios ${testCase.name}`, async function () {
|
|
434
|
+
const scenario: TestScenario = {
|
|
435
|
+
name: testCase.name,
|
|
436
|
+
config: testCase.config,
|
|
437
|
+
input: { payload: 'fetch' },
|
|
438
|
+
expectedError: testCase.expectedError,
|
|
439
|
+
expectedStatus: testCase.expectedStatus,
|
|
440
|
+
timeout: 3000,
|
|
441
|
+
};
|
|
442
|
+
console.log(`\n🧪 Starting test: ${testCase.name}`);
|
|
443
|
+
console.log('📝 Config:', JSON.stringify(scenario.config));
|
|
444
|
+
console.log('📝 Input:', JSON.stringify(scenario.input));
|
|
445
|
+
|
|
446
|
+
const context = await NodeTestRunner.runScenario(emailReceiverNode, scenario, mockOptions);
|
|
447
|
+
|
|
448
|
+
// 🔍 DEBUG
|
|
449
|
+
console.log('📦 Node constructed');
|
|
450
|
+
console.log('❌ Errors so far:', context.errors);
|
|
451
|
+
console.log('📊 Statuses so far:', context.statuses);
|
|
452
|
+
console.log('🐛 Has configError:', !!(context.nodeInstance as any).configError);
|
|
453
|
+
|
|
454
|
+
setTimeout(() => {
|
|
455
|
+
console.log('⏰ After 100ms:');
|
|
456
|
+
console.log('❌ Errors:', context.errors);
|
|
457
|
+
console.log('📊 Statuses:', context.statuses);
|
|
458
|
+
}, 100);
|
|
459
|
+
expect(context.nodeInstance).to.exist;
|
|
460
|
+
|
|
461
|
+
if (scenario.expectedStatus) {
|
|
462
|
+
NodeAssertions.expectStatus(context, scenario.expectedStatus);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (scenario.expectedError) {
|
|
466
|
+
NodeAssertions.expectError(context, scenario.expectedError);
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
});
|
|
471
|
+
});
|