UNPKG

mimetext

Version:

RFC-5322 compliant, fully typed and documented email message generator for javascript runtimes.

254 lines (231 loc) 11.4 kB
import {EOL} from 'node:os' import {expect, test} from '@jest/globals' import * as mime from 'mime-types' import {MIMEMessage, Mailbox, MIMEMessageContent} from '../src/entrypoints/node.js' const envctx = { toBase64: function toBase64(data) { return (new Buffer(data)).toString('base64') }, toBase64WebSafe: function toBase64WebSafe(data) { return (new Buffer(data)).toString('base64') .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, '') }, eol: EOL, validateContentType: (v) => { return mime.contentType(v) } } const sampleImageBase64 = '/9j/4AAQSkZJRgABAgEASABIAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAgICAgICAgICAgMDAwMDAwMDAwMBAQEBAQEBAgEBAgICAQICAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA//AABEIAAUABQMAEQABEQECEQH/xABPAAEAAAAAAAAAAAAAAAAAAAAKEAEBAQEBAQAAAAAAAAAAAAAFBgQDAgEBAQAAAAAAAAAAAAAAAAAAAAARAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwAAARECEQA/AHsDDIlo1m7dWUFHmo6DMyOOzmleB0EdwlZme6ycn1npkJbZP7FgtTvTo7qaV+KtbefPb4N8Hn4A/9k=' test('sets and gets headers', () => { const msg = new MIMEMessage(envctx) msg.setSender('test@mail.com') expect(msg.getSender().addr).toBe('test@mail.com') msg.setRecipients(['to@mail.com', '"Lorem Ipsum" <to2@mail.com>']) expect(msg.getRecipients()).toContainEqual(new Mailbox('to@mail.com')) expect(msg.getRecipients()).toContainEqual(new Mailbox('"Lorem Ipsum" <to2@mail.com>')) msg.setCc('cc@mail.com') expect(msg.getRecipients({type: 'Cc'})).toContainEqual(new Mailbox('cc@mail.com', {type: 'Cc'})) msg.setBcc('bcc@mail.com') expect(msg.getRecipients({type: 'Bcc'})).toContainEqual(new Mailbox('bcc@mail.com', {type: 'Bcc'})) msg.setSubject('Lorem Ipsum') expect(msg.getSubject()).toBe('Lorem Ipsum') msg.setSubject('Gözel 🐬') expect(msg.getSubject()).toBe('Gözel 🐬') expect(msg.hasInlineAttachments()).toBe(false) msg.addAttachment({ inline: true, filename: 'sample.jpg', contentType: 'image/jpeg', data: sampleImageBase64, headers: {'Content-ID': 'abcdef'} }) expect(msg.hasInlineAttachments()).toBe(true) }) test('generates plain text messages', () => { const msg = new MIMEMessage(envctx) msg.setHeader('Date', 'Wed, 22 Mar 2023 23:36:33 +0000') msg.setHeader('Message-ID', '<oliusb0xvxc@mail.com>') msg.setSender('test@mail.com') msg.setSubject('Lorem Ipsum') const result = msg.addMessage({contentType: 'text/plain', data: 'hello there'}) expect(msg.getMessageByType('text/plain')).toBeInstanceOf(MIMEMessageContent) expect(msg.asRaw()).toBe('Date: Wed, 22 Mar 2023 23:36:33 +0000' + envctx.eol + 'From: <test@mail.com>' + envctx.eol + 'Message-ID: <oliusb0xvxc@mail.com>' + envctx.eol + 'Subject: =?utf-8?B?TG9yZW0gSXBzdW0=?=' + envctx.eol + 'MIME-Version: 1.0' + envctx.eol + 'Content-Type: text/plain; charset=UTF-8' + envctx.eol + 'Content-Transfer-Encoding: 7bit' + envctx.eol + envctx.eol + 'hello there' ) }) test('generates html messages', () => { const msg = new MIMEMessage(envctx) msg.setHeader('Date', 'Wed, 22 Mar 2023 23:36:33 +0000') msg.setHeader('Message-ID', '<oliusb0xvxc@mail.com>') msg.setSender('test@mail.com') msg.setSubject('Lorem Ipsum') msg.addMessage({contentType: 'text/html', data: 'hello there <b>Murat</b>'}) expect(msg.asRaw()).toBe('Date: Wed, 22 Mar 2023 23:36:33 +0000' + envctx.eol + 'From: <test@mail.com>' + envctx.eol + 'Message-ID: <oliusb0xvxc@mail.com>' + envctx.eol + 'Subject: =?utf-8?B?TG9yZW0gSXBzdW0=?=' + envctx.eol + 'MIME-Version: 1.0' + envctx.eol + 'Content-Type: text/html; charset=UTF-8' + envctx.eol + 'Content-Transfer-Encoding: 7bit' + envctx.eol + envctx.eol + 'hello there <b>Murat</b>' ) }) test('generates plain text and html mixed messages', () => { const msg = new MIMEMessage(envctx) msg.boundaries = {mixed: 'abcdef', alt: 'qwerty'} msg.setHeader('Date', 'Wed, 22 Mar 2023 23:36:33 +0000') msg.setHeader('Message-ID', '<oliusb0xvxc@mail.com>') msg.setSender('test@mail.com') msg.setSubject('Lorem Ipsum') msg.addMessage({contentType: 'text/plain', data: 'hello there'}) msg.addMessage({contentType: 'text/html', data: 'hello there <b>Murat</b>'}) expect(msg.asRaw()).toBe('Date: Wed, 22 Mar 2023 23:36:33 +0000' + envctx.eol + 'From: <test@mail.com>' + envctx.eol + 'Message-ID: <oliusb0xvxc@mail.com>' + envctx.eol + 'Subject: =?utf-8?B?TG9yZW0gSXBzdW0=?=' + envctx.eol + 'MIME-Version: 1.0' + envctx.eol + 'Content-Type: multipart/alternative; boundary=qwerty' + envctx.eol + envctx.eol + '--qwerty' + envctx.eol + 'Content-Type: text/plain; charset=UTF-8' + envctx.eol + 'Content-Transfer-Encoding: 7bit' + envctx.eol + envctx.eol + 'hello there' + envctx.eol + envctx.eol + '--qwerty' + envctx.eol + 'Content-Type: text/html; charset=UTF-8' + envctx.eol + 'Content-Transfer-Encoding: 7bit' + envctx.eol + envctx.eol + 'hello there <b>Murat</b>' + envctx.eol + envctx.eol + '--qwerty--' ) }) test('generates plain text message with an attachment', () => { const msg = new MIMEMessage(envctx) msg.boundaries = {mixed: 'abcdef', alt: 'qwerty'} msg.setHeader('Date', 'Wed, 22 Mar 2023 23:36:33 +0000') msg.setHeader('Message-ID', '<oliusb0xvxc@mail.com>') msg.setSender('test@mail.com') msg.setSubject('Lorem Ipsum') msg.addMessage({contentType: 'text/plain', data: 'hello there'}) msg.addAttachment({ contentType: 'image/jpg', filename: 'sample.jpg', data: sampleImageBase64 }) expect(msg.asRaw()).toBe('Date: Wed, 22 Mar 2023 23:36:33 +0000' + envctx.eol + 'From: <test@mail.com>' + envctx.eol + 'Message-ID: <oliusb0xvxc@mail.com>' + envctx.eol + 'Subject: =?utf-8?B?TG9yZW0gSXBzdW0=?=' + envctx.eol + 'MIME-Version: 1.0' + envctx.eol + 'Content-Type: multipart/mixed; boundary=abcdef' + envctx.eol + envctx.eol + '--abcdef' + envctx.eol + 'Content-Type: text/plain; charset=UTF-8' + envctx.eol + 'Content-Transfer-Encoding: 7bit' + envctx.eol + envctx.eol + 'hello there' + envctx.eol + envctx.eol + '--abcdef' + envctx.eol + 'Content-Type: image/jpg; name="sample.jpg"' + envctx.eol + 'Content-Transfer-Encoding: base64' + envctx.eol + 'Content-Disposition: attachment; filename="sample.jpg"' + envctx.eol + envctx.eol + sampleImageBase64 + envctx.eol + '--abcdef--' ) }) test('generates plain text and html mixed message with an attachment', () => { const msg = new MIMEMessage(envctx) msg.boundaries = {mixed: 'abcdef', alt: 'qwerty'} msg.setHeader('Date', 'Wed, 22 Mar 2023 23:36:33 +0000') msg.setHeader('Message-ID', '<oliusb0xvxc@mail.com>') msg.setSender('test@mail.com') msg.setSubject('Lorem Ipsum') msg.addMessage({contentType: 'text/plain', data: 'hello there'}) msg.addMessage({contentType: 'text/html', data: 'hello there <b>Murat</b>'}) msg.addAttachment({ contentType: 'image/jpg', filename: 'sample.jpg', data: sampleImageBase64 }) expect(msg.asRaw()).toBe('Date: Wed, 22 Mar 2023 23:36:33 +0000' + envctx.eol + 'From: <test@mail.com>' + envctx.eol + 'Message-ID: <oliusb0xvxc@mail.com>' + envctx.eol + 'Subject: =?utf-8?B?TG9yZW0gSXBzdW0=?=' + envctx.eol + 'MIME-Version: 1.0' + envctx.eol + 'Content-Type: multipart/mixed; boundary=abcdef' + envctx.eol + envctx.eol + '--abcdef' + envctx.eol + 'Content-Type: multipart/alternative; boundary=qwerty' + envctx.eol + envctx.eol + '--qwerty' + envctx.eol + 'Content-Type: text/plain; charset=UTF-8' + envctx.eol + 'Content-Transfer-Encoding: 7bit' + envctx.eol + envctx.eol + 'hello there' + envctx.eol + envctx.eol + '--qwerty' + envctx.eol + 'Content-Type: text/html; charset=UTF-8' + envctx.eol + 'Content-Transfer-Encoding: 7bit' + envctx.eol + envctx.eol + 'hello there <b>Murat</b>' + envctx.eol + envctx.eol + '--qwerty--' + envctx.eol + '--abcdef' + envctx.eol + 'Content-Type: image/jpg; name="sample.jpg"' + envctx.eol + 'Content-Transfer-Encoding: base64' + envctx.eol + 'Content-Disposition: attachment; filename="sample.jpg"' + envctx.eol + envctx.eol + sampleImageBase64 + envctx.eol + '--abcdef--' ) }) test('generates plain text and html related message with an inline attachment', () => { const msg = new MIMEMessage(envctx) msg.boundaries = {related: 'abcdef', alt: 'qwerty'} msg.setHeader('Date', 'Wed, 22 Mar 2023 23:36:33 +0000') msg.setHeader('Message-ID', '<oliusb0xvxc@mail.com>') msg.setSender('test@mail.com') msg.setSubject('Lorem Ipsum') msg.addMessage({contentType: 'text/plain', data: 'hello there'}) msg.addMessage({contentType: 'text/html', data: 'hello there <b>Murat</b>'}) msg.addAttachment({ inline: true, contentType: 'image/jpg', filename: 'sample.jpg', data: sampleImageBase64 }) expect(msg.hasInlineAttachments()).toBe(true); expect(msg.getMessageByType("text/plain")?.data).toBe("hello there") expect(msg.asRaw()).toBe('Date: Wed, 22 Mar 2023 23:36:33 +0000' + envctx.eol + 'From: <test@mail.com>' + envctx.eol + 'Message-ID: <oliusb0xvxc@mail.com>' + envctx.eol + 'Subject: =?utf-8?B?TG9yZW0gSXBzdW0=?=' + envctx.eol + 'MIME-Version: 1.0' + envctx.eol + 'Content-Type: multipart/related; boundary=abcdef' + envctx.eol + envctx.eol + '--abcdef' + envctx.eol + 'Content-Type: multipart/alternative; boundary=qwerty' + envctx.eol + envctx.eol + '--qwerty' + envctx.eol + 'Content-Type: text/plain; charset=UTF-8' + envctx.eol + 'Content-Transfer-Encoding: 7bit' + envctx.eol + envctx.eol + 'hello there' + envctx.eol + envctx.eol + '--qwerty' + envctx.eol + 'Content-Type: text/html; charset=UTF-8' + envctx.eol + 'Content-Transfer-Encoding: 7bit' + envctx.eol + envctx.eol + 'hello there <b>Murat</b>' + envctx.eol + envctx.eol + '--qwerty--' + envctx.eol + envctx.eol + '--abcdef' + envctx.eol + 'Content-Type: image/jpg; name="sample.jpg"' + envctx.eol + 'Content-Transfer-Encoding: base64' + envctx.eol + 'Content-Disposition: inline; filename="sample.jpg"' + envctx.eol + envctx.eol + sampleImageBase64 + envctx.eol + '--abcdef--' ) }) test('sending only an attachment, without content is not allowed', async () => { const msg = new MIMEMessage(envctx) msg.setHeader('Date', 'Wed, 22 Mar 2023 23:36:33 +0000') msg.setHeader('Message-ID', '<oliusb0xvxc@mail.com>') msg.setSender('test@mail.com') msg.setSubject('Lorem Ipsum') msg.addAttachment({ contentType: 'image/jpg', filename: 'sample.jpg', data: sampleImageBase64 }) expect(() => msg.asRaw()).toThrow('No content added to the message.') })