mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
* Reapply "[web] Remove SubscriptionFormatters, format subscription dates in the…" This reverts commit 2939e71e5b919529cbb8a602916d5f597d117792. * Fixup after rename conflict: `nextPaymentDueDate`->`periodEnd` GitOrigin-RevId: c024a3a2cd08c1f8f9d4c99f9ba6f018d334439e
This commit is contained in:
+7
-3
@@ -22,6 +22,7 @@ import { reactivateSubscriptionUrl } from '../../../../../../frontend/js/feature
|
||||
import fetchMock from 'fetch-mock'
|
||||
import sinon from 'sinon'
|
||||
import { location } from '@/shared/components/location'
|
||||
import { formatPaymentDateTime } from '@/features/subscription/util/payment-dates'
|
||||
|
||||
describe('<PersonalSubscription />', function () {
|
||||
afterEach(function () {
|
||||
@@ -77,9 +78,12 @@ describe('<PersonalSubscription />', function () {
|
||||
'Your subscription has been canceled and will terminate on',
|
||||
{ exact: false }
|
||||
)
|
||||
screen.getByText(canceledSubscription.payment!.nextPaymentDueAt, {
|
||||
exact: false,
|
||||
})
|
||||
screen.getByText(
|
||||
formatPaymentDateTime(canceledSubscription.payment!.periodEnd)!,
|
||||
{
|
||||
exact: false,
|
||||
}
|
||||
)
|
||||
|
||||
screen.getByText('No further payments will be taken.', { exact: false })
|
||||
|
||||
|
||||
+12
-5
@@ -27,6 +27,10 @@ import {
|
||||
} from '@/features/subscription/data/subscription-url'
|
||||
import { location } from '@/shared/components/location'
|
||||
import { MetaTag } from '@/utils/meta'
|
||||
import {
|
||||
formatPaymentDate,
|
||||
formatPaymentDateTime,
|
||||
} from '@/features/subscription/util/payment-dates'
|
||||
|
||||
describe('<ActiveSubscription />', function () {
|
||||
let sendMBSpy: sinon.SinonSpy
|
||||
@@ -75,7 +79,7 @@ describe('<ActiveSubscription />', function () {
|
||||
within(screen.getByTestId('renews-on')).getByText((_, el) =>
|
||||
Boolean(
|
||||
el?.textContent?.includes(
|
||||
`Renews on ${subscription.payment.nextPaymentDueDate}`
|
||||
`Renews on ${formatPaymentDate(subscription.payment.periodEnd)}`
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -210,7 +214,7 @@ describe('<ActiveSubscription />', function () {
|
||||
within(screen.getByTestId('trial-ending')).getByText((_, el) =>
|
||||
Boolean(
|
||||
el?.textContent?.includes(
|
||||
`You’re on a free trial which ends on ${trialSubscription.payment.trialEndsAtFormatted}`
|
||||
`You’re on a free trial which ends on ${formatPaymentDateTime(trialSubscription.payment.trialEndsAt)}`
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -288,7 +292,7 @@ describe('<ActiveSubscription />', function () {
|
||||
{ exact: false }
|
||||
)
|
||||
const dates = screen.getAllByText(
|
||||
annualActiveSubscription.payment.nextPaymentDueAt,
|
||||
formatPaymentDate(annualActiveSubscription.payment.periodEnd)!,
|
||||
{
|
||||
exact: false,
|
||||
}
|
||||
@@ -307,7 +311,10 @@ describe('<ActiveSubscription />', function () {
|
||||
{ exact: false }
|
||||
)
|
||||
const dates = screen.getAllByText(
|
||||
trialSubscription.payment.trialEndsAtFormatted!
|
||||
formatPaymentDate(trialSubscription.payment.trialEndsAt)!,
|
||||
{
|
||||
exact: false,
|
||||
}
|
||||
)
|
||||
expect(dates.length).to.equal(3)
|
||||
const button = screen.getByRole('button', {
|
||||
@@ -401,7 +408,7 @@ describe('<ActiveSubscription />', function () {
|
||||
name: 'Are you sure you want to cancel?',
|
||||
})
|
||||
screen.getByText(
|
||||
`Cancelling will end your subscription on ${annualActiveSubscription.payment.nextPaymentDueDate}.`
|
||||
`Cancelling will end your subscription on ${formatPaymentDate(annualActiveSubscription.payment.periodEnd)}.`
|
||||
)
|
||||
screen.getByRole('heading', {
|
||||
name: 'You’ll be moved to the Free plan',
|
||||
|
||||
+2
-1
@@ -9,6 +9,7 @@ import {
|
||||
} from '../../fixtures/subscriptions'
|
||||
import { ExposedSettings } from '../../../../../../types/exposed-settings'
|
||||
import { UserProvider } from '@/shared/context/user-context'
|
||||
import { formatPaymentDateTime } from '@/features/subscription/util/payment-dates'
|
||||
|
||||
describe('successful subscription page', function () {
|
||||
it('renders the invoices link', function () {
|
||||
@@ -122,7 +123,7 @@ describe('successful subscription page', function () {
|
||||
.getByText(/the next payment of/i)
|
||||
.textContent?.replace(/\xA0/g, ' ')
|
||||
).to.equal(
|
||||
`The next payment of ${annualActiveSubscriptionPro.payment.displayPrice} will be collected on ${annualActiveSubscriptionPro.payment.nextPaymentDueAt}.`
|
||||
`The next payment of ${annualActiveSubscriptionPro.payment.displayPrice} will be collected on ${formatPaymentDateTime(annualActiveSubscriptionPro.payment.periodEnd)}.`
|
||||
)
|
||||
screen.getByText(/taxes may be added, depending on your billing address/i)
|
||||
|
||||
|
||||
@@ -3,17 +3,11 @@ import {
|
||||
GroupSubscription,
|
||||
PaidSubscription,
|
||||
} from '../../../../../types/subscription/dashboard/subscription'
|
||||
import dateformat from 'dateformat'
|
||||
|
||||
const today = new Date()
|
||||
const oneYearFromToday = new Date().setFullYear(today.getFullYear() + 1)
|
||||
const nextPaymentDueAt = dateformat(oneYearFromToday, 'dS mmmm yyyy')
|
||||
const nextPaymentDueDate = dateformat(oneYearFromToday, 'dS mmmm yyyy')
|
||||
const periodEnd = new Date(oneYearFromToday).toISOString()
|
||||
const sevenDaysFromToday = new Date().setDate(today.getDate() + 7)
|
||||
const sevenDaysFromTodayFormatted = dateformat(
|
||||
sevenDaysFromToday,
|
||||
'dS mmmm yyyy'
|
||||
)
|
||||
const sevenDaysFromTodayISO = new Date(sevenDaysFromToday).toISOString()
|
||||
|
||||
export const annualActiveSubscription: PaidSubscription = {
|
||||
manager_ids: ['abc123'],
|
||||
@@ -39,11 +33,9 @@ export const annualActiveSubscription: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -84,11 +76,9 @@ export const pastDueActiveSubscription: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'past_due',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -129,11 +119,9 @@ export const annualActiveSubscriptionWithCoupons: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [
|
||||
{ name: 'Coupon1', code: 'c1', description: 'Coupon1 for 10% off' },
|
||||
@@ -177,12 +165,10 @@ export const pendingPausedSubscription: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
remainingPauseCycles: 1,
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -223,12 +209,10 @@ export const pausedSubscription: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'paused',
|
||||
remainingPauseCycles: 1,
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -269,11 +253,9 @@ export const annualActiveSubscriptionWithAddons: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -317,11 +299,9 @@ export const annualActiveSubscriptionEuro: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'EUR',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -361,11 +341,9 @@ export const annualActiveSubscriptionPro: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -406,11 +384,9 @@ export const pastDueExpiredSubscription: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'expired',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -451,11 +427,9 @@ export const canceledSubscription: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'canceled',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -496,11 +470,9 @@ export const pendingAddOnChange: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -555,11 +527,9 @@ export const pendingSubscriptionChange: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -611,11 +581,9 @@ export const groupActiveSubscription: GroupSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 10,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -660,11 +628,9 @@ export const groupProfessionalActiveSubscription: GroupSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 10,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -710,11 +676,9 @@ export const groupActiveSubscriptionWithPendingLicenseChange: GroupSubscription
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 11,
|
||||
totalLicenses: 21,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
@@ -766,12 +730,10 @@ export const trialSubscription: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt: sevenDaysFromTodayFormatted,
|
||||
nextPaymentDueDate: sevenDaysFromTodayFormatted,
|
||||
periodEnd: sevenDaysFromTodayISO,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: sevenDaysFromTodayFormatted,
|
||||
trialEndsAt: new Date(sevenDaysFromToday).toString(),
|
||||
trialEndsAt: sevenDaysFromTodayISO,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'fake@example.com',
|
||||
hasPastDueInvoice: false,
|
||||
@@ -831,12 +793,10 @@ export const trialCollaboratorSubscription: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt: sevenDaysFromTodayFormatted,
|
||||
nextPaymentDueDate: sevenDaysFromTodayFormatted,
|
||||
periodEnd: sevenDaysFromTodayISO,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: sevenDaysFromTodayFormatted,
|
||||
trialEndsAt: new Date(sevenDaysFromToday).toString(),
|
||||
trialEndsAt: sevenDaysFromTodayISO,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'foo@example.com',
|
||||
hasPastDueInvoice: false,
|
||||
@@ -875,11 +835,9 @@ export const monthlyActiveCollaborator: PaidSubscription = {
|
||||
accountManagementLink: '/user/subscription/payment/account-management',
|
||||
additionalLicenses: 0,
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt,
|
||||
nextPaymentDueDate,
|
||||
periodEnd,
|
||||
currency: 'USD',
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'foo@example.com',
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { expect } from 'chai'
|
||||
import isInFreeTrial from '../../../../../frontend/js/features/subscription/util/is-in-free-trial'
|
||||
import dateformat from 'dateformat'
|
||||
|
||||
describe('isInFreeTrial', function () {
|
||||
it('returns false when no date sent', function () {
|
||||
@@ -15,10 +14,6 @@ describe('isInFreeTrial', function () {
|
||||
it('returns true when date is in the future', function () {
|
||||
const today = new Date()
|
||||
const sevenDaysFromToday = new Date().setDate(today.getDate() + 7)
|
||||
const sevenDaysFromTodayFormatted = dateformat(
|
||||
sevenDaysFromToday,
|
||||
'dS mmmm yyyy'
|
||||
)
|
||||
expect(isInFreeTrial(sevenDaysFromTodayFormatted)).to.be.true
|
||||
expect(isInFreeTrial(new Date(sevenDaysFromToday).toISOString())).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { expect } from 'chai'
|
||||
import {
|
||||
formatPaymentDate,
|
||||
formatPaymentDateTime,
|
||||
} from '../../../../../frontend/js/features/subscription/util/payment-dates'
|
||||
|
||||
describe('payment-dates', function () {
|
||||
describe('formatPaymentDate', function () {
|
||||
it('formats a date in UTC', function () {
|
||||
expect(formatPaymentDate('2025-02-20T12:00:00.000Z')).to.equal(
|
||||
'February 20th, 2025'
|
||||
)
|
||||
})
|
||||
it('returns null for missing dates', function () {
|
||||
expect(formatPaymentDate(null)).to.be.null
|
||||
expect(formatPaymentDate(undefined)).to.be.null
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatPaymentDateTime', function () {
|
||||
it('formats a date and time in UTC', function () {
|
||||
expect(formatPaymentDateTime('2025-02-20T12:00:00.000Z')).to.equal(
|
||||
'February 20th, 2025 12:00 PM UTC'
|
||||
)
|
||||
})
|
||||
it('returns null for missing dates', function () {
|
||||
expect(formatPaymentDateTime(null)).to.be.null
|
||||
expect(formatPaymentDateTime(undefined)).to.be.null
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,30 +0,0 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import SubscriptionFormatters from '../../../../app/src/Features/Subscription/SubscriptionFormatters.mjs'
|
||||
|
||||
describe('SubscriptionFormatters', function () {
|
||||
describe('formatDateTime', function () {
|
||||
it('should return null if no date', function () {
|
||||
const result = SubscriptionFormatters.formatDateTime(null)
|
||||
expect(result).to.equal(null)
|
||||
})
|
||||
|
||||
it('should format date with time', function () {
|
||||
const date = new Date(1639904485000)
|
||||
const result = SubscriptionFormatters.formatDateTime(date)
|
||||
expect(result).to.equal('December 19th, 2021 9:01 AM UTC')
|
||||
})
|
||||
})
|
||||
|
||||
describe('formatDate', function () {
|
||||
it('should return null if no date', function () {
|
||||
const result = SubscriptionFormatters.formatDate(null)
|
||||
expect(result).to.equal(null)
|
||||
})
|
||||
|
||||
it('should format date', function () {
|
||||
const date = new Date(1639904485000)
|
||||
const result = SubscriptionFormatters.formatDate(date)
|
||||
expect(result).to.equal('December 19th, 2021')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -745,12 +745,10 @@ describe('SubscriptionViewModelBuilder', function () {
|
||||
},
|
||||
],
|
||||
totalLicenses: 0,
|
||||
nextPaymentDueAt: 'February 20th, 2025 12:00 PM UTC',
|
||||
nextPaymentDueDate: 'February 20th, 2025',
|
||||
periodEnd: new Date('2025-02-20T12:00:00.000Z'),
|
||||
currency: 'EUR',
|
||||
planPrice: 13,
|
||||
state: 'active',
|
||||
trialEndsAtFormatted: null,
|
||||
trialEndsAt: null,
|
||||
activeCoupons: [],
|
||||
accountEmail: 'example@example.com',
|
||||
|
||||
Reference in New Issue
Block a user