diff --git a/blocks/subscriptions-block/_index.scss b/blocks/subscriptions-block/_index.scss
index f58a46ee1c..c380d4f7ef 100644
--- a/blocks/subscriptions-block/_index.scss
+++ b/blocks/subscriptions-block/_index.scss
@@ -136,24 +136,40 @@
@include scss.block-properties("checkout-payment");
}
- &__test {
- &-1 {
- @include scss.block-components("checkout-payment-test-1");
- @include scss.block-properties("checkout-payment-test-1");
+ &__orderCard {
+ &--productPrice {
+ @include scss.block-components("checkout-order-card-productPrice");
+ @include scss.block-properties("checkout-order-card-productPrice");
}
- &-2 {
- @include scss.block-components("checkout-payment-test-2");
- @include scss.block-properties("checkout-payment-test-2");
+ &__card--features {
+ &--feature-item {
+ @include scss.block-components("checkout-order-card--features--item");
+ @include scss.block-properties("checkout-order-card--features--item");
+ }
+ @include scss.block-components("checkout-order-card--features");
+ @include scss.block-properties("checkout-order-card--features");
}
- &-row {
- @include scss.block-components("checkout-payment-test-row");
- @include scss.block-properties("checkout-payment-test-row");
+ &__summary {
+ &--dueToday{
+ @include scss.block-components("checkout-order-card--summary--dueToday");
+ @include scss.block-properties("checkout-order-card--summary--dueToday");
+ }
+ &--details{
+ &--item{
+ @include scss.block-components("checkout-order-card--summary--details--item");
+ @include scss.block-properties("checkout-order-card--summary--details--item");
+ }
+ @include scss.block-components("checkout-order-card--summary--details");
+ @include scss.block-properties("checkout-order-card--summary--details");
+ }
+ @include scss.block-components("checkout-order-card--summary");
+ @include scss.block-properties("checkout-order-card--summary");
}
- @include scss.block-components("checkout-payment-test");
- @include scss.block-properties("checkout-payment-test");
+ @include scss.block-components("checkout-order-card");
+ @include scss.block-properties("checkout-order-card");
}
@include scss.block-components("checkout");
diff --git a/blocks/subscriptions-block/components/OfferCard/index.jsx b/blocks/subscriptions-block/components/OfferCard/index.jsx
index 7cd4adb89d..f026511480 100644
--- a/blocks/subscriptions-block/components/OfferCard/index.jsx
+++ b/blocks/subscriptions-block/components/OfferCard/index.jsx
@@ -2,7 +2,25 @@ import React from "react";
import PropTypes from "@arc-fusion/prop-types";
import { Heading, Button, Stack, Paragraph, Icon } from "@wpmedia/arc-themes-components";
-// TO-DO: Change the Icon
{phrases.t("checkout-block.subtotal")}
+{`${currency(orderDetails?.currency)}${orderDetails?.subtotal}`}
+{phrases.t("checkout-block.salesTax")}
++ {orderDetails?.tax > 0 + ? `${currency(orderDetails?.currency)}${orderDetails?.tax}` + : "--"} +
+{phrases.t("checkout-block.due-today")}
+{`${currency(orderDetails?.currency)}${orderDetails?.total}`}
+with tax description price
", + priceName: "All access Annual", + priceSummary: "with tax summary price
", + productDescription: "COP Currency description
", + quantity: 1, + shortDescription: "COP Currency description
", + sku: "0987", + subtotal: 20100, + tax: 0, + taxInclusive: undefined, + total: 20000, + productAttributes: [ + { + featureText: "Unlimited access to The Daily Intelligencer
", + }, + { + featureText: "Save $40
", + }, + { + featureText: "A bonus subscription to share
", + }, + ], + }, + ], +}; + +jest.mock("@arc-publishing/sdk-identity", () => ({ + __esModule: true, + default: { + apiOrigin: "", + options: jest.fn(), + }, +})); + +jest.mock("fusion:properties", () => + jest.fn(() => ({ + api: { + identity: { + origin: "https://corecomponents-arc-demo-3-prod.api.cdn.arcpublishing.com", + }, + retail: { + origin: "https://corecomponents-arc-demo-3-prod.api.cdn.arcpublishing.com", + endpoint: "/retail/public/v1/offer/live/", + }, + }, + })), +); + +jest.mock("fusion:context", () => ({ + __esModule: true, + useFusionContext: () => ({ + arcSite: "Test Site", + }), +})); + +const className = 'checkout'; + +describe('Order Information component', () => { + it("renders order info", () => { + const showProductF = true; + render( +Free trial: first month free, then $10/mo
", - pageTitle: "Default subscription
", - templateName: "bottom-drawer", - campaigns: [ - { - canRenew: true, - canRestart: true, - canStart: true, - name: "augpromo", - validFrom: 1629216600000, - validUntil: 1630468800000, - }, - ], - products: [ - { - sku: "premium", - description: "Get access to premium content
", - image: null, - imageAction: null, - name: "Premium Content", - thumbnail: null, - maxSubscriptionAssociations: 0, - attributes: [ - { - name: "p", - value: "get access to sports, business, cooking sections
", - }, - ], - pricingStrategies: [ - { - pricingStrategyId: 1169, - priceCode: "1B1HCQ", - name: "Premium free trial", - description: "free trial price
", - gift: false, - summary: null, - currencyCode: "USD", - currencyDisplayFormat: "symbol", - currencyLocale: "en-US", - rates: [ - { - amount: "0.00", - billingCount: 1, - billingFrequency: "Month", - durationCount: 1, - duration: "Month", - }, - { - amount: "10.00", - billingCount: 1, - billingFrequency: "Month", - durationCount: 1, - duration: "UntilCancelled", - }, - ], - taxInclusive: false, - }, - { - pricingStrategyId: 1168, - priceCode: "H7SCJB", - name: "premium all access", - description: "Get access to premium content for a low rate
", - gift: false, - summary: null, - currencyCode: "USD", - currencyDisplayFormat: "symbol", - currencyLocale: "en-US", - rates: [ - { - amount: "10.00", - billingCount: 1, - billingFrequency: "Month", - durationCount: 1, - duration: "UntilCancelled", - }, - ], - taxInclusive: false, - }, - ], - defaultSwgProduct: false, - }, - ], - attributes: [], - default: true, -}; - -function TestOfferComponent({ code }) { - const { offer, isFetching, error } = useOffer({ - campaignCode: code, - }); - if (error) { - returnFree trial: first month free, then $10/mo
", + pageTitle: "Default subscription
", + templateName: "bottom-drawer", + campaigns: [ + { + canRenew: true, + canRestart: true, + canStart: true, + name: "augpromo", + validFrom: 1629216600000, + validUntil: 1630468800000, + }, + ], + products: [ + { + sku: "premium", + description: "Get access to premium content
", + image: null, + imageAction: null, + name: "Premium Content", + thumbnail: null, + maxSubscriptionAssociations: 0, + attributes: [ + { + name: "p", + value: "get access to sports, business, cooking sections
", + }, + ], + pricingStrategies: [ + { + pricingStrategyId: 1169, + priceCode: "1B1HCQ", + name: "Premium free trial", + description: "free trial price
", + gift: false, + summary: null, + currencyCode: "USD", + currencyDisplayFormat: "symbol", + currencyLocale: "en-US", + rates: [ + { + amount: "0.00", + billingCount: 1, + billingFrequency: "Month", + durationCount: 1, + duration: "Month", + }, + { + amount: "10.00", + billingCount: 1, + billingFrequency: "Month", + durationCount: 1, + duration: "UntilCancelled", + }, + ], + taxInclusive: false, + }, + { + pricingStrategyId: 1168, + priceCode: "H7SCJB", + name: "premium all access", + description: "Get access to premium content for a low rate
", + gift: false, + summary: null, + currencyCode: "USD", + currencyDisplayFormat: "symbol", + currencyLocale: "en-US", + rates: [ + { + amount: "10.00", + billingCount: 1, + billingFrequency: "Month", + durationCount: 1, + duration: "UntilCancelled", + }, + ], + taxInclusive: false, + }, + ], + defaultSwgProduct: false, + }, + ], + attributes: [], + default: true, +}; + +global.fetch = jest.fn(() => + Promise.resolve({ + json: () => Promise.resolve(testOfferResponse), + }), +); + +jest.mock("fusion:properties", () => { + const retailOrigin = "https://corecomponents-arc-demo-3-prod.api.cdn.arcpublishing.com"; + const retailEndpoint = "/retail/public/v1/offer/live/"; + return jest.fn(() => ({ + __esModule: true, + api: { + retail: { + origin: retailOrigin, + endpoint: retailEndpoint, + }, + }, + })); +}); + +describe("useOffer", () => { + beforeEach(() => { + jest.resetModules(); + jest.clearAllMocks(); + }); + + it("useOffer hook runs correctly", async () => { + const { result } = renderHook(() => useOffer({ campaignCode: "default" })); + + expect(result.current.error).toBe(null); + expect(result.current.offer).toBe(null); + expect(result.current.isFetching).toBe(true); + + await waitFor(() => expect(result.current.error).toEqual(null)); + await waitFor(() => expect(result.current.offer).toEqual(testOfferResponse)); + await waitFor(() => expect(result.current.isFetching).toEqual(false)); + }); + + it("use offer uses fallback default string", async () => { + const { result } = renderHook(() => useOffer({ campaignCode: "" })); + + expect(result.current.error).toBe(null); + expect(result.current.offer).toBe(null); + expect(result.current.isFetching).toBe(true); + + await waitFor(() => expect(result.current.error).toEqual(null)); + await waitFor(() => expect(result.current.offer).toEqual(testOfferResponse)); + await waitFor(() => expect(result.current.isFetching).toEqual(false)); + }); + + it("useOffer hook handles an error state during fetch", async () => { + global.fetch = jest.fn().mockRejectedValue(new Error("fetch error")); + + const { result } = renderHook(() => useOffer({ campaignCode: "default" })); + + expect(result.current.error).toBe(null); + expect(result.current.offer).toBe(null); + expect(result.current.isFetching).toBe(true); + + await waitFor(() => + expect(result.current.error).toEqual("Error in fetching retail offers: Error: fetch error"), + ); + await waitFor(() => expect(result.current.offer).toEqual(null)); + await waitFor(() => expect(result.current.isFetching).toEqual(false)); + }); + + it("useOffer hook handles an error state during fetch", async () => { + global.fetch = jest.fn().mockRejectedValue(new Error("fetch error")); + + const { result } = renderHook(() => useOffer({ campaignCode: "default" })); + + expect(result.current.error).toBe(null); + expect(result.current.offer).toBe(null); + expect(result.current.isFetching).toBe(true); + + await waitFor(() => + expect(result.current.error).toEqual("Error in fetching retail offers: Error: fetch error"), + ); + await waitFor(() => expect(result.current.offer).toEqual(null)); + await waitFor(() => expect(result.current.isFetching).toEqual(false)); + }); +}); + diff --git a/blocks/subscriptions-block/components/useOrder.jsx b/blocks/subscriptions-block/components/useOrder.jsx new file mode 100644 index 0000000000..766bf8913e --- /dev/null +++ b/blocks/subscriptions-block/components/useOrder.jsx @@ -0,0 +1,152 @@ +import { useState, useEffect } from "react"; + +import { useSales } from "@wpmedia/arc-themes-components"; +import { ARCXP_CAMPAIGN } from "./OfferToProductList"; +import useOffer from "./useOffer"; + +const useOrder = (orderNumber) => { + const { Sales } = useSales(); + + const [order, setOrder] = useState(); + const [orderDetails, setOrderDetails] = useState(); + const [cart, setCart] = useState(); + const [cartDetails, setCartDetails] = useState(); + const [error, setError] = useState(); + + const [campaignName, setCampaignName] = useState(); + + const { offer } = useOffer({ + campaignCode: campaignName, + }); + + useEffect(() => { + const getCart = async () => { + try { + const currentCart = await Sales.getCart(); + if(currentCart?.items?.length){ + setCart(currentCart); + } + } catch (e) { + setError(e); + } + }; + getCart(); + + const campaignNameStored = localStorage.getItem(ARCXP_CAMPAIGN); + setCampaignName(campaignNameStored); + // eslint-disable-next-line + }, []); + + useEffect(() => { + const getOrder = async () => { + try { + const currentOrder = await Sales.getOrderDetails(orderNumber); + if(currentOrder?.items?.length){ + setOrder(currentOrder); + } + } catch (e) { + setError(e); + } + }; + if (orderNumber) { + getOrder(); + } + // eslint-disable-next-line + }, [orderNumber]); + + useEffect(() => { + const getProductPriceDetailsFromOffer = (sku, priceCode) => { + let productAttributes; + let productDescription; + let priceName; + let priceDescription; + let priceSummary; + let rates; + + const productBySku = offer?.products?.find((item) => item?.sku === sku); + + if (productBySku) { + productAttributes = + typeof productBySku?.attributes !== "undefined" && productBySku?.attributes?.length !== 0 + ? productBySku?.attributes.map((feature) => ({ + featureText: feature.value, + })) + : []; + productDescription = productBySku?.description; + const pricingStrategy = productBySku?.pricingStrategies?.find( + (price) => price?.priceCode === priceCode, + ); + + priceName = pricingStrategy?.name; + priceDescription = pricingStrategy?.description; + priceSummary = pricingStrategy?.summary; + rates = pricingStrategy?.rates; + } + + return { + productAttributes, + productDescription, + priceName, + priceDescription, + priceSummary, + rates, + }; + }; + + if (offer) { + if (order) { + const itemsDetail = order?.items?.map((item) => { + const { + productAttributes, + productDescription, + priceName, + priceDescription, + priceSummary, + rates, + } = getProductPriceDetailsFromOffer(item?.sku, item?.priceCode); + return { + ...item, + productAttributes, + productDescription, + priceName, + priceDescription, + priceSummary, + rates, + }; + }); + setOrderDetails({ ...order, items: itemsDetail }); + } else if (cart) { + const itemsDetail = cart?.items?.map((item) => { + const { + productAttributes, + productDescription, + priceName, + priceDescription, + priceSummary, + rates, + taxInclusive, + } = getProductPriceDetailsFromOffer(item?.sku, item?.priceCode); + return { + ...item, + productAttributes, + productDescription, + priceName, + priceDescription, + priceSummary, + rates, + taxInclusive, + }; + }); + setCartDetails({ ...cart, items: itemsDetail }); + } + } + }, [order, cart, offer]); + + return { + cartDetails, + orderDetails, + error, + }; +}; + +export default useOrder; diff --git a/blocks/subscriptions-block/components/useOrder.test.jsx b/blocks/subscriptions-block/components/useOrder.test.jsx new file mode 100644 index 0000000000..1290d634a5 --- /dev/null +++ b/blocks/subscriptions-block/components/useOrder.test.jsx @@ -0,0 +1,387 @@ +import { useSales } from "@wpmedia/arc-themes-components"; +import { waitFor, renderHook } from "@testing-library/react"; + +import useOrder from "./useOrder"; +import useOffer from "./useOffer"; + +// Mock setTimeout and clearTimeout +jest.useFakeTimers(); + +jest.mock("@arc-publishing/sdk-identity", () => ({ + __esModule: true, + default: { + apiOrigin: "", + options: jest.fn(), + }, +})); + +jest.mock("fusion:properties", () => + jest.fn(() => ({ + api: { + identity: { + origin: "https://corecomponents-arc-demo-3-prod.api.cdn.arcpublishing.com", + }, + retail: { + origin: "https://corecomponents-arc-demo-3-prod.api.cdn.arcpublishing.com", + endpoint: "/retail/public/v1/offer/live/", + }, + }, + })), +); + +jest.mock("fusion:context", () => ({ + __esModule: true, + useFusionContext: () => ({ + arcSite: "Test Site", + }), +})); + +const cartDetail = { + total: 20000, + subtotal: 20000, + tax: 0, + shipping: 0, + currency: "COP", + taxSupported: true, + items: [ + { + sku: "0987", + quantity: 1, + shortDescription: "COP Currency description
", + name: "COP Currency", + price: 20000, + tax: 0, + subtotal: 20000, + total: 20000, + priceCode: "Q6R7UO", + eventId: null, + ownerClientId: null, + attributes: [], + gift: false, + }, + ], +}; + +const mockSales = { + getCart: jest.fn(() => Promise.resolve(cartDetail)), + getOrderDetails: jest.fn(() => {}), +}; + +jest.mock("@wpmedia/arc-themes-components", () => ({ + ...jest.requireActual("@wpmedia/arc-themes-components"), + useIdentity: jest.fn(() => ({ + isInitialized: true, + })), + useSales: jest.fn(() => ({ + isInitialized: true, + Sales: { + ...mockSales, + }, + })), +})); + +const localStorageMock = (() => { + let store = {}; + + return { + getItem: (key) => store[key], + setItem: (key, value) => { + store[key] = value.toString(); + }, + clear: () => { + store = {}; + }, + }; +})(); + +const sampleOffer = { + name: "test_campaign", + disclaimerText: null, + largeImage: null, + mediumImage: null, + smallImage: null, + pageSubTitle: "test_campaign
", + pageTitle: "test_campaign
", + templateName: "test-template", + campaigns: [ + { + canRenew: true, + canRestart: true, + canStart: true, + name: "demoCampaign", + validFrom: 1710888000000, + validUntil: 1711060801000, + }, + ], + products: [ + { + sku: "0987", + description: "COP Currency description
", + image: null, + imageAction: null, + name: "COP Currency", + thumbnail: null, + maxSubscriptionAssociations: 0, + attributes: [ + { + name: "test-style", + value: "Unlimited access to The Daily Intelligencer
", + }, + { + name: "test-style", + value: "Save $40
", + }, + { + name: "test-style", + value: "A bonus subscription to share
", + }, + ], + pricingStrategies: [ + { + pricingStrategyId: 4186, + priceCode: "Q6R7UO", + name: "All access Annual", + description: "with tax description price
", + gift: false, + summary: "with tax summary price
", + currencyCode: "COP", + currencyDisplayFormat: "symbol", + currencyLocale: "es-CO", + rates: [ + { + amount: "20000.00", + billingCount: 1, + billingFrequency: "Month", + durationCount: 1, + duration: "UntilCancelled", + }, + ], + taxInclusive: false, + }, + { + pricingStrategyId: 4187, + priceCode: "Z53LGY", + name: "taxIncluded priceName", + description: "tax included priceDescription
", + gift: false, + summary: "tax included priceSummary
", + currencyCode: "COP", + currencyDisplayFormat: "symbol", + currencyLocale: "es-CO", + rates: [ + { + amount: "40000.00", + billingCount: 1, + billingFrequency: "Month", + durationCount: 1, + duration: "UntilCancelled", + }, + ], + taxInclusive: true, + }, + ], + defaultSwgProduct: false, + }, + ], + attributes: [], + default: true, +}; + +jest.mock("./useOffer"); +useOffer.mockReturnValue({ + offer: sampleOffer, + fetchOffer: () => sampleOffer, + isFetching: false, +}); + +const emptyCart = { + total: 0, + subtotal: 0, + tax: 0, + shipping: 0, + items: [], + currency: "USD", + taxSupported: true, +}; + +describe("The OfferToProductList component", () => { + beforeEach(() => { + Object.defineProperty(window, "localStorage", { + value: localStorageMock, + }); + localStorage.setItem("ArcXP_campaignName", "demoCampaign"); + }); + + it("User has a cart", async () => { + const { result } = renderHook(() => useOrder()); + + expect(result.current.cartDetails).toBe(undefined); + expect(result.current.orderDetails).toBe(undefined); + expect(result.current.error).toBe(undefined); + + const newCartDetails = { + ...cartDetail, + items: [ + { + ...cartDetail?.items?.[0], + productAttributes: [ + { featureText: "Unlimited access to The Daily Intelligencer
" }, + { + featureText: "Save $40
", + }, + { + featureText: "A bonus subscription to share
", + }, + ], + productDescription: "COP Currency description
", + priceName: "All access Annual", + priceDescription: "with tax description price
", + priceSummary: "with tax summary price
", + rates: [ + { + amount: "20000.00", + billingCount: 1, + billingFrequency: "Month", + durationCount: 1, + duration: "UntilCancelled", + }, + ], + }, + ], + }; + + await waitFor(() => expect(result.current.cartDetails).toEqual(newCartDetails)); + await waitFor(() => expect(result.current.orderDetails).toEqual(undefined)); + await waitFor(() => expect(result.current.error).toEqual(undefined)); + }); + + it("User has order", async () => { + + const orderDetail = { + total: 22000, + subtotal: 20000, + tax: 2000, + shipping: 0, + items: [ + { + sku: "0987", + quantity: 1, + shortDescription: "COP Currency description
", + name: "COP Currency", + price: 20000, + tax: 2000, + subtotal: 20000, + total: 22000, + priceCode: "Q6R7UO", + eventId: null, + ownerClientId: null, + attributes: [], + gift: false, + }, + ], + currency: "COP", + orderNumber: "6OGJP2GGVJ7GT8L3", + status: "Pending", + email: "laurapinb@gmail.com", + phone: "NA", + firstName: "laura", + lastName: "pin", + orderDateUTC: 1711936392300, + taxDelegated: false, + paymentPending: false, + }; + + useSales.mockReturnValueOnce({ + isInitialized: true, + Sales: { + getCart: jest.fn(() => Promise.resolve(emptyCart)), + getOrderDetails: jest.fn(() => + Promise.resolve(orderDetail) + ), + }, + }); + + const newOrderDetail = { + ...orderDetail, + items: [ + { + ...orderDetail?.items?.[0], + productAttributes: [ + { featureText: "Unlimited access to The Daily Intelligencer
" }, + { + featureText: "Save $40
", + }, + { + featureText: "A bonus subscription to share
", + }, + ], + productDescription: "COP Currency description
", + priceName: "All access Annual", + priceDescription: "with tax description price
", + priceSummary: "with tax summary price
", + rates: [ + { + amount: "20000.00", + billingCount: 1, + billingFrequency: "Month", + durationCount: 1, + duration: "UntilCancelled", + }, + ], + }, + ], + }; + + const { result } = renderHook(() => useOrder("6OGJP2GGVJ7GT8L3")); + + expect(result.current.cartDetails).toBe(undefined); + expect(result.current.orderDetails).toBe(undefined); + expect(result.current.error).toBe(undefined); + + await waitFor(() => expect(result.current.cartDetails).toEqual(undefined)); + await waitFor(() => expect(result.current.orderDetails).toEqual(newOrderDetail)); + await waitFor(() => expect(result.current.error).toEqual(undefined)); + }); + + it("getOrderDetail is returning an error", async () => { + const error = { code: "200019", message: "Access Denied" }; + useSales.mockReturnValueOnce({ + isInitialized: true, + Sales: { + getCart: jest.fn(() => Promise.resolve(emptyCart)), + getOrderDetails: jest.fn().mockRejectedValueOnce(error), + }, + }); + + const { result } = renderHook(() => useOrder("6OGJP2GGVJ7GT8L3")); + + expect(result.current.cartDetails).toBe(undefined); + expect(result.current.orderDetails).toBe(undefined); + expect(result.current.error).toBe(undefined); + + await waitFor(() => expect(result.current.cartDetails).toEqual(undefined)); + await waitFor(() => expect(result.current.orderDetails).toEqual(undefined)); + await waitFor(() => expect(result.current.error).toEqual(error)); + }); + + it("getCart is returning an error", async () => { + const error = { code: "0", message: "Unexpected Server error" }; + useSales.mockReturnValueOnce({ + isInitialized: true, + Sales: { + getCart: jest.fn().mockRejectedValueOnce(error), + getOrderDetails: jest.fn(() => {}), + }, + }); + + const { result } = renderHook(() => useOrder()); + + expect(result.current.cartDetails).toBe(undefined); + expect(result.current.orderDetails).toBe(undefined); + expect(result.current.error).toBe(undefined); + + await waitFor(() => expect(result.current.cartDetails).toEqual(undefined)); + await waitFor(() => expect(result.current.orderDetails).toEqual(undefined)); + await waitFor(() => expect(result.current.error).toEqual(error)); + }); +}); diff --git a/blocks/subscriptions-block/intl.json b/blocks/subscriptions-block/intl.json index 07358dc45b..9f22f06403 100644 --- a/blocks/subscriptions-block/intl.json +++ b/blocks/subscriptions-block/intl.json @@ -6848,5 +6848,14 @@ "vi": "Cập nhật phương thức thanh toán", "zh-CN": "更新付款方式", "zh-TW": "更新付款方式" + }, + "checkout-block.view-subscription-offers": { + "en": "View subscription offers" + }, + "checkout-block.subtotal": { + "en": "Subtotal" + }, + "checkout-block.salesTax": { + "en": "Sales tax" } } \ No newline at end of file diff --git a/blocks/subscriptions-block/themes/news.json b/blocks/subscriptions-block/themes/news.json index a1223d662f..5c8940e0c7 100644 --- a/blocks/subscriptions-block/themes/news.json +++ b/blocks/subscriptions-block/themes/news.json @@ -401,6 +401,126 @@ } } }, + "checkout-order-card": { + "styles": { + "default": { + "display": "flex", + "flex-direction": "column", + "padding-block-start": "var(--global-spacing-4)", + "padding-inline-end": "var(--global-spacing-4)", + "padding-block-end": "var(--global-spacing-4)", + "padding-inline-start": "var(--global-spacing-4)", + "gap": "var(--global-spacing-5)", + "column-gap": "var(--global-spacing-5)", + "components": { + "link": { + "color": "var(--text-color)", + "text-decoration": "underline", + "font-size": "var(--global-font-size-4)", + "font-weight": "var(--global-font-weight-4)" + } + } + } + } + }, + "checkout-order-card-productPrice": { + "styles": { + "default": { + "display": "flex", + "flex-direction": "column", + "gap": "var(--global-spacing-5)", + "column-gap": "var(--global-spacing-5)", + "components": { + "heading": { + "font-size": "var(--global-font-size-9)", + "font-weight": "var(--global-font-weight-7)", + "line-height": "var(--global-line-height-6)" + } + } + } + } + }, + "checkout-order-card--features": { + "styles": { + "default": { + "align-self": "baseline" + } + } + }, + "checkout-order-card--features--item": { + "styles": { + "default": { + "align-items": "center", + "display": "flex", + "margin-block-end": "var(--global-spacing-2)", + "components": { + "icon": { + "fill": "var(--status-color-success)", + "display": "flex", + "inline-size": "var(--global-spacing-4)", + "block-size": "var(--global-spacing-4)", + "margin-block-start": "0", + "margin-inline-end": "var(--global-spacing-2)", + "margin-block-end": "0", + "margin-inline-start": "0" + } + } + } + } + }, + "checkout-order-card--summary": { + "styles": { + "default": { + "gap": "var(--global-spacing-2)", + "components": { + "heading": { + "font-family": "var(--font-family-secondary)", + "font-weight": "var(--global-font-weight-7)", + "font-size": "var(--global-font-size-4)", + "padding-block-end": "var(--global-spacing-2)", + "border-block-end-width": "1px", + "border-block-end-style": "solid", + "border-block-end-color": "var(--border-color)" + } + } + } + } + }, + "checkout-order-card--summary--dueToday": { + "styles": { + "default": { + "display": "flex", + "justify-content": "space-between", + "padding-block-start": "var(--global-spacing-2)", + "border-block-start-width": "1px", + "border-block-start-style": "solid", + "border-block-start-color": "var(--border-color)", + "font-family": "var(--font-family-secondary)", + "font-weight": "var(--global-font-weight-7)", + "font-size": "var(--global-font-size-7)", + "inline-size": "100%", + "align-items": "flex-start" + } + } + }, + "checkout-order-card--summary--details":{ + "styles": { + "default": { + "gap": "var(--global-spacing-2)" + } + } + }, + "checkout-order-card--summary--details--item": { + "styles": { + "default": { + "flex-direction": "row", + "justify-content": "space-between", + "font-family": "var(--font-family-primary)", + "font-weight": "var(--global-font-weight-4)", + "font-size": "var(--global-font-size-3)" + } + } + }, "offer": { "styles": { "default": { diff --git a/blocks/subscriptions-block/utils/currency.test.jsx b/blocks/subscriptions-block/utils/currency.test.jsx index bd73f71416..1905a22b98 100644 --- a/blocks/subscriptions-block/utils/currency.test.jsx +++ b/blocks/subscriptions-block/utils/currency.test.jsx @@ -8,4 +8,8 @@ describe("Currency", () => { it("returns null if currency is not supported", () => { expect(currency("HKD")).toBe(null); }); + + it("returns null if currency is sent", () => { + expect(currency()).toBe(null); + }); }); \ No newline at end of file diff --git a/locale/en.json b/locale/en.json index d8234a2270..e0f85f7d17 100644 --- a/locale/en.json +++ b/locale/en.json @@ -465,6 +465,7 @@ "checkout-block.Zambia": "Zambia", "checkout-block.Zimbabwe": "Zimbabwe", "checkout-block.back-to-offer-page": "Back to subscription selection", + "checkout-block.view-subscription-offers": "View subscription offers", "checkout-block.cardNumber": "Card number", "checkout-block.cardholderName": "Name on card", "checkout-block.cardholderName-requirements": "Please enter name on card", @@ -473,6 +474,8 @@ "checkout-block.country": "Country or region", "checkout-block.country-requirements": "Please select country or region", "checkout-block.due-today": "Due today", + "checkout-block.subtotal": "Subtotal", + "checkout-block.salesTax": "Sales tax", "checkout-block.email": "Email address", "checkout-block.email-requirements": "Please enter a valid email address", "checkout-block.empty-cart-message": "Select from one of our offers",