{{#each tier.subscriptions as |sub index|}}
-
-
-
- {{sub.price.currencySymbol}}
- {{format-number sub.price.nonDecimalAmount}}
+
{{/each}}
{{#if (eq tier.subscriptions.length 0)}}
diff --git a/ghost/admin/app/utils/subscription-data.js b/ghost/admin/app/utils/subscription-data.js
index 347265ace4..9a396963d9 100644
--- a/ghost/admin/app/utils/subscription-data.js
+++ b/ghost/admin/app/utils/subscription-data.js
@@ -24,7 +24,8 @@ export function getSubscriptionData(sub) {
trialUntil: trialUntil(sub)
};
- data.validityDetails = validityDetails(data);
+ data.priceLabel = priceLabel(data);
+ data.validityDetails = validityDetails(data, !!data.priceLabel);
return data;
}
@@ -77,22 +78,39 @@ export function trialUntil(sub) {
return undefined;
}
-export function validityDetails(data) {
- if (data.isComplimentary && data.compExpiry) {
- return `Expires ${data.compExpiry}`;
+export function validityDetails(data, separatorNeeded = false) {
+ const separator = separatorNeeded ? ' – ' : '';
+ const space = data.validUntil ? ' ' : '';
+
+ if (data.isComplimentary) {
+ if (data.compExpiry) {
+ return `${separator}Expires ${data.compExpiry}`;
+ } else {
+ return '';
+ }
}
if (data.hasEnded) {
- return `Ended ${data.validUntil}`;
+ return `${separator}Ended${space}${data.validUntil}`;
}
if (data.willEndSoon) {
- return `Has access until ${data.validUntil}`;
+ return `${separator}Has access until${space}${data.validUntil}`;
}
if (data.trialUntil) {
- return `Ends ${data.trialUntil}`;
+ return `${separator}Ends ${data.trialUntil}`;
}
- return `Renews ${data.validUntil}`;
+ return `${separator}Renews${space}${data.validUntil}`;
+}
+
+export function priceLabel(data) {
+ if (data.trialUntil) {
+ return 'Free trial';
+ }
+
+ if (data.price.nickname && data.price.nickname.length > 0 && data.price.nickname !== 'Monthly' && data.price.nickname !== 'Yearly') {
+ return data.price.nickname;
+ }
}
diff --git a/ghost/admin/tests/unit/utils/subscription-data-test.js b/ghost/admin/tests/unit/utils/subscription-data-test.js
index 5b396b20d8..660b4d72c4 100644
--- a/ghost/admin/tests/unit/utils/subscription-data-test.js
+++ b/ghost/admin/tests/unit/utils/subscription-data-test.js
@@ -1,5 +1,5 @@
import moment from 'moment-timezone';
-import {compExpiry, getSubscriptionData, isActive, isCanceled, isComplimentary, isSetToCancel, trialUntil, validUntil, validityDetails} from 'ghost-admin/utils/subscription-data';
+import {compExpiry, getSubscriptionData, isActive, isCanceled, isComplimentary, isSetToCancel, priceLabel, trialUntil, validUntil, validityDetails} from 'ghost-admin/utils/subscription-data';
import {describe, it} from 'mocha';
import {expect} from 'chai';
@@ -165,6 +165,26 @@ describe('Unit: Util: subscription-data', function () {
});
});
+ describe('priceLabel', function () {
+ it('returns "Free trial" for trial subscriptions', function () {
+ let data = {trialUntil: '31 May 2021'};
+ expect(priceLabel(data)).to.equal('Free trial');
+ });
+
+ it('returns nothing if the price nickname is the default "monthly" or "yearly"', function () {
+ let data = {price: {nickname: 'Monthly'}};
+ expect(priceLabel(data)).to.be.undefined;
+
+ data = {price: {nickname: 'Yearly'}};
+ expect(priceLabel(data)).to.be.undefined;
+ });
+
+ it('returns the price nickname for non-default prices', function () {
+ let data = {price: {nickname: 'Custom'}};
+ expect(priceLabel(data)).to.equal('Custom');
+ });
+ });
+
describe('validityDetails', function () {
it('returns "Expires {compExpiry}" for expired complimentary subscriptions', function () {
let data = {
@@ -174,6 +194,14 @@ describe('Unit: Util: subscription-data', function () {
expect(validityDetails(data)).to.equal('Expires 31 May 2021');
});
+ it('returns "" for forever complimentary subscriptions', function () {
+ let data = {
+ isComplimentary: true,
+ compExpiry: undefined
+ };
+ expect(validityDetails(data)).to.equal('');
+ });
+
it('returns "Ended {validUntil}" for canceled subscriptions', function () {
let data = {
hasEnded: true,
@@ -228,6 +256,7 @@ describe('Unit: Util: subscription-data', function () {
validUntil: '31 May 2021',
willEndSoon: false,
trialUntil: undefined,
+ priceLabel: undefined,
validityDetails: 'Renews 31 May 2021'
});
});
@@ -254,7 +283,8 @@ describe('Unit: Util: subscription-data', function () {
validUntil: '31 May 2222',
willEndSoon: false,
trialUntil: '31 May 2222',
- validityDetails: 'Ends 31 May 2222'
+ priceLabel: 'Free trial',
+ validityDetails: ' – Ends 31 May 2222'
});
});
@@ -280,7 +310,8 @@ describe('Unit: Util: subscription-data', function () {
validUntil: '',
willEndSoon: false,
trialUntil: undefined,
- validityDetails: 'Ended '
+ priceLabel: undefined,
+ validityDetails: 'Ended'
});
});
@@ -306,11 +337,42 @@ describe('Unit: Util: subscription-data', function () {
validUntil: '31 May 2021',
willEndSoon: true,
trialUntil: undefined,
+ priceLabel: undefined,
validityDetails: 'Has access until 31 May 2021'
});
});
- it('returns the correct data for a complimentary subscription', function () {
+ it('returns the correct data for a complimentary subscription active forever', function () {
+ let sub = {
+ id: null,
+ status: 'active',
+ cancel_at_period_end: false,
+ current_period_end: '2021-05-31',
+ trial_end_at: null,
+ tier: {
+ expiry_at: null
+ },
+ price: {
+ currency: 'usd',
+ amount: 0,
+ nickname: 'Complimentary'
+ }
+ };
+ let data = getSubscriptionData(sub);
+
+ expect(data).to.include({
+ isComplimentary: true,
+ compExpiry: undefined,
+ hasEnded: false,
+ validUntil: '31 May 2021',
+ willEndSoon: false,
+ trialUntil: undefined,
+ priceLabel: 'Complimentary',
+ validityDetails: ''
+ });
+ });
+
+ it('returns the correct data for a complimentary subscription with an expiration date', function () {
let sub = {
id: null,
status: 'active',
@@ -322,7 +384,8 @@ describe('Unit: Util: subscription-data', function () {
},
price: {
currency: 'usd',
- amount: 0
+ amount: 0,
+ nickname: 'Complimentary'
}
};
let data = getSubscriptionData(sub);
@@ -334,7 +397,8 @@ describe('Unit: Util: subscription-data', function () {
validUntil: '31 May 2021',
willEndSoon: false,
trialUntil: undefined,
- validityDetails: 'Expires 31 May 2021'
+ priceLabel: 'Complimentary',
+ validityDetails: ' – Expires 31 May 2021'
});
});
});
+
-
+
-
+ {{sub.price.currencySymbol}}
+ {{format-number sub.price.nonDecimalAmount}}
+
+ {{if (eq sub.price.interval "year") "yearly" "monthly"}}
{{if (eq sub.price.interval "year") "yearly" "monthly"}}
-
-
+
+
+
+ {{/if}}
+ - {{tier.name}} - {{#if (eq sub.status "canceled")}} - Canceled - {{else if sub.cancel_at_period_end}} - Canceled - {{else if sub.compExpiry}} - Active - {{else if sub.trialUntil}} - Active - {{else}} - Active - {{/if}} - {{#if (gt tier.subscriptions.length 1)}} - {{tier.subscriptions.length}} subscriptions - {{/if}} -
-
- {{#if sub.trialUntil}}
- Free trial
- {{else}}
- {{#if (or (eq sub.price.nickname "Monthly") (eq sub.price.nickname "Yearly"))}}
+
-
- {{#if sub.isComplimentary}}
-
- {{else}}
-
+
- + {{tier.name}} + {{#if (eq sub.status "canceled")}} + Canceled + {{else if sub.cancel_at_period_end}} + Canceled + {{else if sub.compExpiry}} + Active + {{else if sub.trialUntil}} + Active {{else}} - {{sub.price.nickname}} + Active {{/if}} - {{/if}} - - {{#if sub.trialUntil}} - – + {{#if (gt tier.subscriptions.length 1)}} + {{tier.subscriptions.length}} subscriptions + {{/if}} +
+
+ {{sub.priceLabel}}
{{sub.validityDetails}}
- {{/if}}
-
- {{#if sub.compExpiry}}
- –
- {{sub.validityDetails}}
- {{/if}}
-
-
+
+