1397 lines
49 KiB
JavaScript
Executable File
1397 lines
49 KiB
JavaScript
Executable File
/* eslint no-unused-expressions:0 */
|
||
/* globals afterEach, beforeEach, describe, it */
|
||
|
||
'use strict';
|
||
|
||
var chai = require('chai');
|
||
var sinon = require('sinon');
|
||
var Buildmail = require('../lib/buildmail');
|
||
var http = require('http');
|
||
var stream = require('stream');
|
||
var Transform = stream.Transform;
|
||
var PassThrough = stream.PassThrough;
|
||
|
||
var expect = chai.expect;
|
||
chai.config.includeStack = true;
|
||
|
||
describe('Buildmail', function () {
|
||
it('should create Buildmail object', function () {
|
||
expect(new Buildmail()).to.exist;
|
||
});
|
||
|
||
describe('#createChild', function () {
|
||
it('should create child', function () {
|
||
var mb = new Buildmail('multipart/mixed');
|
||
|
||
var child = mb.createChild('multipart/mixed');
|
||
expect(child.parentNode).to.equal(mb);
|
||
expect(child.rootNode).to.equal(mb);
|
||
|
||
var subchild1 = child.createChild('text/html');
|
||
expect(subchild1.parentNode).to.equal(child);
|
||
expect(subchild1.rootNode).to.equal(mb);
|
||
|
||
var subchild2 = child.createChild('text/html');
|
||
expect(subchild2.parentNode).to.equal(child);
|
||
expect(subchild2.rootNode).to.equal(mb);
|
||
});
|
||
});
|
||
|
||
describe('#appendChild', function () {
|
||
it('should append child node', function () {
|
||
var mb = new Buildmail('multipart/mixed');
|
||
|
||
var child = new Buildmail('text/plain');
|
||
mb.appendChild(child);
|
||
expect(child.parentNode).to.equal(mb);
|
||
expect(child.rootNode).to.equal(mb);
|
||
expect(mb.childNodes.length).to.equal(1);
|
||
expect(mb.childNodes[0]).to.equal(child);
|
||
});
|
||
});
|
||
|
||
describe('#replace', function () {
|
||
it('should replace node', function () {
|
||
var mb = new Buildmail(),
|
||
child = mb.createChild('text/plain'),
|
||
replacement = new Buildmail('image/png');
|
||
|
||
child.replace(replacement);
|
||
|
||
expect(mb.childNodes.length).to.equal(1);
|
||
expect(mb.childNodes[0]).to.equal(replacement);
|
||
});
|
||
});
|
||
|
||
describe('#remove', function () {
|
||
it('should remove node', function () {
|
||
var mb = new Buildmail(),
|
||
child = mb.createChild('text/plain');
|
||
|
||
child.remove();
|
||
expect(mb.childNodes.length).to.equal(0);
|
||
expect(child.parenNode).to.not.exist;
|
||
});
|
||
});
|
||
|
||
describe('#setHeader', function () {
|
||
it('should set header', function () {
|
||
var mb = new Buildmail();
|
||
|
||
mb.setHeader('key', 'value');
|
||
mb.setHeader('key', 'value1');
|
||
expect(mb.getHeader('Key')).to.equal('value1');
|
||
|
||
mb.setHeader([{
|
||
key: 'key',
|
||
value: 'value2'
|
||
}, {
|
||
key: 'key2',
|
||
value: 'value3'
|
||
}]);
|
||
|
||
expect(mb._headers).to.deep.equal([{
|
||
key: 'Key',
|
||
value: 'value2'
|
||
}, {
|
||
key: 'Key2',
|
||
value: 'value3'
|
||
}]);
|
||
|
||
mb.setHeader({
|
||
key: 'value4',
|
||
key2: 'value5'
|
||
});
|
||
|
||
expect(mb._headers).to.deep.equal([{
|
||
key: 'Key',
|
||
value: 'value4'
|
||
}, {
|
||
key: 'Key2',
|
||
value: 'value5'
|
||
}]);
|
||
});
|
||
|
||
it('should set multiple headers with the same key', function () {
|
||
var mb = new Buildmail();
|
||
|
||
mb.setHeader('key', ['value1', 'value2', 'value3']);
|
||
expect(mb._headers).to.deep.equal([{
|
||
key: 'Key',
|
||
value: ['value1', 'value2', 'value3']
|
||
}]);
|
||
});
|
||
});
|
||
|
||
describe('#addHeader', function () {
|
||
it('should add header', function () {
|
||
var mb = new Buildmail();
|
||
|
||
mb.addHeader('key', 'value1');
|
||
mb.addHeader('key', 'value2');
|
||
|
||
mb.addHeader([{
|
||
key: 'key',
|
||
value: 'value2'
|
||
}, {
|
||
key: 'key2',
|
||
value: 'value3'
|
||
}]);
|
||
|
||
mb.addHeader({
|
||
key: 'value4',
|
||
key2: 'value5'
|
||
});
|
||
|
||
expect(mb._headers).to.deep.equal([{
|
||
key: 'Key',
|
||
value: 'value1'
|
||
}, {
|
||
key: 'Key',
|
||
value: 'value2'
|
||
}, {
|
||
key: 'Key',
|
||
value: 'value2'
|
||
}, {
|
||
key: 'Key2',
|
||
value: 'value3'
|
||
}, {
|
||
key: 'Key',
|
||
value: 'value4'
|
||
}, {
|
||
key: 'Key2',
|
||
value: 'value5'
|
||
}]);
|
||
});
|
||
|
||
it('should set multiple headers with the same key', function () {
|
||
var mb = new Buildmail();
|
||
mb.addHeader('key', ['value1', 'value2', 'value3']);
|
||
expect(mb._headers).to.deep.equal([{
|
||
key: 'Key',
|
||
value: 'value1'
|
||
}, {
|
||
key: 'Key',
|
||
value: 'value2'
|
||
}, {
|
||
key: 'Key',
|
||
value: 'value3'
|
||
}]);
|
||
});
|
||
});
|
||
|
||
describe('#getHeader', function () {
|
||
it('should return first matching header value', function () {
|
||
var mb = new Buildmail();
|
||
mb._headers = [{
|
||
key: 'Key',
|
||
value: 'value4'
|
||
}, {
|
||
key: 'Key2',
|
||
value: 'value5'
|
||
}];
|
||
|
||
expect(mb.getHeader('KEY')).to.equal('value4');
|
||
});
|
||
});
|
||
|
||
describe('#setContent', function () {
|
||
it('should set the contents for a node', function () {
|
||
var mb = new Buildmail();
|
||
mb.setContent('abc');
|
||
expect(mb.content).to.equal('abc');
|
||
});
|
||
});
|
||
|
||
|
||
describe('#build', function () {
|
||
|
||
it('should build root node', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setHeader({
|
||
date: '12345',
|
||
'message-id': '67890'
|
||
}).
|
||
setContent('Hello world!'),
|
||
|
||
expected = 'Content-Type: text/plain\r\n' +
|
||
'Date: 12345\r\n' +
|
||
'Message-ID: <67890>\r\n' +
|
||
'Content-Transfer-Encoding: 7bit\r\n' +
|
||
'MIME-Version: 1.0\r\n' +
|
||
'\r\n' +
|
||
'Hello world!';
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should build child node', function (done) {
|
||
var mb = new Buildmail('multipart/mixed'),
|
||
childNode = mb.createChild('text/plain').
|
||
setContent('Hello world!'),
|
||
|
||
expected = 'Content-Type: text/plain\r\n' +
|
||
'Content-Transfer-Encoding: 7bit\r\n' +
|
||
'\r\n' +
|
||
'Hello world!';
|
||
|
||
childNode.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should build multipart node', function (done) {
|
||
var mb = new Buildmail('multipart/mixed', {
|
||
baseBoundary: 'test'
|
||
}).setHeader({
|
||
date: '12345',
|
||
'message-id': '67890'
|
||
}),
|
||
|
||
expected = 'Content-Type: multipart/mixed; boundary="----sinikael-?=_1-test"\r\n' +
|
||
'Date: 12345\r\n' +
|
||
'Message-ID: <67890>\r\n' +
|
||
'MIME-Version: 1.0\r\n' +
|
||
'\r\n' +
|
||
'------sinikael-?=_1-test\r\n' +
|
||
'Content-Type: text/plain\r\n' +
|
||
'Content-Transfer-Encoding: 7bit\r\n' +
|
||
'\r\n' +
|
||
'Hello world!\r\n' +
|
||
'------sinikael-?=_1-test--\r\n';
|
||
|
||
mb.createChild('text/plain').setContent('Hello world!');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should build root with generated headers', function (done) {
|
||
var mb = new Buildmail('text/plain');
|
||
mb.hostname = 'abc';
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^Date:\s/m.test(msg)).to.be.true;
|
||
expect(/^Message\-ID:\s/m.test(msg)).to.be.true;
|
||
expect(/^MIME-Version: 1\.0$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should not include bcc missing in output, but in envelope', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setHeader({
|
||
from: 'sender@example.com',
|
||
to: 'receiver@example.com',
|
||
bcc: 'bcc@example.com'
|
||
});
|
||
var envelope = mb.getEnvelope();
|
||
|
||
expect(envelope).to.deep.equal({
|
||
from: 'sender@example.com',
|
||
to: ['receiver@example.com', 'bcc@example.com']
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^From: sender@example.com$/m.test(msg)).to.be.true;
|
||
expect(/^To: receiver@example.com$/m.test(msg)).to.be.true;
|
||
expect(!/^Bcc:/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should include bcc missing in output and in envelope', function (done) {
|
||
var mb = new Buildmail(
|
||
'text/plain', {
|
||
keepBcc: true
|
||
}).
|
||
setHeader({
|
||
from: 'sender@example.com',
|
||
to: 'receiver@example.com',
|
||
bcc: 'bcc@example.com'
|
||
});
|
||
var envelope = mb.getEnvelope();
|
||
|
||
expect(envelope).to.deep.equal({
|
||
from: 'sender@example.com',
|
||
to: ['receiver@example.com', 'bcc@example.com']
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^From: sender@example.com$/m.test(msg)).to.be.true;
|
||
expect(/^To: receiver@example.com$/m.test(msg)).to.be.true;
|
||
expect(/^Bcc: bcc@example.com$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should use set envelope', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setHeader({
|
||
from: 'sender@example.com',
|
||
to: 'receiver@example.com',
|
||
bcc: 'bcc@example.com'
|
||
}).setEnvelope({
|
||
from: 'U Name, A Name <a@a.a>',
|
||
to: 'B Name <b@b.b>, c@c.c',
|
||
bcc: 'P P P, <u@u.u>'
|
||
});
|
||
var envelope = mb.getEnvelope();
|
||
|
||
expect(envelope).to.deep.equal({
|
||
from: 'a@a.a',
|
||
to: ['b@b.b', 'c@c.c', 'u@u.u']
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^From: sender@example.com$/m.test(msg)).to.be.true;
|
||
expect(/^To: receiver@example.com$/m.test(msg)).to.be.true;
|
||
expect(!/^Bcc:/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should have unicode subject', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setHeader({
|
||
subject: 'jõgeval istus kägu metsas'
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^Subject: =\?UTF-8\?Q\?j=C3=B5geval\?= istus =\?UTF-8\?Q\?k=C3=A4gu\?= metsas$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should have unicode subject with strange characters', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setHeader({
|
||
subject: 'ˆ¸ÁÌÓıÏˇÁÛ^¸\\ÁıˆÌÁÛØ^\\˜Û˝™ˇıÓ¸^\\˜fi^\\·\\˜Ø^£˜#fi^\\£fi^\\£fi^\\'
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg.match(/\bSubject: [^\r]*\r\n( [^\r]*\r\n)*/)[0]).to.equal('Subject: =?UTF-8?B?y4bCuMOBw4zDk8Sxw4/Lh8OBw5tewrhcw4HEscuG?=\r\n =?UTF-8?B?w4zDgcObw5heXMucw5vLneKEosuHxLHDk8K4Xlw=?=\r\n =?UTF-8?B?y5zvrIFeXMK3XMucw5hewqPLnCPvrIFeXMKj76yB?=\r\n =?UTF-8?B?XlzCo++sgV5c?=\r\n');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should keep 7bit text as is', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setContent('tere tere');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/\r\n\r\ntere tere$/.test(msg)).to.be.true;
|
||
expect(/^Content-Type: text\/plain$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Transfer-Encoding: 7bit$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should prefer base64', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setHeader({
|
||
subject: 'õõõõ'
|
||
}).
|
||
setContent('õõõõõõõõ');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
|
||
expect(/^Content-Type: text\/plain; charset=utf-8$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Transfer-Encoding: base64$/m.test(msg)).to.be.true;
|
||
expect(/^Subject: =\?UTF-8\?B\?w7XDtcO1w7U=\?=$/m.test(msg)).to.be.true;
|
||
msg = msg.split('\r\n\r\n');
|
||
msg.shift();
|
||
msg = msg.join('\r\n\r\n');
|
||
|
||
expect(msg).to.equal('w7XDtcO1w7XDtcO1w7XDtQ==');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should force quoted-printable', function (done) {
|
||
var mb = new Buildmail('text/plain', {
|
||
textEncoding: 'quoted-printable'
|
||
}).setHeader({
|
||
subject: 'õõõõ'
|
||
}).
|
||
setContent('õõõõõõõõ');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
|
||
expect(/^Content-Type: text\/plain; charset=utf-8$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Transfer-Encoding: quoted-printable$/m.test(msg)).to.be.true;
|
||
expect(/^Subject: =\?UTF-8\?Q\?=C3=B5=C3=B5=C3=B5=C3=B5\?=$/m.test(msg)).to.be.true;
|
||
|
||
msg = msg.split('\r\n\r\n');
|
||
msg.shift();
|
||
msg = msg.join('\r\n\r\n');
|
||
|
||
expect(msg).to.equal('=C3=B5=C3=B5=C3=B5=C3=B5=C3=B5=C3=B5=C3=B5=C3=B5');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should prefer quoted-printable', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setContent('ooooooooõ');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
|
||
expect(/^Content-Type: text\/plain; charset=utf-8$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Transfer-Encoding: quoted-printable$/m.test(msg)).to.be.true;
|
||
|
||
msg = msg.split('\r\n\r\n');
|
||
msg.shift();
|
||
msg = msg.join('\r\n\r\n');
|
||
|
||
expect(msg).to.equal('oooooooo=C3=B5');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should not flow text', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setContent('a b c d e f g h i j k l m o p q r s t u w x y z 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m o p q r s t u w x y z 1 2 3 4 5 6 7 8 9 0');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
|
||
expect(/^Content-Type: text\/plain$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Transfer-Encoding: quoted-printable$/m.test(msg)).to.be.true;
|
||
|
||
msg = msg.split('\r\n\r\n');
|
||
msg.shift();
|
||
msg = msg.join('\r\n\r\n');
|
||
|
||
expect(msg).to.equal('a b c d e f g h i j k l m o p q r s t u w x y z 1 2 3 4 5 6 7 8 9 0 a b c d=\r\n e f g h i j k l m o p q r s t u w x y z 1 2 3 4 5 6 7 8 9 =\r\n0');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should not flow html', function (done) {
|
||
var mb = new Buildmail('text/html').
|
||
setContent('a b c d e f g h i j k l m o p q r s t u w x y z 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m o p q r s t u w x y z 1 2 3 4 5 6 7 8 9 0');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^Content-Type: text\/html$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Transfer-Encoding: quoted-printable$/m.test(msg)).to.be.true;
|
||
|
||
msg = msg.split('\r\n\r\n');
|
||
msg.shift();
|
||
msg = msg.join('\r\n\r\n');
|
||
|
||
expect(msg).to.equal('a b c d e f g h i j k l m o p q r s t u w x y z 1 2 3 4 5 6 7 8 9 0 a b c d=\r\n e f g h i j k l m o p q r s t u w x y z 1 2 3 4 5 6 7 8 9 =\r\n0');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should use 7bit for html', function (done) {
|
||
var mb = new Buildmail('text/html').
|
||
setContent('a b c d e f g h i j k l m o p\r\nq r s t u w x y z 1 2 3 4 5 6\r\n7 8 9 0 a b c d e f g h i j k\r\nl m o p q r s t u w x y z\r\n1 2 3 4 5 6 7 8 9 0');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^Content-Type: text\/html$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Transfer-Encoding: 7bit$/m.test(msg)).to.be.true;
|
||
|
||
msg = msg.split('\r\n\r\n');
|
||
msg.shift();
|
||
msg = msg.join('\r\n\r\n');
|
||
|
||
expect(msg).to.equal('a b c d e f g h i j k l m o p\r\nq r s t u w x y z 1 2 3 4 5 6\r\n7 8 9 0 a b c d e f g h i j k\r\nl m o p q r s t u w x y z\r\n1 2 3 4 5 6 7 8 9 0');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should fetch ascii filename', function (done) {
|
||
var mb = new Buildmail('text/plain', {
|
||
filename: 'jogeva.txt'
|
||
}).
|
||
setContent('jogeva');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/\r\n\r\njogeva$/.test(msg)).to.be.true;
|
||
expect(/^Content-Type: text\/plain; name=jogeva.txt$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Transfer-Encoding: 7bit$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Disposition: attachment; filename=jogeva.txt$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should set unicode filename', function (done) {
|
||
var mb = new Buildmail('text/plain', {
|
||
filename: 'jõgeva.txt'
|
||
}).
|
||
setContent('jõgeva');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^Content-Type: text\/plain; charset=utf-8;/m.test(msg)).to.be.true;
|
||
expect(/^Content-Transfer-Encoding: quoted-printable$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Disposition: attachment; filename\*0\*=utf-8''j%C3%B5geva.txt$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should set dashed filename', function (done) {
|
||
var mb = new Buildmail('text/plain', {
|
||
filename: 'Ɣ------Ɣ------Ɣ------Ɣ------Ɣ------Ɣ------Ɣ------.pdf'
|
||
}).
|
||
setContent('jõgeva');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg.indexOf('Content-Disposition: attachment;\r\n' +
|
||
' filename*0*=utf-8\'\'%C6%94------%C6%94------%C6%94------%C6%94;\r\n' +
|
||
' filename*1*=------%C6%94------%C6%94------%C6%94------.pdf')).to.be.gte(0);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should encode filename with a space', function (done) {
|
||
var mb = new Buildmail('text/plain', {
|
||
filename: 'document a.test.pdf'
|
||
}).
|
||
setContent('jõgeva');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^Content-Type: text\/plain; charset=utf-8;/m.test(msg)).to.be.true;
|
||
expect(/^Content-Transfer-Encoding: quoted-printable$/m.test(msg)).to.be.true;
|
||
expect(/^Content-Disposition: attachment; filename="document a.test.pdf"$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should detect content type from filename', function (done) {
|
||
var mb = new Buildmail(false, {
|
||
filename: 'jogeva.zip'
|
||
}).
|
||
setContent('jogeva');
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^Content-Type: application\/zip;/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should convert address objects', function (done) {
|
||
var mb = new Buildmail(false).
|
||
setHeader({
|
||
from: [{
|
||
name: 'the safewithme testuser',
|
||
address: 'safewithme.testuser@jõgeva.com'
|
||
}],
|
||
cc: [{
|
||
name: 'the safewithme testuser',
|
||
address: 'safewithme.testuser@jõgeva.com'
|
||
}]
|
||
});
|
||
|
||
expect(mb.getEnvelope()).to.deep.equal({
|
||
from: 'safewithme.testuser@xn--jgeva-dua.com',
|
||
to: [
|
||
'safewithme.testuser@xn--jgeva-dua.com'
|
||
]
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^From: the safewithme testuser <safewithme.testuser@xn\-\-jgeva-dua.com>$/m.test(msg)).to.be.true;
|
||
expect(/^Cc: the safewithme testuser <safewithme.testuser@xn\-\-jgeva-dua.com>$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should skip empty header', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setHeader({
|
||
a: 'b',
|
||
cc: '',
|
||
dd: [],
|
||
o: false,
|
||
date: 'zzz',
|
||
'message-id': '67890'
|
||
}).
|
||
setContent('Hello world!'),
|
||
|
||
expected = 'Content-Type: text/plain\r\n' +
|
||
'A: b\r\n' +
|
||
'Date: zzz\r\n' +
|
||
'Message-ID: <67890>\r\n' +
|
||
'Content-Transfer-Encoding: 7bit\r\n' +
|
||
'MIME-Version: 1.0\r\n' +
|
||
'\r\n' +
|
||
'Hello world!';
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should not process prepared headers', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setHeader({
|
||
unprepared: {
|
||
value: new Array(100).join('a b')
|
||
},
|
||
prepared: {
|
||
value: new Array(100).join('a b'),
|
||
prepared: true
|
||
},
|
||
unicode: {
|
||
value: 'õäöü',
|
||
prepared: true
|
||
},
|
||
date: 'zzz',
|
||
'message-id': '67890'
|
||
}).
|
||
setContent('Hello world!'),
|
||
|
||
expected = 'Content-Type: text/plain\r\n' +
|
||
|
||
// long folded value
|
||
'Unprepared: a ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba\r\n' +
|
||
' ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba\r\n' +
|
||
' ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba\r\n' +
|
||
' ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba\r\n' +
|
||
' ba ba ba b\r\n' +
|
||
|
||
// long unfolded value
|
||
'Prepared: a ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba ba b\r\n' +
|
||
|
||
// non-ascii value
|
||
'Unicode: õäöü\r\n' +
|
||
|
||
'Date: zzz\r\n' +
|
||
'Message-ID: <67890>\r\n' +
|
||
'Content-Transfer-Encoding: 7bit\r\n' +
|
||
'MIME-Version: 1.0\r\n' +
|
||
'\r\n' +
|
||
'Hello world!';
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should set default transfer encoding for application content', function (done) {
|
||
var mb = new Buildmail('application/x-my-stuff').
|
||
setHeader({
|
||
date: '12345',
|
||
'message-id': '67890'
|
||
}).
|
||
setContent('Hello world!'),
|
||
|
||
expected = 'Content-Type: application/x-my-stuff\r\n' +
|
||
'Date: 12345\r\n' +
|
||
'Message-ID: <67890>\r\n' +
|
||
'Content-Transfer-Encoding: base64\r\n' +
|
||
'MIME-Version: 1.0\r\n' +
|
||
'\r\n' +
|
||
'SGVsbG8gd29ybGQh';
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should not set transfer encoding for multipart content', function (done) {
|
||
var mb = new Buildmail('multipart/global').
|
||
setHeader({
|
||
date: '12345',
|
||
'message-id': '67890'
|
||
}).
|
||
setContent('Hello world!'),
|
||
|
||
expected = 'Content-Type: multipart/global; boundary=abc\r\n' +
|
||
'Date: 12345\r\n' +
|
||
'Message-ID: <67890>\r\n' +
|
||
'MIME-Version: 1.0\r\n' +
|
||
'\r\n' +
|
||
'Hello world!\r\n' +
|
||
'--abc--' +
|
||
'\r\n';
|
||
|
||
mb.boundary = 'abc';
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should not set transfer encoding for message/ content', function (done) {
|
||
var mb = new Buildmail('message/rfc822').
|
||
setHeader({
|
||
date: '12345',
|
||
'message-id': '67890'
|
||
}).
|
||
setContent('Hello world!'),
|
||
|
||
expected = 'Content-Type: message/rfc822\r\n' +
|
||
'Date: 12345\r\n' +
|
||
'Message-ID: <67890>\r\n' +
|
||
'MIME-Version: 1.0\r\n' +
|
||
'\r\n' +
|
||
'Hello world!';
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should use from domain for message-id', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setHeader({
|
||
from: 'test@example.com'
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^Message-ID: <[0-9a-f\-]+@example\.com>$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should fallback to hostname for message-id', function (done) {
|
||
var mb = new Buildmail('text/plain');
|
||
mb.hostname = 'abc';
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^Message-ID: <[0-9a-f\-]+@abc>$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('#getEnvelope', function () {
|
||
it('should get envelope', function () {
|
||
expect(new Buildmail().addHeader({
|
||
from: 'From <from@example.com>',
|
||
sender: 'Sender <sender@example.com>',
|
||
to: 'receiver1@example.com'
|
||
}).addHeader({
|
||
to: 'receiver2@example.com',
|
||
cc: 'receiver1@example.com, receiver3@example.com',
|
||
bcc: 'receiver4@example.com, Rec5 <receiver5@example.com>'
|
||
}).getEnvelope()).to.deep.equal({
|
||
from: 'from@example.com',
|
||
to: ['receiver1@example.com', 'receiver2@example.com', 'receiver3@example.com', 'receiver4@example.com', 'receiver5@example.com']
|
||
});
|
||
|
||
expect(new Buildmail().addHeader({
|
||
sender: 'Sender <sender@example.com>',
|
||
to: 'receiver1@example.com'
|
||
}).addHeader({
|
||
to: 'receiver2@example.com',
|
||
cc: 'receiver1@example.com, receiver3@example.com',
|
||
bcc: 'receiver4@example.com, Rec5 <receiver5@example.com>'
|
||
}).getEnvelope()).to.deep.equal({
|
||
from: 'sender@example.com',
|
||
to: ['receiver1@example.com', 'receiver2@example.com', 'receiver3@example.com', 'receiver4@example.com', 'receiver5@example.com']
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('#messageId', function () {
|
||
it('should create and return message-Id', function () {
|
||
var mail = new Buildmail().addHeader({
|
||
from: 'From <from@example.com>'
|
||
});
|
||
|
||
var messageId = mail.messageId();
|
||
expect(/^<[\w\-]+@example\.com>$/.test(messageId)).to.be.true;
|
||
expect(messageId).to.equal(mail.messageId());
|
||
});
|
||
});
|
||
|
||
describe('#getAddresses', function () {
|
||
it('should get address object', function () {
|
||
expect(new Buildmail().addHeader({
|
||
from: 'From <from@example.com>',
|
||
sender: 'Sender <sender@example.com>',
|
||
to: 'receiver1@example.com'
|
||
}).addHeader({
|
||
to: 'receiver2@example.com',
|
||
cc: 'receiver1@example.com, receiver3@example.com',
|
||
bcc: 'receiver4@example.com, Rec5 <receiver5@example.com>'
|
||
}).getAddresses()).to.deep.equal({
|
||
from: [{
|
||
address: 'from@example.com',
|
||
name: 'From'
|
||
}],
|
||
sender: [{
|
||
address: 'sender@example.com',
|
||
name: 'Sender'
|
||
}],
|
||
to: [{
|
||
address: 'receiver1@example.com',
|
||
name: ''
|
||
}, {
|
||
address: 'receiver2@example.com',
|
||
name: ''
|
||
}],
|
||
cc: [{
|
||
address: 'receiver1@example.com',
|
||
name: ''
|
||
}, {
|
||
address: 'receiver3@example.com',
|
||
name: ''
|
||
}],
|
||
bcc: [{
|
||
address: 'receiver4@example.com',
|
||
name: ''
|
||
}, {
|
||
address: 'receiver5@example.com',
|
||
name: 'Rec5'
|
||
}]
|
||
});
|
||
|
||
expect(new Buildmail().addHeader({
|
||
sender: 'Sender <sender@example.com>',
|
||
to: 'receiver1@example.com'
|
||
}).addHeader({
|
||
to: 'receiver2@example.com',
|
||
cc: 'receiver1@example.com, receiver1@example.com',
|
||
bcc: 'receiver4@example.com, Rec5 <receiver5@example.com>'
|
||
}).getAddresses()).to.deep.equal({
|
||
sender: [{
|
||
address: 'sender@example.com',
|
||
name: 'Sender'
|
||
}],
|
||
to: [{
|
||
address: 'receiver1@example.com',
|
||
name: ''
|
||
}, {
|
||
address: 'receiver2@example.com',
|
||
name: ''
|
||
}],
|
||
cc: [{
|
||
address: 'receiver1@example.com',
|
||
name: ''
|
||
}],
|
||
bcc: [{
|
||
address: 'receiver4@example.com',
|
||
name: ''
|
||
}, {
|
||
address: 'receiver5@example.com',
|
||
name: 'Rec5'
|
||
}]
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('#_parseAddresses', function () {
|
||
it('should normalize header key', function () {
|
||
var mb = new Buildmail();
|
||
|
||
expect(mb._parseAddresses('test address@example.com')).to.deep.equal([{
|
||
address: 'address@example.com',
|
||
name: 'test'
|
||
}]);
|
||
|
||
expect(mb._parseAddresses(['test address@example.com'])).to.deep.equal([{
|
||
address: 'address@example.com',
|
||
name: 'test'
|
||
}]);
|
||
|
||
expect(mb._parseAddresses([
|
||
['test address@example.com']
|
||
])).to.deep.equal([{
|
||
address: 'address@example.com',
|
||
name: 'test'
|
||
}]);
|
||
|
||
expect(mb._parseAddresses([{
|
||
address: 'address@example.com',
|
||
name: 'test'
|
||
}])).to.deep.equal([{
|
||
address: 'address@example.com',
|
||
name: 'test'
|
||
}]);
|
||
});
|
||
});
|
||
|
||
describe('#_normalizeHeaderKey', function () {
|
||
it('should normalize header key', function () {
|
||
var mb = new Buildmail();
|
||
|
||
expect(mb._normalizeHeaderKey('key')).to.equal('Key');
|
||
expect(mb._normalizeHeaderKey('mime-vERSION')).to.equal('MIME-Version');
|
||
expect(mb._normalizeHeaderKey('-a-long-name')).to.equal('-A-Long-Name');
|
||
expect(mb._normalizeHeaderKey('some-spf')).to.equal('Some-SPF');
|
||
expect(mb._normalizeHeaderKey('dkim-some')).to.equal('DKIM-Some');
|
||
expect(mb._normalizeHeaderKey('x-smtpapi')).to.equal('X-SMTPAPI');
|
||
expect(mb._normalizeHeaderKey('message-id')).to.equal('Message-ID');
|
||
expect(mb._normalizeHeaderKey('CONTENT-FEATUres')).to.equal('Content-features');
|
||
});
|
||
});
|
||
|
||
describe('#_handleContentType', function () {
|
||
it('should do nothing on non multipart', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb.boundary).to.not.exist;
|
||
mb._handleContentType({
|
||
value: 'text/plain'
|
||
});
|
||
expect(mb.boundary).to.be.false;
|
||
expect(mb.multipart).to.be.false;
|
||
});
|
||
|
||
it('should use provided boundary', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb.boundary).to.not.exist;
|
||
mb._handleContentType({
|
||
value: 'multipart/mixed',
|
||
params: {
|
||
boundary: 'abc'
|
||
}
|
||
});
|
||
expect(mb.boundary).to.equal('abc');
|
||
expect(mb.multipart).to.equal('mixed');
|
||
});
|
||
|
||
it('should generate boundary', function () {
|
||
var mb = new Buildmail();
|
||
sinon.stub(mb, '_generateBoundary').returns('def');
|
||
|
||
expect(mb.boundary).to.not.exist;
|
||
mb._handleContentType({
|
||
value: 'multipart/mixed',
|
||
params: {}
|
||
});
|
||
expect(mb.boundary).to.equal('def');
|
||
expect(mb.multipart).to.equal('mixed');
|
||
|
||
mb._generateBoundary.restore();
|
||
});
|
||
});
|
||
|
||
describe('#_generateBoundary ', function () {
|
||
it('should genereate boundary string', function () {
|
||
var mb = new Buildmail();
|
||
mb._nodeId = 'abc';
|
||
mb.rootNode.baseBoundary = 'def';
|
||
expect(mb._generateBoundary()).to.equal('----sinikael-?=_abc-def');
|
||
});
|
||
});
|
||
|
||
describe('#_encodeHeaderValue', function () {
|
||
it('should do noting if possible', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb._encodeHeaderValue('x-my', 'test value')).to.equal('test value');
|
||
});
|
||
|
||
it('should encode non ascii characters', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb._encodeHeaderValue('x-my', 'test jõgeva value')).to.equal('test =?UTF-8?Q?j=C3=B5geva?= value');
|
||
});
|
||
|
||
it('should format references', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb._encodeHeaderValue('references', 'abc def')).to.equal('<abc> <def>');
|
||
expect(mb._encodeHeaderValue('references', ['abc', 'def'])).to.equal('<abc> <def>');
|
||
});
|
||
|
||
it('should format message-id', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb._encodeHeaderValue('message-id', 'abc')).to.equal('<abc>');
|
||
});
|
||
|
||
it('should format addresses', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb._encodeHeaderValue('from', {
|
||
name: 'the safewithme testuser',
|
||
address: 'safewithme.testuser@jõgeva.com'
|
||
})).to.equal('the safewithme testuser <safewithme.testuser@xn--jgeva-dua.com>');
|
||
});
|
||
});
|
||
|
||
describe('#_convertAddresses', function () {
|
||
it('should convert address object to a string', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb._convertAddresses([{
|
||
name: 'Jõgeva Ants',
|
||
address: 'ants@jõgeva.ee'
|
||
}, {
|
||
name: 'Composers',
|
||
group: [{
|
||
address: 'sebu@example.com',
|
||
name: 'Bach, Sebastian'
|
||
}, {
|
||
address: 'mozart@example.com',
|
||
name: 'Mozzie'
|
||
}]
|
||
}])).to.equal('=?UTF-8?Q?J=C3=B5geva_Ants?= <ants@xn--jgeva-dua.ee>, Composers:"Bach, Sebastian" <sebu@example.com>, Mozzie <mozart@example.com>;');
|
||
});
|
||
|
||
it('should keep ascii name as is', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb._convertAddresses([{
|
||
name: 'O\'Vigala Sass',
|
||
address: 'a@b.c'
|
||
}])).to.equal('O\'Vigala Sass <a@b.c>');
|
||
});
|
||
|
||
it('should include name in quotes for special symbols', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb._convertAddresses([{
|
||
name: 'Sass, Vigala',
|
||
address: 'a@b.c'
|
||
}])).to.equal('"Sass, Vigala" <a@b.c>');
|
||
});
|
||
|
||
it('should escape quotes', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb._convertAddresses([{
|
||
name: '"Vigala Sass"',
|
||
address: 'a@b.c'
|
||
}])).to.equal('"\\"Vigala Sass\\"" <a@b.c>');
|
||
});
|
||
|
||
it('should mime encode unicode names', function () {
|
||
var mb = new Buildmail();
|
||
expect(mb._convertAddresses([{
|
||
name: '"Jõgeva Sass"',
|
||
address: 'a@b.c'
|
||
}])).to.equal('=?UTF-8?Q?=22J=C3=B5geva_Sass=22?= <a@b.c>');
|
||
});
|
||
});
|
||
|
||
describe('#_generateMessageId', function(){
|
||
it('should generate uuid-looking message-id', function(){
|
||
var mb = new Buildmail();
|
||
var mid = mb._generateMessageId();
|
||
expect(/^<[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12}@.*>/.test(mid)).to.be.true;
|
||
});
|
||
});
|
||
|
||
describe('Attachment streaming', function () {
|
||
var port = 10337;
|
||
var server;
|
||
|
||
beforeEach(function (done) {
|
||
server = http.createServer(function (req, res) {
|
||
res.writeHead(200, {
|
||
'Content-Type': 'text/plain'
|
||
});
|
||
var data = new Buffer(new Array(1024 + 1).join('ä'), 'utf-8');
|
||
var i = 0;
|
||
var sendByte = function () {
|
||
if (i >= data.length) {
|
||
return res.end();
|
||
}
|
||
res.write(new Buffer([data[i++]]));
|
||
setImmediate(sendByte);
|
||
};
|
||
|
||
sendByte();
|
||
});
|
||
|
||
server.listen(port, done);
|
||
});
|
||
|
||
afterEach(function (done) {
|
||
server.close(done);
|
||
});
|
||
|
||
it('should pipe URL as an attachment', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setContent({
|
||
href: 'http://localhost:' + port
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^=C3=A4/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should reject URL attachment', function (done) {
|
||
var mb = new Buildmail('text/plain', {disableUrlAccess: true}).
|
||
setContent({
|
||
href: 'http://localhost:' + port
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.exist;
|
||
expect(msg).to.not.exist;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should return an error on invalid url', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setContent({
|
||
href: 'http://__should_not_exist:58888'
|
||
});
|
||
|
||
mb.build(function (err) {
|
||
expect(err).to.exist;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should pipe file as an attachment', function (done) {
|
||
var mb = new Buildmail('application/octet-stream').
|
||
setContent({
|
||
path: __dirname + '/fixtures/attachment.bin'
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(/^w7VrdmEK$/m.test(msg)).to.be.true;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should reject file as an attachment', function (done) {
|
||
var mb = new Buildmail('application/octet-stream', {disableFileAccess: true}).
|
||
setContent({
|
||
path: __dirname + '/fixtures/attachment.bin'
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.exist;
|
||
expect(msg).to.not.exist;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should return an error on invalid file path', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setContent({
|
||
href: '/ASfsdfsdf/Sdgsgdfg/SDFgdfgdfg'
|
||
});
|
||
|
||
mb.build(function (err) {
|
||
expect(err).to.exist;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should return a error for an errored stream', function (done) {
|
||
var s = new PassThrough();
|
||
var mb = new Buildmail('text/plain').
|
||
setContent(s);
|
||
|
||
s.write('abc');
|
||
s.emit('error', new Error('Stream error'));
|
||
|
||
setTimeout(function () {
|
||
mb.build(function (err) {
|
||
expect(err).to.exist;
|
||
done();
|
||
});
|
||
}, 100);
|
||
});
|
||
|
||
it('should return a stream error', function (done) {
|
||
var s = new PassThrough();
|
||
var mb = new Buildmail('text/plain').
|
||
setContent(s);
|
||
|
||
mb.build(function (err) {
|
||
expect(err).to.exist;
|
||
done();
|
||
});
|
||
|
||
s.write('abc');
|
||
setTimeout(function () {
|
||
s.emit('error', new Error('Stream error'));
|
||
}, 100);
|
||
});
|
||
});
|
||
|
||
describe('#transform', function () {
|
||
it('should pipe through provided stream', function (done) {
|
||
var mb = new Buildmail('text/plain').
|
||
setHeader({
|
||
date: '12345',
|
||
'message-id': '67890'
|
||
}).
|
||
setContent('Hello world!');
|
||
|
||
var expected = 'Content-Type:\ttext/plain\r\n' +
|
||
'Date:\t12345\r\n' +
|
||
'Message-ID:\t<67890>\r\n' +
|
||
'Content-Transfer-Encoding:\t7bit\r\n' +
|
||
'MIME-Version:\t1.0\r\n' +
|
||
'\r\n' +
|
||
'Hello\tworld!';
|
||
|
||
// Transform stream that replaces all spaces with tabs
|
||
var transform = new Transform();
|
||
transform._transform = function (chunk, encoding, done) {
|
||
if (encoding !== 'buffer') {
|
||
chunk = new Buffer(chunk, encoding);
|
||
}
|
||
for (var i = 0, len = chunk.length; i < len; i++) {
|
||
if (chunk[i] === 0x20) {
|
||
chunk[i] = 0x09;
|
||
}
|
||
}
|
||
this.push(chunk);
|
||
done();
|
||
};
|
||
|
||
mb.transform(transform);
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('Raw content', function () {
|
||
it('should return pregenerated content', function (done) {
|
||
var expected = new Array(100).join('Test\n');
|
||
var mb = new Buildmail('text/plain').setRaw(expected);
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should return pregenerated content for a child node', function (done) {
|
||
var expected = new Array(100).join('Test\n');
|
||
var mb = new Buildmail('multipart/mixed', {
|
||
baseBoundary: 'test'
|
||
}).setHeader({
|
||
date: '12345',
|
||
'message-id': '67890'
|
||
});
|
||
var child = mb.createChild();
|
||
child.setRaw(expected);
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal('Content-Type: multipart/mixed; boundary="----sinikael-?=_1-test"\r\n' +
|
||
'Date: 12345\r\n' +
|
||
'Message-ID: <67890>\r\n' +
|
||
'MIME-Version: 1.0\r\n' +
|
||
'\r\n' +
|
||
'------sinikael-?=_1-test\r\n' +
|
||
expected +
|
||
'\r\n' +
|
||
'------sinikael-?=_1-test--\r\n');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should return pregenerated content from a stream', function (done) {
|
||
var expected = new Array(100).join('Test\n');
|
||
var raw = new PassThrough();
|
||
var mb = new Buildmail('text/plain').setRaw(raw);
|
||
|
||
setImmediate(function () {
|
||
raw.end(expected);
|
||
});
|
||
|
||
mb.build(function (err, msg) {
|
||
expect(err).to.not.exist;
|
||
msg = msg.toString();
|
||
expect(msg).to.equal(expected);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should catch error from a raw stream 1', function (done) {
|
||
var raw = new PassThrough();
|
||
var mb = new Buildmail('text/plain').setRaw(raw);
|
||
|
||
raw.emit('error', new Error('Stream error'));
|
||
|
||
mb.build(function (err) {
|
||
expect(err).to.exist;
|
||
done();
|
||
});
|
||
});
|
||
|
||
it('should catch error from a raw stream 2', function (done) {
|
||
var raw = new PassThrough();
|
||
var mb = new Buildmail('text/plain').setRaw(raw);
|
||
|
||
mb.build(function (err) {
|
||
expect(err).to.exist;
|
||
done();
|
||
});
|
||
|
||
setImmediate(function () {
|
||
raw.emit('error', new Error('Stream error'));
|
||
});
|
||
});
|
||
});
|
||
});
|