22import { Provider } from 'react-redux' ;
33import { BrowserRouter as Router } from 'react-router-dom' ;
44import configureStore from 'redux-mock-store' ;
5- import { fireEvent , render , screen } from '@testing-library/react' ;
5+ import {
6+ fireEvent , render , screen , waitFor , act , within ,
7+ } from '@testing-library/react' ;
68import * as auth from '@edx/frontend-platform/auth' ;
79import { IntlProvider } from '@edx/frontend-platform/i18n' ;
810import NotificationPreferences from './NotificationPreferences' ;
@@ -29,37 +31,51 @@ const defaultPreferences = {
2931 ] ,
3032 preferences : [
3133 {
32- id : 'newPost ' ,
34+ id : 'core ' ,
3335 appId : 'discussion' ,
34- web : false ,
35- push : false ,
36- mobile : false ,
36+ web : true ,
37+ push : true ,
38+ email : true ,
3739 } ,
3840 {
3941 id : 'newComment' ,
4042 appId : 'discussion' ,
4143 web : false ,
4244 push : false ,
43- mobile : false ,
45+ email : false ,
4446 } ,
4547 {
4648 id : 'newAssignment' ,
4749 appId : 'coursework' ,
4850 web : false ,
4951 push : false ,
50- mobile : false ,
52+ email : false ,
5153 } ,
5254 {
5355 id : 'newGrade' ,
5456 appId : 'coursework' ,
5557 web : false ,
5658 push : false ,
57- mobile : false ,
59+ email : false ,
5860 } ,
5961 ] ,
60- nonEditable : { } ,
62+ nonEditable : {
63+ discussion : {
64+ core : [
65+ 'web' ,
66+ ] ,
67+ } ,
68+ } ,
6169} ;
6270
71+ const updateChannelPreferences = ( toggleVal = false ) => ( {
72+ preferences : [
73+ { id : 'core' , appId : 'discussion' , web : true } ,
74+ { id : 'newComment' , appId : 'discussion' , web : toggleVal } ,
75+ { id : 'newAssignment' , appId : 'coursework' , web : toggleVal } ,
76+ ] ,
77+ } ) ;
78+
6379const setupStore = ( override = { } ) => {
6480 const storeState = defaultState ;
6581 storeState . courses = {
@@ -78,17 +94,19 @@ const setupStore = (override = {}) => {
7894 return store ;
7995} ;
8096
81- const renderComponent = ( store = { } ) => render (
97+ const notificationPreferences = ( store = { } ) => (
8298 < Router >
8399 < IntlProvider locale = "en" >
84100 < Provider store = { store } >
85101 < NotificationPreferences />
86102 </ Provider >
87103 </ IntlProvider >
88- </ Router > ,
104+ </ Router >
89105) ;
106+
90107describe ( 'Notification Preferences' , ( ) => {
91108 let store ;
109+
92110 beforeEach ( ( ) => {
93111 store = setupStore ( {
94112 ...defaultPreferences ,
@@ -108,38 +126,76 @@ describe('Notification Preferences', () => {
108126 afterEach ( ( ) => jest . clearAllMocks ( ) ) ;
109127
110128 it ( 'tests if all notification apps are listed' , async ( ) => {
111- await renderComponent ( store ) ;
112- expect ( screen . queryAllByTestId ( 'notification-app' ) ) . toHaveLength ( 2 ) ;
129+ await render ( notificationPreferences ( store ) ) ;
130+ expect ( screen . queryByTestId ( 'discussion-app' ) ) . toBeInTheDocument ( ) ;
131+ expect ( screen . queryByTestId ( 'coursework-app' ) ) . toBeInTheDocument ( ) ;
113132 } ) ;
133+
114134 it ( 'show spinner if api call is in progress' , async ( ) => {
115135 store = setupStore ( { status : LOADING_STATUS } ) ;
116- await renderComponent ( store ) ;
136+ await render ( notificationPreferences ( store ) ) ;
117137 expect ( screen . queryByTestId ( 'loading-spinner' ) ) . toBeInTheDocument ( ) ;
118138 } ) ;
119139
120140 it ( 'tests if all notification preferences are listed' , async ( ) => {
121- await renderComponent ( store ) ;
141+ await render ( notificationPreferences ( store ) ) ;
122142 expect ( screen . queryAllByTestId ( 'notification-preference' ) ) . toHaveLength ( 4 ) ;
123143 } ) ;
124144
125145 it ( 'update group on click' , async ( ) => {
126- const wrapper = await renderComponent ( store ) ;
146+ const wrapper = await render ( notificationPreferences ( store ) ) ;
127147 const element = wrapper . container . querySelector ( '#discussion-app-toggle' ) ;
128148 await fireEvent . click ( element ) ;
129149 expect ( mockDispatch ) . toHaveBeenCalled ( ) ;
130150 } ) ;
131151
132152 it ( 'update preference on click' , async ( ) => {
133- const wrapper = await renderComponent ( store ) ;
134- const element = wrapper . container . querySelector ( '#newPost -web' ) ;
153+ const wrapper = await render ( notificationPreferences ( store ) ) ;
154+ const element = wrapper . container . querySelector ( '#core -web' ) ;
135155 expect ( element ) . not . toBeChecked ( ) ;
136156 await fireEvent . click ( element ) ;
137157 expect ( mockDispatch ) . toHaveBeenCalled ( ) ;
138158 } ) ;
139159
140160 it ( 'show not found page if invalid course id is entered in url' , async ( ) => {
141161 store = setupStore ( { status : FAILURE_STATUS , selectedCourse : 'invalid-course-id' } ) ;
142- await renderComponent ( store ) ;
162+ await render ( notificationPreferences ( store ) ) ;
143163 expect ( screen . queryByTestId ( 'not-found-page' ) ) . toBeInTheDocument ( ) ;
144164 } ) ;
165+
166+ it ( 'updates all preferences in the column on web channel click' , async ( ) => {
167+ store = setupStore ( updateChannelPreferences ( true ) ) ;
168+ const wrapper = render ( notificationPreferences ( store ) ) ;
169+
170+ const getChannelSwitch = ( id ) => screen . queryByTestId ( `${ id } -web` ) ;
171+ const notificationTypes = [ 'newComment' , 'newAssignment' ] ;
172+
173+ const verifyState = ( toggleState ) => {
174+ notificationTypes . forEach ( ( notificationType ) => {
175+ if ( toggleState ) {
176+ expect ( getChannelSwitch ( notificationType ) ) . toBeChecked ( ) ;
177+ } else {
178+ expect ( getChannelSwitch ( notificationType ) ) . not . toBeChecked ( ) ;
179+ }
180+ } ) ;
181+ } ;
182+
183+ verifyState ( true ) ;
184+ expect ( getChannelSwitch ( 'core' ) ) . toBeChecked ( ) ;
185+
186+ const discussionApp = screen . queryByTestId ( 'discussion-app' ) ;
187+ const webChannel = within ( discussionApp ) . queryByText ( 'Web' ) ;
188+
189+ await act ( async ( ) => {
190+ await fireEvent . click ( webChannel ) ;
191+ } ) ;
192+
193+ store = setupStore ( updateChannelPreferences ( false ) ) ;
194+ wrapper . rerender ( notificationPreferences ( store ) ) ;
195+
196+ await waitFor ( ( ) => {
197+ verifyState ( false ) ;
198+ expect ( getChannelSwitch ( 'core' ) ) . toBeChecked ( ) ;
199+ } ) ;
200+ } ) ;
145201} ) ;
0 commit comments