mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-03 16:38:22 +03:00
Fixed subscription status not showing correctly in emails
refs https://github.com/TryGhost/Team/issues/2674 - The segment detection doesn't work outside the main post content. So the data-gh-segment attribute didn't work. It is now replaced with just a simple email replacement that is empty for a free member. - Fixed that a trialing member was shown as 'paid'. This is now replaced with 'trialing'. This commit also includes E2E tests for a couple of member statusses.
This commit is contained in:
parent
eb1d63eac0
commit
0107d2bb77
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@ const {settingsCache} = require('../../../../core/server/services/settings-helpe
|
|||||||
const DomainEvents = require('@tryghost/domain-events');
|
const DomainEvents = require('@tryghost/domain-events');
|
||||||
const emailService = require('../../../../core/server/services/email-service');
|
const emailService = require('../../../../core/server/services/email-service');
|
||||||
const should = require('should');
|
const should = require('should');
|
||||||
const {mockSetting} = require('../../../utils/e2e-framework-mock-manager');
|
const {mockSetting, stripeMocker} = require('../../../utils/e2e-framework-mock-manager');
|
||||||
|
|
||||||
const mobileDocExample = '{"version":"0.3.1","atoms":[],"cards":[],"markups":[],"sections":[[1,"p",[[0,[],0,"Hello world"]]]],"ghostVersion":"4.0"}';
|
const mobileDocExample = '{"version":"0.3.1","atoms":[],"cards":[],"markups":[],"sections":[[1,"p",[[0,[],0,"Hello world"]]]],"ghostVersion":"4.0"}';
|
||||||
const mobileDocWithPaywall = '{"version":"0.3.1","markups":[],"atoms":[],"cards":[["paywall",{}]],"sections":[[1,"p",[[0,[],0,"Free content"]]],[10,0],[1,"p",[[0,[],0,"Members content"]]]]}';
|
const mobileDocWithPaywall = '{"version":"0.3.1","markups":[],"atoms":[],"cards":[["paywall",{}]],"sections":[[1,"p",[[0,[],0,"Free content"]]],[10,0],[1,"p",[[0,[],0,"Members content"]]]]}';
|
||||||
@ -263,6 +263,7 @@ describe('Batch sending tests', function () {
|
|||||||
// Allows for setting stubbedSend during tests
|
// Allows for setting stubbedSend during tests
|
||||||
return stubbedSend.call(this, ...arguments);
|
return stubbedSend.call(this, ...arguments);
|
||||||
});
|
});
|
||||||
|
mockManager.mockStripe();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async function () {
|
afterEach(async function () {
|
||||||
@ -1039,19 +1040,189 @@ describe('Batch sending tests', function () {
|
|||||||
await models.Newsletter.edit({show_comment_cta: true}, {id: defaultNewsletter.id});
|
await models.Newsletter.edit({show_comment_cta: true}, {id: defaultNewsletter.id});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Shows subscription details box', async function () {
|
it('Shows subscription details box for free members', async function () {
|
||||||
|
// Create a new member without a first_name
|
||||||
|
await models.Member.add({
|
||||||
|
email: 'subscription-box-1@example.com',
|
||||||
|
labels: [{name: 'subscription-box-tests'}],
|
||||||
|
newsletters: [{
|
||||||
|
id: fixtureManager.get('newsletters', 0).id
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
mockSetting('email_track_clicks', false); // Disable link replacement for this test
|
mockSetting('email_track_clicks', false); // Disable link replacement for this test
|
||||||
|
|
||||||
const defaultNewsletter = await getDefaultNewsletter();
|
const defaultNewsletter = await getDefaultNewsletter();
|
||||||
await models.Newsletter.edit({show_subscription_details: true}, {id: defaultNewsletter.id});
|
await models.Newsletter.edit({show_subscription_details: true}, {id: defaultNewsletter.id});
|
||||||
|
|
||||||
const {html} = await sendEmail({
|
const {html, plaintext} = await sendEmail({
|
||||||
title: 'This is a test post title',
|
title: 'This is a test post title',
|
||||||
mobiledoc: mobileDocExample
|
mobiledoc: mobileDocExample
|
||||||
});
|
}, 'label:subscription-box-tests');
|
||||||
|
|
||||||
// Currently the link is not present in plaintext version (because no text)
|
// Currently the link is not present in plaintext version (because no text)
|
||||||
assert.equal(html.match(/#\/portal\/account/g).length, 1, 'Subscription details box should contain a link to the account page');
|
assert.equal(html.match(/#\/portal\/account/g).length, 1, 'Subscription details box should contain a link to the account page');
|
||||||
|
|
||||||
|
// Check text matches
|
||||||
|
assert.match(plaintext, /You are receiving this because you are a free subscriber to Ghost\./);
|
||||||
|
|
||||||
|
await lastEmailMatchSnapshot();
|
||||||
|
|
||||||
|
// undo
|
||||||
|
await models.Newsletter.edit({show_subscription_details: false}, {id: defaultNewsletter.id});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Shows subscription details box for comped members', async function () {
|
||||||
|
// Create a new member without a first_name
|
||||||
|
await models.Member.add({
|
||||||
|
email: 'subscription-box-comped@example.com',
|
||||||
|
labels: [{name: 'subscription-box-comped-tests'}],
|
||||||
|
newsletters: [{
|
||||||
|
id: fixtureManager.get('newsletters', 0).id
|
||||||
|
}],
|
||||||
|
status: 'comped'
|
||||||
|
});
|
||||||
|
|
||||||
|
mockSetting('email_track_clicks', false); // Disable link replacement for this test
|
||||||
|
|
||||||
|
const defaultNewsletter = await getDefaultNewsletter();
|
||||||
|
await models.Newsletter.edit({show_subscription_details: true}, {id: defaultNewsletter.id});
|
||||||
|
|
||||||
|
const {html, plaintext} = await sendEmail({
|
||||||
|
title: 'This is a test post title',
|
||||||
|
mobiledoc: mobileDocExample
|
||||||
|
}, 'label:subscription-box-comped-tests');
|
||||||
|
|
||||||
|
// Currently the link is not present in plaintext version (because no text)
|
||||||
|
assert.equal(html.match(/#\/portal\/account/g).length, 1, 'Subscription details box should contain a link to the account page');
|
||||||
|
|
||||||
|
// Check text matches
|
||||||
|
assert.match(plaintext, /You are receiving this because you are a complimentary subscriber to Ghost\./);
|
||||||
|
|
||||||
|
await lastEmailMatchSnapshot();
|
||||||
|
|
||||||
|
// undo
|
||||||
|
await models.Newsletter.edit({show_subscription_details: false}, {id: defaultNewsletter.id});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Shows subscription details box for trialing member', async function () {
|
||||||
|
mockSetting('email_track_clicks', false); // Disable link replacement for this test
|
||||||
|
|
||||||
|
// Create a new member without a first_name
|
||||||
|
const customer = stripeMocker.createCustomer({
|
||||||
|
email: 'trialing-paid@example.com'
|
||||||
|
});
|
||||||
|
const price = await stripeMocker.getPriceForTier('default-product', 'month');
|
||||||
|
await stripeMocker.createTrialSubscription({
|
||||||
|
customer,
|
||||||
|
price
|
||||||
|
});
|
||||||
|
|
||||||
|
const member = await models.Member.findOne({email: customer.email}, {require: true});
|
||||||
|
await models.Member.edit({
|
||||||
|
labels: [{name: 'subscription-box-trialing-tests'}],
|
||||||
|
newsletters: [{
|
||||||
|
id: fixtureManager.get('newsletters', 0).id
|
||||||
|
}]
|
||||||
|
}, {id: member.id});
|
||||||
|
|
||||||
|
const defaultNewsletter = await getDefaultNewsletter();
|
||||||
|
await models.Newsletter.edit({show_subscription_details: true}, {id: defaultNewsletter.id});
|
||||||
|
|
||||||
|
const {html, plaintext} = await sendEmail({
|
||||||
|
title: 'This is a test post title',
|
||||||
|
mobiledoc: mobileDocExample
|
||||||
|
}, 'label:subscription-box-trialing-tests');
|
||||||
|
|
||||||
|
// Currently the link is not present in plaintext version (because no text)
|
||||||
|
assert.equal(html.match(/#\/portal\/account/g).length, 1, 'Subscription details box should contain a link to the account page');
|
||||||
|
|
||||||
|
// Check text matches
|
||||||
|
assert.match(plaintext, /You are receiving this because you are a trialing subscriber to Ghost\. Your free trial ends on \d+ \w+ \d+, at which time you will be charged the regular price\. You can always cancel before then\./);
|
||||||
|
|
||||||
|
await lastEmailMatchSnapshot();
|
||||||
|
|
||||||
|
// undo
|
||||||
|
await models.Newsletter.edit({show_subscription_details: false}, {id: defaultNewsletter.id});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Shows subscription details box for paid member', async function () {
|
||||||
|
mockSetting('email_track_clicks', false); // Disable link replacement for this test
|
||||||
|
|
||||||
|
// Create a new member without a first_name
|
||||||
|
const customer = stripeMocker.createCustomer({
|
||||||
|
email: 'paid@example.com'
|
||||||
|
});
|
||||||
|
const price = await stripeMocker.getPriceForTier('default-product', 'month');
|
||||||
|
await stripeMocker.createSubscription({
|
||||||
|
customer,
|
||||||
|
price
|
||||||
|
});
|
||||||
|
|
||||||
|
const member = await models.Member.findOne({email: customer.email}, {require: true});
|
||||||
|
await models.Member.edit({
|
||||||
|
labels: [{name: 'subscription-box-paid-tests'}],
|
||||||
|
newsletters: [{
|
||||||
|
id: fixtureManager.get('newsletters', 0).id
|
||||||
|
}]
|
||||||
|
}, {id: member.id});
|
||||||
|
|
||||||
|
const defaultNewsletter = await getDefaultNewsletter();
|
||||||
|
await models.Newsletter.edit({show_subscription_details: true}, {id: defaultNewsletter.id});
|
||||||
|
|
||||||
|
const {html, plaintext} = await sendEmail({
|
||||||
|
title: 'This is a test post title',
|
||||||
|
mobiledoc: mobileDocExample
|
||||||
|
}, 'label:subscription-box-paid-tests');
|
||||||
|
|
||||||
|
// Currently the link is not present in plaintext version (because no text)
|
||||||
|
assert.equal(html.match(/#\/portal\/account/g).length, 1, 'Subscription details box should contain a link to the account page');
|
||||||
|
|
||||||
|
// Check text matches
|
||||||
|
assert.match(plaintext, /You are receiving this because you are a paid subscriber to Ghost\. Your subscription will renew on \d+ \w+ \d+\./);
|
||||||
|
|
||||||
|
await lastEmailMatchSnapshot();
|
||||||
|
|
||||||
|
// undo
|
||||||
|
await models.Newsletter.edit({show_subscription_details: false}, {id: defaultNewsletter.id});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Shows subscription details box for canceled paid member', async function () {
|
||||||
|
mockSetting('email_track_clicks', false); // Disable link replacement for this test
|
||||||
|
|
||||||
|
// Create a new member without a first_name
|
||||||
|
const customer = stripeMocker.createCustomer({
|
||||||
|
email: 'canceled-paid@example.com'
|
||||||
|
});
|
||||||
|
const price = await stripeMocker.getPriceForTier('default-product', 'month');
|
||||||
|
await stripeMocker.createSubscription({
|
||||||
|
customer,
|
||||||
|
price,
|
||||||
|
cancel_at_period_end: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const member = await models.Member.findOne({email: customer.email}, {require: true});
|
||||||
|
await models.Member.edit({
|
||||||
|
labels: [{name: 'subscription-box-canceled-tests'}],
|
||||||
|
newsletters: [{
|
||||||
|
id: fixtureManager.get('newsletters', 0).id
|
||||||
|
}]
|
||||||
|
}, {id: member.id});
|
||||||
|
|
||||||
|
const defaultNewsletter = await getDefaultNewsletter();
|
||||||
|
await models.Newsletter.edit({show_subscription_details: true}, {id: defaultNewsletter.id});
|
||||||
|
|
||||||
|
const {html, plaintext} = await sendEmail({
|
||||||
|
title: 'This is a test post title',
|
||||||
|
mobiledoc: mobileDocExample
|
||||||
|
}, 'label:subscription-box-canceled-tests');
|
||||||
|
|
||||||
|
// Currently the link is not present in plaintext version (because no text)
|
||||||
|
assert.equal(html.match(/#\/portal\/account/g).length, 1, 'Subscription details box should contain a link to the account page');
|
||||||
|
|
||||||
|
// Check text matches
|
||||||
|
assert.match(plaintext, /You are receiving this because you are a paid subscriber to Ghost\. Your subscription has been canceled and will expire on \d+ \w+ \d+\. You can resume your subscription via your account settings\./);
|
||||||
|
|
||||||
await lastEmailMatchSnapshot();
|
await lastEmailMatchSnapshot();
|
||||||
|
|
||||||
// undo
|
// undo
|
||||||
|
@ -85,7 +85,8 @@ class StripeMocker {
|
|||||||
customer,
|
customer,
|
||||||
price,
|
price,
|
||||||
status: 'trialing',
|
status: 'trialing',
|
||||||
trial_end_at: (Date.now() + 1000 * 60 * 60 * 24 * 7) / 1000,
|
trial_start: Date.now() / 1000,
|
||||||
|
trial_end: (Date.now() + 1000 * 60 * 60 * 24 * 7) / 1000,
|
||||||
...overrides
|
...overrides
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ const tpl = require('@tryghost/tpl');
|
|||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
subscriptionStatus: {
|
subscriptionStatus: {
|
||||||
free: 'You are currently subscribed to the free plan.',
|
free: '',
|
||||||
expired: 'Your subscription has expired.',
|
expired: 'Your subscription has expired.',
|
||||||
canceled: 'Your subscription has been canceled and will expire on {date}. You can resume your subscription via your account settings.',
|
canceled: 'Your subscription has been canceled and will expire on {date}. You can resume your subscription via your account settings.',
|
||||||
active: 'Your subscription will renew on {date}.',
|
active: 'Your subscription will renew on {date}.',
|
||||||
@ -405,6 +405,29 @@ class EmailRenderer {
|
|||||||
return url.href;
|
return url.href;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a paid member is trialing a subscription
|
||||||
|
*/
|
||||||
|
isMemberTrialing(member) {
|
||||||
|
// Do we have an active subscription?
|
||||||
|
if (member.status === 'paid') {
|
||||||
|
let activeSubscription = member.subscriptions.find((subscription) => {
|
||||||
|
return subscription.status === 'trialing';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!activeSubscription) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate to a human readable string
|
||||||
|
if (activeSubscription.trial_end_at && activeSubscription.trial_end_at > new Date() && activeSubscription.status === 'trialing') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {MemberLike} member
|
* @param {MemberLike} member
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
@ -528,6 +551,9 @@ class EmailRenderer {
|
|||||||
if (member.status === 'comped') {
|
if (member.status === 'comped') {
|
||||||
return 'complimentary';
|
return 'complimentary';
|
||||||
}
|
}
|
||||||
|
if (this.isMemberTrialing(member)) {
|
||||||
|
return 'trialing';
|
||||||
|
}
|
||||||
return member.status;
|
return member.status;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -180,8 +180,7 @@
|
|||||||
<td class="subscription-box">
|
<td class="subscription-box">
|
||||||
<h3>Subscription details</h3>
|
<h3>Subscription details</h3>
|
||||||
<p style="margin-bottom: 16px;">
|
<p style="margin-bottom: 16px;">
|
||||||
<span>You are receiving this because you are a <strong>%%{status}%% subscriber</strong> to {{site.title}}.</span>
|
<span>You are receiving this because you are a <strong>%%{status}%% subscriber</strong> to {{site.title}}.</span> %%{status_text}%%
|
||||||
<span data-gh-segment="status:-free">%%{status_text}%%</span>
|
|
||||||
</p>
|
</p>
|
||||||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -203,6 +203,24 @@ describe('Email renderer', function () {
|
|||||||
assert.equal(replacements[0].getValue(member), 'complimentary');
|
assert.equal(replacements[0].getValue(member), 'complimentary');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns mapped trialing status', function () {
|
||||||
|
member.status = 'paid';
|
||||||
|
member.subscriptions = [
|
||||||
|
{
|
||||||
|
status: 'trialing',
|
||||||
|
trial_end_at: new Date(2050, 2, 13, 12, 0),
|
||||||
|
current_period_end: new Date(2023, 2, 13, 12, 0),
|
||||||
|
cancel_at_period_end: false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const html = 'Hello %%{status}%%,';
|
||||||
|
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||||
|
assert.equal(replacements.length, 1);
|
||||||
|
assert.equal(replacements[0].token.toString(), '/%%\\{status\\}%%/g');
|
||||||
|
assert.equal(replacements[0].id, 'status');
|
||||||
|
assert.equal(replacements[0].getValue(member), 'trialing');
|
||||||
|
});
|
||||||
|
|
||||||
it('returns manage_account_url', function () {
|
it('returns manage_account_url', function () {
|
||||||
const html = 'Hello %%{manage_account_url}%%,';
|
const html = 'Hello %%{manage_account_url}%%,';
|
||||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||||
@ -214,11 +232,21 @@ describe('Email renderer', function () {
|
|||||||
|
|
||||||
it('returns status_text', function () {
|
it('returns status_text', function () {
|
||||||
const html = 'Hello %%{status_text}%%,';
|
const html = 'Hello %%{status_text}%%,';
|
||||||
|
member.status = 'paid';
|
||||||
|
member.subscriptions = [
|
||||||
|
{
|
||||||
|
status: 'trialing',
|
||||||
|
trial_end_at: new Date(2050, 2, 13, 12, 0),
|
||||||
|
current_period_end: new Date(2023, 2, 13, 12, 0),
|
||||||
|
cancel_at_period_end: false
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
const replacements = emailRenderer.buildReplacementDefinitions({html, newsletterUuid: newsletter.get('uuid')});
|
||||||
assert.equal(replacements.length, 1);
|
assert.equal(replacements.length, 1);
|
||||||
assert.equal(replacements[0].token.toString(), '/%%\\{status_text\\}%%/g');
|
assert.equal(replacements[0].token.toString(), '/%%\\{status_text\\}%%/g');
|
||||||
assert.equal(replacements[0].id, 'status_text');
|
assert.equal(replacements[0].id, 'status_text');
|
||||||
assert.equal(replacements[0].getValue(member), 'You are currently subscribed to the free plan.');
|
assert.equal(replacements[0].getValue(member), 'Your free trial ends on 13 March 2050, at which time you will be charged the regular price. You can always cancel before then.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns correct createdAt', function () {
|
it('returns correct createdAt', function () {
|
||||||
@ -279,6 +307,109 @@ describe('Email renderer', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isMemberTrialing', function () {
|
||||||
|
let emailRenderer;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
emailRenderer = new EmailRenderer({
|
||||||
|
urlUtils: {
|
||||||
|
urlFor: () => 'http://example.com/subdirectory/'
|
||||||
|
},
|
||||||
|
labs: {
|
||||||
|
isSet: () => true
|
||||||
|
},
|
||||||
|
settingsCache: {
|
||||||
|
get: (key) => {
|
||||||
|
if (key === 'timezone') {
|
||||||
|
return 'UTC';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns false for free member', function () {
|
||||||
|
const member = {
|
||||||
|
id: '456',
|
||||||
|
uuid: 'myuuid',
|
||||||
|
name: 'Test User',
|
||||||
|
email: 'test@example.com',
|
||||||
|
createdAt: new Date(2023, 2, 13, 12, 0),
|
||||||
|
status: 'free'
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = emailRenderer.isMemberTrialing(member);
|
||||||
|
assert.equal(result, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns false for paid member without trial', function () {
|
||||||
|
const member = {
|
||||||
|
id: '456',
|
||||||
|
uuid: 'myuuid',
|
||||||
|
name: 'Test User',
|
||||||
|
email: 'test@example.com',
|
||||||
|
createdAt: new Date(2023, 2, 13, 12, 0),
|
||||||
|
status: 'paid',
|
||||||
|
subscriptions: [
|
||||||
|
{
|
||||||
|
status: 'active',
|
||||||
|
current_period_end: new Date(2023, 2, 13, 12, 0),
|
||||||
|
cancel_at_period_end: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = emailRenderer.isMemberTrialing(member);
|
||||||
|
assert.equal(result, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns true for trialing paid member', function () {
|
||||||
|
const member = {
|
||||||
|
id: '456',
|
||||||
|
uuid: 'myuuid',
|
||||||
|
name: 'Test User',
|
||||||
|
email: 'test@example.com',
|
||||||
|
createdAt: new Date(2023, 2, 13, 12, 0),
|
||||||
|
status: 'paid',
|
||||||
|
subscriptions: [
|
||||||
|
{
|
||||||
|
status: 'trialing',
|
||||||
|
trial_end_at: new Date(2050, 2, 13, 12, 0),
|
||||||
|
current_period_end: new Date(2023, 2, 13, 12, 0),
|
||||||
|
cancel_at_period_end: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tiers: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = emailRenderer.isMemberTrialing(member);
|
||||||
|
assert.equal(result, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns false for expired trialing paid member', function () {
|
||||||
|
const member = {
|
||||||
|
id: '456',
|
||||||
|
uuid: 'myuuid',
|
||||||
|
name: 'Test User',
|
||||||
|
email: 'test@example.com',
|
||||||
|
createdAt: new Date(2023, 2, 13, 12, 0),
|
||||||
|
status: 'paid',
|
||||||
|
subscriptions: [
|
||||||
|
{
|
||||||
|
status: 'trialing',
|
||||||
|
trial_end_at: new Date(2000, 2, 13, 12, 0),
|
||||||
|
current_period_end: new Date(2023, 2, 13, 12, 0),
|
||||||
|
cancel_at_period_end: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tiers: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = emailRenderer.isMemberTrialing(member);
|
||||||
|
assert.equal(result, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('getMemberStatusText', function () {
|
describe('getMemberStatusText', function () {
|
||||||
let emailRenderer;
|
let emailRenderer;
|
||||||
|
|
||||||
@ -311,7 +442,7 @@ describe('Email renderer', function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const result = emailRenderer.getMemberStatusText(member);
|
const result = emailRenderer.getMemberStatusText(member);
|
||||||
assert.equal(result, 'You are currently subscribed to the free plan.');
|
assert.equal(result, '');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Returns for active paid member', function () {
|
it('Returns for active paid member', function () {
|
||||||
|
Loading…
Reference in New Issue
Block a user