Skip to content

Commit 0a1f5eb

Browse files
feat: update the hooks action
1 parent c53deb0 commit 0a1f5eb

File tree

4 files changed

+67
-58
lines changed

4 files changed

+67
-58
lines changed

packages/template-retail-react-app/app/components/_app/index.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ import Seo from '@salesforce/retail-react-app/app/components/seo'
8787
import ShopperAgent from '@salesforce/retail-react-app/app/components/shopper-agent'
8888
import {getPathWithLocale} from '@salesforce/retail-react-app/app/utils/url'
8989
import {getCommerceAgentConfig} from '@salesforce/retail-react-app/app/utils/config-utils'
90-
import {useOpenShopperAgent} from '@salesforce/retail-react-app/app/hooks/use-open-shopper-agent'
90+
import {useShopperAgent} from '@salesforce/retail-react-app/app/hooks/use-shopper-agent'
9191

9292
const PlaceholderComponent = () => (
9393
<Center p="2">
@@ -286,7 +286,7 @@ const App = (props) => {
286286
history.push(path)
287287
}
288288

289-
const openShopperAgent = useOpenShopperAgent()
289+
const {actions: shopperAgentActions} = useShopperAgent()
290290

291291
const trackPage = () => {
292292
activeData.trackPage(site.id, locale.id, currency)
@@ -396,7 +396,7 @@ const App = (props) => {
396396
onMyAccountClick={onAccountClick}
397397
onWishlistClick={onWishlistClick}
398398
onStoreLocatorClick={onOpenStoreLocator}
399-
onAgentClick={openShopperAgent}
399+
onAgentClick={shopperAgentActions.open}
400400
>
401401
<HideOnDesktop>
402402
<DrawerMenu

packages/template-retail-react-app/app/hooks/use-open-shopper-agent.test.js

Lines changed: 0 additions & 48 deletions
This file was deleted.

packages/template-retail-react-app/app/hooks/use-open-shopper-agent.js renamed to packages/template-retail-react-app/app/hooks/use-shopper-agent.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@ import {useCallback} from 'react'
88
import {launchChat} from '@salesforce/retail-react-app/app/utils/shopper-agent-utils'
99

1010
/**
11-
* React hook that returns a stable callback to open the shopper agent chat window.
12-
* Uses the embedded service bootstrap API to launch the chat.
13-
*
14-
* @returns {Function} openShopperAgent - Stable callback to open the shopper agent chat
11+
* React hook that returns shopper agent actions.
12+
* Uses the embedded service bootstrap API. Structured for future extension (e.g. close, sendMessage).
1513
*/
16-
export function useOpenShopperAgent() {
17-
const openShopperAgent = useCallback(() => {
14+
export function useShopperAgent() {
15+
const open = useCallback(() => {
1816
launchChat()
1917
}, [])
2018

21-
return openShopperAgent
19+
return {actions: {open}}
2220
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2025, Salesforce, Inc.
3+
* All rights reserved.
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6+
*/
7+
8+
import {renderHook, act} from '@testing-library/react'
9+
import {useShopperAgent} from '@salesforce/retail-react-app/app/hooks/use-shopper-agent'
10+
import {launchChat} from '@salesforce/retail-react-app/app/utils/shopper-agent-utils'
11+
12+
jest.mock('@salesforce/retail-react-app/app/utils/shopper-agent-utils', () => ({
13+
launchChat: jest.fn()
14+
}))
15+
16+
describe('useShopperAgent', () => {
17+
beforeEach(() => {
18+
jest.clearAllMocks()
19+
})
20+
21+
test('should return an object with actions', () => {
22+
const {result} = renderHook(() => useShopperAgent())
23+
24+
expect(result.current).toEqual({actions: expect.any(Object)})
25+
expect(result.current.actions).toHaveProperty('open')
26+
expect(typeof result.current.actions.open).toBe('function')
27+
})
28+
29+
test('should call launchChat when actions.open is invoked', () => {
30+
const {result} = renderHook(() => useShopperAgent())
31+
32+
act(() => {
33+
result.current.actions.open()
34+
})
35+
36+
expect(launchChat).toHaveBeenCalledTimes(1)
37+
})
38+
39+
test('should call launchChat each time actions.open is invoked', () => {
40+
const {result} = renderHook(() => useShopperAgent())
41+
42+
act(() => {
43+
result.current.actions.open()
44+
result.current.actions.open()
45+
})
46+
47+
expect(launchChat).toHaveBeenCalledTimes(2)
48+
})
49+
50+
test('should return a stable open callback reference across re-renders', () => {
51+
const {result, rerender} = renderHook(() => useShopperAgent())
52+
53+
const firstOpen = result.current.actions.open
54+
rerender()
55+
const secondOpen = result.current.actions.open
56+
57+
expect(firstOpen).toBe(secondOpen)
58+
})
59+
})

0 commit comments

Comments
 (0)