Skip to content

Commit b57df69

Browse files
committed
feat(auth): update subscription reminders script for cron
Because: - The subscription reminders script needs to support daily subscription prices. This commit: - Optionally adds support for daily subscription prices, so that it can be toggled on and off where required. - Updates script to allow unsupported params. This was done to allow updates to the CRON jobs with new parameters, before those parameters have shipped. Closes #PAY-2294
1 parent 184f8f6 commit b57df69

File tree

6 files changed

+61
-1
lines changed

6 files changed

+61
-1
lines changed

libs/payments/stripe/src/lib/factories/subscription.factory.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { StripePriceFactory } from './price.factory';
77
import {
88
StripeSubscription,
99
StripeSubscriptionItem,
10+
type StripeApiListPromise,
1011
} from '../stripe.client.types';
1112

1213
export const StripeSubscriptionFactory = (

libs/payments/stripe/src/lib/stripe.client.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,18 @@ import { StripePaymentMethodFactory } from './factories/payment-method.factory';
1717
import { StripePriceFactory } from './factories/price.factory';
1818
import { StripeProductFactory } from './factories/product.factory';
1919
import { StripePromotionCodeFactory } from './factories/promotion-code.factory';
20-
import { StripeSubscriptionFactory } from './factories/subscription.factory';
20+
import {
21+
StripeSubscriptionAsyncGeneratorFactory,
22+
StripeSubscriptionFactory,
23+
} from './factories/subscription.factory';
2124
import { StripeUpcomingInvoiceFactory } from './factories/upcoming-invoice.factory';
2225
import { StripeClient } from './stripe.client';
2326
import { MockStripeConfigProvider } from './stripe.config';
2427
import { MockStatsDProvider } from '@fxa/shared/metrics/statsd';
28+
import type {
29+
StripeApiListPromise,
30+
StripeSubscription,
31+
} from './stripe.client.types';
2532

2633
const mockJestFnGenerator = <T extends (...args: any[]) => any>() => {
2734
return jest.fn<ReturnType<T>, Parameters<T>>();

packages/fxa-auth-server/lib/payments/initSubplat.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ export async function initSubplat({
216216
paypalCustomerManager,
217217
logger
218218
);
219+
219220
/**
220221
* Add initialized instances to Container
221222
*/

packages/fxa-auth-server/lib/payments/subscription-reminders.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const planIntervalsToDuration = {
3434
interface EndingRemindersOptions {
3535
enabled: boolean;
3636
paymentsNextUrl: string;
37+
dailyReminderDays?: number;
3738
monthlyReminderDays: number;
3839
yearlyReminderDays: number;
3940
}
@@ -45,6 +46,7 @@ export class SubscriptionReminders {
4546
private planDuration: Duration;
4647
private reminderDuration: Duration;
4748
private endingReminderEnabled: boolean;
49+
private dailyEndingReminderDuration: Duration | undefined;
4850
private monthlyEndingReminderDuration: Duration;
4951
private yearlyEndingReminderDuration: Duration;
5052
private paymentsNextUrl: string;
@@ -74,6 +76,11 @@ export class SubscriptionReminders {
7476
this.planDuration = Duration.fromObject({ days: planLength });
7577
this.reminderDuration = Duration.fromObject({ days: reminderLength });
7678
this.endingReminderEnabled = endingReminderOptions.enabled;
79+
if (endingReminderOptions.dailyReminderDays) {
80+
this.dailyEndingReminderDuration = Duration.fromObject({
81+
days: endingReminderOptions.dailyReminderDays,
82+
});
83+
}
7784
this.monthlyEndingReminderDuration = Duration.fromObject({
7885
days: endingReminderOptions.monthlyReminderDays,
7986
});
@@ -414,6 +421,13 @@ export class SubscriptionReminders {
414421

415422
// 4
416423
if (this.endingReminderEnabled) {
424+
// Daily
425+
if (this.dailyEndingReminderDuration) {
426+
await this.sendEndingReminders(
427+
this.dailyEndingReminderDuration,
428+
SubplatInterval.Daily
429+
);
430+
}
417431
// Monthly
418432
await this.sendEndingReminders(
419433
this.monthlyEndingReminderDuration,

packages/fxa-auth-server/scripts/subscription-reminders.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { parseBooleanArg } from './lib/args';
2020

2121
const DEFAULT_PLAN_LENGTH = 180;
2222
const DEFAULT_REMINDER_LENGTH = 14;
23+
const DEFAULT_ENDING_REMINDER_DAILY_LENGTH = 0;
2324
const DEFAULT_ENDING_REMINDER_MONTHLY_LENGTH = 7;
2425
const DEFAULT_ENDING_REMINDER_YEARLY_LENGTH = 14;
2526

@@ -28,6 +29,7 @@ Sentry.init({});
2829
async function init() {
2930
program
3031
.version(pckg.version)
32+
.allowUnknownOption(true)
3133
.option(
3234
'-p, --plan-length [days]',
3335
'Plan length in days beyond which a reminder email before the next recurring charge should be sent. Defaults to 180.',
@@ -43,6 +45,11 @@ async function init() {
4345
'Enable the sending of subscription ending reminder emails. Defaults to false.',
4446
false
4547
)
48+
.option(
49+
'-d, --ending-reminder-daily-length [days]',
50+
'Reminder length in days before the daily subscription ending date to send the reminder email. Defaults to 0.',
51+
DEFAULT_ENDING_REMINDER_DAILY_LENGTH.toString()
52+
)
4653
.option(
4754
'-m, --ending-reminder-monthly-length [days]',
4855
'Reminder length in days before the montly subscription ending date to send the reminder email. Defaults to 7.',
@@ -78,6 +85,7 @@ async function init() {
7885
{
7986
enabled: parseBooleanArg(program.enableEndingReminders),
8087
paymentsNextUrl: config.smtp.subscriptionSettingsUrl,
88+
dailyReminderDays: parseInt(program.endingReminderDailyLength),
8189
monthlyReminderDays: parseInt(program.endingReminderMonthlyLength),
8290
yearlyReminderDays: parseInt(program.endingReminderYearlyLength),
8391
},

packages/fxa-auth-server/test/local/payments/subscription-reminders.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const { SentEmail } = require('fxa-shared/db/models/auth/sent-email');
1616
const {
1717
EMAIL_TYPE,
1818
SubscriptionReminders,
19+
SubscriptionRemindersPlanRecurringError,
1920
} = require('../../../lib/payments/subscription-reminders');
2021
const invoicePreview = require('./fixtures/stripe/invoice_preview_tax.json');
2122
const longPlan1 = require('./fixtures/stripe/plan1.json');
@@ -60,6 +61,7 @@ describe('SubscriptionReminders', () => {
6061
let mockConfig;
6162
let realDateNow;
6263

64+
const mockDailyReminderDuration = undefined;
6365
const mockMonthlyReminderDuration = 7;
6466
const mockYearlyReminderDuration = 14;
6567

@@ -97,6 +99,7 @@ describe('SubscriptionReminders', () => {
9799
{
98100
enabled: false,
99101
paymentsNextUrl: 'http://localhost:3035',
102+
dailyReminderDays: mockDailyReminderDuration,
100103
monthlyReminderDays: mockMonthlyReminderDuration,
101104
yearlyReminderDays: mockYearlyReminderDuration,
102105
},
@@ -727,6 +730,32 @@ describe('SubscriptionReminders', () => {
727730
'yearly'
728731
);
729732
});
733+
734+
it('calls sendEndingReminders for daily if dailyEndingReminderDuration is provided', async () => {
735+
const mockDailyReminderDays = 3;
736+
reminder.sendEndingReminders = sandbox.fake.resolves({});
737+
reminder.endingReminderEnabled = true;
738+
reminder.dailyEndingReminderDuration = Duration.fromObject({
739+
days: mockDailyReminderDays,
740+
});
741+
await reminder.sendReminders();
742+
743+
sinon.assert.calledWith(
744+
reminder.sendEndingReminders,
745+
Duration.fromObject({ days: mockDailyReminderDays }),
746+
'daily'
747+
);
748+
sinon.assert.calledWith(
749+
reminder.sendEndingReminders,
750+
Duration.fromObject({ days: mockMonthlyReminderDuration }),
751+
'monthly'
752+
);
753+
sinon.assert.calledWith(
754+
reminder.sendEndingReminders,
755+
Duration.fromObject({ days: mockYearlyReminderDuration }),
756+
'yearly'
757+
);
758+
});
730759
});
731760

732761
describe('sendEndingReminders', () => {

0 commit comments

Comments
 (0)