@5minds/node-red-contrib-processcube-tools 1.0.1-feature-24a79f-mfgha47l → 1.0.1-feature-cf0d8b-mfl5sxpl
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/email-receiver/email-receiver.html +165 -133
- package/email-receiver/email-receiver.js +49 -35
- package/email-sender/email-sender.html +109 -85
- package/email-sender/email-sender.js +66 -34
- package/package.json +2 -4
- package/processcube-html-to-text/processcube-html-to-text.html +9 -9
- package/processcube-html-to-text/processcube-html-to-text.js +0 -3
- package/test/helpers/email-receiver.mocks.js +394 -399
- package/test/helpers/email-sender.mocks.js +364 -0
- package/test/integration/email-receiver.integration.test.js +473 -482
- package/test/integration/email-sender.integration.test.js +242 -0
- package/test/unit/email-receiver.unit.test.js +284 -289
- package/test/unit/email-sender.unit.test.js +376 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
const { expect } = require('chai');
|
|
2
|
+
const {
|
|
3
|
+
createMockNodeRED,
|
|
4
|
+
setupModuleMocks,
|
|
5
|
+
emailSenderConfigs,
|
|
6
|
+
createMockNodemailer,
|
|
7
|
+
} = require('../helpers/email-sender.mocks.js');
|
|
8
|
+
|
|
9
|
+
describe('E-Mail Sender Node Unit Tests', function () {
|
|
10
|
+
this.timeout(10000);
|
|
11
|
+
|
|
12
|
+
let emailSenderNode;
|
|
13
|
+
let cleanupMocks;
|
|
14
|
+
|
|
15
|
+
before(function () {
|
|
16
|
+
// Set up module mocks using helper
|
|
17
|
+
cleanupMocks = setupModuleMocks();
|
|
18
|
+
|
|
19
|
+
// Load the node with mocked dependencies
|
|
20
|
+
emailSenderNode = require('../../email-sender/email-sender.js');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
after(function () {
|
|
24
|
+
// Clean up mocks
|
|
25
|
+
if (cleanupMocks) {
|
|
26
|
+
cleanupMocks();
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// A separate describe block for module export
|
|
31
|
+
describe('Module Export', function () {
|
|
32
|
+
it('should export a function', function () {
|
|
33
|
+
expect(emailSenderNode).to.be.a('function');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('Node Registration', function () {
|
|
38
|
+
it('should register node type without errors', function () {
|
|
39
|
+
// ARRANGE: Create mock Node-RED with tracking
|
|
40
|
+
const mockRED = createMockNodeRED();
|
|
41
|
+
|
|
42
|
+
// ACT: Register the node
|
|
43
|
+
emailSenderNode(mockRED);
|
|
44
|
+
|
|
45
|
+
// ASSERT: Verify registration
|
|
46
|
+
expect(mockRED.nodes.lastRegisteredType).to.equal('email-sender');
|
|
47
|
+
expect(mockRED.nodes.lastRegisteredConstructor).to.be.a('function');
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('Node Instantiation', function () {
|
|
52
|
+
it('should handle node instantiation with valid config', function () {
|
|
53
|
+
// ARRANGE: Track node creation
|
|
54
|
+
let createdNode = null;
|
|
55
|
+
const mockRED = createMockNodeRED({
|
|
56
|
+
onHandler: function (event, callback) {
|
|
57
|
+
createdNode = this;
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// ACT: Register and create node instance
|
|
62
|
+
emailSenderNode(mockRED);
|
|
63
|
+
new mockRED.nodes.lastRegisteredConstructor(emailSenderConfigs.valid);
|
|
64
|
+
|
|
65
|
+
// ASSERT: Verify node was created with correct properties
|
|
66
|
+
expect(createdNode).to.exist;
|
|
67
|
+
expect(createdNode).to.have.property('name', emailSenderConfigs.valid.name);
|
|
68
|
+
expect(createdNode).to.have.property('id', emailSenderConfigs.valid.id);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should handle minimal config', function () {
|
|
72
|
+
// ARRANGE: Use minimal test config
|
|
73
|
+
let createdNode = null;
|
|
74
|
+
const mockRED = createMockNodeRED({
|
|
75
|
+
onHandler: function (event, callback) {
|
|
76
|
+
createdNode = this;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// ACT: Register and create node with minimal config
|
|
81
|
+
emailSenderNode(mockRED);
|
|
82
|
+
new mockRED.nodes.lastRegisteredConstructor(emailSenderConfigs.minimal);
|
|
83
|
+
|
|
84
|
+
// ASSERT: Verify node creation
|
|
85
|
+
expect(createdNode).to.exist;
|
|
86
|
+
expect(createdNode).to.have.property('id', emailSenderConfigs.minimal.id);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('Node Functionality', function () {
|
|
91
|
+
beforeEach(function () {
|
|
92
|
+
// Clear the module cache BEFORE requiring anything
|
|
93
|
+
delete require.cache[require.resolve('nodemailer')];
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
afterEach(function () {
|
|
97
|
+
delete require.cache[require.resolve('nodemailer')];
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should send email successfully and set status to "sent"', function (done) {
|
|
101
|
+
let statusSet = false;
|
|
102
|
+
|
|
103
|
+
// ARRANGE: Initialisiere mockNodemailer
|
|
104
|
+
const mockNodemailer = createMockNodemailer();
|
|
105
|
+
|
|
106
|
+
// Mock the nodemailer module
|
|
107
|
+
delete require.cache[require.resolve('nodemailer')];
|
|
108
|
+
require.cache[require.resolve('nodemailer')] = {
|
|
109
|
+
exports: mockNodemailer,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// ARRANGE: Create mock Node-RED environment
|
|
113
|
+
const mockRED = createMockNodeRED({
|
|
114
|
+
onHandler: function (event, callback) {
|
|
115
|
+
if (event === 'input') {
|
|
116
|
+
this.inputCallback = callback;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
statusHandler: function (status) {
|
|
120
|
+
if (status.fill === 'green') {
|
|
121
|
+
expect(status.text).to.include('sent');
|
|
122
|
+
expect(status.shape).to.equal('dot');
|
|
123
|
+
statusSet = true;
|
|
124
|
+
done();
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
errorHandler: function (err) {
|
|
128
|
+
done(err || new Error('Unexpected error handler called'));
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// ACT: Initialize the email sender node
|
|
133
|
+
const emailSenderNode = require('../../email-sender/email-sender.js');
|
|
134
|
+
emailSenderNode(mockRED);
|
|
135
|
+
|
|
136
|
+
const nodeConstructor = mockRED.nodes.lastRegisteredConstructor;
|
|
137
|
+
const nodeInstance = new nodeConstructor(emailSenderConfigs.valid);
|
|
138
|
+
|
|
139
|
+
nodeInstance.inputCallback({
|
|
140
|
+
payload: 'test',
|
|
141
|
+
topic: 'test message',
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should handle sendMail error and set status to "error sending"', function (done) {
|
|
146
|
+
let errorHandlerCalled = false;
|
|
147
|
+
let redStatusSet = false;
|
|
148
|
+
|
|
149
|
+
function checkDone() {
|
|
150
|
+
console.log('Check done - Error:', errorHandlerCalled, 'Status:', redStatusSet);
|
|
151
|
+
if (errorHandlerCalled && redStatusSet) {
|
|
152
|
+
done();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Explizit shouldFail auf true setzen
|
|
157
|
+
const mockOptions = { shouldFail: true };
|
|
158
|
+
console.log('Creating mock with options:', mockOptions); // Debug log
|
|
159
|
+
|
|
160
|
+
const mockNodemailer = createMockNodemailer(mockOptions);
|
|
161
|
+
|
|
162
|
+
// Mock the nodemailer module
|
|
163
|
+
delete require.cache[require.resolve('nodemailer')];
|
|
164
|
+
require.cache[require.resolve('nodemailer')] = {
|
|
165
|
+
exports: mockNodemailer,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const mockRED = createMockNodeRED({
|
|
169
|
+
onHandler: function (event, callback) {
|
|
170
|
+
if (event === 'input') {
|
|
171
|
+
this.inputCallback = callback;
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
statusHandler: function (status) {
|
|
175
|
+
console.log('Status received:', status);
|
|
176
|
+
if (status.fill === 'red' && status.text === 'error sending') {
|
|
177
|
+
redStatusSet = true;
|
|
178
|
+
checkDone();
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
errorHandler: function (err) {
|
|
182
|
+
console.log('Error received:', err);
|
|
183
|
+
expect(err.message).to.equal('Mock sendMail error');
|
|
184
|
+
errorHandlerCalled = true;
|
|
185
|
+
checkDone();
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const emailSenderNode = require('../../email-sender/email-sender.js');
|
|
190
|
+
emailSenderNode(mockRED);
|
|
191
|
+
|
|
192
|
+
const nodeConstructor = mockRED.nodes.lastRegisteredConstructor;
|
|
193
|
+
const nodeInstance = new nodeConstructor(emailSenderConfigs.valid);
|
|
194
|
+
|
|
195
|
+
nodeInstance.inputCallback({
|
|
196
|
+
payload: 'test',
|
|
197
|
+
topic: 'test message',
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('should handle an array of attachments correctly', function (done) {
|
|
202
|
+
let attachmentsChecked = false;
|
|
203
|
+
let statusSet = false;
|
|
204
|
+
|
|
205
|
+
function checkDone() {
|
|
206
|
+
console.log('checkDone called - attachmentsChecked:', attachmentsChecked, 'statusSet:', statusSet);
|
|
207
|
+
if (attachmentsChecked && statusSet) {
|
|
208
|
+
console.log('Both conditions met, calling done');
|
|
209
|
+
done();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// ARRANGE: Configure test attachments
|
|
214
|
+
const attachments = [
|
|
215
|
+
{
|
|
216
|
+
filename: 'test1.txt',
|
|
217
|
+
content: 'This is the first test file.',
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
filename: 'test2.txt',
|
|
221
|
+
content: 'This is the second test file.',
|
|
222
|
+
},
|
|
223
|
+
];
|
|
224
|
+
console.log('Test attachments configured');
|
|
225
|
+
|
|
226
|
+
const mockNodemailer = createMockNodemailer({
|
|
227
|
+
onSendMail: (mailOptions) => {
|
|
228
|
+
console.log('onSendMail called with attachments:', mailOptions.attachments);
|
|
229
|
+
expect(mailOptions.attachments).to.be.an('array').with.lengthOf(2);
|
|
230
|
+
expect(mailOptions.attachments[0].filename).to.equal('test1.txt');
|
|
231
|
+
expect(mailOptions.attachments[1].content).to.equal('This is the second test file.');
|
|
232
|
+
attachmentsChecked = true;
|
|
233
|
+
console.log('Attachments checked successfully');
|
|
234
|
+
checkDone();
|
|
235
|
+
},
|
|
236
|
+
});
|
|
237
|
+
console.log('Mock nodemailer created');
|
|
238
|
+
|
|
239
|
+
// Mock the nodemailer module
|
|
240
|
+
delete require.cache[require.resolve('nodemailer')];
|
|
241
|
+
require.cache[require.resolve('nodemailer')] = {
|
|
242
|
+
exports: mockNodemailer,
|
|
243
|
+
};
|
|
244
|
+
console.log('Nodemailer mock installed');
|
|
245
|
+
|
|
246
|
+
const mockRED = createMockNodeRED({
|
|
247
|
+
onHandler: function (event, callback) {
|
|
248
|
+
console.log('onHandler called with event:', event);
|
|
249
|
+
if (event === 'input') {
|
|
250
|
+
this.inputCallback = callback;
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
statusHandler: function (status) {
|
|
254
|
+
console.log('statusHandler called with status:', status);
|
|
255
|
+
if (status.fill === 'green') {
|
|
256
|
+
expect(status.text).to.include('sent');
|
|
257
|
+
expect(status.shape).to.equal('dot');
|
|
258
|
+
statusSet = true;
|
|
259
|
+
console.log('Status set successfully');
|
|
260
|
+
checkDone();
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
errorHandler: function (err) {
|
|
264
|
+
console.log('errorHandler called with:', err);
|
|
265
|
+
done(err || new Error('Unexpected error handler called'));
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const emailSenderNode = require('../../email-sender/email-sender.js');
|
|
270
|
+
emailSenderNode(mockRED);
|
|
271
|
+
console.log('Email sender node initialized');
|
|
272
|
+
|
|
273
|
+
const config = { ...emailSenderConfigs.valid };
|
|
274
|
+
config.attachments = JSON.stringify(attachments);
|
|
275
|
+
config.attachmentsType = 'json';
|
|
276
|
+
|
|
277
|
+
const nodeConstructor = mockRED.nodes.lastRegisteredConstructor;
|
|
278
|
+
const nodeInstance = new nodeConstructor(config);
|
|
279
|
+
console.log('Node instance created');
|
|
280
|
+
|
|
281
|
+
setTimeout(() => {
|
|
282
|
+
nodeInstance.inputCallback({
|
|
283
|
+
payload: 'test',
|
|
284
|
+
topic: 'test message',
|
|
285
|
+
});
|
|
286
|
+
}, 100);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it('should throw error for malformed attachments', function (done) {
|
|
290
|
+
let errorHandlerCalled = false;
|
|
291
|
+
let redStatusSet = false;
|
|
292
|
+
|
|
293
|
+
function checkDone() {
|
|
294
|
+
console.log('Check done - Error:', errorHandlerCalled, 'Status:', redStatusSet);
|
|
295
|
+
if (errorHandlerCalled && redStatusSet) {
|
|
296
|
+
done();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ARRANGE: Configure the node with a JSON string containing a malformed attachment
|
|
301
|
+
const malformedAttachments = [
|
|
302
|
+
{
|
|
303
|
+
filename: 'test.txt',
|
|
304
|
+
content: 'This is a test file.',
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
// Malformed attachment with missing content
|
|
308
|
+
filename: 'invalid.txt',
|
|
309
|
+
},
|
|
310
|
+
];
|
|
311
|
+
|
|
312
|
+
const mockNodemailer = createMockNodemailer();
|
|
313
|
+
|
|
314
|
+
// Mock the nodemailer module
|
|
315
|
+
delete require.cache[require.resolve('nodemailer')];
|
|
316
|
+
require.cache[require.resolve('nodemailer')] = {
|
|
317
|
+
exports: mockNodemailer,
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const mockRED = createMockNodeRED({
|
|
321
|
+
onHandler: function (event, callback) {
|
|
322
|
+
if (event === 'input') {
|
|
323
|
+
this.inputCallback = callback;
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
statusHandler: function (status) {
|
|
327
|
+
if (status.fill === 'red') {
|
|
328
|
+
redStatusSet = true;
|
|
329
|
+
checkDone();
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
errorHandler: function (err) {
|
|
333
|
+
console.log('Error received:', err);
|
|
334
|
+
expect(err).to.equal("Attachment object is missing 'filename' or 'content' property.");
|
|
335
|
+
errorHandlerCalled = true;
|
|
336
|
+
checkDone();
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
const emailSenderNode = require('../../email-sender/email-sender.js');
|
|
341
|
+
emailSenderNode(mockRED);
|
|
342
|
+
|
|
343
|
+
const config = { ...emailSenderConfigs.valid };
|
|
344
|
+
config.attachments = JSON.stringify(malformedAttachments);
|
|
345
|
+
config.attachmentsType = 'json';
|
|
346
|
+
|
|
347
|
+
const nodeConstructor = mockRED.nodes.lastRegisteredConstructor;
|
|
348
|
+
const nodeInstance = new nodeConstructor(config);
|
|
349
|
+
|
|
350
|
+
nodeInstance.inputCallback({
|
|
351
|
+
payload: 'test',
|
|
352
|
+
topic: 'test message',
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it('should handle rejected emails and set status to rejected', function (done) {
|
|
358
|
+
// To be implemented
|
|
359
|
+
done();
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it('should handle pending emails and set status to pending', function (done) {
|
|
363
|
+
// To be implemented
|
|
364
|
+
done();
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it('should handle a single attachment object correctly', function (done) {
|
|
368
|
+
// To be implemented
|
|
369
|
+
done();
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
it('should handle an empty attachments string without error', function (done) {
|
|
373
|
+
// To be implemented
|
|
374
|
+
done();
|
|
375
|
+
});
|
|
376
|
+
});
|