Skip to content

Commit 837ac4e

Browse files
test: added test cases to change toggle based on channel
1 parent 7ef1b5b commit 837ac4e

3 files changed

Lines changed: 76 additions & 13 deletions

File tree

src/notification-preferences/NotificationPreferenceRow.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ const NotificationPreferenceRow = ({ appId, preferenceName }) => {
7878
value={preference[channel]}
7979
onChange={onToggle}
8080
disabled={nonEditable.includes(channel) || updatePreferencesStatus === LOADING_STATUS}
81+
dataTestId={`${preferenceName}-${channel}`}
8182
/>
8283
</div>
8384
))}

src/notification-preferences/NotificationPreferences.test.jsx

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
import { Provider } from 'react-redux';
33
import { BrowserRouter as Router } from 'react-router-dom';
44
import configureStore from 'redux-mock-store';
5-
import { fireEvent, render, screen } from '@testing-library/react';
5+
import {
6+
fireEvent, render, screen, waitFor, act,
7+
} from '@testing-library/react';
68
import * as auth from '@edx/frontend-platform/auth';
79
import { IntlProvider } from '@edx/frontend-platform/i18n';
810
import NotificationPreferences from './NotificationPreferences';
@@ -33,33 +35,50 @@ const defaultPreferences = {
3335
appId: 'discussion',
3436
web: false,
3537
push: false,
36-
mobile: false,
38+
email: false,
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
],
6062
nonEditable: {},
6163
};
6264

65+
const updateChannelPreferences = (toggleVal = false) => ({
66+
preferences: [
67+
{
68+
id: 'newPost', appId: 'discussion', web: toggleVal, push: toggleVal, email: toggleVal,
69+
},
70+
{
71+
id: 'newComment', appId: 'discussion', web: toggleVal, push: toggleVal, email: toggleVal,
72+
},
73+
{
74+
id: 'newAssignment', appId: 'coursework', web: toggleVal, push: toggleVal, email: toggleVal,
75+
},
76+
{
77+
id: 'newGrade', appId: 'coursework', web: toggleVal, push: toggleVal, email: toggleVal,
78+
},
79+
],
80+
});
81+
6382
const setupStore = (override = {}) => {
6483
const storeState = defaultState;
6584
storeState.courses = {
@@ -78,17 +97,19 @@ const setupStore = (override = {}) => {
7897
return store;
7998
};
8099

81-
const renderComponent = (store = {}) => render(
100+
const renderComponent = (store = {}) => (
82101
<Router>
83102
<IntlProvider locale="en">
84103
<Provider store={store}>
85104
<NotificationPreferences />
86105
</Provider>
87106
</IntlProvider>
88-
</Router>,
107+
</Router>
89108
);
109+
90110
describe('Notification Preferences', () => {
91111
let store;
112+
92113
beforeEach(() => {
93114
store = setupStore({
94115
...defaultPreferences,
@@ -108,29 +129,30 @@ describe('Notification Preferences', () => {
108129
afterEach(() => jest.clearAllMocks());
109130

110131
it('tests if all notification apps are listed', async () => {
111-
await renderComponent(store);
132+
await render(renderComponent(store));
112133
expect(screen.queryAllByTestId('notification-app')).toHaveLength(2);
113134
});
135+
114136
it('show spinner if api call is in progress', async () => {
115137
store = setupStore({ status: LOADING_STATUS });
116-
await renderComponent(store);
138+
await render(renderComponent(store));
117139
expect(screen.queryByTestId('loading-spinner')).toBeInTheDocument();
118140
});
119141

120142
it('tests if all notification preferences are listed', async () => {
121-
await renderComponent(store);
143+
await render(renderComponent(store));
122144
expect(screen.queryAllByTestId('notification-preference')).toHaveLength(4);
123145
});
124146

125147
it('update group on click', async () => {
126-
const wrapper = await renderComponent(store);
148+
const wrapper = await render(renderComponent(store));
127149
const element = wrapper.container.querySelector('#discussion-app-toggle');
128150
await fireEvent.click(element);
129151
expect(mockDispatch).toHaveBeenCalled();
130152
});
131153

132154
it('update preference on click', async () => {
133-
const wrapper = await renderComponent(store);
155+
const wrapper = await render(renderComponent(store));
134156
const element = wrapper.container.querySelector('#newPost-web');
135157
expect(element).not.toBeChecked();
136158
await fireEvent.click(element);
@@ -139,7 +161,43 @@ describe('Notification Preferences', () => {
139161

140162
it('show not found page if invalid course id is entered in url', async () => {
141163
store = setupStore({ status: FAILURE_STATUS, selectedCourse: 'invalid-course-id' });
142-
await renderComponent(store);
164+
await render(renderComponent(store));
143165
expect(screen.queryByTestId('not-found-page')).toBeInTheDocument();
144166
});
167+
168+
it.each([false, true])(
169+
'updates all preferences in the column on web channel click when toggle state is - %s',
170+
async (toggleState) => {
171+
store = setupStore(updateChannelPreferences(toggleState));
172+
const wrapper = render(renderComponent(store));
173+
174+
const getCheckbox = (id) => screen.queryByTestId(`${id}-web`);
175+
const checkboxes = ['newPost', 'newComment', 'newAssignment', 'newGrade'];
176+
177+
const verifyState = (expectedState) => {
178+
checkboxes.forEach((checkbox) => {
179+
if (expectedState) {
180+
expect(getCheckbox(checkbox)).toBeChecked();
181+
} else {
182+
expect(getCheckbox(checkbox)).not.toBeChecked();
183+
}
184+
});
185+
};
186+
187+
verifyState(toggleState);
188+
189+
const element = screen.queryAllByText('Web')[0];
190+
191+
await act(async () => {
192+
await fireEvent.click(element);
193+
});
194+
195+
store = setupStore(updateChannelPreferences(!toggleState));
196+
wrapper.rerender(renderComponent(store));
197+
198+
await waitFor(() => {
199+
verifyState(!toggleState);
200+
});
201+
},
202+
);
145203
});

src/notification-preferences/ToggleSwitch.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ const ToggleSwitch = ({
77
value,
88
disabled,
99
onChange,
10+
dataTestId,
1011
}) => (
1112
<Form.Switch
1213
name={name}
1314
checked={value}
1415
disabled={disabled}
1516
onChange={onChange}
17+
data-testid={dataTestId}
1618
/>
1719
);
1820

@@ -21,11 +23,13 @@ ToggleSwitch.propTypes = {
2123
value: PropTypes.bool.isRequired,
2224
disabled: PropTypes.bool,
2325
onChange: PropTypes.func,
26+
dataTestId: PropTypes.string,
2427
};
2528

2629
ToggleSwitch.defaultProps = {
2730
onChange: () => null,
2831
disabled: false,
32+
dataTestId: '',
2933
};
3034

3135
export default React.memo(ToggleSwitch);

0 commit comments

Comments
 (0)