feat: email tests

This commit is contained in:
Ben Warzeski
2022-06-13 15:05:55 -04:00
parent 4172f5c4db
commit 61cff124a8
8 changed files with 3916 additions and 3454 deletions

7074
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,7 @@
},
"dependencies": {
"@edx/brand": "npm:@edx/brand-edx.org@^2.0.3",
"@edx/frontend-component-footer": "10.1.6",
"@edx/frontend-component-footer": "11.0.0",
"@edx/frontend-component-header": "^2.4.6",
"@edx/frontend-platform": "^2.3.0",
"@edx/paragon": "19.25.0",

View File

@@ -0,0 +1,163 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`EmailSettingsModal render snapshot: emails disabled, show: false 1`] = `
<ModalDialog
hasCloseButton={false}
isOpen={false}
onClose={[MockFunction hooks.nullMethod]}
title=""
>
<div
className="bg-white p-3 rounded shadow"
style={
Object {
"textAlign": "start",
}
}
>
<h4>
<formatMessage
msg="Receive course emails?"
/>
</h4>
<Form.Switch
checked={true}
onChange={[MockFunction hooks.onToggle]}
>
<formatMessage
msg="Course emails are on"
/>
</Form.Switch>
<p>
<formatMessage
msg="Course emailsi include important information about your course."
/>
</p>
<ActionRow>
<Button
onClick={[MockFunction closeModal]}
variant="tertiary"
>
<formatMessage
msg="Nevermind"
/>
</Button>
<Button
onClick={[MockFunction hooks.save]}
>
<formatMessage
msg="Save settings"
/>
</Button>
</ActionRow>
</div>
</ModalDialog>
`;
exports[`EmailSettingsModal render snapshot: emails disabled, show: true 1`] = `
<ModalDialog
hasCloseButton={false}
isOpen={true}
onClose={[MockFunction hooks.nullMethod]}
title=""
>
<div
className="bg-white p-3 rounded shadow"
style={
Object {
"textAlign": "start",
}
}
>
<h4>
<formatMessage
msg="Receive course emails?"
/>
</h4>
<Form.Switch
checked={true}
onChange={[MockFunction hooks.onToggle]}
>
<formatMessage
msg="Course emails are on"
/>
</Form.Switch>
<p>
<formatMessage
msg="Course emailsi include important information about your course."
/>
</p>
<ActionRow>
<Button
onClick={[MockFunction closeModal]}
variant="tertiary"
>
<formatMessage
msg="Nevermind"
/>
</Button>
<Button
onClick={[MockFunction hooks.save]}
>
<formatMessage
msg="Save settings"
/>
</Button>
</ActionRow>
</div>
</ModalDialog>
`;
exports[`EmailSettingsModal render snapshot: emails enabled, show: true 1`] = `
<ModalDialog
hasCloseButton={false}
isOpen={true}
onClose={[MockFunction hooks.nullMethod]}
title=""
>
<div
className="bg-white p-3 rounded shadow"
style={
Object {
"textAlign": "start",
}
}
>
<h4>
<formatMessage
msg="Receive course emails?"
/>
</h4>
<Form.Switch
checked={true}
onChange={[MockFunction hooks.onToggle]}
>
<formatMessage
msg="Course emails are on"
/>
</Form.Switch>
<p>
<formatMessage
msg="Course emailsi include important information about your course."
/>
</p>
<ActionRow>
<Button
onClick={[MockFunction closeModal]}
variant="tertiary"
>
<formatMessage
msg="Nevermind"
/>
</Button>
<Button
onClick={[MockFunction hooks.save]}
>
<formatMessage
msg="Save settings"
/>
</Button>
</ActionRow>
</div>
</ModalDialog>
`;

View File

@@ -3,7 +3,7 @@ import React from 'react';
import { StrictDict } from 'utils';
// import { thunkActions } from 'data/redux';
import { selectors } from 'data/redux';
import { getCardValue } from 'hooks';
import { getCardValues } from 'hooks';
import * as module from './hooks';
@@ -18,14 +18,13 @@ export const modalHooks = ({
courseNumber,
// dispatch,
}) => {
const cardValue = getCardValue(courseNumber);
const isEmailEnabled = cardValue(cardData.isEmailEnabled);
const [toggleValue, setToggleValue] = module.state.toggle(isEmailEnabled);
const data = getCardValues(courseNumber, {
isEnabled: cardData.isEmailEnabled,
});
const [toggleValue, setToggleValue] = module.state.toggle(data.isEnabled);
const onToggle = React.useCallback(() => setToggleValue(!toggleValue), [toggleValue]);
const save = React.useCallback(
() => {
console.log('save email settings');
closeModal();
},
[],

View File

@@ -0,0 +1,56 @@
import { MockUseState, testCardValues } from 'testUtils';
import * as appHooks from 'hooks';
import { selectors } from 'data/redux';
import * as hooks from './hooks';
const { fieldKeys } = selectors.cardData;
const courseNumber = 'my-test-course-number';
const closeModal = jest.fn();
const state = new MockUseState(hooks);
describe('EmailSettingsModal hooks', () => {
let out;
describe('state values', () => {
state.testGetter(state.keys.toggle);
});
beforeEach(() => {
jest.clearAllMocks();
});
describe('modalHooks', () => {
beforeEach(() => {
state.mock();
appHooks.getCardValues.mockReturnValueOnce({ isEnabled: true });
out = hooks.modalHooks({ closeModal, courseNumber });
});
afterEach(state.restore);
testCardValues(courseNumber, { isEnabled: fieldKeys.isEmailEnabled });
test('initializes toggle value to cardData.isEmailEnabled', () => {
state.expectInitializedWith(state.keys.toggle, true);
expect(out.toggleValue).toEqual(true);
appHooks.getCardValues.mockReturnValueOnce({ isEnabled: false });
out = hooks.modalHooks({ closeModal, courseNumber });
state.expectInitializedWith(state.keys.toggle, false);
expect(out.toggleValue).toEqual(false);
});
describe('onToggle - returned callback', () => {
it('is based on toggle state value', () => {
expect(out.onToggle.useCallback.prereqs).toEqual([out.toggleValue]);
});
it('sets toggle state value to opposite current value', () => {
out.onToggle.useCallback.cb();
expect(state.setState.toggle).toHaveBeenCalledWith(!out.toggleValue);
});
});
describe('save', () => {
it('returns a callback with no prereqs', () => {
expect(out.save.useCallback.prereqs).toEqual([]);
});
});
});
});

View File

@@ -0,0 +1,59 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import { shallow } from 'enzyme';
import hooks from './hooks';
import EmailSettingsModal from '.';
jest.mock('./hooks', () => ({
__esModule: true,
default: jest.fn(),
}));
const hookProps = {
toggleValue: false,
onToggle: jest.fn().mockName('hooks.onToggle'),
save: jest.fn().mockName('hooks.save'),
};
const props = {
closeModal: jest.fn().mockName('closeModal'),
show: true,
courseNumber: 'test-course-number',
};
const dispatch = useDispatch();
describe('EmailSettingsModal', () => {
beforeEach(() => {
jest.clearAllMocks();
hooks.mockReturnValueOnce(hookProps);
});
describe('behavior', () => {
beforeEach(() => {
shallow(<EmailSettingsModal {...props} />);
});
it('calls hook w/ dispatch from redux hook, and closeModal, courseNumber from props', () => {
expect(hooks).toHaveBeenCalledWith({
closeModal: props.closeModal,
dispatch,
courseNumber: props.courseNumber,
});
});
});
describe('render', () => {
test('snapshot: emails disabled, show: false', () => {
expect(shallow(<EmailSettingsModal {...props} show={false} />)).toMatchSnapshot();
});
test('snapshot: emails disabled, show: true', () => {
expect(shallow(<EmailSettingsModal {...props} />)).toMatchSnapshot();
});
test('snapshot: emails enabled, show: true', () => {
hooks.mockReturnValueOnce({
...hookProps,
toggleValue: true,
});
expect(shallow(<EmailSettingsModal {...props} />)).toMatchSnapshot();
});
});
});

View File

@@ -81,6 +81,7 @@ jest.mock('@edx/paragon', () => jest.requireActual('testUtils').mockNestedCompon
Label: 'Form.Label',
Radio: 'Form.Radio',
RadioSet: 'Form.RadioSet',
Switch: 'Form.Switch',
},
FormControlFeedback: 'FormControlFeedback',
FullscreenModal: 'FullscreenModal',

View File

@@ -166,6 +166,10 @@ export class MockUseState {
);
}
expectInitializedWith(key, value) {
expect(this.hooks.state[key]).toHaveBeenCalledWith(value);
}
/**
* Restore the hook module's state object to the actual code.
*/