Skip to content
Merged
2 changes: 1 addition & 1 deletion packages/document/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
Subtitle,
Title,
} from "@storybook/addon-docs/blocks"
import type { Decorator, Parameters, Preview } from "@storybook/react-vite"
import type { Parameters, Preview } from "@storybook/react-vite"
import React from "react"
import { worker } from "../mocks/browser"

Expand Down
2 changes: 1 addition & 1 deletion packages/react-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"@adyen/adyen-web": "^6.28.0",
"@commercelayer/core": "workspace:*",
"@commercelayer/hooks": "workspace:*",
"@commercelayer/organization-config": "^2.4.0",
"@commercelayer/organization-config": "^2.8.4",
"@commercelayer/sdk": "^7.4.1",
"@stripe/react-stripe-js": "^5.4.1",
"@stripe/stripe-js": "^8.6.1",
Expand Down
96 changes: 96 additions & 0 deletions packages/react-components/specs/orders/hosted-cart.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import CommerceLayerContext from "#context/CommerceLayerContext"
import OrderContext, { defaultOrderContext } from "#context/OrderContext"
import OrderStorageContext from "#context/OrderStorageContext"
import { HostedCart } from "#components/orders/HostedCart"
import * as organizationUtils from "#utils/organization"
import * as applicationLinkUtils from "#utils/getApplicationLink"
import { render, waitFor } from "@testing-library/react"
import { vi } from "vitest"

vi.mock("iframe-resizer", () => ({
iframeResizer: vi.fn(),
}))

describe("HostedCart component", () => {
beforeEach(() => {
localStorage.clear()
vi.restoreAllMocks()
})

it("updates minicart url when persistKey changes", async () => {
localStorage.setItem("cart-key-1", "order-id-1")
localStorage.setItem("cart-key-2", "order-id-2")

vi.spyOn(organizationUtils, "getOrganizationConfig").mockResolvedValue(null)

const getApplicationLinkSpy = vi
.spyOn(applicationLinkUtils, "getApplicationLink")
.mockImplementation(
({ orderId }) => `https://test-cart.local/cart/${orderId}`,
)

const orderContextValue = {
...defaultOrderContext,
createOrder: vi.fn().mockResolvedValue("created-order-id"),
}

const commonProps = {
clearWhenPlaced: true,
getLocalOrder: vi.fn(),
setLocalOrder: vi.fn(),
deleteLocalOrder: vi.fn(),
}

const { rerender } = render(
<CommerceLayerContext.Provider
value={{
accessToken: "test-token",
endpoint: "https://acme.commercelayer.io",
}}
>
<OrderContext.Provider value={orderContextValue}>
<OrderStorageContext.Provider
value={{
persistKey: "cart-key-1",
...commonProps,
}}
>
<HostedCart />
</OrderStorageContext.Provider>
</OrderContext.Provider>
</CommerceLayerContext.Provider>,
)

await waitFor(() => {
expect(getApplicationLinkSpy).toHaveBeenCalledWith(
expect.objectContaining({ orderId: "order-id-1" }),
)
})

rerender(
<CommerceLayerContext.Provider
value={{
accessToken: "test-token",
endpoint: "https://acme.commercelayer.io",
}}
>
<OrderContext.Provider value={orderContextValue}>
<OrderStorageContext.Provider
value={{
persistKey: "cart-key-2",
...commonProps,
}}
>
<HostedCart />
</OrderStorageContext.Provider>
</OrderContext.Provider>
</CommerceLayerContext.Provider>,
)

await waitFor(() => {
expect(getApplicationLinkSpy).toHaveBeenCalledWith(
expect.objectContaining({ orderId: "order-id-2" }),
)
})
})
})
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { useContext, useEffect, useState, type JSX } from 'react';
import Parent from '../utils/Parent'
import type { ChildrenFunction } from '#typings/index'
import CommerceLayerContext from '#context/CommerceLayerContext'
import { getApplicationLink } from '#utils/getApplicationLink'
import { getDomain } from '#utils/getDomain'
import { getOrganizationConfig } from '#utils/organization'
import { type JSX, useContext, useEffect, useState } from "react"
import CommerceLayerContext from "#context/CommerceLayerContext"
import type { ChildrenFunction } from "#typings/index"
import { getApplicationLink } from "#utils/getApplicationLink"
import { getDomain } from "#utils/getDomain"
import { getOrganizationConfig } from "#utils/organization"
import Parent from "../utils/Parent"

interface ChildrenProps extends Omit<Props, 'children'> {
interface ChildrenProps extends Omit<Props, "children"> {
/**
* The link href
*/
href: string
}

interface Props extends Omit<JSX.IntrinsicElements['a'], 'children'> {
interface Props extends Omit<JSX.IntrinsicElements["a"], "children"> {
/**
* A render function to render your own custom component
*/
Expand All @@ -25,7 +25,7 @@ interface Props extends Omit<JSX.IntrinsicElements['a'], 'children'> {
/**
* The type of the link
*/
type: 'login' | 'signup'
type: "login" | "signup"
/**
* The client id of the Commerce Layer application
*/
Expand Down Expand Up @@ -78,32 +78,35 @@ export function MyIdentityLink(props: Props): JSX.Element {
const { accessToken, endpoint } = useContext(CommerceLayerContext)
const [href, setHref] = useState<string | undefined>(undefined)
if (accessToken == null || endpoint == null)
throw new Error('Cannot use `MyIdentityLink` outside of `CommerceLayer`')
const { domain, slug } = getDomain(endpoint)
throw new Error("Cannot use `MyIdentityLink` outside of `CommerceLayer`")
useEffect(() => {
if (accessToken && endpoint) {
const { domain, slug } = getDomain(endpoint)
getOrganizationConfig({
accessToken,
endpoint,
params: {
accessToken,
slug
}
slug, identityType: type,
clientId,
scope,
returnUrl: returnUrl ?? window.location.href,
resetPasswordUrl, },
}).then((config) => {
if (config?.links?.identity) {
setHref(config.links.identity)
} else {
const link = getApplicationLink({
slug,
accessToken,
applicationType: 'identity',
applicationType: "identity",
domain,
modeType: type,
clientId,
scope,
returnUrl: returnUrl ?? window.location.href,
resetPasswordUrl,
customDomain
customDomain,
})
setHref(link)
}
Expand All @@ -112,14 +115,14 @@ export function MyIdentityLink(props: Props): JSX.Element {
return () => {
setHref(undefined)
}
}, [accessToken, endpoint])
}, [accessToken, endpoint, type, clientId, scope, returnUrl, resetPasswordUrl, customDomain])

const parentProps = {
label,
href,
clientId,
scope,
...p
...p,
}
return children ? (
<Parent {...parentProps}>{children}</Parent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ export function AddToCartButton(props: Props): JSX.Element {
orderId,
accessToken,
slug,
skuListId,
skuId: sku?.id,
},
})
location.href =
Expand Down
Loading
Loading