Skip to content

Commit 3799c43

Browse files
[MM-770]: Added webapp testcase for create issue modal (#850)
* [MM-770]: Added webapp testcase for create issue modal * [MM-770]: removed extra comments * [MM-770]: fixed lint issues * [MM-770]: review fixes
1 parent e435c76 commit 3799c43

File tree

5 files changed

+244
-0
lines changed

5 files changed

+244
-0
lines changed

webapp/package-lock.json

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webapp/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"@emotion/babel-preset-css-prop": "10.0.27",
2828
"@emotion/core": "10.0.35",
2929
"@types/enzyme": "3.10.6",
30+
"@types/enzyme-adapter-react-16": "1.0.9",
3031
"@types/jest": "26.0.14",
3132
"@types/node": "14.11.1",
3233
"@types/react": "16.9.49",
@@ -118,6 +119,9 @@
118119
"setupFiles": [
119120
"jest-canvas-mock"
120121
],
122+
"setupFilesAfterEnv": [
123+
"<rootDir>/tests/setup.tsx"
124+
],
121125
"testURL": "http://localhost:8065"
122126
}
123127
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`CreateIssueModal should render correctly with default props 1`] = `
4+
<Modal
5+
animation={true}
6+
autoFocus={true}
7+
backdrop="static"
8+
bsSize="large"
9+
dialogAs={
10+
Object {
11+
"$$typeof": Symbol(react.forward_ref),
12+
"displayName": "ModalDialog",
13+
"render": [Function],
14+
}
15+
}
16+
dialogClassName="modal--scroll"
17+
enforceFocus={true}
18+
keyboard={true}
19+
onExited={[Function]}
20+
onHide={[Function]}
21+
restoreFocus={true}
22+
show={true}
23+
>
24+
<ModalHeader
25+
closeButton={true}
26+
closeLabel="Close"
27+
>
28+
<ModalTitle>
29+
Create GitHub Issue
30+
</ModalTitle>
31+
</ModalHeader>
32+
<form
33+
onSubmit={[Function]}
34+
role="form"
35+
>
36+
<ModalBody
37+
style={
38+
Object {
39+
"backgroundColor": "#fff",
40+
"color": "#000",
41+
"padding": "2em 2em 3em",
42+
}
43+
}
44+
>
45+
<div>
46+
<Connect(GithubRepoSelector)
47+
addValidate={[Function]}
48+
onChange={[Function]}
49+
removeValidate={[Function]}
50+
required={true}
51+
theme={
52+
Object {
53+
"centerChannelBg": "#fff",
54+
"centerChannelColor": "#000",
55+
}
56+
}
57+
value={null}
58+
/>
59+
<Input
60+
disabled={false}
61+
id="title"
62+
label="Title for the GitHub Issue"
63+
maxLength={256}
64+
onChange={[Function]}
65+
readOnly={false}
66+
required={true}
67+
type="input"
68+
value=""
69+
/>
70+
<Input
71+
label="Description for the GitHub Issue"
72+
maxLength={null}
73+
onChange={[Function]}
74+
readOnly={false}
75+
required={false}
76+
type="textarea"
77+
value=""
78+
/>
79+
</div>
80+
</ModalBody>
81+
<ModalFooter>
82+
<FormButton
83+
btnClass="btn-link"
84+
defaultMessage="Cancel"
85+
disabled={false}
86+
extraClasses=""
87+
onClick={[Function]}
88+
savingMessage="Creating"
89+
type="button"
90+
/>
91+
<FormButton
92+
btnClass="btn btn-primary"
93+
defaultMessage="Submit"
94+
disabled={false}
95+
extraClasses=""
96+
saving={false}
97+
savingMessage="Submitting"
98+
type="submit"
99+
>
100+
Submit
101+
</FormButton>
102+
</ModalFooter>
103+
</form>
104+
</Modal>
105+
`;
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React from 'react';
2+
import {shallow} from 'enzyme';
3+
4+
import CreateIssueModal from './create_issue';
5+
6+
jest.mock('utils/user_utils', () => ({
7+
getErrorMessage: jest.fn(() => 'Error occurred'),
8+
}));
9+
10+
describe('CreateIssueModal', () => {
11+
const defaultProps = {
12+
close: jest.fn(),
13+
create: jest.fn(() => Promise.resolve({})),
14+
post: null,
15+
theme: {
16+
centerChannelColor: '#000',
17+
centerChannelBg: '#fff',
18+
},
19+
visible: true,
20+
};
21+
22+
it('should render correctly with default props', () => {
23+
const wrapper = shallow(<CreateIssueModal {...defaultProps}/>);
24+
expect(wrapper).toMatchSnapshot();
25+
});
26+
27+
it('should call close prop when handleClose is called', () => {
28+
const wrapper = shallow(<CreateIssueModal {...defaultProps}/>);
29+
wrapper.instance().handleClose();
30+
expect(defaultProps.close).toHaveBeenCalled();
31+
});
32+
33+
it('should call create prop when form is submitted with valid data', async () => {
34+
const wrapper = shallow(<CreateIssueModal {...defaultProps}/>);
35+
wrapper.setState({issueTitle: 'Test Issue'});
36+
37+
await wrapper.instance().handleCreate({preventDefault: jest.fn()});
38+
expect(defaultProps.create).toHaveBeenCalled();
39+
});
40+
41+
it('should display error message when create returns an error', async () => {
42+
const mockCreateFunction = jest.fn().mockResolvedValue({error: {message: 'Some error'}});
43+
const errorProps = {
44+
...defaultProps,
45+
create: mockCreateFunction,
46+
};
47+
48+
const wrapper = shallow(<CreateIssueModal {...errorProps}/>);
49+
wrapper.setState({issueTitle: 'Test Issue'});
50+
51+
await wrapper.instance().handleCreate({preventDefault: jest.fn()});
52+
wrapper.update();
53+
54+
expect(wrapper.find('.help-text.error-text').text()).toEqual('Error occurred');
55+
});
56+
57+
it('should show validation error when issueTitle is empty', async () => {
58+
const wrapper = shallow(<CreateIssueModal {...defaultProps}/>);
59+
wrapper.setState({issueTitle: ''});
60+
61+
await wrapper.instance().handleCreate({preventDefault: jest.fn()});
62+
expect(wrapper.state('issueTitleValid')).toBe(false);
63+
expect(wrapper.state('showErrors')).toBe(true);
64+
});
65+
66+
it('should update repo state when handleRepoChange is called', () => {
67+
const wrapper = shallow(<CreateIssueModal {...defaultProps}/>);
68+
const repo = {name: 'repo-name'};
69+
70+
wrapper.instance().handleRepoChange(repo);
71+
expect(wrapper.state('repo')).toEqual(repo);
72+
});
73+
74+
it('should update labels state when handleLabelsChange is called', () => {
75+
const wrapper = shallow(<CreateIssueModal {...defaultProps}/>);
76+
const labels = ['label1', 'label2'];
77+
78+
wrapper.instance().handleLabelsChange(labels);
79+
expect(wrapper.state('labels')).toEqual(labels);
80+
});
81+
82+
it('should update assignees state when handleAssigneesChange is called', () => {
83+
const wrapper = shallow(<CreateIssueModal {...defaultProps}/>);
84+
const assignees = ['user1', 'user2'];
85+
86+
wrapper.instance().handleAssigneesChange(assignees);
87+
expect(wrapper.state('assignees')).toEqual(assignees);
88+
});
89+
90+
it('should set issueDescription state when post prop is updated', () => {
91+
const wrapper = shallow(<CreateIssueModal {...defaultProps}/>);
92+
const post = {message: 'test post'};
93+
wrapper.setProps({post});
94+
95+
expect(wrapper.state('issueDescription')).toEqual(post.message);
96+
});
97+
98+
it('should not display attribute selectors when repo does not have push permissions', () => {
99+
const wrapper = shallow(<CreateIssueModal {...defaultProps}/>);
100+
wrapper.setState({repo: {name: 'repo-name', permissions: {push: false}}});
101+
102+
expect(wrapper.instance().renderIssueAttributeSelectors()).toBeNull();
103+
});
104+
105+
it('should display attribute selectors when repo has push permissions', () => {
106+
const wrapper = shallow(<CreateIssueModal {...defaultProps}/>);
107+
wrapper.setState({repo: {name: 'repo-name', permissions: {push: true}}});
108+
109+
const selectors = wrapper.instance().renderIssueAttributeSelectors();
110+
expect(selectors).not.toBeNull();
111+
});
112+
});

webapp/tests/setup.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Adapter from 'enzyme-adapter-react-16';
2+
import {configure} from 'enzyme';
3+
4+
configure({adapter: new Adapter()});

0 commit comments

Comments
 (0)