Skip to content

Commit

Permalink
WIP - fix
Browse files Browse the repository at this point in the history
  • Loading branch information
xlisachan committed Jan 16, 2025
1 parent 73d418d commit 56dc183
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 320 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ export default async function UpgradeLayout({
cms.defaultPurchase.purchaseDetails.localizations.at(0) ||
cms.defaultPurchase.purchaseDetails;

const currentOfferingId = cart.fromOfferingConfigId;
const currentCmsDataPromise = fetchCMSData(currentOfferingId, locale);
const currentCmsDataPromise = fetchCMSData(cart.fromOfferingConfigId, locale);
const currentCms = await currentCmsDataPromise;
const currentPurchaseDetails =
currentCms.defaultPurchase.purchaseDetails.localizations.at(0) ||
Expand Down
16 changes: 0 additions & 16 deletions libs/payments/cart/src/lib/cart.error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,19 +163,3 @@ export class CartSuccessMissingRequired extends CartError {
});
}
}

export class CartUpgradeMissingRequired extends CartError {
constructor(cartId: string) {
super('Upgrade cart is missing required fields', {
cartId,
});
}
}

export class CartUpgradeNotValid extends CartError {
constructor(cartId: string) {
super('Upgrade cart does not have current plan', {
cartId,
});
}
}
15 changes: 15 additions & 0 deletions libs/payments/cart/src/lib/cart.factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
SuccessCart,
TaxAmount,
UpdateCart,
UpgradeCart,
WithContextCart,
} from './cart.types';

Expand Down Expand Up @@ -133,3 +134,17 @@ export const SuccessCartFactory = (
paymentInfo: PaymentInfoFactory(),
...override,
});

export const UpgradeCartFactory = (
override?: Partial<UpgradeCart>
): UpgradeCart => ({
...WithContextCartFactory(),
eligibilityStatus: CartEligibilityStatus.UPGRADE,
fromOfferingConfigId: faker.string.uuid(),
upgradeFromPrice: {
currency: faker.finance.currencyCode(),
interval: faker.helpers.arrayElement(['day', 'month', 'week', 'year']),
listAmount: faker.number.int({ max: 1000 }),
},
...override,
});
152 changes: 0 additions & 152 deletions libs/payments/cart/src/lib/cart.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ import {
} from '@fxa/profile/client';
import {
MockStrapiClientConfigProvider,
PageContentOfferingTransformedFactory,
ProductConfigurationManager,
StrapiClient,
} from '@fxa/shared/cms';
Expand Down Expand Up @@ -86,16 +85,13 @@ import { CartManager } from './cart.manager';
import { CartService } from './cart.service';
import { CheckoutService } from './checkout.service';
import {
CartEligibilityMismatchError,
CartError,
CartInvalidCurrencyError,
CartInvalidPromoCodeError,
CartInvalidStateForActionError,
CartStateProcessingError,
CartSubscriptionNotFoundError,
CartSuccessMissingRequired,
CartUpgradeMissingRequired,
CartUpgradeNotValid,
} from './cart.error';
import { CurrencyManager } from '@fxa/payments/currency';
import { MockCurrencyConfigProvider } from 'libs/payments/currency/src/lib/currency.config';
Expand Down Expand Up @@ -961,154 +957,6 @@ describe('CartService', () => {
});
});

describe('getUpgradeCart', () => {
it('returns cart with current plan and offering id', async () => {
const mockCart = ResultCartFactory({
stripeSubscriptionId: null,
eligibilityStatus: CartEligibilityStatus.UPGRADE,
});
const mockCustomer = StripeResponseFactory(StripeCustomerFactory());
const mockPrice = StripePriceFactory();
const mockInvoicePreview = InvoicePreviewFactory({
oneTimeCharge: 4500,
});
const mockCurrentPrice = StripePriceFactory();
const mockCurrentOffering = PageContentOfferingTransformedFactory();

jest.spyOn(cartManager, 'fetchCartById').mockResolvedValue(mockCart);
jest
.spyOn(productConfigurationManager, 'retrieveStripePrice')
.mockResolvedValue(mockPrice);
jest.spyOn(customerManager, 'retrieve').mockResolvedValue(mockCustomer);
jest.spyOn(eligibilityService, 'checkEligibility').mockResolvedValue({
subscriptionEligibilityResult: EligibilityStatus.UPGRADE,
fromOfferingConfigId: mockCurrentOffering.apiIdentifier,
upgradeFromPrice: mockCurrentPrice,
});
jest
.spyOn(invoiceManager, 'previewUpcomingForUpgrade')
.mockResolvedValue(mockInvoicePreview);

const result = await cartService.getUpgradeCart(mockCart.id);
expect(result).toEqual({
...mockCart,
upcomingInvoicePreview: mockInvoicePreview,
metricsOptedOut: false,
eligibilityStatus: CartEligibilityStatus.UPGRADE,
fromOfferingConfigId: mockCurrentOffering.apiIdentifier,
oneTimeCharge: 4500,
upgradeFromPrice: {
currency: mockCurrentPrice.currency,
interval: mockCurrentPrice.recurring?.interval,
listAmount: mockCurrentPrice.unit_amount,
},
});

expect(cartManager.fetchCartById).toHaveBeenCalledWith(mockCart.id);
expect(
productConfigurationManager.retrieveStripePrice
).toHaveBeenCalledWith(mockCart.offeringConfigId, mockCart.interval);
expect(customerManager.retrieve).toHaveBeenCalledWith(
mockCart.stripeCustomerId
);
expect(invoiceManager.previewUpcomingForUpgrade).toHaveBeenCalledWith({
priceId: mockPrice.id,
currency: mockCart.currency,
customer: mockCustomer,
taxAddress: mockCart.taxAddress,
upgradeFromPrice: mockCurrentPrice,
});
});

it('throws error if eligibility status is not upgrade for getUpgradeCart', async () => {
const mockCart = ResultCartFactory({
stripeSubscriptionId: null,
eligibilityStatus: CartEligibilityStatus.CREATE,
});
const mockCustomer = StripeResponseFactory(StripeCustomerFactory());
const mockPrice = StripePriceFactory();
const mockInvoicePreview = InvoicePreviewFactory({
oneTimeCharge: 4500,
});

jest.spyOn(cartManager, 'fetchCartById').mockResolvedValue(mockCart);
jest
.spyOn(productConfigurationManager, 'retrieveStripePrice')
.mockResolvedValue(mockPrice);
jest.spyOn(customerManager, 'retrieve').mockResolvedValue(mockCustomer);
jest.spyOn(eligibilityService, 'checkEligibility').mockResolvedValue({
subscriptionEligibilityResult: EligibilityStatus.CREATE,
});
jest
.spyOn(invoiceManager, 'previewUpcomingForUpgrade')
.mockResolvedValue(mockInvoicePreview);

await expect(
cartService.getUpgradeCart(mockCart.id)
).rejects.toThrowError(CartEligibilityMismatchError);
});

it('throws error if upgrade is missing offering id or price from current plan', async () => {
const mockCart = ResultCartFactory({
stripeSubscriptionId: null,
eligibilityStatus: CartEligibilityStatus.UPGRADE,
});
const mockCustomer = StripeResponseFactory(StripeCustomerFactory());
const mockPrice = StripePriceFactory();
const mockInvoicePreview = InvoicePreviewFactory({
oneTimeCharge: 4500,
});

jest.spyOn(cartManager, 'fetchCartById').mockResolvedValue(mockCart);
jest
.spyOn(productConfigurationManager, 'retrieveStripePrice')
.mockResolvedValue(mockPrice);
jest.spyOn(customerManager, 'retrieve').mockResolvedValue(mockCustomer);
jest.spyOn(eligibilityService, 'checkEligibility').mockResolvedValue({
subscriptionEligibilityResult: EligibilityStatus.UPGRADE,
});
jest
.spyOn(invoiceManager, 'previewUpcomingForUpgrade')
.mockResolvedValue(mockInvoicePreview);

await expect(
cartService.getUpgradeCart(mockCart.id)
).rejects.toThrowError(CartUpgradeNotValid);
});

it('throws error if upgrade is missing oneTimeCharge from invoice', async () => {
const mockCart = ResultCartFactory({
stripeSubscriptionId: null,
eligibilityStatus: CartEligibilityStatus.UPGRADE,
});
const mockCustomer = StripeResponseFactory(StripeCustomerFactory());
const mockPrice = StripePriceFactory();
const mockInvoicePreview = InvoicePreviewFactory({
oneTimeCharge: undefined,
});
const mockCurrentPrice = StripePriceFactory();
const mockCurrentOffering = PageContentOfferingTransformedFactory();

jest.spyOn(cartManager, 'fetchCartById').mockResolvedValue(mockCart);
jest
.spyOn(productConfigurationManager, 'retrieveStripePrice')
.mockResolvedValue(mockPrice);
jest.spyOn(customerManager, 'retrieve').mockResolvedValue(mockCustomer);
jest.spyOn(eligibilityService, 'checkEligibility').mockResolvedValue({
subscriptionEligibilityResult: EligibilityStatus.UPGRADE,
fromOfferingConfigId: mockCurrentOffering.apiIdentifier,
upgradeFromPrice: mockCurrentPrice,
});
jest
.spyOn(invoiceManager, 'previewUpcomingForUpgrade')
.mockResolvedValue(mockInvoicePreview);

await expect(
cartService.getUpgradeCart(mockCart.id)
).rejects.toThrowError(CartUpgradeMissingRequired);
});
});

describe('getSuccessCart', () => {
const mockSuccessCart = SuccessCartFactory();
it('should return success cart', async () => {
Expand Down
Loading

0 comments on commit 56dc183

Please sign in to comment.