@itentialopensource/adapter-email
Version:
Email notification adapter
306 lines (269 loc) • 9.26 kB
JavaScript
/* @copyright Itential, LLC 2019 (pre-modifications) */
// Set globals
/* eslint global-require:warn */
/* eslint no-unused-vars:warn */
/* eslint import/no-dynamic-require:warn */
const { expect } = require('chai');
const td = require('testdouble');
const jsonschema = require('jsonschema');
const validate = td.replace(jsonschema, 'validate');
const nodemailer = td.replace('nodemailer');
global.log = td.object(['info', 'error']);
// read in the properties from the sampleProperties files
let adaptdir = __dirname;
if (adaptdir.endsWith('/test/integration')) {
adaptdir = adaptdir.substring(0, adaptdir.length - 17);
} else if (adaptdir.endsWith('/test/unit')) {
adaptdir = adaptdir.substring(0, adaptdir.length - 10);
}
const samProps = require(`${adaptdir}/sampleProperties.json`).properties;
// uncomment if connecting
// samProps.host = 'replace.hostorip.here';
// samProps.port = 80;
// samProps.service = 'service';
// samProps.auth.user = 'username';
// samProps.auth.pass = 'password';
// these are the adapter properties. You generally should not need to alter
// any of these after they are initially set up
global.pronghornProps = {
pathProps: {
encrypted: false
},
adapterProps: {
adapters: [{
id: 'email',
type: 'Email',
properties: samProps
}]
}
};
describe('[unit] Email Adapter Test', function () {
describe('Email Class Tests', function () {
const Email = require('../../adapter');
let email;
const any = td.matchers.anything();
const transportDouble = td.object();
transportDouble.sendMail = td.function();
beforeEach(() => {
td.when(nodemailer.createTransport(any)).thenReturn(transportDouble);
td.when(validate(pronghornProps.adapterProps.adapters[0].properties, any, { nestedErrors: true })).thenReturn({
valid: true
});
email = new Email(
pronghornProps.adapterProps.adapters[0].type,
pronghornProps.adapterProps.adapters[0].properties
);
});
describe('constructor should', function () {
it('exist.', () => {
expect(email instanceof Email);
});
});
describe('Function - mailWithOptions', function () {
it('should invoke notify with attachments argument as a string', (done) => {
const from = any;
const to = any;
const subject = any;
const body = any;
const displayName = any;
const cc = any;
const bcc = any;
const attachments = '';
const notifyDouble = td.func();
td.replace(email, 'notify', notifyDouble);
td.when(email.notify(any, any)).thenCallback('Called back');
email.mailWithOptions(from, to, subject, body, displayName, cc, bcc, attachments, (result, error) => {
expect(result).to.equal('Called back');
expect(error).to.equal(undefined);
done();
});
});
it('should invoke notify with attachments argument as an array', (done) => {
const from = any;
const to = any;
const subject = any;
const body = any;
const displayName = any;
const cc = any;
const bcc = any;
const attachments = [];
const notifyDouble = td.func();
td.replace(email, 'notify', notifyDouble);
td.when(email.notify(any, any)).thenCallback('Called back');
email.mailWithOptions(from, to, subject, body, displayName, cc, bcc, attachments, (result, error) => {
expect(result).to.equal('Called back');
expect(error).to.equal(undefined);
done();
});
});
});
describe('Function - notify', function () {
it('should be called successfully with required fields', (done) => {
const from = 'name@email.com';
const to = ['name@email.com'];
const subject = 'subject';
const text = 'text';
const mockTargets = {
from,
to
};
const mockMessage = {
subject,
text
};
const mockTransportInfo = {
accepted: true,
rejected: true
};
td.when(validate(mockTargets, any)).thenReturn({ valid: true });
td.when(validate(mockMessage, any)).thenReturn({ valid: true });
td.when(email.transport.sendMail(any)).thenCallback(null, mockTransportInfo);
email.notify(mockTargets, mockMessage, (result, error) => {
expect(JSON.stringify(result)).to.equal(JSON.stringify(mockTransportInfo));
expect(error).to.equal(undefined);
done();
});
});
it('should be called successfully with all possible target fields and message with text', (done) => {
const from = 'name@email.com';
const to = ['name@email.com'];
const cc = ['name@email.com'];
const bcc = ['name@email.com'];
const attachments = [
{
name: 'name',
content: 'content'
}
];
const subject = 'subject';
const text = 'text';
const mockTargets = {
from,
to,
cc,
bcc,
attachments
};
const mockMessage = {
subject,
text
};
const mockTransportInfo = {
accepted: true,
rejected: true
};
td.when(validate(mockTargets, any)).thenReturn({ valid: true });
td.when(validate(mockMessage, any)).thenReturn({ valid: true });
td.when(email.transport.sendMail(any)).thenCallback(null, mockTransportInfo);
email.notify(mockTargets, mockMessage, (result, error) => {
expect(JSON.stringify(result)).to.equal(JSON.stringify(mockTransportInfo));
expect(error).to.equal(undefined);
done();
});
});
it('should be called successfully with all possible target fields and message with html', (done) => {
const from = 'name@email.com';
const to = ['name@email.com'];
const cc = ['name@email.com'];
const bcc = ['name@email.com'];
const attachments = [
{
name: 'name',
content: 'content'
}
];
const subject = 'subject';
const text = '<h1>text</h1>';
const mockTargets = {
from,
to,
cc,
bcc,
attachments
};
const mockMessage = {
subject,
text
};
const mockTransportInfo = {
accepted: true,
rejected: true
};
td.when(validate(mockTargets, any)).thenReturn({ valid: true });
td.when(validate(mockMessage, any)).thenReturn({ valid: true });
td.when(email.transport.sendMail(any)).thenCallback(null, mockTransportInfo);
email.notify(mockTargets, mockMessage, (result, error) => {
expect(JSON.stringify(result)).to.equal(JSON.stringify(mockTransportInfo));
expect(error).to.equal(undefined);
done();
});
});
it('should be called and return with error when validation errors of targets and message', (done) => {
const from = 'name@email.com';
const to = ['name@email.com'];
const cc = ['name@email.com'];
const bcc = ['name@email.com'];
const attachments = [
{
name: 'name',
content: 'content'
}
];
const subject = 'subject';
const text = '<h1>text</h1>';
const mockTargets = {
from,
to,
cc,
bcc,
attachments
};
const mockMessage = {
subject,
text
};
const expectedErrors = ['target error', 'message error'];
td.when(validate(mockTargets, any)).thenReturn({ errors: [{ message: 'error' }] });
td.when(validate(mockMessage, any)).thenReturn({ errors: [{ message: 'error' }] });
email.notify(mockTargets, mockMessage, (result, error) => {
expect(result).to.equal(null);
expect(error).to.deep.equal(expectedErrors);
done();
});
});
it('should be called and return with error when error returned from sendMail', (done) => {
const from = 'name@email.com';
const to = ['name@email.com'];
const cc = ['name@email.com'];
const bcc = ['name@email.com'];
const attachments = [
{
name: 'name',
content: 'content'
}
];
const subject = 'subject';
const text = '<h1>text</h1>';
const mockTargets = {
from,
to,
cc,
bcc,
attachments
};
const mockMessage = {
subject,
text
};
td.when(validate(mockTargets, any)).thenReturn({ valid: true });
td.when(validate(mockMessage, any)).thenReturn({ valid: true });
td.when(email.transport.sendMail(any)).thenCallback('error', null);
email.notify(mockTargets, mockMessage, (result, error) => {
expect(result).to.equal(null);
expect(error).to.equal('error');
done();
});
});
});
});
});