Skip to content

Commit d80500d

Browse files
refactor(atomic): address PR review feedback for atomic-category-facet
- Combine headless imports - Remove InitializeBindingsMixin (use @bindings decorator directly) - Use booleanConverter for boolean properties - Add TODO comments for filterByBasePath and filterFacetCount deprecation - Refactor Schema as static readonly propsSchema - Use ValidatePropsController with throwOnError=false - Remove unnecessary CSS @reference directive - Remove mixin mock from tests - Flatten single-test describe blocks in tests - Add prop validation tests with skip for V4 Co-authored-by: fbeaudoincoveo <23503066+fbeaudoincoveo@users.noreply.github.com>
1 parent 543a7cf commit d80500d

File tree

2 files changed

+191
-156
lines changed

2 files changed

+191
-156
lines changed

packages/atomic/src/components/search/atomic-category-facet/atomic-category-facet.spec.ts

Lines changed: 125 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,6 @@ import type {AtomicCategoryFacet} from './atomic-category-facet';
1818
import './atomic-category-facet';
1919

2020
vi.mock('@coveo/headless', {spy: true});
21-
vi.mock('@/src/mixins/bindings-mixin', () => ({
22-
InitializeBindingsMixin: vi.fn().mockImplementation((superClass) => {
23-
return class extends superClass {
24-
// biome-ignore lint/complexity/noUselessConstructor: <mocking the mixin for testing>
25-
constructor(...args: unknown[]) {
26-
super(...args);
27-
}
28-
};
29-
}),
30-
}));
3121

3222
describe('atomic-category-facet', () => {
3323
let mockedConsoleWarn: MockInstance;
@@ -171,120 +161,104 @@ describe('atomic-category-facet', () => {
171161
};
172162
};
173163

174-
describe('when first search not executed', () => {
175-
it('should render placeholder', async () => {
176-
const {placeholder} = await renderCategoryFacet(undefined, {
177-
searchStatusState: {firstSearchExecuted: false},
178-
});
179-
expect(placeholder).toBeInTheDocument();
164+
it('should render placeholder when first search has not been executed', async () => {
165+
const {placeholder} = await renderCategoryFacet(undefined, {
166+
searchStatusState: {firstSearchExecuted: false},
180167
});
168+
expect(placeholder).toBeInTheDocument();
181169
});
182170

183-
describe('when first search executed', () => {
184-
it('should render the facet container', async () => {
185-
const {facet} = await renderCategoryFacet();
186-
expect(facet).toBeInTheDocument();
187-
});
171+
it('should render the facet container when first search is executed', async () => {
172+
const {facet} = await renderCategoryFacet();
173+
expect(facet).toBeInTheDocument();
174+
});
188175

189-
it('should render facet values', async () => {
190-
const {valueLinks} = await renderCategoryFacet();
191-
expect(valueLinks?.length).toBeGreaterThan(0);
192-
});
176+
it('should render facet values when first search is executed', async () => {
177+
const {valueLinks} = await renderCategoryFacet();
178+
expect(valueLinks?.length).toBeGreaterThan(0);
179+
});
193180

194-
it('should render show more button when canShowMoreValues is true', async () => {
195-
const {showMore} = await renderCategoryFacet(undefined, {
196-
facetState: {canShowMoreValues: true},
197-
});
198-
expect(showMore).toBeInTheDocument();
181+
it('should render show more button when canShowMoreValues is true', async () => {
182+
const {showMore} = await renderCategoryFacet(undefined, {
183+
facetState: {canShowMoreValues: true},
199184
});
185+
expect(showMore).toBeInTheDocument();
186+
});
200187

201-
it('should render show less button when canShowLessValues is true', async () => {
202-
const {showLess} = await renderCategoryFacet(undefined, {
203-
facetState: {canShowLessValues: true},
204-
});
205-
expect(showLess).toBeInTheDocument();
188+
it('should render show less button when canShowLessValues is true', async () => {
189+
const {showLess} = await renderCategoryFacet(undefined, {
190+
facetState: {canShowLessValues: true},
206191
});
192+
expect(showLess).toBeInTheDocument();
193+
});
207194

208-
it('should not render show more button when canShowMoreValues is false', async () => {
209-
const {showMore} = await renderCategoryFacet(undefined, {
210-
facetState: {canShowMoreValues: false},
211-
});
212-
expect(showMore).not.toBeInTheDocument();
195+
it('should not render show more button when canShowMoreValues is false', async () => {
196+
const {showMore} = await renderCategoryFacet(undefined, {
197+
facetState: {canShowMoreValues: false},
213198
});
199+
expect(showMore).not.toBeInTheDocument();
214200
});
215201

216-
describe('with search enabled', () => {
217-
it('should render search wrapper', async () => {
218-
const {searchWrapper} = await renderCategoryFacet({withSearch: true});
219-
expect(searchWrapper).toBeInTheDocument();
220-
});
202+
it('should render search wrapper when search is enabled', async () => {
203+
const {searchWrapper} = await renderCategoryFacet({withSearch: true});
204+
expect(searchWrapper).toBeInTheDocument();
221205
});
222206

223-
describe('without search enabled', () => {
224-
it('should not render search wrapper', async () => {
225-
const {searchWrapper} = await renderCategoryFacet({withSearch: false});
226-
expect(searchWrapper).not.toBeInTheDocument();
227-
});
207+
it('should not render search wrapper when search is disabled', async () => {
208+
const {searchWrapper} = await renderCategoryFacet({withSearch: false});
209+
expect(searchWrapper).not.toBeInTheDocument();
228210
});
229211

230-
describe('when collapsed', () => {
231-
it('should not render values', async () => {
232-
const {values} = await renderCategoryFacet({isCollapsed: true});
233-
expect(values).not.toBeInTheDocument();
234-
});
212+
it('should not render values when facet is collapsed', async () => {
213+
const {values} = await renderCategoryFacet({isCollapsed: true});
214+
expect(values).not.toBeInTheDocument();
235215
});
236216

237-
describe('when has error', () => {
238-
it('should not render facet', async () => {
239-
const {facet} = await renderCategoryFacet(undefined, {
240-
searchStatusState: {hasError: true},
241-
});
242-
expect(facet).not.toBeInTheDocument();
217+
it('should not render facet when there is an error', async () => {
218+
const {facet} = await renderCategoryFacet(undefined, {
219+
searchStatusState: {hasError: true},
243220
});
221+
expect(facet).not.toBeInTheDocument();
244222
});
245223

246-
describe('when facet is disabled', () => {
247-
it('should not render facet', async () => {
248-
const {facet} = await renderCategoryFacet(undefined, {
249-
facetState: {enabled: false},
250-
});
251-
expect(facet).not.toBeInTheDocument();
224+
it('should not render facet when it is disabled', async () => {
225+
const {facet} = await renderCategoryFacet(undefined, {
226+
facetState: {enabled: false},
252227
});
228+
expect(facet).not.toBeInTheDocument();
253229
});
254230

255-
describe('when no values', () => {
256-
it('should not render facet', async () => {
257-
const {facet} = await renderCategoryFacet(undefined, {
258-
facetState: {valuesAsTrees: [], values: []},
259-
});
260-
expect(facet).not.toBeInTheDocument();
231+
it('should not render facet when there are no values', async () => {
232+
const {facet} = await renderCategoryFacet(undefined, {
233+
facetState: {valuesAsTrees: [], values: []},
261234
});
235+
expect(facet).not.toBeInTheDocument();
262236
});
263237

264238
describe('when has selected value ancestry', () => {
265-
it('should render all categories button', async () => {
266-
const selectedAncestry = [
267-
{
268-
value: 'Electronics',
269-
numberOfResults: 25,
270-
moreValuesAvailable: true,
271-
state: 'selected' as const,
272-
path: ['Electronics'],
273-
children: [
274-
{
275-
value: 'Laptops',
276-
numberOfResults: 12,
277-
moreValuesAvailable: false,
278-
state: 'idle' as const,
279-
path: ['Electronics', 'Laptops'],
280-
children: [],
281-
isLeafValue: true,
282-
},
283-
],
284-
isLeafValue: false,
285-
},
286-
];
239+
const selectedAncestry = [
240+
{
241+
value: 'Electronics',
242+
numberOfResults: 25,
243+
moreValuesAvailable: true,
244+
state: 'selected' as const,
245+
path: ['Electronics'],
246+
children: [
247+
{
248+
value: 'Laptops',
249+
numberOfResults: 12,
250+
moreValuesAvailable: false,
251+
state: 'idle' as const,
252+
path: ['Electronics', 'Laptops'],
253+
children: [],
254+
isLeafValue: true,
255+
},
256+
],
257+
isLeafValue: false,
258+
},
259+
];
287260

261+
it('should render all categories button', async () => {
288262
const {allCategoriesButton} = await renderCategoryFacet(undefined, {
289263
facetState: {
290264
selectedValueAncestry: selectedAncestry,
@@ -295,28 +269,6 @@ describe('atomic-category-facet', () => {
295269
});
296270

297271
it('should render parents container', async () => {
298-
const selectedAncestry = [
299-
{
300-
value: 'Electronics',
301-
numberOfResults: 25,
302-
moreValuesAvailable: true,
303-
state: 'selected' as const,
304-
path: ['Electronics'],
305-
children: [
306-
{
307-
value: 'Laptops',
308-
numberOfResults: 12,
309-
moreValuesAvailable: false,
310-
state: 'idle' as const,
311-
path: ['Electronics', 'Laptops'],
312-
children: [],
313-
isLeafValue: true,
314-
},
315-
],
316-
isLeafValue: false,
317-
},
318-
];
319-
320272
const {parents} = await renderCategoryFacet(undefined, {
321273
facetState: {
322274
selectedValueAncestry: selectedAncestry,
@@ -353,16 +305,66 @@ describe('atomic-category-facet', () => {
353305
});
354306
});
355307

356-
describe('tabs configuration warning', () => {
357-
it('should log warning when both tabsIncluded and tabsExcluded are provided', async () => {
358-
await renderCategoryFacet({
359-
tabsIncluded: ['tab1'],
360-
tabsExcluded: ['tab2'],
308+
describe('prop validation', () => {
309+
// TODO V4: KIT-XXXX - Remove skip and enable validation errors
310+
it.skip('should set error when field is not provided', async () => {
311+
const {element} = await renderCategoryFacet({field: ''});
312+
expect(element.error).toBeDefined();
313+
expect(element.error.message).toMatch(/field/i);
314+
});
315+
316+
// TODO V4: KIT-XXXX - Remove this test
317+
it('should log validation warning when field is empty', async () => {
318+
await renderCategoryFacet({field: ''});
319+
expect(mockedConsoleWarn).toHaveBeenCalledWith(
320+
expect.stringContaining('Prop validation failed'),
321+
expect.anything()
322+
);
323+
});
324+
325+
// TODO V4: KIT-XXXX - Remove skip and enable validation errors
326+
it.skip('should set error when numberOfValues is less than 1', async () => {
327+
const {element} = await renderCategoryFacet({numberOfValues: 0});
328+
expect(element.error).toBeDefined();
329+
expect(element.error.message).toMatch(/numberOfValues/i);
330+
});
331+
332+
// TODO V4: KIT-XXXX - Remove this test
333+
it('should log validation warning when numberOfValues is less than 1', async () => {
334+
await renderCategoryFacet({numberOfValues: 0});
335+
expect(mockedConsoleWarn).toHaveBeenCalledWith(
336+
expect.stringContaining('Prop validation failed'),
337+
expect.anything()
338+
);
339+
});
340+
341+
// TODO V4: KIT-XXXX - Remove skip and enable validation errors
342+
it.skip('should set error when sortCriteria is invalid', async () => {
343+
const {element} = await renderCategoryFacet({
344+
sortCriteria: 'invalid' as 'alphanumeric',
361345
});
346+
expect(element.error).toBeDefined();
347+
expect(element.error.message).toMatch(/sortCriteria/i);
348+
});
362349

350+
// TODO V4: KIT-XXXX - Remove this test
351+
it('should log validation warning when sortCriteria is invalid', async () => {
352+
await renderCategoryFacet({sortCriteria: 'invalid' as 'alphanumeric'});
363353
expect(mockedConsoleWarn).toHaveBeenCalledWith(
364-
expect.stringContaining('tabs-included')
354+
expect.stringContaining('Prop validation failed'),
355+
expect.anything()
365356
);
366357
});
367358
});
359+
360+
it('should log warning when both tabsIncluded and tabsExcluded are provided', async () => {
361+
await renderCategoryFacet({
362+
tabsIncluded: ['tab1'],
363+
tabsExcluded: ['tab2'],
364+
});
365+
366+
expect(mockedConsoleWarn).toHaveBeenCalledWith(
367+
expect.stringContaining('tabs-included')
368+
);
369+
});
368370
});

0 commit comments

Comments
 (0)