-
Notifications
You must be signed in to change notification settings - Fork 214
Expand file tree
/
Copy pathsearch-suggestions-section.test.jsx
More file actions
237 lines (204 loc) · 8.19 KB
/
search-suggestions-section.test.jsx
File metadata and controls
237 lines (204 loc) · 8.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/*
* Copyright (c) 2021, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import React from 'react'
import {screen, within} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
import SuggestionSection from '@salesforce/retail-react-app/app/components/search/partials/search-suggestions-section'
// Mock dynamic image to keep DOM simple when HorizontalSuggestions renders
jest.mock('@salesforce/retail-react-app/app/components/dynamic-image', () => {
return function MockDynamicImage(props) {
const {src, widths, imageProps} = props || {}
return (
<img
data-testid="dynamic-image"
data-src={src}
data-widths={(widths || []).join(',')}
alt={imageProps?.alt ?? ''}
/>
)
}
})
const baseStyles = {
textContainer: {},
sectionHeader: {},
phraseContainer: {},
askAssistantBanner: {},
askAssistantBannerContent: {},
askAssistantBannerTitleRow: {},
askAssistantBannerIcon: {},
askAssistantBannerTitle: {},
askAssistantBannerDescription: {},
askAssistantBannerArrow: {}
}
const makeSearchSuggestions = (overrides = {}) => ({
searchPhrase: 'Dress',
phraseSuggestions: [],
categorySuggestions: [],
productSuggestions: [],
...overrides
})
test('renders "Did you mean" with suggestion link when non-exact phrase exists (mobile and desktop)', () => {
const searchSuggestions = makeSearchSuggestions({
phraseSuggestions: [{name: 'dresses', link: '/search?q=dresses', exactMatch: false}]
})
renderWithProviders(
<SuggestionSection
searchSuggestions={searchSuggestions}
closeAndNavigate={jest.fn()}
styles={baseStyles}
/>
)
// Appears in both mobile and desktop sections
const didYouMeanTexts = screen.getAllByText(/Did you mean/i)
expect(didYouMeanTexts.length).toBeGreaterThanOrEqual(1)
const links = screen.getAllByRole('link', {name: /dresses\?/i})
expect(links.length).toBeGreaterThanOrEqual(1)
})
test('renders Categories header and category suggestions', () => {
const searchSuggestions = makeSearchSuggestions({
categorySuggestions: [
{type: 'category', name: 'Women', link: '/women'},
{type: 'category', name: 'Men', link: '/men'}
]
})
renderWithProviders(
<SuggestionSection
searchSuggestions={searchSuggestions}
closeAndNavigate={jest.fn()}
styles={baseStyles}
/>
)
// Header present (could be duplicated for mobile/desktop)
expect(screen.getAllByText('Categories').length).toBeGreaterThanOrEqual(1)
// Suggestions component renders buttons; ensure names are present
expect(screen.getAllByText('Women').length).toBeGreaterThanOrEqual(1)
expect(screen.getAllByText('Men').length).toBeGreaterThanOrEqual(1)
})
test('renders horizontal product suggestions and "View All"; clicking a tile calls closeAndNavigate', async () => {
const user = userEvent.setup()
const closeAndNavigate = jest.fn()
const searchSuggestions = makeSearchSuggestions({
productSuggestions: [
{
type: 'product',
name: 'Product 1',
link: '/p1',
image: 'https://example.com/p1.jpg',
price: '19.99'
},
{type: 'product', name: 'Product 2', link: '/p2'}
]
})
renderWithProviders(
<SuggestionSection
searchSuggestions={searchSuggestions}
closeAndNavigate={closeAndNavigate}
styles={baseStyles}
/>
)
// HorizontalSuggestions container
expect(screen.getByTestId('sf-horizontal-product-suggestions')).toBeInTheDocument()
// "View All" link only renders when products exist (may be hidden by responsive wrapper in tests)
expect(screen.getByText(/View All/i, {selector: 'a'})).toBeInTheDocument()
// Click a product tile (desktop horizontal suggestions)
const container = screen.getByTestId('sf-horizontal-product-suggestions')
const tiles = within(container).getAllByTestId('product-tile')
await user.click(tiles[1])
expect(closeAndNavigate).toHaveBeenCalledWith('/p2')
})
test('renders nothing when there are no categories, products, or phrase suggestions', () => {
const searchSuggestions = makeSearchSuggestions()
renderWithProviders(
<SuggestionSection
searchSuggestions={searchSuggestions}
closeAndNavigate={jest.fn()}
styles={baseStyles}
/>
)
expect(screen.queryByText('Categories')).not.toBeInTheDocument()
expect(screen.queryByText('Products')).not.toBeInTheDocument()
expect(screen.queryByTestId('sf-horizontal-product-suggestions')).not.toBeInTheDocument()
})
describe('Ask Shopping Agent banner', () => {
test('renders Ask Shopping Agent banner when showAskAssistantBanner and onAskAssistantClick are provided', () => {
const searchSuggestions = makeSearchSuggestions({
categorySuggestions: [{type: 'category', name: 'Women', link: '/women'}]
})
renderWithProviders(
<SuggestionSection
searchSuggestions={searchSuggestions}
closeAndNavigate={jest.fn()}
styles={baseStyles}
showAskAssistantBanner={true}
onAskAssistantClick={jest.fn()}
/>
)
const banners = screen.getAllByRole('button', {
name: /Ask Shopping Agent.*discover, compare,? and shop smarter/i
})
expect(banners.length).toBeGreaterThanOrEqual(1)
})
test('does not render Ask Shopping Agent banner when showAskAssistantBanner is false', () => {
const searchSuggestions = makeSearchSuggestions({
categorySuggestions: [{type: 'category', name: 'Women', link: '/women'}]
})
renderWithProviders(
<SuggestionSection
searchSuggestions={searchSuggestions}
closeAndNavigate={jest.fn()}
styles={baseStyles}
showAskAssistantBanner={false}
onAskAssistantClick={jest.fn()}
/>
)
expect(
screen.queryByRole('button', {
name: /Ask Shopping Agent.*discover, compare,? and shop smarter/i
})
).not.toBeInTheDocument()
})
test('does not render Ask Shopping Agent banner when onAskAssistantClick is not provided', () => {
const searchSuggestions = makeSearchSuggestions({
categorySuggestions: [{type: 'category', name: 'Women', link: '/women'}]
})
renderWithProviders(
<SuggestionSection
searchSuggestions={searchSuggestions}
closeAndNavigate={jest.fn()}
styles={baseStyles}
showAskAssistantBanner={true}
/>
)
expect(
screen.queryByRole('button', {
name: /Ask Shopping Agent.*discover, compare,? and shop smarter/i
})
).not.toBeInTheDocument()
})
test('clicking Ask Shopping Agent banner calls onAskAssistantClick', async () => {
const user = userEvent.setup()
const onAskAssistantClick = jest.fn()
const searchSuggestions = makeSearchSuggestions({
recentSearchSuggestions: [{type: 'recent', name: 'shoes', link: '/search?q=shoes'}]
})
renderWithProviders(
<SuggestionSection
searchSuggestions={searchSuggestions}
closeAndNavigate={jest.fn()}
styles={baseStyles}
showAskAssistantBanner={true}
onAskAssistantClick={onAskAssistantClick}
/>
)
const banner = screen.getAllByRole('button', {
name: /Ask Shopping Agent.*discover, compare,? and shop smarter/i
})[0]
await user.click(banner)
expect(onAskAssistantClick).toHaveBeenCalledTimes(1)
})
})