Skip to content

Commit 88fd6d5

Browse files
author
vvo
committed
feat(connectRefinementList): first good iteration
1 parent 441293d commit 88fd6d5

File tree

7 files changed

+531
-391
lines changed

7 files changed

+531
-391
lines changed
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/* eslint-env mocha */
2+
3+
import expect from 'expect';
4+
import sinon from 'sinon';
5+
6+
import algoliasearchHelper from 'algoliasearch-helper';
7+
const SearchResults = algoliasearchHelper.SearchResults;
8+
9+
import connectRefinementList from '../connectRefinementList.js';
10+
11+
const fakeClient = {addAlgoliaAgent: () => {}};
12+
13+
describe('connectRefinementList', () => {
14+
let rendering;
15+
let makeWidget;
16+
beforeEach(() => {
17+
rendering = sinon.stub();
18+
makeWidget = connectRefinementList(rendering);
19+
});
20+
21+
it('throws on bad usage', () => {
22+
expect(
23+
connectRefinementList
24+
).toThrow();
25+
26+
expect(
27+
() => connectRefinementList({
28+
operator: 'and',
29+
})
30+
).toThrow();
31+
32+
expect(
33+
() => connectRefinementList(() => {})()
34+
).toThrow();
35+
36+
expect(
37+
() => connectRefinementList(() => {})({
38+
operator: 'and',
39+
})
40+
).toThrow();
41+
42+
expect(
43+
() => connectRefinementList(() => {})({
44+
attributeName: 'company',
45+
operator: 'YUP',
46+
})
47+
).toThrow();
48+
});
49+
50+
context('options configuring the helper', () => {
51+
it('`attributeName`', () => {
52+
const widget = makeWidget({
53+
attributeName: 'myFacet',
54+
});
55+
56+
expect(widget.getConfiguration())
57+
.toEqual({
58+
disjunctiveFacets: ['myFacet'],
59+
});
60+
});
61+
62+
it('`limit`', () => {
63+
const widget = makeWidget({
64+
attributeName: 'myFacet',
65+
limit: 20,
66+
});
67+
68+
expect(widget.getConfiguration())
69+
.toEqual({
70+
disjunctiveFacets: ['myFacet'],
71+
maxValuesPerFacet: 20,
72+
});
73+
74+
expect(widget.getConfiguration({maxValuesPerFacet: 100}))
75+
.toEqual({
76+
disjunctiveFacets: ['myFacet'],
77+
maxValuesPerFacet: 100,
78+
}, 'Can read the previous maxValuesPerFacet value');
79+
});
80+
81+
it('`operator="and"`', () => {
82+
const widget = makeWidget({
83+
attributeName: 'myFacet',
84+
operator: 'and',
85+
});
86+
87+
expect(widget.getConfiguration())
88+
.toEqual({
89+
facets: ['myFacet'],
90+
});
91+
});
92+
});
93+
94+
it('calls render method at init time', () => {
95+
96+
});
97+
98+
it('calls render method when we have new results', () => {
99+
100+
});
101+
102+
it('Renders during init and render', () => {
103+
// test that the dummyRendering is called with the isFirstRendering
104+
// flag set accordingly
105+
const widget = makeWidget({
106+
attributeName: 'myFacet',
107+
limit: 9,
108+
});
109+
110+
const config = widget.getConfiguration({});
111+
expect(config).toEqual({
112+
disjunctiveFacets: ['myFacet'],
113+
maxValuesPerFacet: 9,
114+
});
115+
116+
// test if widget is not rendered yet at this point
117+
expect(rendering.callCount).toBe(0);
118+
119+
const helper = algoliasearchHelper(fakeClient, '', config);
120+
helper.search = sinon.stub();
121+
122+
widget.init({
123+
helper,
124+
state: helper.state,
125+
createURL: () => '#',
126+
onHistoryChange: () => {},
127+
});
128+
129+
// test that rendering has been called during init with isFirstRendering = true
130+
expect(rendering.callCount).toBe(1);
131+
// test if isFirstRendering is true during init
132+
expect(rendering.lastCall.args[1]).toBe(true);
133+
134+
const firstRenderingOptions = rendering.lastCall.args[0];
135+
expect(firstRenderingOptions.canRefine).toBe(false);
136+
137+
widget.render({
138+
results: new SearchResults(helper.state, [{}]),
139+
state: helper.state,
140+
helper,
141+
createURL: () => '#',
142+
});
143+
144+
// test that rendering has been called during init with isFirstRendering = false
145+
expect(rendering.callCount).toBe(2);
146+
expect(rendering.lastCall.args[1]).toBe(false);
147+
148+
const secondRenderingOptions = rendering.lastCall.args[0];
149+
expect(secondRenderingOptions.canRefine).toBe(false);
150+
});
151+
152+
it('Provide a function to clear the refinements at each step', () => {
153+
const widget = makeWidget({
154+
attributeName: 'category',
155+
});
156+
157+
const helper = algoliasearchHelper(fakeClient, '', widget.getConfiguration({}));
158+
helper.search = sinon.stub();
159+
160+
helper.toggleRefinement('category', 'value');
161+
162+
widget.init({
163+
helper,
164+
state: helper.state,
165+
createURL: () => '#',
166+
onHistoryChange: () => {},
167+
});
168+
169+
const firstRenderingOptions = rendering.lastCall.args[0];
170+
const {refine} = firstRenderingOptions;
171+
refine('value');
172+
expect(helper.hasRefinements('category')).toBe(false);
173+
refine('value');
174+
expect(helper.hasRefinements('category')).toBe(true);
175+
176+
widget.render({
177+
results: new SearchResults(helper.state, [{}, {}]),
178+
state: helper.state,
179+
helper,
180+
createURL: () => '#',
181+
});
182+
183+
const secondRenderingOptions = rendering.lastCall.args[0];
184+
const {refine: renderToggleRefinement} = secondRenderingOptions;
185+
renderToggleRefinement('value');
186+
expect(helper.hasRefinements('category')).toBe(false);
187+
renderToggleRefinement('value');
188+
expect(helper.hasRefinements('category')).toBe(true);
189+
});
190+
191+
it('provides the correct facet values', () => {
192+
const widget = makeWidget({
193+
attributeName: 'category',
194+
});
195+
196+
const helper = algoliasearchHelper(fakeClient, '', widget.getConfiguration({}));
197+
helper.search = sinon.stub();
198+
199+
helper.toggleRefinement('category', 'Decoration');
200+
201+
widget.init({
202+
helper,
203+
state: helper.state,
204+
createURL: () => '#',
205+
onHistoryChange: () => {},
206+
});
207+
208+
const firstRenderingOptions = rendering.lastCall.args[0];
209+
// During the first rendering there are no facet values
210+
// The function get an empty array so that it doesn't break
211+
// over null-ish values.
212+
expect(firstRenderingOptions.items).toEqual([]);
213+
214+
widget.render({
215+
results: new SearchResults(helper.state, [{
216+
hits: [],
217+
facets: {
218+
category: {
219+
Decoration: 880,
220+
},
221+
},
222+
}, {
223+
facets: {
224+
category: {
225+
Decoration: 880,
226+
Outdoor: 47,
227+
},
228+
},
229+
}]),
230+
state: helper.state,
231+
helper,
232+
createURL: () => '#',
233+
});
234+
235+
const secondRenderingOptions = rendering.lastCall.args[0];
236+
expect(secondRenderingOptions.items).toEqual([
237+
{
238+
name: 'Decoration',
239+
highlighted: 'Decoration',
240+
count: 880,
241+
isRefined: true,
242+
},
243+
{
244+
name: 'Outdoor',
245+
highlighted: 'Outdoor',
246+
count: 47,
247+
isRefined: false,
248+
},
249+
]);
250+
});
251+
});

0 commit comments

Comments
 (0)