11import React from 'react' ;
2- import { shallow } from '@edx/react-unit-test-utils' ;
2+ import PropTypes from 'prop-types' ;
3+ import { render } from '@testing-library/react' ;
4+ import { DataTableContext } from '@openedx/paragon' ;
35
46import * as module from './FilterStatusComponent' ;
57
6- const fieldIds = [
7- 'field-id-0' ,
8- 'field-id-1' ,
9- 'field-id-2' ,
10- 'field-id-3' ,
11- ] ;
8+ jest . unmock ( '@openedx/paragon' ) ;
9+ jest . unmock ( 'react' ) ;
10+
11+ const fieldIds = [ 'field-id-0' , 'field-id-1' , 'field-id-2' , 'field-id-3' ] ;
1212const filterOrder = [ 1 , 0 , 3 , 2 ] ;
13- const filters = filterOrder . map ( v => ( { id : fieldIds [ v ] } ) ) ;
14- const headers = [ 0 , 1 , 2 , 3 ] . map ( v => ( {
13+ const filters = filterOrder . map ( ( v ) => ( { id : fieldIds [ v ] } ) ) ;
14+ const headers = [ 0 , 1 , 2 , 3 ] . map ( ( v ) => ( {
1515 id : fieldIds [ v ] ,
1616 Header : `HeaDer-${ v } ` ,
1717} ) ) ;
1818
19- describe ( 'FilterStatusComponent hooks' , ( ) => {
20- const context = { headers, state : { filters } } ;
21- const mockTableContext = ( newContext ) => {
22- React . useContext . mockReturnValueOnce ( newContext ) ;
23- } ;
24- beforeEach ( ( ) => {
25- context . setAllFilters = jest . fn ( ) ;
26- } ) ;
27- it ( 'returns empty dict if setAllFilters or state.filters is falsey' , ( ) => {
28- mockTableContext ( { ...context , setAllFilters : null } ) ;
29- expect ( module . filterHooks ( ) ) . toEqual ( { } ) ;
30- mockTableContext ( { ...context , state : { filters : null } } ) ;
31- expect ( module . filterHooks ( ) ) . toEqual ( { } ) ;
32- } ) ;
33- describe ( 'clearFilters' , ( ) => {
34- it ( 'uses React.useCallback to clear filters, only once' , ( ) => {
35- mockTableContext ( context ) ;
36- const { cb, prereqs } = module . filterHooks ( ) . clearFilters . useCallback ;
37- expect ( prereqs ) . toEqual ( [ context . setAllFilters ] ) ;
38- expect ( context . setAllFilters ) . not . toHaveBeenCalled ( ) ;
39- cb ( ) ;
40- expect ( context . setAllFilters ) . toHaveBeenCalledWith ( [ ] ) ;
41- } ) ;
42- } ) ;
43- describe ( 'filterNames' , ( ) => {
44- it ( 'returns list of Header values by filter order' , ( ) => {
45- mockTableContext ( context ) ;
46- expect ( module . filterHooks ( ) . filterNames ) . toEqual (
47- filterOrder . map ( v => headers [ v ] . Header ) ,
48- ) ;
49- } ) ;
50- } ) ;
51- } ) ;
5219describe ( 'FilterStatusComponent component' , ( ) => {
5320 const props = {
5421 className : 'css-class-name' ,
@@ -58,34 +25,98 @@ describe('FilterStatusComponent component', () => {
5825 buttonClassName : 'css-class-name-for-button' ,
5926 showFilteredFields : true ,
6027 } ;
61- const hookProps = {
62- clearFilters : jest . fn ( ) . mockName ( 'hookProps.clearFilters' ) ,
63- filterNames : [ 'filter-name-0' , 'filter-name-1' ] ,
64- } ;
6528 const { FilterStatusComponent } = module ;
66- const mockHooks = ( value ) => {
67- jest . spyOn ( module , 'filterHooks' ) . mockReturnValueOnce ( value ) ;
29+
30+ const renderWithContext = ( contextValue , componentProps = props ) => {
31+ const TestWrapper = ( { children } ) => (
32+ < DataTableContext . Provider value = { contextValue } >
33+ { children }
34+ </ DataTableContext . Provider >
35+ ) ;
36+ TestWrapper . propTypes = {
37+ children : PropTypes . node ,
38+ } ;
39+ return render (
40+ < TestWrapper >
41+ < FilterStatusComponent { ...componentProps } />
42+ </ TestWrapper > ,
43+ ) ;
6844 } ;
69- describe ( 'snapshot' , ( ) => {
70- describe ( 'with filters' , ( ) => {
71- test ( 'showFilteredFields' , ( ) => {
72- mockHooks ( hookProps ) ;
73- const el = shallow ( < FilterStatusComponent { ...props } /> ) ;
74- expect ( el . snapshot ) . toMatchSnapshot ( ) ;
45+
46+ beforeEach ( ( ) => {
47+ jest . clearAllMocks ( ) ;
48+ } ) ;
49+
50+ describe ( 'behavior' , ( ) => {
51+ it ( 'does not render when there are no filters' , ( ) => {
52+ const contextValue = {
53+ headers,
54+ state : { filters : null } ,
55+ setAllFilters : jest . fn ( ) ,
56+ } ;
57+ const { container } = renderWithContext ( contextValue ) ;
58+ expect ( container . firstChild ) . toBeNull ( ) ;
59+ } ) ;
60+
61+ it ( 'does not render when setAllFilters is not available' , ( ) => {
62+ const contextValue = { headers, state : { filters } , setAllFilters : null } ;
63+ const { container } = renderWithContext ( contextValue ) ;
64+ expect ( container . firstChild ) . toBeNull ( ) ;
65+ } ) ;
66+
67+ it ( 'renders clear filters button with correct text when filters exist' , ( ) => {
68+ const contextValue = {
69+ headers,
70+ state : { filters } ,
71+ setAllFilters : jest . fn ( ) ,
72+ } ;
73+ const { getByText } = renderWithContext ( contextValue ) ;
74+ expect ( getByText ( props . clearFiltersText ) ) . toBeInTheDocument ( ) ;
75+ } ) ;
76+
77+ it ( 'displays filtered field names when showFilteredFields is true' , ( ) => {
78+ const contextValue = {
79+ headers,
80+ state : { filters } ,
81+ setAllFilters : jest . fn ( ) ,
82+ } ;
83+ const { getByText } = renderWithContext ( contextValue ) ;
84+ const expectedFilterNames = filterOrder . map ( ( v ) => headers [ v ] . Header ) ;
85+ expectedFilterNames . forEach ( ( name ) => {
86+ expect ( getByText ( name , { exact : false } ) ) . toBeInTheDocument ( ) ;
7587 } ) ;
76- test ( 'showFilteredFields=false - hide filterTexts' , ( ) => {
77- mockHooks ( hookProps ) ;
78- const el = shallow (
79- < FilterStatusComponent { ...props } showFilteredFields = { false } /> ,
80- ) ;
81- expect ( el . snapshot ) . toMatchSnapshot ( ) ;
88+ } ) ;
89+
90+ it ( 'does not display filtered field names when showFilteredFields is false' , ( ) => {
91+ const contextValue = {
92+ headers,
93+ state : { filters } ,
94+ setAllFilters : jest . fn ( ) ,
95+ } ;
96+ const { queryByText } = renderWithContext ( contextValue , {
97+ ...props ,
98+ showFilteredFields : false ,
8299 } ) ;
100+ expect ( queryByText ( / F i l t e r e d b y / ) ) . not . toBeInTheDocument ( ) ;
83101 } ) ;
84- test ( 'without filters' , ( ) => {
85- mockHooks ( { } ) ;
86- const el = shallow ( < FilterStatusComponent { ...props } /> ) ;
87- expect ( el . snapshot ) . toMatchSnapshot ( ) ;
88- expect ( el . isEmptyRender ( ) ) . toEqual ( true ) ;
102+
103+ it ( 'applies correct CSS classes to the component' , ( ) => {
104+ const contextValue = {
105+ headers,
106+ state : { filters } ,
107+ setAllFilters : jest . fn ( ) ,
108+ } ;
109+ const { container } = renderWithContext ( contextValue ) ;
110+ expect ( container . firstChild ) . toHaveClass ( props . className ) ;
111+ } ) ;
112+
113+ it ( 'calls setAllFilters with empty array when clear button is clicked' , ( ) => {
114+ const setAllFilters = jest . fn ( ) ;
115+ const contextValue = { headers, state : { filters } , setAllFilters } ;
116+ const { getByText } = renderWithContext ( contextValue ) ;
117+ const clearButton = getByText ( props . clearFiltersText ) ;
118+ clearButton . click ( ) ;
119+ expect ( setAllFilters ) . toHaveBeenCalledWith ( [ ] ) ;
89120 } ) ;
90121 } ) ;
91122} ) ;
0 commit comments