@internetarchive/donation-monthly-portal 7.6.0 → 7.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -47,6 +47,7 @@ export declare class MonthlyPlan {
|
|
|
47
47
|
setAmount(newAmount: number): void;
|
|
48
48
|
get nextBillingDate(): string;
|
|
49
49
|
setNextBillingDate(newDate: string): void;
|
|
50
|
+
private formatDateUTC;
|
|
50
51
|
get nextBillingDateLocale(): string;
|
|
51
52
|
get lastBillingDateLocale(): string;
|
|
52
53
|
get hasBeenCancelled(): boolean;
|
package/dist/src/models/plan.js
CHANGED
|
@@ -34,29 +34,30 @@ export class MonthlyPlan {
|
|
|
34
34
|
this.payment.nextBillingDate.date = newDate;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
formatDateUTC(dateStr) {
|
|
38
|
+
const date = new Date(dateStr);
|
|
39
|
+
if (Number.isNaN(date.getTime()))
|
|
40
|
+
return 'Invalid date';
|
|
41
|
+
return new Intl.DateTimeFormat('en-US', {
|
|
42
|
+
year: 'numeric',
|
|
43
|
+
month: 'short',
|
|
44
|
+
day: 'numeric',
|
|
45
|
+
timeZone: 'UTC',
|
|
46
|
+
}).format(date);
|
|
47
|
+
}
|
|
37
48
|
get nextBillingDateLocale() {
|
|
38
49
|
var _a, _b;
|
|
39
50
|
const dateStr = (_b = (_a = this.payment) === null || _a === void 0 ? void 0 : _a.nextBillingDate.date) !== null && _b !== void 0 ? _b : '';
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
month: 'short',
|
|
44
|
-
day: 'numeric',
|
|
45
|
-
})
|
|
46
|
-
: 'not found';
|
|
47
|
-
return nextBillingDate;
|
|
51
|
+
if (!dateStr)
|
|
52
|
+
return 'not found';
|
|
53
|
+
return this.formatDateUTC(dateStr);
|
|
48
54
|
}
|
|
49
55
|
get lastBillingDateLocale() {
|
|
50
|
-
var _a;
|
|
51
|
-
|
|
56
|
+
var _a, _b;
|
|
57
|
+
const dateStr = (_b = (_a = this.payment) === null || _a === void 0 ? void 0 : _a.lastBillingDate.date) !== null && _b !== void 0 ? _b : '';
|
|
58
|
+
if (!dateStr)
|
|
52
59
|
return '';
|
|
53
|
-
|
|
54
|
-
const lastBillingDate = new Date(this.payment.lastBillingDate.date).toLocaleDateString(undefined, {
|
|
55
|
-
year: 'numeric',
|
|
56
|
-
month: 'short',
|
|
57
|
-
day: 'numeric',
|
|
58
|
-
});
|
|
59
|
-
return lastBillingDate !== null && lastBillingDate !== void 0 ? lastBillingDate : 'not found';
|
|
60
|
+
return this.formatDateUTC(dateStr);
|
|
60
61
|
}
|
|
61
62
|
get hasBeenCancelled() {
|
|
62
63
|
return this.plan.isCancelled === true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/models/plan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAyC1D,MAAM,OAAO,WAAW;IAKtB,YAAY,IAAU;;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,MAAA,IAAI,CAAC,QAAQ,mCAAI,KAAK,CAAC,CAAC,cAAc;IACxD,CAAC;IAED,IAAI,EAAE;QACJ,yBAAyB;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IACzB,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED,SAAS,CAAC,SAAiB;QACzB,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IAC/B,CAAC;IAED,IAAI,eAAe;;QACjB,uBAAuB;QACvB,OAAO,MAAA,MAAA,MAAA,IAAI,CAAC,OAAO,0CAAE,eAAe,0CAAE,IAAI,mCAAI,EAAE,CAAC;IACnD,CAAC;IAED,kBAAkB,CAAC,OAAe;QAChC,uBAAuB;QACvB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC;YACzE,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,GAAG,OAAO,CAAC;QAC9C,CAAC;IACH,CAAC;
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/models/plan.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PaymentMethodRequest } from './payment-method-request';\nimport { formatCurrency } from '../utils/currency-format';\n\nexport type BtData = {\n billingDayOfMonth: number;\n nextBillingDate: {\n date: string;\n timezone_type: number;\n timezone: string;\n oldDate?: string; // optional for updates ISO UTC date string\n };\n lastBillingDate: {\n date: string | null;\n timezone_type: number;\n timezone: string;\n };\n status: string; // active, inactive\n paymentMethodType: string; // cc, paypal, venmo, etc\n last4: string | null;\n cardType: string | null;\n expirationMonth: string | null;\n expirationYear: string | null;\n paypalEmail?: string;\n venmoUsername?: string;\n};\n\nexport type Plan = {\n token: string;\n amount: number;\n currency: string;\n start_date: string; // UTC\n is_test: boolean;\n btdata: BtData;\n oldAmount?: number;\n oldDate?: string;\n isCancelled?: boolean;\n processor_id?: string; // used when editing date\n oldProcessorId?: string;\n old_btData?: any;\n new_payment_method_details?: PaymentMethodRequest; // used when updating payment method\n};\n\nexport class MonthlyPlan {\n plan: Plan;\n\n currency: string;\n\n constructor(plan: Plan) {\n this.plan = plan;\n this.currency = plan.currency ?? 'USD'; // not in data\n }\n\n get id(): string {\n // use token as unique id\n return this.plan.token;\n }\n\n get amount(): number {\n return this.plan.amount;\n }\n\n get amountFormatted(): string {\n return formatCurrency(this.plan.amount, this.currency);\n }\n\n get payment(): BtData | null {\n return this.plan.btdata;\n }\n\n setAmount(newAmount: number) {\n this.plan.oldAmount = this.plan.amount;\n this.plan.amount = newAmount;\n }\n\n get nextBillingDate(): string {\n // iso08601 date string\n return this.payment?.nextBillingDate?.date ?? '';\n }\n\n setNextBillingDate(newDate: string) {\n // iso08601 date string\n if (this.payment) {\n this.payment.nextBillingDate.oldDate = this.payment.nextBillingDate.date;\n this.payment.nextBillingDate.date = newDate;\n }\n }\n\n private formatDateUTC(dateStr: string): string {\n const date = new Date(dateStr);\n if (Number.isNaN(date.getTime())) return 'Invalid date';\n return new Intl.DateTimeFormat('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n timeZone: 'UTC',\n }).format(date);\n }\n\n get nextBillingDateLocale(): string {\n const dateStr = this.payment?.nextBillingDate.date ?? '';\n if (!dateStr) return 'not found';\n return this.formatDateUTC(dateStr);\n }\n\n get lastBillingDateLocale(): string {\n const dateStr = this.payment?.lastBillingDate.date ?? '';\n if (!dateStr) return '';\n return this.formatDateUTC(dateStr);\n }\n\n get hasBeenCancelled(): boolean {\n return this.plan.isCancelled === true;\n }\n\n get isTest(): boolean {\n return this.plan.is_test;\n }\n\n cancelPlan(): void {\n this.plan.isCancelled = true;\n }\n\n setNewProcessorId(newProcessorId: string): void {\n const currentProcessorId = this.plan.processor_id;\n this.plan.processor_id = newProcessorId;\n this.plan.oldProcessorId = currentProcessorId;\n }\n\n setNewPaymentMethod(newPaymentMethodRequest: PaymentMethodRequest): void {\n const currentPaymentMethod = this.payment;\n const mergedBtData = {\n ...this.plan.btdata,\n ...newPaymentMethodRequest.paymentMethodInfo.details,\n ...{\n last4:\n newPaymentMethodRequest.paymentMethodInfo.details.lastFour ??\n 'unknown',\n },\n };\n this.plan.old_btData = currentPaymentMethod;\n this.plan.btdata = mergedBtData;\n }\n}\n"]}
|
|
@@ -110,6 +110,39 @@ describe('MonthlyPlan', () => {
|
|
|
110
110
|
const mp = new MonthlyPlan(makePlan({ btdata }));
|
|
111
111
|
expect(mp.nextBillingDateLocale).to.equal('not found');
|
|
112
112
|
});
|
|
113
|
+
it('formats dates in UTC to avoid timezone shift', () => {
|
|
114
|
+
const btdata = makeBtData({
|
|
115
|
+
nextBillingDate: {
|
|
116
|
+
date: '2024-09-01 00:00:00.000000',
|
|
117
|
+
timezone_type: 3,
|
|
118
|
+
timezone: 'UTC',
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
const mp = new MonthlyPlan(makePlan({ btdata }));
|
|
122
|
+
expect(mp.nextBillingDateLocale).to.equal('Sep 1, 2024');
|
|
123
|
+
});
|
|
124
|
+
it('returns "Invalid date" for an invalid date string', () => {
|
|
125
|
+
const btdata = makeBtData({
|
|
126
|
+
nextBillingDate: {
|
|
127
|
+
date: 'not-a-date',
|
|
128
|
+
timezone_type: 3,
|
|
129
|
+
timezone: 'UTC',
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
const mp = new MonthlyPlan(makePlan({ btdata }));
|
|
133
|
+
expect(mp.nextBillingDateLocale).to.equal('Invalid date');
|
|
134
|
+
});
|
|
135
|
+
it('returns "Invalid date" for an out-of-range date string', () => {
|
|
136
|
+
const btdata = makeBtData({
|
|
137
|
+
nextBillingDate: {
|
|
138
|
+
date: '2024-13-01',
|
|
139
|
+
timezone_type: 3,
|
|
140
|
+
timezone: 'UTC',
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
const mp = new MonthlyPlan(makePlan({ btdata }));
|
|
144
|
+
expect(mp.nextBillingDateLocale).to.equal('Invalid date');
|
|
145
|
+
});
|
|
113
146
|
});
|
|
114
147
|
describe('lastBillingDateLocale', () => {
|
|
115
148
|
it('returns a locale-formatted date string', () => {
|
|
@@ -123,6 +156,39 @@ describe('MonthlyPlan', () => {
|
|
|
123
156
|
const mp = new MonthlyPlan(makePlan({ btdata }));
|
|
124
157
|
expect(mp.lastBillingDateLocale).to.equal('');
|
|
125
158
|
});
|
|
159
|
+
it('formats dates in UTC to avoid timezone shift', () => {
|
|
160
|
+
const btdata = makeBtData({
|
|
161
|
+
lastBillingDate: {
|
|
162
|
+
date: '2024-07-01 00:00:00.000000',
|
|
163
|
+
timezone_type: 3,
|
|
164
|
+
timezone: 'UTC',
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
const mp = new MonthlyPlan(makePlan({ btdata }));
|
|
168
|
+
expect(mp.lastBillingDateLocale).to.equal('Jul 1, 2024');
|
|
169
|
+
});
|
|
170
|
+
it('returns "Invalid date" for an invalid date string', () => {
|
|
171
|
+
const btdata = makeBtData({
|
|
172
|
+
lastBillingDate: {
|
|
173
|
+
date: 'garbage',
|
|
174
|
+
timezone_type: 3,
|
|
175
|
+
timezone: 'UTC',
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
const mp = new MonthlyPlan(makePlan({ btdata }));
|
|
179
|
+
expect(mp.lastBillingDateLocale).to.equal('Invalid date');
|
|
180
|
+
});
|
|
181
|
+
it('returns "Invalid date" for an out-of-range date string', () => {
|
|
182
|
+
const btdata = makeBtData({
|
|
183
|
+
lastBillingDate: {
|
|
184
|
+
date: '2024-13-01',
|
|
185
|
+
timezone_type: 3,
|
|
186
|
+
timezone: 'UTC',
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
const mp = new MonthlyPlan(makePlan({ btdata }));
|
|
190
|
+
expect(mp.lastBillingDateLocale).to.equal('Invalid date');
|
|
191
|
+
});
|
|
126
192
|
});
|
|
127
193
|
describe('hasBeenCancelled', () => {
|
|
128
194
|
it('returns false by default', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.test.js","sourceRoot":"","sources":["../../../test/models/plan.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { PaymentProvider } from '@internetarchive/donation-form-data-models';\nimport { MonthlyPlan } from '../../src/models/plan';\nimport type { Plan, BtData } from '../../src/models/plan';\nimport { PaymentMethodRequest } from '../../src/models/payment-method-request';\n\nfunction makeBtData(overrides: Partial<BtData> = {}): BtData {\n return {\n billingDayOfMonth: 15,\n nextBillingDate: {\n date: '2024-08-15 00:00:00',\n timezone_type: 3,\n timezone: 'UTC',\n },\n lastBillingDate: {\n date: '2024-07-15 00:00:00',\n timezone_type: 3,\n timezone: 'UTC',\n },\n status: 'Active',\n paymentMethodType: 'CreditCard',\n last4: '1234',\n cardType: 'Visa',\n expirationMonth: '12',\n expirationYear: '2026',\n ...overrides,\n };\n}\n\nfunction makePlan(overrides: Partial<Plan> = {}): Plan {\n return {\n token: 'tok_plan_1',\n amount: 5,\n currency: 'USD',\n start_date: '2024-07-01 00:00:00',\n is_test: false,\n btdata: makeBtData(),\n ...overrides,\n };\n}\n\ndescribe('MonthlyPlan', () => {\n describe('constructor', () => {\n it('assigns the plan object', () => {\n const plan = makePlan();\n const mp = new MonthlyPlan(plan);\n expect(mp.plan).to.equal(plan);\n });\n\n it('sets currency from plan', () => {\n const mp = new MonthlyPlan(makePlan({ currency: 'EUR' }));\n expect(mp.currency).to.equal('EUR');\n });\n\n it('defaults currency to USD when not provided', () => {\n const plan = makePlan();\n (plan as any).currency = undefined;\n const mp = new MonthlyPlan(plan);\n expect(mp.currency).to.equal('USD');\n });\n });\n\n describe('id', () => {\n it('returns the plan token', () => {\n const mp = new MonthlyPlan(makePlan({ token: 'my-token' }));\n expect(mp.id).to.equal('my-token');\n });\n });\n\n describe('amount', () => {\n it('returns the plan amount as a number', () => {\n const mp = new MonthlyPlan(makePlan({ amount: 25 }));\n expect(mp.amount).to.equal(25);\n });\n });\n\n describe('amountFormatted', () => {\n it('returns currency-formatted amount for USD', () => {\n const mp = new MonthlyPlan(makePlan({ amount: 10 }));\n expect(mp.amountFormatted).to.equal('$10.00');\n });\n\n it('handles fractional amounts', () => {\n const mp = new MonthlyPlan(makePlan({ amount: 7.5 }));\n expect(mp.amountFormatted).to.equal('$7.50');\n });\n\n it('formats non-USD currency', () => {\n const mp = new MonthlyPlan(makePlan({ amount: 25, currency: 'EUR' }));\n expect(mp.amountFormatted).to.equal('€25.00');\n });\n });\n\n describe('payment', () => {\n it('returns btdata', () => {\n const btdata = makeBtData();\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.payment).to.equal(btdata);\n });\n });\n\n describe('nextBillingDate', () => {\n it('returns the ISO date string', () => {\n const mp = new MonthlyPlan(makePlan());\n expect(mp.nextBillingDate).to.equal('2024-08-15 00:00:00');\n });\n\n it('returns empty string when payment is null', () => {\n const mp = new MonthlyPlan(makePlan({ btdata: null as any }));\n expect(mp.nextBillingDate).to.equal('');\n });\n });\n\n describe('nextBillingDateLocale', () => {\n it('returns a locale-formatted date string', () => {\n const mp = new MonthlyPlan(makePlan());\n // Just verify it's a non-empty string (locale varies by environment)\n expect(mp.nextBillingDateLocale).to.be.a('string');\n expect(mp.nextBillingDateLocale).to.not.equal('not found');\n expect(mp.nextBillingDateLocale.length).to.be.greaterThan(0);\n });\n\n it('returns \"not found\" when date is empty', () => {\n const btdata = makeBtData();\n btdata.nextBillingDate.date = '';\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.nextBillingDateLocale).to.equal('not found');\n });\n });\n\n describe('lastBillingDateLocale', () => {\n it('returns a locale-formatted date string', () => {\n const mp = new MonthlyPlan(makePlan());\n expect(mp.lastBillingDateLocale).to.be.a('string');\n expect(mp.lastBillingDateLocale.length).to.be.greaterThan(0);\n });\n\n it('returns empty string when lastBillingDate.date is null', () => {\n const btdata = makeBtData();\n btdata.lastBillingDate.date = null;\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.lastBillingDateLocale).to.equal('');\n });\n });\n\n describe('hasBeenCancelled', () => {\n it('returns false by default', () => {\n const mp = new MonthlyPlan(makePlan());\n expect(mp.hasBeenCancelled).to.equal(false);\n });\n\n it('returns true when isCancelled is true', () => {\n const mp = new MonthlyPlan(makePlan({ isCancelled: true }));\n expect(mp.hasBeenCancelled).to.equal(true);\n });\n });\n\n describe('isTest', () => {\n it('returns the is_test value', () => {\n const mp = new MonthlyPlan(makePlan({ is_test: true }));\n expect(mp.isTest).to.equal(true);\n });\n });\n\n describe('setAmount', () => {\n it('updates the amount and stores old amount', () => {\n const mp = new MonthlyPlan(makePlan({ amount: 5 }));\n mp.setAmount(20);\n expect(mp.amount).to.equal(20);\n expect(mp.plan.oldAmount).to.equal(5);\n });\n });\n\n describe('setNextBillingDate', () => {\n it('updates the date and stores old date', () => {\n const mp = new MonthlyPlan(makePlan());\n const oldDate = mp.nextBillingDate;\n mp.setNextBillingDate('2024-09-01 00:00:00');\n expect(mp.nextBillingDate).to.equal('2024-09-01 00:00:00');\n expect(mp.payment?.nextBillingDate.oldDate).to.equal(oldDate);\n });\n\n it('does nothing when payment is null', () => {\n const mp = new MonthlyPlan(makePlan({ btdata: null as any }));\n mp.setNextBillingDate('2024-09-01 00:00:00');\n expect(mp.payment).to.equal(null);\n });\n });\n\n describe('cancelPlan', () => {\n it('sets isCancelled to true', () => {\n const mp = new MonthlyPlan(makePlan());\n expect(mp.hasBeenCancelled).to.equal(false);\n mp.cancelPlan();\n expect(mp.hasBeenCancelled).to.equal(true);\n });\n });\n\n describe('setNewProcessorId', () => {\n it('updates processor_id and stores old value', () => {\n const mp = new MonthlyPlan(makePlan({ processor_id: 'proc_old' }));\n mp.setNewProcessorId('proc_new');\n expect(mp.plan.processor_id).to.equal('proc_new');\n expect(mp.plan.oldProcessorId).to.equal('proc_old');\n });\n\n it('stores undefined as old when no previous processor_id', () => {\n const mp = new MonthlyPlan(makePlan());\n mp.setNewProcessorId('proc_new');\n expect(mp.plan.processor_id).to.equal('proc_new');\n expect(mp.plan.oldProcessorId).to.equal(undefined);\n });\n });\n\n describe('setNewPaymentMethod', () => {\n it('merges new payment method into btdata and stores old', () => {\n const mp = new MonthlyPlan(makePlan());\n const oldBtData = mp.payment;\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'New card',\n nonce: 'nonce_123',\n type: 'CreditCard',\n details: {\n cardType: 'Mastercard',\n lastFour: '5678',\n expirationMonth: '06',\n expirationYear: '2028',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n\n expect(mp.plan.old_btData).to.equal(oldBtData);\n expect(mp.plan.btdata.cardType).to.equal('Mastercard');\n expect(mp.plan.btdata.last4).to.equal('5678');\n expect(mp.plan.btdata.expirationMonth).to.equal('06');\n expect(mp.plan.btdata.expirationYear).to.equal('2028');\n // Existing fields preserved via spread\n expect(mp.plan.btdata.billingDayOfMonth).to.equal(15);\n });\n\n it('defaults last4 to \"unknown\" when lastFour is not provided', () => {\n const mp = new MonthlyPlan(makePlan());\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'PayPal',\n nonce: 'nonce_456',\n type: 'PayPal',\n details: {},\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n expect(mp.plan.btdata.last4).to.equal('unknown');\n });\n\n it('preserves nextBillingDate and lastBillingDate through the merge', () => {\n const mp = new MonthlyPlan(makePlan());\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'New card',\n nonce: 'nonce_789',\n type: 'CreditCard',\n details: {\n cardType: 'Amex',\n lastFour: '9999',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n\n expect(mp.plan.btdata.nextBillingDate.date).to.equal(\n '2024-08-15 00:00:00',\n );\n expect(mp.plan.btdata.lastBillingDate.date).to.equal(\n '2024-07-15 00:00:00',\n );\n });\n\n it('preserves status field through the merge', () => {\n const mp = new MonthlyPlan(makePlan());\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'New card',\n nonce: 'nonce_abc',\n type: 'CreditCard',\n details: {\n cardType: 'Visa',\n lastFour: '1111',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n expect(mp.plan.btdata.status).to.equal('Active');\n expect(mp.plan.btdata.paymentMethodType).to.equal('CreditCard');\n });\n\n it('stores old_btData as a snapshot when called twice', () => {\n const mp = new MonthlyPlan(makePlan());\n\n const firstRequest = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'First update',\n nonce: 'nonce_1',\n type: 'CreditCard',\n details: {\n cardType: 'Mastercard',\n lastFour: '2222',\n expirationMonth: '03',\n expirationYear: '2027',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(firstRequest);\n const afterFirstUpdate = mp.plan.btdata;\n\n const secondRequest = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'Second update',\n nonce: 'nonce_2',\n type: 'CreditCard',\n details: {\n cardType: 'Amex',\n lastFour: '3333',\n expirationMonth: '11',\n expirationYear: '2029',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(secondRequest);\n\n // old_btData should be the intermediate state, not the original\n expect(mp.plan.old_btData).to.equal(afterFirstUpdate);\n expect(mp.plan.btdata.cardType).to.equal('Amex');\n expect(mp.plan.btdata.last4).to.equal('3333');\n });\n\n it('handles PayPal details with paypalEmail on original btdata', () => {\n const btdata = makeBtData({\n paymentMethodType: 'PayPal',\n paypalEmail: 'donor@example.com',\n last4: null,\n cardType: null,\n });\n const mp = new MonthlyPlan(makePlan({ btdata }));\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'New PayPal',\n nonce: 'nonce_pp',\n type: 'PayPal',\n details: {\n description: 'new-donor@example.com',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n\n // paypalEmail from original btdata is preserved via spread\n expect(mp.plan.btdata.paypalEmail).to.equal('donor@example.com');\n expect(mp.plan.btdata.last4).to.equal('unknown');\n });\n\n it('handles Venmo details with venmoUsername on original btdata', () => {\n const btdata = makeBtData({\n paymentMethodType: 'Venmo',\n venmoUsername: '@donor',\n last4: null,\n cardType: null,\n });\n const mp = new MonthlyPlan(makePlan({ btdata }));\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'New Venmo',\n nonce: 'nonce_venmo',\n type: 'Venmo',\n details: {},\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n\n expect(mp.plan.btdata.venmoUsername).to.equal('@donor');\n expect(mp.plan.btdata.last4).to.equal('unknown');\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"plan.test.js","sourceRoot":"","sources":["../../../test/models/plan.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from '@open-wc/testing';\nimport { PaymentProvider } from '@internetarchive/donation-form-data-models';\nimport { MonthlyPlan } from '../../src/models/plan';\nimport type { Plan, BtData } from '../../src/models/plan';\nimport { PaymentMethodRequest } from '../../src/models/payment-method-request';\n\nfunction makeBtData(overrides: Partial<BtData> = {}): BtData {\n return {\n billingDayOfMonth: 15,\n nextBillingDate: {\n date: '2024-08-15 00:00:00',\n timezone_type: 3,\n timezone: 'UTC',\n },\n lastBillingDate: {\n date: '2024-07-15 00:00:00',\n timezone_type: 3,\n timezone: 'UTC',\n },\n status: 'Active',\n paymentMethodType: 'CreditCard',\n last4: '1234',\n cardType: 'Visa',\n expirationMonth: '12',\n expirationYear: '2026',\n ...overrides,\n };\n}\n\nfunction makePlan(overrides: Partial<Plan> = {}): Plan {\n return {\n token: 'tok_plan_1',\n amount: 5,\n currency: 'USD',\n start_date: '2024-07-01 00:00:00',\n is_test: false,\n btdata: makeBtData(),\n ...overrides,\n };\n}\n\ndescribe('MonthlyPlan', () => {\n describe('constructor', () => {\n it('assigns the plan object', () => {\n const plan = makePlan();\n const mp = new MonthlyPlan(plan);\n expect(mp.plan).to.equal(plan);\n });\n\n it('sets currency from plan', () => {\n const mp = new MonthlyPlan(makePlan({ currency: 'EUR' }));\n expect(mp.currency).to.equal('EUR');\n });\n\n it('defaults currency to USD when not provided', () => {\n const plan = makePlan();\n (plan as any).currency = undefined;\n const mp = new MonthlyPlan(plan);\n expect(mp.currency).to.equal('USD');\n });\n });\n\n describe('id', () => {\n it('returns the plan token', () => {\n const mp = new MonthlyPlan(makePlan({ token: 'my-token' }));\n expect(mp.id).to.equal('my-token');\n });\n });\n\n describe('amount', () => {\n it('returns the plan amount as a number', () => {\n const mp = new MonthlyPlan(makePlan({ amount: 25 }));\n expect(mp.amount).to.equal(25);\n });\n });\n\n describe('amountFormatted', () => {\n it('returns currency-formatted amount for USD', () => {\n const mp = new MonthlyPlan(makePlan({ amount: 10 }));\n expect(mp.amountFormatted).to.equal('$10.00');\n });\n\n it('handles fractional amounts', () => {\n const mp = new MonthlyPlan(makePlan({ amount: 7.5 }));\n expect(mp.amountFormatted).to.equal('$7.50');\n });\n\n it('formats non-USD currency', () => {\n const mp = new MonthlyPlan(makePlan({ amount: 25, currency: 'EUR' }));\n expect(mp.amountFormatted).to.equal('€25.00');\n });\n });\n\n describe('payment', () => {\n it('returns btdata', () => {\n const btdata = makeBtData();\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.payment).to.equal(btdata);\n });\n });\n\n describe('nextBillingDate', () => {\n it('returns the ISO date string', () => {\n const mp = new MonthlyPlan(makePlan());\n expect(mp.nextBillingDate).to.equal('2024-08-15 00:00:00');\n });\n\n it('returns empty string when payment is null', () => {\n const mp = new MonthlyPlan(makePlan({ btdata: null as any }));\n expect(mp.nextBillingDate).to.equal('');\n });\n });\n\n describe('nextBillingDateLocale', () => {\n it('returns a locale-formatted date string', () => {\n const mp = new MonthlyPlan(makePlan());\n // Just verify it's a non-empty string (locale varies by environment)\n expect(mp.nextBillingDateLocale).to.be.a('string');\n expect(mp.nextBillingDateLocale).to.not.equal('not found');\n expect(mp.nextBillingDateLocale.length).to.be.greaterThan(0);\n });\n\n it('returns \"not found\" when date is empty', () => {\n const btdata = makeBtData();\n btdata.nextBillingDate.date = '';\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.nextBillingDateLocale).to.equal('not found');\n });\n\n it('formats dates in UTC to avoid timezone shift', () => {\n const btdata = makeBtData({\n nextBillingDate: {\n date: '2024-09-01 00:00:00.000000',\n timezone_type: 3,\n timezone: 'UTC',\n },\n });\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.nextBillingDateLocale).to.equal('Sep 1, 2024');\n });\n\n it('returns \"Invalid date\" for an invalid date string', () => {\n const btdata = makeBtData({\n nextBillingDate: {\n date: 'not-a-date',\n timezone_type: 3,\n timezone: 'UTC',\n },\n });\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.nextBillingDateLocale).to.equal('Invalid date');\n });\n\n it('returns \"Invalid date\" for an out-of-range date string', () => {\n const btdata = makeBtData({\n nextBillingDate: {\n date: '2024-13-01',\n timezone_type: 3,\n timezone: 'UTC',\n },\n });\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.nextBillingDateLocale).to.equal('Invalid date');\n });\n });\n\n describe('lastBillingDateLocale', () => {\n it('returns a locale-formatted date string', () => {\n const mp = new MonthlyPlan(makePlan());\n expect(mp.lastBillingDateLocale).to.be.a('string');\n expect(mp.lastBillingDateLocale.length).to.be.greaterThan(0);\n });\n\n it('returns empty string when lastBillingDate.date is null', () => {\n const btdata = makeBtData();\n btdata.lastBillingDate.date = null;\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.lastBillingDateLocale).to.equal('');\n });\n\n it('formats dates in UTC to avoid timezone shift', () => {\n const btdata = makeBtData({\n lastBillingDate: {\n date: '2024-07-01 00:00:00.000000',\n timezone_type: 3,\n timezone: 'UTC',\n },\n });\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.lastBillingDateLocale).to.equal('Jul 1, 2024');\n });\n\n it('returns \"Invalid date\" for an invalid date string', () => {\n const btdata = makeBtData({\n lastBillingDate: {\n date: 'garbage',\n timezone_type: 3,\n timezone: 'UTC',\n },\n });\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.lastBillingDateLocale).to.equal('Invalid date');\n });\n\n it('returns \"Invalid date\" for an out-of-range date string', () => {\n const btdata = makeBtData({\n lastBillingDate: {\n date: '2024-13-01',\n timezone_type: 3,\n timezone: 'UTC',\n },\n });\n const mp = new MonthlyPlan(makePlan({ btdata }));\n expect(mp.lastBillingDateLocale).to.equal('Invalid date');\n });\n });\n\n describe('hasBeenCancelled', () => {\n it('returns false by default', () => {\n const mp = new MonthlyPlan(makePlan());\n expect(mp.hasBeenCancelled).to.equal(false);\n });\n\n it('returns true when isCancelled is true', () => {\n const mp = new MonthlyPlan(makePlan({ isCancelled: true }));\n expect(mp.hasBeenCancelled).to.equal(true);\n });\n });\n\n describe('isTest', () => {\n it('returns the is_test value', () => {\n const mp = new MonthlyPlan(makePlan({ is_test: true }));\n expect(mp.isTest).to.equal(true);\n });\n });\n\n describe('setAmount', () => {\n it('updates the amount and stores old amount', () => {\n const mp = new MonthlyPlan(makePlan({ amount: 5 }));\n mp.setAmount(20);\n expect(mp.amount).to.equal(20);\n expect(mp.plan.oldAmount).to.equal(5);\n });\n });\n\n describe('setNextBillingDate', () => {\n it('updates the date and stores old date', () => {\n const mp = new MonthlyPlan(makePlan());\n const oldDate = mp.nextBillingDate;\n mp.setNextBillingDate('2024-09-01 00:00:00');\n expect(mp.nextBillingDate).to.equal('2024-09-01 00:00:00');\n expect(mp.payment?.nextBillingDate.oldDate).to.equal(oldDate);\n });\n\n it('does nothing when payment is null', () => {\n const mp = new MonthlyPlan(makePlan({ btdata: null as any }));\n mp.setNextBillingDate('2024-09-01 00:00:00');\n expect(mp.payment).to.equal(null);\n });\n });\n\n describe('cancelPlan', () => {\n it('sets isCancelled to true', () => {\n const mp = new MonthlyPlan(makePlan());\n expect(mp.hasBeenCancelled).to.equal(false);\n mp.cancelPlan();\n expect(mp.hasBeenCancelled).to.equal(true);\n });\n });\n\n describe('setNewProcessorId', () => {\n it('updates processor_id and stores old value', () => {\n const mp = new MonthlyPlan(makePlan({ processor_id: 'proc_old' }));\n mp.setNewProcessorId('proc_new');\n expect(mp.plan.processor_id).to.equal('proc_new');\n expect(mp.plan.oldProcessorId).to.equal('proc_old');\n });\n\n it('stores undefined as old when no previous processor_id', () => {\n const mp = new MonthlyPlan(makePlan());\n mp.setNewProcessorId('proc_new');\n expect(mp.plan.processor_id).to.equal('proc_new');\n expect(mp.plan.oldProcessorId).to.equal(undefined);\n });\n });\n\n describe('setNewPaymentMethod', () => {\n it('merges new payment method into btdata and stores old', () => {\n const mp = new MonthlyPlan(makePlan());\n const oldBtData = mp.payment;\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'New card',\n nonce: 'nonce_123',\n type: 'CreditCard',\n details: {\n cardType: 'Mastercard',\n lastFour: '5678',\n expirationMonth: '06',\n expirationYear: '2028',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n\n expect(mp.plan.old_btData).to.equal(oldBtData);\n expect(mp.plan.btdata.cardType).to.equal('Mastercard');\n expect(mp.plan.btdata.last4).to.equal('5678');\n expect(mp.plan.btdata.expirationMonth).to.equal('06');\n expect(mp.plan.btdata.expirationYear).to.equal('2028');\n // Existing fields preserved via spread\n expect(mp.plan.btdata.billingDayOfMonth).to.equal(15);\n });\n\n it('defaults last4 to \"unknown\" when lastFour is not provided', () => {\n const mp = new MonthlyPlan(makePlan());\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'PayPal',\n nonce: 'nonce_456',\n type: 'PayPal',\n details: {},\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n expect(mp.plan.btdata.last4).to.equal('unknown');\n });\n\n it('preserves nextBillingDate and lastBillingDate through the merge', () => {\n const mp = new MonthlyPlan(makePlan());\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'New card',\n nonce: 'nonce_789',\n type: 'CreditCard',\n details: {\n cardType: 'Amex',\n lastFour: '9999',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n\n expect(mp.plan.btdata.nextBillingDate.date).to.equal(\n '2024-08-15 00:00:00',\n );\n expect(mp.plan.btdata.lastBillingDate.date).to.equal(\n '2024-07-15 00:00:00',\n );\n });\n\n it('preserves status field through the merge', () => {\n const mp = new MonthlyPlan(makePlan());\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'New card',\n nonce: 'nonce_abc',\n type: 'CreditCard',\n details: {\n cardType: 'Visa',\n lastFour: '1111',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n expect(mp.plan.btdata.status).to.equal('Active');\n expect(mp.plan.btdata.paymentMethodType).to.equal('CreditCard');\n });\n\n it('stores old_btData as a snapshot when called twice', () => {\n const mp = new MonthlyPlan(makePlan());\n\n const firstRequest = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'First update',\n nonce: 'nonce_1',\n type: 'CreditCard',\n details: {\n cardType: 'Mastercard',\n lastFour: '2222',\n expirationMonth: '03',\n expirationYear: '2027',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(firstRequest);\n const afterFirstUpdate = mp.plan.btdata;\n\n const secondRequest = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'Second update',\n nonce: 'nonce_2',\n type: 'CreditCard',\n details: {\n cardType: 'Amex',\n lastFour: '3333',\n expirationMonth: '11',\n expirationYear: '2029',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(secondRequest);\n\n // old_btData should be the intermediate state, not the original\n expect(mp.plan.old_btData).to.equal(afterFirstUpdate);\n expect(mp.plan.btdata.cardType).to.equal('Amex');\n expect(mp.plan.btdata.last4).to.equal('3333');\n });\n\n it('handles PayPal details with paypalEmail on original btdata', () => {\n const btdata = makeBtData({\n paymentMethodType: 'PayPal',\n paypalEmail: 'donor@example.com',\n last4: null,\n cardType: null,\n });\n const mp = new MonthlyPlan(makePlan({ btdata }));\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'New PayPal',\n nonce: 'nonce_pp',\n type: 'PayPal',\n details: {\n description: 'new-donor@example.com',\n },\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n\n // paypalEmail from original btdata is preserved via spread\n expect(mp.plan.btdata.paypalEmail).to.equal('donor@example.com');\n expect(mp.plan.btdata.last4).to.equal('unknown');\n });\n\n it('handles Venmo details with venmoUsername on original btdata', () => {\n const btdata = makeBtData({\n paymentMethodType: 'Venmo',\n venmoUsername: '@donor',\n last4: null,\n cardType: null,\n });\n const mp = new MonthlyPlan(makePlan({ btdata }));\n\n const request = new PaymentMethodRequest({\n paymentMethodInfo: {\n description: 'New Venmo',\n nonce: 'nonce_venmo',\n type: 'Venmo',\n details: {},\n },\n donorContactInfo: {},\n paymentProvider: PaymentProvider.CreditCard,\n });\n\n mp.setNewPaymentMethod(request);\n\n expect(mp.plan.btdata.venmoUsername).to.equal('@donor');\n expect(mp.plan.btdata.last4).to.equal('unknown');\n });\n });\n});\n"]}
|
package/package.json
CHANGED
package/src/models/plan.ts
CHANGED
|
@@ -85,31 +85,27 @@ export class MonthlyPlan {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
private formatDateUTC(dateStr: string): string {
|
|
89
|
+
const date = new Date(dateStr);
|
|
90
|
+
if (Number.isNaN(date.getTime())) return 'Invalid date';
|
|
91
|
+
return new Intl.DateTimeFormat('en-US', {
|
|
92
|
+
year: 'numeric',
|
|
93
|
+
month: 'short',
|
|
94
|
+
day: 'numeric',
|
|
95
|
+
timeZone: 'UTC',
|
|
96
|
+
}).format(date);
|
|
97
|
+
}
|
|
98
|
+
|
|
88
99
|
get nextBillingDateLocale(): string {
|
|
89
100
|
const dateStr = this.payment?.nextBillingDate.date ?? '';
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
year: 'numeric',
|
|
93
|
-
month: 'short',
|
|
94
|
-
day: 'numeric',
|
|
95
|
-
})
|
|
96
|
-
: 'not found';
|
|
97
|
-
return nextBillingDate;
|
|
101
|
+
if (!dateStr) return 'not found';
|
|
102
|
+
return this.formatDateUTC(dateStr);
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
get lastBillingDateLocale(): string {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const lastBillingDate = new Date(
|
|
106
|
-
this.payment.lastBillingDate.date,
|
|
107
|
-
).toLocaleDateString(undefined, {
|
|
108
|
-
year: 'numeric',
|
|
109
|
-
month: 'short',
|
|
110
|
-
day: 'numeric',
|
|
111
|
-
});
|
|
112
|
-
return lastBillingDate ?? 'not found';
|
|
106
|
+
const dateStr = this.payment?.lastBillingDate.date ?? '';
|
|
107
|
+
if (!dateStr) return '';
|
|
108
|
+
return this.formatDateUTC(dateStr);
|
|
113
109
|
}
|
|
114
110
|
|
|
115
111
|
get hasBeenCancelled(): boolean {
|