Skip to content

Commit 0def699

Browse files
authored
fix: localize url for checkout button (#3355)
1 parent 2780600 commit 0def699

File tree

2 files changed

+96
-51
lines changed

2 files changed

+96
-51
lines changed

packages/template-retail-react-app/app/components/shopper-agent/index.jsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,11 @@ const ShopperAgentWindow = ({commerceAgentConfiguration, domainUrl}) => {
259259
conversationContext
260260
})
261261
}
262+
} else if (event.data.type === 'lwc.getDomainUrl') {
263+
// Handle domain URL request
264+
sendConversationContext('conversational.domainUrl', {
265+
domainUrl
266+
})
262267
}
263268
} catch (error) {
264269
console.error('Error handling Miaw event:', error)
@@ -421,15 +426,14 @@ const ShopperAgent = ({commerceAgentConfiguration, basketDoneLoading}) => {
421426
const {enabled} = commerceAgentConfiguration
422427

423428
// Get current location and app origin for domain URL
424-
const location = useLocation()
425429
const appOrigin = useAppOrigin()
426430
const {buildUrl} = useMultiSite()
427431

428432
// Check if agent is enabled and running on client side
429433
const isShopperAgentEnabled = isEnabled(enabled)
430434

431435
// Build the current domain URL
432-
const domainUrl = `${appOrigin}${buildUrl(location.pathname)}`
436+
const domainUrl = `${appOrigin}${buildUrl('')}`
433437

434438
// Conditional rendering: only render when all conditions are met
435439
// 1. Agent is enabled and running on client

packages/template-retail-react-app/app/components/shopper-agent/index.test.js

Lines changed: 90 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ describe('ShopperAgent Component', () => {
139139
// Mock useMultiSite hook with proper structure
140140
mockedUseMultiSite.mockReturnValue({
141141
locale: {id: 'en-US', preferredCurrency: 'USD'},
142-
buildUrl: jest.fn((path) => path)
142+
buildUrl: jest.fn(() => '/us/en-US')
143143
})
144144

145145
// Mock useTheme hook
@@ -239,7 +239,7 @@ describe('ShopperAgent Component', () => {
239239
RefreshToken: 'test-refresh-token',
240240
Currency: 'USD',
241241
Language: 'en_US',
242-
DomainUrl: 'https://example.com/current-page'
242+
DomainUrl: 'https://example.com/us/en-US'
243243
})
244244
})
245245

@@ -263,7 +263,7 @@ describe('ShopperAgent Component', () => {
263263
RefreshToken: 'initial-token',
264264
Currency: 'USD',
265265
Language: 'en_US',
266-
DomainUrl: 'https://example.com/current-page'
266+
DomainUrl: 'https://example.com/us/en-US'
267267
})
268268

269269
// Clear mock and change refresh token
@@ -287,7 +287,7 @@ describe('ShopperAgent Component', () => {
287287
RefreshToken: 'updated-token',
288288
Currency: 'USD',
289289
Language: 'en_US',
290-
DomainUrl: 'https://example.com/current-page'
290+
DomainUrl: 'https://example.com/us/en-US'
291291
})
292292
})
293293

@@ -310,15 +310,15 @@ describe('ShopperAgent Component', () => {
310310
RefreshToken: null,
311311
Currency: 'USD',
312312
Language: 'en_US',
313-
DomainUrl: 'https://example.com/current-page'
313+
DomainUrl: 'https://example.com/us/en-US'
314314
})
315315
})
316316

317317
test('should update prechat fields when currency changes', async () => {
318318
// Mock useMultiSite to return different currency values
319319
mockedUseMultiSite.mockReturnValue({
320320
locale: {id: 'en-US', preferredCurrency: 'USD'},
321-
buildUrl: jest.fn((path) => path)
321+
buildUrl: jest.fn(() => '/us/en-US')
322322
})
323323

324324
render(<ShopperAgent {...defaultProps} />)
@@ -337,14 +337,14 @@ describe('ShopperAgent Component', () => {
337337
RefreshToken: 'test-refresh-token',
338338
Currency: 'USD',
339339
Language: 'en_US',
340-
DomainUrl: 'https://example.com/current-page'
340+
DomainUrl: 'https://example.com/us/en-US'
341341
})
342342

343343
// Clear mock and change currency to EUR
344344
mockEmbeddedService.prechatAPI.setHiddenPrechatFields.mockClear()
345345
mockedUseMultiSite.mockReturnValue({
346346
locale: {id: 'en-US', preferredCurrency: 'EUR'},
347-
buildUrl: jest.fn((path) => path)
347+
buildUrl: jest.fn(() => '/us/en-US')
348348
})
349349

350350
// Re-render with new currency
@@ -364,15 +364,15 @@ describe('ShopperAgent Component', () => {
364364
RefreshToken: 'test-refresh-token',
365365
Currency: 'EUR',
366366
Language: 'en_US',
367-
DomainUrl: 'https://example.com/current-page'
367+
DomainUrl: 'https://example.com/us/en-US'
368368
})
369369
})
370370

371371
test('should update prechat fields when locale changes', async () => {
372372
// Mock useMultiSite to return different locale values
373373
mockedUseMultiSite.mockReturnValue({
374374
locale: {id: 'en-US', preferredCurrency: 'USD'},
375-
buildUrl: jest.fn((path) => path)
375+
buildUrl: jest.fn(() => '/us/en-US')
376376
})
377377

378378
render(<ShopperAgent {...defaultProps} />)
@@ -391,14 +391,14 @@ describe('ShopperAgent Component', () => {
391391
RefreshToken: 'test-refresh-token',
392392
Currency: 'USD',
393393
Language: 'en_US',
394-
DomainUrl: 'https://example.com/current-page'
394+
DomainUrl: 'https://example.com/us/en-US'
395395
})
396396

397397
// Clear mock and change locale to en-GB
398398
mockEmbeddedService.prechatAPI.setHiddenPrechatFields.mockClear()
399399
mockedUseMultiSite.mockReturnValue({
400400
locale: {id: 'en-GB', preferredCurrency: 'GBP'},
401-
buildUrl: jest.fn((path) => path)
401+
buildUrl: jest.fn(() => '/us/en-US')
402402
})
403403

404404
// Re-render with new locale
@@ -418,7 +418,7 @@ describe('ShopperAgent Component', () => {
418418
RefreshToken: 'test-refresh-token',
419419
Currency: 'GBP',
420420
Language: 'en_GB',
421-
DomainUrl: 'https://example.com/current-page'
421+
DomainUrl: 'https://example.com/us/en-US'
422422
})
423423
})
424424

@@ -449,7 +449,7 @@ describe('ShopperAgent Component', () => {
449449
RefreshToken: 'test-refresh-token',
450450
Currency: 'USD',
451451
Language: 'en_US',
452-
DomainUrl: 'https://example.com/current-page'
452+
DomainUrl: 'https://example.com/us/en-US'
453453
})
454454
})
455455

@@ -560,7 +560,7 @@ describe('ShopperAgent Component', () => {
560560
RefreshToken: 'test-refresh-token',
561561
Currency: 'USD',
562562
Language: 'en_US',
563-
DomainUrl: 'https://example.com/current-page'
563+
DomainUrl: 'https://example.com/us/en-US'
564564
})
565565
})
566566

@@ -585,7 +585,7 @@ describe('ShopperAgent Component', () => {
585585
RefreshToken: 'test-refresh-token',
586586
Currency: 'USD',
587587
Language: 'en_US',
588-
DomainUrl: 'https://example.com/current-page'
588+
DomainUrl: 'https://example.com/us/en-US'
589589
})
590590
})
591591

@@ -597,39 +597,6 @@ describe('ShopperAgent Component', () => {
597597
render(<ShopperAgent {...props} />)
598598
expect(screen.queryByTestId('shopper-agent')).toBeInTheDocument()
599599
})
600-
601-
test('should handle complex domainUrl with query parameters and fragments', async () => {
602-
// Mock complex location data
603-
mockUseLocation.mockReturnValue({
604-
pathname: '/products/shoes',
605-
search: '?color=red&size=10',
606-
hash: '#reviews'
607-
})
608-
mockUseAppOrigin.mockReturnValue('https://test-store.com')
609-
610-
const props = {
611-
...defaultProps
612-
}
613-
614-
render(<ShopperAgent {...props} />)
615-
616-
// Trigger the onEmbeddedMessagingReady event
617-
await act(async () => {
618-
window.dispatchEvent(new Event('onEmbeddedMessagingReady'))
619-
})
620-
621-
expect(mockEmbeddedService.prechatAPI.setHiddenPrechatFields).toHaveBeenCalledWith({
622-
SiteId: 'RefArchGlobal',
623-
Locale: 'en-US',
624-
OrganizationId: 'test-commerce-org-id',
625-
UsId: 'test-usid',
626-
IsCartMgmtSupported: 'true',
627-
RefreshToken: 'test-refresh-token',
628-
Currency: 'USD',
629-
Language: 'en_US',
630-
DomainUrl: 'https://test-store.com/products/shoes'
631-
})
632-
})
633600
})
634601

635602
describe('Conversation Context Functionality', () => {
@@ -987,4 +954,78 @@ describe('ShopperAgent Component', () => {
987954
expect(() => render(<ShopperAgent {...props} />)).not.toThrow()
988955
})
989956
})
957+
958+
describe('Domain URL Event Functionality', () => {
959+
beforeEach(() => {
960+
// Mock postMessage for iframe communication
961+
global.postMessage = jest.fn()
962+
963+
// Mock document.querySelector for iframe
964+
const mockIframe = {
965+
src: 'https://test.salesforce.com/iframe',
966+
contentWindow: {
967+
postMessage: jest.fn()
968+
}
969+
}
970+
jest.spyOn(document, 'querySelector').mockReturnValue(mockIframe)
971+
})
972+
973+
afterEach(() => {
974+
jest.restoreAllMocks()
975+
})
976+
977+
test('should handle lwc.getDomainUrl event and send domain URL', async () => {
978+
render(<ShopperAgent {...defaultProps} />)
979+
980+
// Mock iframe for postMessage
981+
const mockIframe = {
982+
src: 'https://test.salesforce.com/iframe',
983+
contentWindow: {
984+
postMessage: jest.fn()
985+
}
986+
}
987+
jest.spyOn(document, 'querySelector').mockReturnValue(mockIframe)
988+
989+
// Simulate MIAW event requesting domain URL
990+
const mockEvent = {
991+
source: {postMessage: jest.fn()},
992+
data: {type: 'lwc.getDomainUrl'}
993+
}
994+
995+
await act(async () => {
996+
window.dispatchEvent(new MessageEvent('message', mockEvent))
997+
})
998+
999+
// Verify postMessage was called with domain URL
1000+
expect(mockIframe.contentWindow.postMessage).toHaveBeenCalledWith(
1001+
{
1002+
type: 'conversational.domainUrl',
1003+
payload: {
1004+
domainUrl: 'https://example.com/us/en-US'
1005+
}
1006+
},
1007+
'https://test.salesforce.com'
1008+
)
1009+
})
1010+
1011+
test('should handle lwc.getDomainUrl event properly when iframe not found', async () => {
1012+
render(<ShopperAgent {...defaultProps} />)
1013+
1014+
// Mock querySelector to return null (iframe not found)
1015+
jest.spyOn(document, 'querySelector').mockReturnValue(null)
1016+
1017+
// Simulate MIAW event
1018+
const mockEvent = {
1019+
source: {postMessage: jest.fn()},
1020+
data: {type: 'lwc.getDomainUrl'}
1021+
}
1022+
1023+
await act(async () => {
1024+
window.dispatchEvent(new MessageEvent('message', mockEvent))
1025+
})
1026+
1027+
// Should handle missing iframe gracefully without throwing
1028+
expect(() => render(<ShopperAgent {...defaultProps} />)).not.toThrow()
1029+
})
1030+
})
9901031
})

0 commit comments

Comments
 (0)