vue-instantsearch 3.6.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/dist/vue-instantsearch.common.js +1 -1
- package/dist/vue-instantsearch.common.js.map +1 -1
- package/dist/vue-instantsearch.js +1 -1
- package/dist/vue-instantsearch.js.map +1 -1
- package/es/package.json.js +1 -1
- package/es/src/components/Breadcrumb.vue.js +1 -1
- package/es/src/components/Breadcrumb.vue.js.map +1 -1
- package/es/src/components/ClearRefinements.vue.js +1 -1
- package/es/src/components/ClearRefinements.vue.js.map +1 -1
- package/es/src/components/CurrentRefinements.vue.js +1 -1
- package/es/src/components/CurrentRefinements.vue.js.map +1 -1
- package/es/src/components/DynamicWidgets.js +2 -0
- package/es/src/components/DynamicWidgets.js.map +1 -0
- package/es/src/components/HierarchicalMenu.vue.js +1 -1
- package/es/src/components/HierarchicalMenu.vue.js.map +1 -1
- package/es/src/components/Highlighter.vue.js.map +1 -1
- package/es/src/components/Hits.vue.js +1 -1
- package/es/src/components/Hits.vue.js.map +1 -1
- package/es/src/components/HitsPerPage.vue.js +1 -1
- package/es/src/components/HitsPerPage.vue.js.map +1 -1
- package/es/src/components/InfiniteHits.vue.js +1 -1
- package/es/src/components/InfiniteHits.vue.js.map +1 -1
- package/es/src/components/InstantSearch.js +1 -1
- package/es/src/components/InstantSearch.js.map +1 -1
- package/es/src/components/Menu.vue.js +1 -1
- package/es/src/components/Menu.vue.js.map +1 -1
- package/es/src/components/MenuSelect.vue.js +1 -1
- package/es/src/components/MenuSelect.vue.js.map +1 -1
- package/es/src/components/NumericMenu.vue.js +1 -1
- package/es/src/components/NumericMenu.vue.js.map +1 -1
- package/es/src/components/Pagination.vue.js +1 -1
- package/es/src/components/Pagination.vue.js.map +1 -1
- package/es/src/components/QueryRuleContext.js +1 -1
- package/es/src/components/QueryRuleContext.js.map +1 -1
- package/es/src/components/QueryRuleCustomData.vue.js +1 -1
- package/es/src/components/QueryRuleCustomData.vue.js.map +1 -1
- package/es/src/components/RangeInput.vue.js +1 -1
- package/es/src/components/RangeInput.vue.js.map +1 -1
- package/es/src/components/RatingMenu.vue.js +1 -1
- package/es/src/components/RatingMenu.vue.js.map +1 -1
- package/es/src/components/RefinementList.vue.js +1 -1
- package/es/src/components/RefinementList.vue.js.map +1 -1
- package/es/src/components/SortBy.vue.js +1 -1
- package/es/src/components/SortBy.vue.js.map +1 -1
- package/es/src/components/ToggleRefinement.vue.js +1 -1
- package/es/src/components/ToggleRefinement.vue.js.map +1 -1
- package/es/src/instantsearch.js +1 -1
- package/es/src/mixins/widget.js +1 -1
- package/es/src/mixins/widget.js.map +1 -1
- package/es/src/util/createInstantSearchComponent.js +1 -1
- package/es/src/util/createInstantSearchComponent.js.map +1 -1
- package/es/src/util/createServerRootMixin.js +1 -1
- package/es/src/util/createServerRootMixin.js.map +1 -1
- package/es/src/widgets.js +1 -1
- package/package.json +5 -5
- package/src/__tests__/index.js +2 -0
- package/src/components/Breadcrumb.vue +3 -5
- package/src/components/ClearRefinements.vue +3 -7
- package/src/components/CurrentRefinements.vue +3 -7
- package/src/components/DynamicWidgets.js +87 -0
- package/src/components/HierarchicalMenu.vue +8 -11
- package/src/components/Highlighter.vue +16 -4
- package/src/components/Hits.vue +2 -3
- package/src/components/HitsPerPage.vue +1 -4
- package/src/components/InfiniteHits.vue +2 -3
- package/src/components/InstantSearch.js +11 -7
- package/src/components/Menu.vue +5 -8
- package/src/components/MenuSelect.vue +2 -3
- package/src/components/NumericMenu.vue +2 -3
- package/src/components/Pagination.vue +1 -1
- package/src/components/QueryRuleContext.js +1 -1
- package/src/components/QueryRuleCustomData.vue +1 -1
- package/src/components/RangeInput.vue +3 -0
- package/src/components/RatingMenu.vue +2 -1
- package/src/components/RefinementList.vue +8 -7
- package/src/components/SortBy.vue +1 -3
- package/src/components/ToggleRefinement.vue +1 -2
- package/src/components/__tests__/DynamicWidgets.js +419 -0
- package/src/components/__tests__/HierarchicalMenu.js +23 -0
- package/src/components/__tests__/Hits.js +22 -1
- package/src/components/__tests__/InfiniteHits.js +21 -0
- package/src/components/__tests__/InstantSearch-integration.js +155 -1
- package/src/components/__tests__/Menu.js +22 -0
- package/src/components/__tests__/MenuSelect.js +22 -0
- package/src/components/__tests__/NumericMenu.js +22 -0
- package/src/components/__tests__/RangeInput.js +22 -0
- package/src/components/__tests__/RatingMenu.js +23 -0
- package/src/components/__tests__/RefinementList.js +22 -0
- package/src/components/__tests__/ToggleRefinement.js +22 -0
- package/src/mixins/widget.js +1 -1
- package/src/util/__tests__/createServerRootMixin.test.js +229 -83
- package/src/util/createInstantSearchComponent.js +16 -0
- package/src/util/createServerRootMixin.js +40 -104
- package/src/util/testutils/helper.js +2 -2
- package/src/widgets.js +1 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import { createLocalVue, mount } from '@vue/test-utils';
|
|
2
|
+
import DynamicWidgets from '../DynamicWidgets';
|
|
3
|
+
import { __setState } from '../../mixins/widget';
|
|
4
|
+
import { plugin } from '../../plugin';
|
|
5
|
+
jest.mock('../../mixins/widget');
|
|
6
|
+
|
|
7
|
+
const MockRefinementList = {
|
|
8
|
+
props: { attribute: { type: String } },
|
|
9
|
+
render(h) {
|
|
10
|
+
return h('div', {
|
|
11
|
+
attrs: {
|
|
12
|
+
'widget-name': 'ais-refinement-list',
|
|
13
|
+
attribute: this.attribute,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const MockMenu = {
|
|
20
|
+
props: { attribute: { type: String } },
|
|
21
|
+
render(h) {
|
|
22
|
+
return h('div', {
|
|
23
|
+
attrs: { 'widget-name': 'ais-menu', attribute: this.attribute },
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const MockHierarchicalMenu = {
|
|
29
|
+
props: { attributes: { type: Array } },
|
|
30
|
+
render(h) {
|
|
31
|
+
return h('div', {
|
|
32
|
+
attrs: {
|
|
33
|
+
'widget-name': 'ais-hierarchical-menu',
|
|
34
|
+
attributes: this.attributes,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
it('renders all children without state', () => {
|
|
41
|
+
const localVue = createLocalVue();
|
|
42
|
+
|
|
43
|
+
localVue.use(plugin);
|
|
44
|
+
|
|
45
|
+
__setState(null);
|
|
46
|
+
|
|
47
|
+
const wrapper = mount(DynamicWidgets, {
|
|
48
|
+
localVue,
|
|
49
|
+
propsData: {
|
|
50
|
+
transformItems: items => items,
|
|
51
|
+
},
|
|
52
|
+
slots: {
|
|
53
|
+
default: `
|
|
54
|
+
<ais-refinement-list attribute="test1"/>
|
|
55
|
+
<ais-menu attribute="test2"/>
|
|
56
|
+
<ais-panel>
|
|
57
|
+
<ais-hierarchical-menu :attributes="['test3', 'test4']" />
|
|
58
|
+
</ais-panel>
|
|
59
|
+
`,
|
|
60
|
+
},
|
|
61
|
+
stubs: {
|
|
62
|
+
'ais-refinement-list': MockRefinementList,
|
|
63
|
+
'ais-menu': MockMenu,
|
|
64
|
+
'ais-hierarchical-menu': MockHierarchicalMenu,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
69
|
+
|
|
70
|
+
<div hidden="hidden"
|
|
71
|
+
class="ais-DynamicWidgets"
|
|
72
|
+
>
|
|
73
|
+
<div class="ais-DynamicWidgets-widget">
|
|
74
|
+
<div widget-name="ais-refinement-list"
|
|
75
|
+
attribute="test1"
|
|
76
|
+
>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="ais-DynamicWidgets-widget">
|
|
80
|
+
<div widget-name="ais-menu"
|
|
81
|
+
attribute="test2"
|
|
82
|
+
>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="ais-DynamicWidgets-widget">
|
|
86
|
+
<div class="ais-Panel">
|
|
87
|
+
<div class="ais-Panel-body">
|
|
88
|
+
<div widget-name="ais-hierarchical-menu"
|
|
89
|
+
attributes="test3,test4"
|
|
90
|
+
>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
`);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('renders nothing without children', () => {
|
|
101
|
+
__setState({
|
|
102
|
+
attributesToRender: ['something-that-does-not-show'],
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const wrapper = mount(DynamicWidgets, {
|
|
106
|
+
propsData: {
|
|
107
|
+
transformItems: items => items,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
111
|
+
|
|
112
|
+
<div class="ais-DynamicWidgets">
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
`);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('renders nothing with empty attributesToRender', () => {
|
|
119
|
+
const localVue = createLocalVue();
|
|
120
|
+
|
|
121
|
+
localVue.use(plugin);
|
|
122
|
+
|
|
123
|
+
__setState({
|
|
124
|
+
attributesToRender: [],
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const wrapper = mount(DynamicWidgets, {
|
|
128
|
+
localVue,
|
|
129
|
+
propsData: {
|
|
130
|
+
transformItems: items => items,
|
|
131
|
+
},
|
|
132
|
+
slots: {
|
|
133
|
+
default: `<ais-refinement-list attribute="test1"/>`,
|
|
134
|
+
},
|
|
135
|
+
stubs: {
|
|
136
|
+
'ais-refinement-list': MockRefinementList,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
141
|
+
|
|
142
|
+
<div class="ais-DynamicWidgets">
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
`);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('renders attributesToRender (menu)', () => {
|
|
149
|
+
const localVue = createLocalVue();
|
|
150
|
+
|
|
151
|
+
localVue.use(plugin);
|
|
152
|
+
|
|
153
|
+
__setState({
|
|
154
|
+
attributesToRender: ['test1'],
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const wrapper = mount(DynamicWidgets, {
|
|
158
|
+
localVue,
|
|
159
|
+
propsData: {
|
|
160
|
+
transformItems: items => items,
|
|
161
|
+
},
|
|
162
|
+
slots: {
|
|
163
|
+
default: `
|
|
164
|
+
<ais-menu attribute="test1" />
|
|
165
|
+
<ais-refinement-list attribute="test2" />
|
|
166
|
+
`,
|
|
167
|
+
},
|
|
168
|
+
stubs: {
|
|
169
|
+
'ais-refinement-list': MockRefinementList,
|
|
170
|
+
'ais-menu': MockMenu,
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
175
|
+
|
|
176
|
+
<div class="ais-DynamicWidgets">
|
|
177
|
+
<div class="ais-DynamicWidgets-widget">
|
|
178
|
+
<div widget-name="ais-menu"
|
|
179
|
+
attribute="test1"
|
|
180
|
+
>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
`);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('renders attributesToRender (refinement list)', () => {
|
|
189
|
+
const localVue = createLocalVue();
|
|
190
|
+
|
|
191
|
+
localVue.use(plugin);
|
|
192
|
+
|
|
193
|
+
__setState({
|
|
194
|
+
attributesToRender: ['test2'],
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const wrapper = mount(DynamicWidgets, {
|
|
198
|
+
localVue,
|
|
199
|
+
propsData: {
|
|
200
|
+
transformItems: items => items,
|
|
201
|
+
},
|
|
202
|
+
slots: {
|
|
203
|
+
default: `
|
|
204
|
+
<ais-menu attribute="test1" />
|
|
205
|
+
<ais-refinement-list attribute="test2" />
|
|
206
|
+
`,
|
|
207
|
+
},
|
|
208
|
+
stubs: {
|
|
209
|
+
'ais-refinement-list': MockRefinementList,
|
|
210
|
+
'ais-menu': MockMenu,
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
215
|
+
|
|
216
|
+
<div class="ais-DynamicWidgets">
|
|
217
|
+
<div class="ais-DynamicWidgets-widget">
|
|
218
|
+
<div widget-name="ais-refinement-list"
|
|
219
|
+
attribute="test2"
|
|
220
|
+
>
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
|
|
225
|
+
`);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('renders attributesToRender (panel)', () => {
|
|
229
|
+
const localVue = createLocalVue();
|
|
230
|
+
|
|
231
|
+
localVue.use(plugin);
|
|
232
|
+
|
|
233
|
+
__setState({
|
|
234
|
+
attributesToRender: ['test2'],
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const wrapper = mount(DynamicWidgets, {
|
|
238
|
+
localVue,
|
|
239
|
+
propsData: {
|
|
240
|
+
transformItems: items => items,
|
|
241
|
+
},
|
|
242
|
+
slots: {
|
|
243
|
+
default: `
|
|
244
|
+
<ais-menu attribute="test1" />
|
|
245
|
+
<ais-panel>
|
|
246
|
+
<ais-refinement-list attribute="test2" />
|
|
247
|
+
</ais-panel>
|
|
248
|
+
`,
|
|
249
|
+
},
|
|
250
|
+
stubs: {
|
|
251
|
+
'ais-refinement-list': MockRefinementList,
|
|
252
|
+
'ais-menu': MockMenu,
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
257
|
+
|
|
258
|
+
<div class="ais-DynamicWidgets">
|
|
259
|
+
<div class="ais-DynamicWidgets-widget">
|
|
260
|
+
<div class="ais-Panel">
|
|
261
|
+
<div class="ais-Panel-body">
|
|
262
|
+
<div widget-name="ais-refinement-list"
|
|
263
|
+
attribute="test2"
|
|
264
|
+
>
|
|
265
|
+
</div>
|
|
266
|
+
</div>
|
|
267
|
+
</div>
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
`);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('renders attributesToRender (hierarchical menu)', () => {
|
|
275
|
+
const localVue = createLocalVue();
|
|
276
|
+
|
|
277
|
+
localVue.use(plugin);
|
|
278
|
+
|
|
279
|
+
__setState({
|
|
280
|
+
attributesToRender: ['test1'],
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
const wrapper = mount(DynamicWidgets, {
|
|
284
|
+
localVue,
|
|
285
|
+
propsData: {
|
|
286
|
+
transformItems: items => items,
|
|
287
|
+
},
|
|
288
|
+
slots: {
|
|
289
|
+
default: `
|
|
290
|
+
<ais-hierarchical-menu :attributes="['test1','test2']" />
|
|
291
|
+
<ais-menu attribute="test3" />
|
|
292
|
+
<ais-panel>
|
|
293
|
+
<ais-refinement-list attribute="test4" />
|
|
294
|
+
</ais-panel>
|
|
295
|
+
`,
|
|
296
|
+
},
|
|
297
|
+
stubs: {
|
|
298
|
+
'ais-refinement-list': MockRefinementList,
|
|
299
|
+
'ais-menu': MockMenu,
|
|
300
|
+
'ais-hierarchical-menu': MockHierarchicalMenu,
|
|
301
|
+
},
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
305
|
+
|
|
306
|
+
<div class="ais-DynamicWidgets">
|
|
307
|
+
<div class="ais-DynamicWidgets-widget">
|
|
308
|
+
<div widget-name="ais-hierarchical-menu"
|
|
309
|
+
attributes="test1,test2"
|
|
310
|
+
>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
|
|
315
|
+
`);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it('updates DOM when attributesToRender changes', () => {
|
|
319
|
+
const localVue = createLocalVue();
|
|
320
|
+
|
|
321
|
+
localVue.use(plugin);
|
|
322
|
+
|
|
323
|
+
let attributesToRender = ['test1'];
|
|
324
|
+
|
|
325
|
+
__setState({
|
|
326
|
+
get attributesToRender() {
|
|
327
|
+
return attributesToRender;
|
|
328
|
+
},
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
const wrapper = mount(DynamicWidgets, {
|
|
332
|
+
localVue,
|
|
333
|
+
propsData: {
|
|
334
|
+
transformItems: items => items,
|
|
335
|
+
},
|
|
336
|
+
slots: {
|
|
337
|
+
default: `
|
|
338
|
+
<ais-hierarchical-menu :attributes="['test1','test2']" />
|
|
339
|
+
<ais-menu attribute="test3" />
|
|
340
|
+
<ais-panel>
|
|
341
|
+
<ais-refinement-list attribute="test4" />
|
|
342
|
+
</ais-panel>
|
|
343
|
+
`,
|
|
344
|
+
},
|
|
345
|
+
stubs: {
|
|
346
|
+
'ais-refinement-list': MockRefinementList,
|
|
347
|
+
'ais-menu': MockMenu,
|
|
348
|
+
'ais-hierarchical-menu': MockHierarchicalMenu,
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
353
|
+
|
|
354
|
+
<div class="ais-DynamicWidgets">
|
|
355
|
+
<div class="ais-DynamicWidgets-widget">
|
|
356
|
+
<div widget-name="ais-hierarchical-menu"
|
|
357
|
+
attributes="test1,test2"
|
|
358
|
+
>
|
|
359
|
+
</div>
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
|
|
363
|
+
`);
|
|
364
|
+
|
|
365
|
+
attributesToRender = ['test3'];
|
|
366
|
+
|
|
367
|
+
wrapper.vm.$forceUpdate();
|
|
368
|
+
|
|
369
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
370
|
+
|
|
371
|
+
<div class="ais-DynamicWidgets">
|
|
372
|
+
<div class="ais-DynamicWidgets-widget">
|
|
373
|
+
<div widget-name="ais-menu"
|
|
374
|
+
attribute="test3"
|
|
375
|
+
>
|
|
376
|
+
</div>
|
|
377
|
+
</div>
|
|
378
|
+
</div>
|
|
379
|
+
|
|
380
|
+
`);
|
|
381
|
+
|
|
382
|
+
attributesToRender = ['test1', 'test4'];
|
|
383
|
+
|
|
384
|
+
wrapper.vm.$forceUpdate();
|
|
385
|
+
|
|
386
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
387
|
+
|
|
388
|
+
<div class="ais-DynamicWidgets">
|
|
389
|
+
<div class="ais-DynamicWidgets-widget">
|
|
390
|
+
<div widget-name="ais-hierarchical-menu"
|
|
391
|
+
attributes="test1,test2"
|
|
392
|
+
>
|
|
393
|
+
</div>
|
|
394
|
+
</div>
|
|
395
|
+
<div class="ais-DynamicWidgets-widget">
|
|
396
|
+
<div class="ais-Panel">
|
|
397
|
+
<div class="ais-Panel-body">
|
|
398
|
+
<div widget-name="ais-refinement-list"
|
|
399
|
+
attribute="test4"
|
|
400
|
+
>
|
|
401
|
+
</div>
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
</div>
|
|
405
|
+
</div>
|
|
406
|
+
|
|
407
|
+
`);
|
|
408
|
+
|
|
409
|
+
attributesToRender = [];
|
|
410
|
+
|
|
411
|
+
wrapper.vm.$forceUpdate();
|
|
412
|
+
|
|
413
|
+
expect(wrapper.html()).toMatchInlineSnapshot(`
|
|
414
|
+
|
|
415
|
+
<div class="ais-DynamicWidgets">
|
|
416
|
+
</div>
|
|
417
|
+
|
|
418
|
+
`);
|
|
419
|
+
});
|
|
@@ -117,6 +117,7 @@ const defaultState = {
|
|
|
117
117
|
isShowingMore: false,
|
|
118
118
|
canToggleShowMore: true,
|
|
119
119
|
toggleShowMore: () => {},
|
|
120
|
+
sendEvent: () => {},
|
|
120
121
|
};
|
|
121
122
|
|
|
122
123
|
const defaultProps = {
|
|
@@ -488,6 +489,28 @@ it('calls the Panel mixin with `items.length`', () => {
|
|
|
488
489
|
expect(wrapper.vm.mapStateToCanRefine({})).toBe(false);
|
|
489
490
|
});
|
|
490
491
|
|
|
492
|
+
it('exposes send-event method for insights middleware', () => {
|
|
493
|
+
const sendEvent = jest.fn();
|
|
494
|
+
__setState({
|
|
495
|
+
...defaultState,
|
|
496
|
+
sendEvent,
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
const wrapper = mount(HierarchicalMenu, {
|
|
500
|
+
propsData: defaultProps,
|
|
501
|
+
scopedSlots: {
|
|
502
|
+
default: `
|
|
503
|
+
<div slot-scope="{ sendEvent }">
|
|
504
|
+
<button @click="sendEvent()">Send Event</button>
|
|
505
|
+
</div>
|
|
506
|
+
`,
|
|
507
|
+
},
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
wrapper.find('button').trigger('click');
|
|
511
|
+
expect(sendEvent).toHaveBeenCalledTimes(1);
|
|
512
|
+
});
|
|
513
|
+
|
|
491
514
|
describe('custom default render', () => {
|
|
492
515
|
const defaultScopedSlot = `
|
|
493
516
|
<div
|
|
@@ -60,7 +60,7 @@ it('exposes insights prop to the default slot', () => {
|
|
|
60
60
|
default: `
|
|
61
61
|
<ul slot-scope="{ items, insights }">
|
|
62
62
|
<li v-for="(item, itemIndex) in items" >
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
<button :id="'add-to-cart-' + item.objectID" @click="insights('clickedObjectIDsAfterSearch', {eventName: 'Add to cart', objectIDs: [item.objectID]})">
|
|
65
65
|
Add to cart
|
|
66
66
|
</button>
|
|
@@ -100,3 +100,24 @@ it('exposes insights prop to the item slot', () => {
|
|
|
100
100
|
objectIDs: ['two'],
|
|
101
101
|
});
|
|
102
102
|
});
|
|
103
|
+
|
|
104
|
+
it('exposes send-event method for insights middleware', () => {
|
|
105
|
+
const sendEvent = jest.fn();
|
|
106
|
+
__setState({
|
|
107
|
+
...defaultState,
|
|
108
|
+
sendEvent,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const wrapper = mount(Hits, {
|
|
112
|
+
scopedSlots: {
|
|
113
|
+
default: `
|
|
114
|
+
<div slot-scope="{ sendEvent }">
|
|
115
|
+
<button @click="sendEvent()">Send Event</button>
|
|
116
|
+
</div>
|
|
117
|
+
`,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
wrapper.find('button').trigger('click');
|
|
122
|
+
expect(sendEvent).toHaveBeenCalledTimes(1);
|
|
123
|
+
});
|
|
@@ -294,3 +294,24 @@ it('exposes insights prop to the item slot', () => {
|
|
|
294
294
|
objectIDs: ['00002'],
|
|
295
295
|
});
|
|
296
296
|
});
|
|
297
|
+
|
|
298
|
+
it('exposes send-event method for insights middleware', () => {
|
|
299
|
+
const sendEvent = jest.fn();
|
|
300
|
+
__setState({
|
|
301
|
+
...defaultState,
|
|
302
|
+
sendEvent,
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const wrapper = mount(InfiniteHits, {
|
|
306
|
+
scopedSlots: {
|
|
307
|
+
default: `
|
|
308
|
+
<div slot-scope="{ sendEvent }">
|
|
309
|
+
<button @click="sendEvent()">Send Event</button>
|
|
310
|
+
</div>
|
|
311
|
+
`,
|
|
312
|
+
},
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
wrapper.find('button').trigger('click');
|
|
316
|
+
expect(sendEvent).toHaveBeenCalledTimes(1);
|
|
317
|
+
});
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import Vue from 'vue';
|
|
1
2
|
import { mount } from '@vue/test-utils';
|
|
2
3
|
import InstantSearch from '../InstantSearch';
|
|
3
4
|
import { createWidgetMixin } from '../../mixins/widget';
|
|
4
5
|
import { createFakeClient } from '../../util/testutils/client';
|
|
5
|
-
|
|
6
|
+
import SearchBox from '../SearchBox.vue';
|
|
6
7
|
jest.unmock('instantsearch.js/es');
|
|
7
8
|
|
|
9
|
+
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
10
|
+
|
|
8
11
|
it('child widgets get added to its parent instantsearch', () => {
|
|
9
12
|
const widgetInstance = {
|
|
10
13
|
render() {},
|
|
@@ -32,3 +35,154 @@ it('child widgets get added to its parent instantsearch', () => {
|
|
|
32
35
|
widgetInstance
|
|
33
36
|
);
|
|
34
37
|
});
|
|
38
|
+
|
|
39
|
+
describe('middlewares', () => {
|
|
40
|
+
const createFakeMiddleware = () => {
|
|
41
|
+
const middlewareSpy = {
|
|
42
|
+
onStateChange: jest.fn(),
|
|
43
|
+
subscribe: jest.fn(),
|
|
44
|
+
unsubscribe: jest.fn(),
|
|
45
|
+
};
|
|
46
|
+
const middleware = jest.fn(() => middlewareSpy);
|
|
47
|
+
|
|
48
|
+
return [middleware, middlewareSpy];
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
it('subscribes middlewares', async () => {
|
|
52
|
+
const [middleware, middlewareSpy] = createFakeMiddleware();
|
|
53
|
+
|
|
54
|
+
mount(InstantSearch, {
|
|
55
|
+
propsData: {
|
|
56
|
+
searchClient: createFakeClient(),
|
|
57
|
+
indexName: 'indexName',
|
|
58
|
+
middlewares: [middleware],
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
await Vue.nextTick();
|
|
62
|
+
|
|
63
|
+
expect(middlewareSpy.subscribe).toHaveBeenCalledTimes(1);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('subscribes newly added middleware', async () => {
|
|
67
|
+
const [middleware1, middlewareSpy1] = createFakeMiddleware();
|
|
68
|
+
|
|
69
|
+
const wrapper = mount({
|
|
70
|
+
components: {
|
|
71
|
+
AisInstantSearch: InstantSearch,
|
|
72
|
+
AisSearchBox: SearchBox,
|
|
73
|
+
},
|
|
74
|
+
template: `
|
|
75
|
+
<ais-instant-search
|
|
76
|
+
:search-client="searchClient"
|
|
77
|
+
:index-name="indexName"
|
|
78
|
+
:middlewares="middlewares"
|
|
79
|
+
>
|
|
80
|
+
<ais-search-box />
|
|
81
|
+
</ais-instant-search>
|
|
82
|
+
`,
|
|
83
|
+
data() {
|
|
84
|
+
return {
|
|
85
|
+
searchClient: createFakeClient(),
|
|
86
|
+
indexName: 'indexName',
|
|
87
|
+
middlewares: [middleware1],
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
await wait(20);
|
|
93
|
+
expect(middlewareSpy1.subscribe).toHaveBeenCalledTimes(1);
|
|
94
|
+
|
|
95
|
+
await wrapper.find('input').setValue('a');
|
|
96
|
+
await Vue.nextTick();
|
|
97
|
+
|
|
98
|
+
expect(middlewareSpy1.onStateChange).toHaveBeenCalledTimes(1);
|
|
99
|
+
expect(middlewareSpy1.onStateChange).toHaveBeenCalledWith({
|
|
100
|
+
uiState: { indexName: { query: 'a' } },
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const [middleware2, middlewareSpy2] = createFakeMiddleware();
|
|
104
|
+
wrapper.setData({
|
|
105
|
+
middlewares: [middleware1, middleware2],
|
|
106
|
+
});
|
|
107
|
+
await Vue.nextTick();
|
|
108
|
+
|
|
109
|
+
expect(middlewareSpy2.subscribe).toHaveBeenCalledTimes(1);
|
|
110
|
+
expect(middlewareSpy2.onStateChange).toHaveBeenCalledTimes(0);
|
|
111
|
+
|
|
112
|
+
await wrapper.find('input').setValue('b');
|
|
113
|
+
await Vue.nextTick();
|
|
114
|
+
|
|
115
|
+
expect(middlewareSpy1.onStateChange).toHaveBeenCalledTimes(2);
|
|
116
|
+
expect(middlewareSpy1.onStateChange).toHaveBeenCalledWith({
|
|
117
|
+
uiState: { indexName: { query: 'b' } },
|
|
118
|
+
});
|
|
119
|
+
expect(middlewareSpy2.onStateChange).toHaveBeenCalledTimes(1);
|
|
120
|
+
expect(middlewareSpy2.onStateChange).toHaveBeenCalledWith({
|
|
121
|
+
uiState: { indexName: { query: 'b' } },
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
expect(middlewareSpy1.unsubscribe).toHaveBeenCalledTimes(0);
|
|
125
|
+
expect(middlewareSpy2.unsubscribe).toHaveBeenCalledTimes(0);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('unsubscribes removed middleware', async () => {
|
|
129
|
+
const [middleware1, middlewareSpy1] = createFakeMiddleware();
|
|
130
|
+
const [middleware2, middlewareSpy2] = createFakeMiddleware();
|
|
131
|
+
|
|
132
|
+
const wrapper = mount({
|
|
133
|
+
components: {
|
|
134
|
+
AisInstantSearch: InstantSearch,
|
|
135
|
+
AisSearchBox: SearchBox,
|
|
136
|
+
},
|
|
137
|
+
template: `
|
|
138
|
+
<ais-instant-search
|
|
139
|
+
:search-client="searchClient"
|
|
140
|
+
:index-name="indexName"
|
|
141
|
+
:middlewares="middlewares"
|
|
142
|
+
>
|
|
143
|
+
<ais-search-box />
|
|
144
|
+
</ais-instant-search>
|
|
145
|
+
`,
|
|
146
|
+
data() {
|
|
147
|
+
return {
|
|
148
|
+
searchClient: createFakeClient(),
|
|
149
|
+
indexName: 'indexName',
|
|
150
|
+
middlewares: [middleware1, middleware2],
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
await wait(20);
|
|
156
|
+
expect(middlewareSpy1.subscribe).toHaveBeenCalledTimes(1);
|
|
157
|
+
expect(middlewareSpy2.subscribe).toHaveBeenCalledTimes(1);
|
|
158
|
+
|
|
159
|
+
await wrapper.find('input').setValue('a');
|
|
160
|
+
await Vue.nextTick();
|
|
161
|
+
|
|
162
|
+
expect(middlewareSpy1.onStateChange).toHaveBeenCalledTimes(1);
|
|
163
|
+
expect(middlewareSpy1.onStateChange).toHaveBeenCalledWith({
|
|
164
|
+
uiState: { indexName: { query: 'a' } },
|
|
165
|
+
});
|
|
166
|
+
expect(middlewareSpy2.onStateChange).toHaveBeenCalledTimes(1);
|
|
167
|
+
expect(middlewareSpy2.onStateChange).toHaveBeenCalledWith({
|
|
168
|
+
uiState: { indexName: { query: 'a' } },
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
wrapper.setData({
|
|
172
|
+
middlewares: [middleware1],
|
|
173
|
+
});
|
|
174
|
+
await Vue.nextTick();
|
|
175
|
+
|
|
176
|
+
expect(middlewareSpy1.unsubscribe).toHaveBeenCalledTimes(0);
|
|
177
|
+
expect(middlewareSpy2.unsubscribe).toHaveBeenCalledTimes(1);
|
|
178
|
+
|
|
179
|
+
await wrapper.find('input').setValue('b');
|
|
180
|
+
await Vue.nextTick();
|
|
181
|
+
|
|
182
|
+
expect(middlewareSpy1.onStateChange).toHaveBeenCalledTimes(2);
|
|
183
|
+
expect(middlewareSpy1.onStateChange).toHaveBeenCalledWith({
|
|
184
|
+
uiState: { indexName: { query: 'b' } },
|
|
185
|
+
});
|
|
186
|
+
expect(middlewareSpy2.onStateChange).toHaveBeenCalledTimes(1);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
@@ -337,6 +337,28 @@ it('calls the Panel mixin with `canRefine`', () => {
|
|
|
337
337
|
expect(wrapper.vm.mapStateToCanRefine({})).toBe(false);
|
|
338
338
|
});
|
|
339
339
|
|
|
340
|
+
it('exposes send-event method for insights middleware', () => {
|
|
341
|
+
const sendEvent = jest.fn();
|
|
342
|
+
__setState({
|
|
343
|
+
...defaultState,
|
|
344
|
+
sendEvent,
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
const wrapper = mount(Menu, {
|
|
348
|
+
propsData: defaultProps,
|
|
349
|
+
scopedSlots: {
|
|
350
|
+
default: `
|
|
351
|
+
<div slot-scope="{ sendEvent }">
|
|
352
|
+
<button @click="sendEvent()">Send Event</button>
|
|
353
|
+
</div>
|
|
354
|
+
`,
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
wrapper.find('button').trigger('click');
|
|
359
|
+
expect(sendEvent).toHaveBeenCalledTimes(1);
|
|
360
|
+
});
|
|
361
|
+
|
|
340
362
|
describe('custom default render', () => {
|
|
341
363
|
const defaultScopedSlot = `
|
|
342
364
|
<div
|