Ghost/ghost/email-service/test/email-controller.test.js

306 lines
10 KiB
JavaScript
Raw Normal View History

const assert = require('assert/strict');
const EmailController = require('../lib/EmailController');
const {createModel, createModelClass} = require('./utils');
describe('Email Controller', function () {
describe('_getFrameData', function () {
it('uses options id to fetch post', async function () {
const controller = new EmailController({}, {
models: {
Post: createModelClass({
findOne: {
title: 'Post title',
newsletter: createModel({slug: 'post-newsletter'})
}
})
}
});
const {post, newsletter} = await controller._getFrameData({
options: {
id: 'options-id'
},
data: {}
});
assert.equal(post.id, 'options-id');
assert.equal(newsletter.get('slug'), 'post-newsletter');
});
it('throws if post is not found', async function () {
const controller = new EmailController({}, {
models: {
Post: createModelClass({
findOne: null
})
}
});
await assert.rejects(controller._getFrameData({
options: {
id: 'options-id'
},
data: {}
}), /Post not found/);
});
it('uses default newsletter if post has no newsletter', async function () {
const controller = new EmailController({}, {
models: {
Post: createModelClass({
findOne: {}
}),
Newsletter: createModelClass({
getDefaultNewsletter: () => {
return createModel({
slug: 'default-newsletter'
});
}
})
}
});
const {newsletter} = await controller._getFrameData({
options: {
id: 'options-id'
},
data: {}
});
assert.equal(newsletter.get('slug'), 'default-newsletter');
});
it('uses newsletter from options', async function () {
const controller = new EmailController({}, {
models: {
Post: createModelClass(),
Newsletter: createModelClass()
}
});
const {newsletter} = await controller._getFrameData({
options: {
id: 'options-id',
newsletter: 'my-newsletter'
},
data: {}
});
assert.equal(newsletter.get('slug'), 'my-newsletter');
});
it('uses post from data', async function () {
const controller = new EmailController({}, {
models: {
Post: createModelClass({
findOne: {
newsletter: createModel({slug: 'post-newsletter'})
}
}),
Newsletter: createModelClass()
}
});
const {post} = await controller._getFrameData({
options: {},
data: {
slug: 'my-post'
}
});
assert.equal(post.get('slug'), 'my-post');
});
it('uses segment from options', async function () {
const controller = new EmailController({}, {
models: {
Post: createModelClass({
findOne: {
newsletter: createModel({slug: 'post-newsletter'})
}
}),
Newsletter: createModelClass()
}
});
const {segment} = await controller._getFrameData({
options: {
id: 'options-id',
memberSegment: 'free'
}
});
assert.equal(segment, 'free');
});
it('uses segment from data', async function () {
const controller = new EmailController({}, {
models: {
Post: createModelClass({
findOne: {
newsletter: createModel({slug: 'post-newsletter'})
}
}),
Newsletter: createModelClass()
}
});
const {segment} = await controller._getFrameData({
options: {
id: 'options-id'
},
data: {
memberSegment: 'free'
}
});
assert.equal(segment, 'free');
});
});
describe('previewEmail', function () {
it('should return preview email', async function () {
const service = {
previewEmail: (post) => {
return {html: 'html', plainText: 'text', subject: post.get('title')};
}
};
const controller = new EmailController(service, {
models: {
Post: createModelClass({
findOne: {
title: 'Post title'
}
}),
Newsletter: createModelClass()
}
});
const result = await controller.previewEmail({
options: {},
data: {
id: '123',
newsletter: 'newsletter-slug'
}
});
assert.equal(result.html, 'html');
assert.equal(result.plainText, 'text');
assert.equal(result.subject, 'Post title');
});
});
describe('sendTestEmail', function () {
it('throws if emails is missing', async function () {
const service = {
sendTestEmail: () => {
return Promise.resolve({id: 'mail@id'});
}
};
const controller = new EmailController(service, {
models: {
Post: createModelClass({
findOne: {
title: 'Post title'
}
}),
Newsletter: createModelClass()
}
});
await assert.rejects(controller.sendTestEmail({
options: {},
data: {
id: '123',
newsletter: 'newsletter-slug'
}
}), /No emails provided/);
});
it('returns undefined', async function () {
const service = {
sendTestEmail: () => {
return Promise.resolve({id: 'mail@id'});
}
};
const controller = new EmailController(service, {
models: {
Post: createModelClass({
findOne: {
title: 'Post title'
}
}),
Newsletter: createModelClass()
}
});
const result = await controller.sendTestEmail({
options: {},
data: {
id: '123',
newsletter: 'newsletter-slug',
emails: ['example@example.com']
}
});
assert.equal(result, undefined);
});
it('throw if more than one email is provided', async function () {
const service = {
sendTestEmail: () => {
return Promise.resolve({id: 'mail@id'});
}
};
const controller = new EmailController(service, {
models: {
Post: createModelClass({
findOne: {
title: 'Post title'
}
}),
Newsletter: createModelClass()
}
});
await assert.rejects(controller.sendTestEmail({
options: {},
data: {
id: '123',
newsletter: 'newsletter-slug',
emails: ['example@example.com', 'example2@example.com']
}
}), /Too many emails provided. Maximum of 1 test email can be sent at once./);
});
});
describe('retryFailedEmail', function () {
it('throws if email not found', async function () {
const controller = new EmailController({}, {
models: {
Email: createModelClass({
findOne: null
})
}
});
await assert.rejects(controller.retryFailedEmail({
options: {},
data: {
id: '123'
}
}), /Email not found/);
});
it('returns email', async function () {
const service = {
retryEmail: (email) => {
return Promise.resolve(email);
}
};
const controller = new EmailController(service, {
models: {
Email: createModelClass({
findOne: {
status: 'failed'
}
})
}
});
const result = await controller.retryFailedEmail({
options: {},
data: {
id: '123'
}
});
assert.equal(result.get('status'), 'failed');
});
});
});