@@ -5,20 +5,27 @@ import { Store } from 'vuex';
55import ChannelSelectionList from '../ChannelSelectionList' ;
66import { ChannelListTypes } from 'shared/constants' ;
77
8+ jest . mock ( 'kolibri-design-system/lib/composables/useKShow' , ( ) => ( {
9+ __esModule : true ,
10+ default : ( ) => ( {
11+ show : ( _id , loading ) => loading ,
12+ } ) ,
13+ } ) ) ;
14+
815const searchWord = 'search test' ;
916
1017const editChannel = {
1118 id : 'editchannel' ,
1219 name : searchWord ,
13- description : '' ,
20+ description : 'A curated collection of math resources ' ,
1421 edit : true ,
1522 published : true ,
1623} ;
1724
1825const editChannel2 = {
1926 id : 'editchannel2' ,
2027 name : 'Another Channel' ,
21- description : '' ,
28+ description : 'Science and nature topics for all ages ' ,
2229 edit : true ,
2330 published : true ,
2431} ;
@@ -79,33 +86,48 @@ describe('ChannelSelectionList', () => {
7986 // Specific wait avoids wrapping the whole block in waitFor
8087 expect ( await screen . findByLabelText ( 'Search for a channel' ) ) . toBeInTheDocument ( ) ;
8188
82- expect ( screen . getByText ( editChannel . name ) ) . toBeInTheDocument ( ) ;
83- expect ( screen . getByText ( editChannel2 . name ) ) . toBeInTheDocument ( ) ;
84- expect ( screen . queryByText ( publicChannel . name ) ) . not . toBeInTheDocument ( ) ;
89+ expect ( screen . getByRole ( 'heading' , { name : editChannel . name } ) ) . toBeInTheDocument ( ) ;
90+ expect ( screen . getByRole ( 'heading' , { name : editChannel2 . name } ) ) . toBeInTheDocument ( ) ;
91+ expect ( screen . queryByRole ( 'heading' , { name : publicChannel . name } ) ) . not . toBeInTheDocument ( ) ;
92+ } ) ;
93+
94+ it ( 'shows loader while the channel list is loading' , async ( ) => {
95+ let resolveLoad ;
96+ const loadingPromise = new Promise ( resolve => {
97+ resolveLoad = resolve ;
98+ } ) ;
99+ mockActions . loadChannelList . mockReturnValueOnce ( loadingPromise ) ;
100+
101+ await renderComponent ( ) ;
102+
103+ expect ( screen . getByTestId ( 'loader' ) ) . toBeInTheDocument ( ) ;
104+
105+ resolveLoad ( ) ;
106+ expect ( await screen . findByLabelText ( 'Search for a channel' ) ) . toBeInTheDocument ( ) ;
85107 } ) ;
86108
87109 it ( 'filters the channel list when the user types in the search box' , async ( ) => {
88110 const user = userEvent . setup ( ) ;
89111 await renderComponent ( ) ;
90112
91113 // Wait for data load
92- expect ( await screen . findByText ( editChannel . name ) ) . toBeInTheDocument ( ) ;
93- expect ( screen . getByText ( editChannel2 . name ) ) . toBeInTheDocument ( ) ;
114+ expect ( await screen . findByRole ( 'heading' , { name : editChannel . name } ) ) . toBeInTheDocument ( ) ;
115+ expect ( screen . getByRole ( 'heading' , { name : editChannel2 . name } ) ) . toBeInTheDocument ( ) ;
94116
95117 const searchInput = screen . getByLabelText ( 'Search for a channel' ) ;
96118 await user . clear ( searchInput ) ;
97119 await user . type ( searchInput , editChannel . name ) ;
98120
99121 // Verify filter happened
100- expect ( await screen . findByText ( editChannel . name ) ) . toBeInTheDocument ( ) ;
101- expect ( screen . queryByText ( editChannel2 . name ) ) . not . toBeInTheDocument ( ) ;
122+ expect ( await screen . findByRole ( 'heading' , { name : editChannel . name } ) ) . toBeInTheDocument ( ) ;
123+ expect ( screen . queryByRole ( 'heading' , { name : editChannel2 . name } ) ) . not . toBeInTheDocument ( ) ;
102124 } ) ;
103125
104126 it ( 'selects a channel when the user clicks the checkbox' , async ( ) => {
105127 const user = userEvent . setup ( ) ;
106128 const { emitted } = await renderComponent ( ) ;
107129
108- await screen . findByText ( editChannel . name ) ;
130+ await screen . findByRole ( 'heading' , { name : editChannel . name } ) ;
109131
110132 // Using getByTestId because the component doesn't expose unique
111133 // accessible roles for individual channel checkboxes
@@ -127,7 +149,7 @@ describe('ChannelSelectionList', () => {
127149 // Initialize with the channel already selected
128150 const { emitted } = await renderComponent ( { value : [ editChannel . id ] } ) ;
129151
130- await screen . findByText ( editChannel . name ) ;
152+ await screen . findByRole ( 'heading' , { name : editChannel . name } ) ;
131153
132154 // Using getByTestId because the component doesn't expose unique
133155 // accessible roles for individual channel checkboxes
@@ -146,7 +168,7 @@ describe('ChannelSelectionList', () => {
146168 const user = userEvent . setup ( ) ;
147169 const { emitted } = await renderComponent ( ) ;
148170
149- await screen . findByText ( editChannel . name ) ;
171+ await screen . findByRole ( 'heading' , { name : editChannel . name } ) ;
150172
151173 // Using getByTestId because the component doesn't expose accessible
152174 // roles for channel cards
@@ -164,7 +186,7 @@ describe('ChannelSelectionList', () => {
164186 // Initialize with the channel already selected
165187 const { emitted } = await renderComponent ( { value : [ editChannel . id ] } ) ;
166188
167- await screen . findByText ( editChannel . name ) ;
189+ await screen . findByRole ( 'heading' , { name : editChannel . name } ) ;
168190
169191 // Using getByTestId because the component doesn't expose accessible
170192 // roles for channel cards
@@ -175,4 +197,13 @@ describe('ChannelSelectionList', () => {
175197 expect ( emitted ( ) . input ) . toHaveLength ( 1 ) ;
176198 expect ( emitted ( ) . input [ 0 ] [ 0 ] ) . toEqual ( [ ] ) ;
177199 } ) ;
200+
201+ it ( 'each checkbox has an accessible name matching its channel name' , async ( ) => {
202+ await renderComponent ( ) ;
203+
204+ // KCheckbox renders a visually-hidden <label for="id"> associated with the input,
205+ // so getByRole resolves the accessible name correctly for screen readers
206+ expect ( await screen . findByRole ( 'checkbox' , { name : editChannel . name } ) ) . toBeInTheDocument ( ) ;
207+ expect ( screen . getByRole ( 'checkbox' , { name : editChannel2 . name } ) ) . toBeInTheDocument ( ) ;
208+ } ) ;
178209} ) ;
0 commit comments