Skip to content
This repository has been archived by the owner on Jun 17, 2021. It is now read-only.

Commit

Permalink
Test ProjectConfigurationModal component (#360)
Browse files Browse the repository at this point in the history
* WIP: Added render test

* WIP: Added tests

* fixed flow

* added focus test

* Merge branch 'master' into test-project-configuration-modal

* fixed linting warnings

* removed typing as no flow used in test files
  • Loading branch information
AWolf81 authored and melanieseltzer committed Mar 24, 2019
1 parent 44e1008 commit 189d2e8
Show file tree
Hide file tree
Showing 4 changed files with 287 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@ type State = {
activeField: string,
};

class ProjectConfigurationModal extends PureComponent<Props, State> {
state = {
newName: '',
projectIcon: '',
activeField: 'projectName',
};
export const initialState = {
newName: '',
projectIcon: '',
activeField: 'projectName',
};

export class ProjectConfigurationModal extends PureComponent<Props, State> {
state = initialState;

componentWillReceiveProps(nextProps) {
componentWillReceiveProps(nextProps: Props) {
if (!nextProps.project) {
return;
}
Expand Down Expand Up @@ -80,12 +82,12 @@ class ProjectConfigurationModal extends PureComponent<Props, State> {
}
};
updateProjectIcon = (src: string, ev) => {
updateProjectIcon = (src: string, ev: SyntheticEvent<*>) => {
ev.preventDefault();
this.setState(prevState => ({
this.setState({
projectIcon: src,
}));
});
};
setActive = (name: string) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/* eslint-disable flowtype/require-valid-file-annotation */
import React from 'react';
import { shallow } from 'enzyme';
import {
ProjectConfigurationModal,
initialState,
} from './ProjectConfigurationModal';
import FormField from '../FormField';

describe('ProjectConfigurationModal component', () => {
let wrapper;
let instance;
let mockActions;

const project = {
id: 'a-project',
name: 'A project',
projectIcon: 'icon',
};

const shallowRender = (installActive = false) => {
mockActions = {
hideModal: jest.fn(),
saveProjectSettings: jest.fn(),
};
return shallow(
<ProjectConfigurationModal
isVisible={true}
project={project}
dependenciesChangingForProject={installActive}
{...mockActions}
/>
);
};

describe('Rendering', () => {
it('should render', () => {
wrapper = shallowRender(false);
expect(wrapper).toMatchSnapshot();
});

it('should render with active dependency installation (save disabled)', () => {
wrapper = shallowRender(true);
expect(wrapper).toMatchSnapshot();
});
});

describe('Component logic', () => {
const newProject = {
name: 'new-project',
icon: 'another-icon',
};

beforeEach(() => {
wrapper = shallowRender();
instance = wrapper.instance();
});

it('should update local form state for new project', () => {
instance.componentWillReceiveProps({
project: newProject,
});
// Note: If there would be more options we could use a project key on state
// so we can easily compare the object here. Or we could use a loop to check each key -
// for now it'S OK to repeat the assertions because there are just two keys.
expect(instance.state.newName).toEqual(newProject.name);
expect(instance.state.projectIcon).toEqual(newProject.icon);
});

it('should not update local form state if project undefined', () => {
// project is always defined - this is needed for flow type check
instance.componentWillReceiveProps({ project: null });
expect(instance.state).toBe(initialState);
});

it('should save new settings', () => {
instance.componentWillReceiveProps({
project: newProject,
});
// Note: Simulate click on save button wasn't working
// that's why I'm submitting the form
wrapper.find('form').simulate('submit', {
preventDefault: jest.fn(),
});

expect(mockActions.saveProjectSettings).toHaveBeenCalledWith(
instance.state.newName,
instance.state.projectIcon,
project
);
});

describe('Form handling', () => {
it('should save settings on enter key', () => {
instance.handleKeyPress({
preventDefault: jest.fn(),
key: 'Enter',
});
expect(mockActions.saveProjectSettings).toHaveBeenCalled();
});

it('should not save on other keypress', () => {
instance.handleKeyPress({
preventDefault: jest.fn(),
key: 'a',
});
expect(mockActions.saveProjectSettings).not.toHaveBeenCalled();
});

it('should updateProject icon in local state', () => {
instance.updateProjectIcon('new-icon', {
preventDefault: jest.fn(),
});
expect(instance.state.projectIcon).toEqual('new-icon');
});

it('should set a form field to active in local state', () => {
instance.setActive('projectName');
expect(instance.state.activeField).toEqual('projectName');
});

it('should set activeField to projectName on text input focus', () => {
instance.setActive('projectIcon');
expect(instance.state.activeField).toEqual('projectIcon');
const input = wrapper
.find(FormField)
.find('[label="Project name"]')
.children();
input.prop('onFocus')();

expect(instance.state.activeField).toEqual('projectName');
});

it('should change newName on input change', () => {
instance.changeProjectName({
currentTarget: {
value: 'New name',
},
});

expect(instance.state.newName).toEqual('New name');
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ProjectConfigurationModal component Rendering should render 1`] = `
<Modal
isVisible={true}
onDismiss={[MockFunction]}
width={750}
>
<ModalHeader
theme="standard"
title="Project settings"
/>
<styled.section>
<form
onSubmit={[Function]}
>
<FormField
focusOnClick={false}
label="Project name"
spacing={30}
>
<TextInput
autoFocus={true}
isFocused={true}
onChange={[Function]}
onFocus={[Function]}
onKeyPress={[Function]}
value=""
/>
</FormField>
<styled.div
size={10}
/>
<FormField
focusOnClick={false}
isFocused={false}
label="Project Icon"
spacing={30}
>
<ProjectIconSelection
limitTo={21}
onSelectIcon={[Function]}
selectedIcon=""
/>
</FormField>
<styled.div>
<FillButton
colors={
Array [
"#00C853",
"#69db0d",
]
}
disabled={false}
size="large"
textColor="#FFF"
>
Save Project
</FillButton>
</styled.div>
</form>
</styled.section>
</Modal>
`;

exports[`ProjectConfigurationModal component Rendering should render with active dependency installation (save disabled) 1`] = `
<Modal
isVisible={true}
onDismiss={[MockFunction]}
width={750}
>
<ModalHeader
theme="standard"
title="Project settings"
/>
<styled.section>
<form
onSubmit={[Function]}
>
<FormField
focusOnClick={false}
label="Project name"
spacing={30}
>
<TextInput
autoFocus={true}
isFocused={true}
onChange={[Function]}
onFocus={[Function]}
onKeyPress={[Function]}
value=""
/>
</FormField>
<styled.div
size={10}
/>
<FormField
focusOnClick={false}
isFocused={false}
label="Project Icon"
spacing={30}
>
<ProjectIconSelection
limitTo={21}
onSelectIcon={[Function]}
selectedIcon=""
/>
</FormField>
<styled.div>
<FillButton
colors={
Array [
"#00C853",
"#69db0d",
]
}
disabled={true}
size="large"
textColor="#FFF"
>
Save Project
</FillButton>
<styled.div>
Waiting for pending tasks to finish…
</styled.div>
</styled.div>
</form>
</styled.section>
</Modal>
`;
1 change: 0 additions & 1 deletion src/components/Sidebar/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ const Wrapper = animated(styled.nav.attrs({
${COLORS.blue[900]},
${COLORS.blue[700]}
);
transform: translateX(${props => props.offset});
will-change: transform;
height: 100vh;
`);
Expand Down

0 comments on commit 189d2e8

Please sign in to comment.