Skip to content

Commit

Permalink
Group tests by form element and standardise names
Browse files Browse the repository at this point in the history
  • Loading branch information
hotblac committed Aug 5, 2018
1 parent 54d4371 commit b5959e6
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 75 deletions.
14 changes: 7 additions & 7 deletions src/Pwnedpasswords.api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ describe('isPasswordPwned', () => {
fetch.mockResponseOnce(apiResponse);
});

it('requests pwned passwords by partial hash', () => {
it('should request pwned passwords by partial hash', () => {
isPasswordPwned(password);
expect(fetch.mock.calls[0][0]).toBe('https://api.pwnedpasswords.com/range/' + expectedHashPrefix);
});

it('returns true when password is pwned', async () => {
const result = await isPasswordPwned(password);
expect(result).toBe(true);
it('should return true when password is pwned', () => {
const result = isPasswordPwned(password);
expect(result).resolves.toBe(true);
});

it('returns false when password is not pwned', async () => {
const result = await isPasswordPwned(uniquePassword);
expect(result).toBe(false);
it('should return false when password is not pwned', () => {
const result = isPasswordPwned(uniquePassword);
expect(result).resolves.toBe(false);
});
});
5 changes: 4 additions & 1 deletion src/UserRegistration.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ export class UserRegistration extends Component {
}

submitEnabled = () => {
return this.state.password && this.state.passwordMatchesConfirm;
return this.state.username &&
this.state.password &&
this.state.passwordMatchesConfirm &&
!this.state.passwordIsPwned;
};

checkForPwnedPassword = (password) => {
Expand Down
161 changes: 94 additions & 67 deletions src/UserRegistration.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,60 @@ import { shallow } from 'enzyme';
import {UserRegistration} from "./UserRegistration";
import * as pwn from "./Pwnedpasswords.api";

describe ('<UserRegistration/>', () => {
const username = 'username';
const goodPassword = 'password';
const pwnedPassword = "pwned";

const username = 'username';
const goodPassword = 'password';
const pwnedPassword = "pwned";

pwn.isPasswordPwned = jest.fn((pwd) => {
return Promise.resolve(pwd !== goodPassword)
});
const onSubmit = jest.fn();
// Mock behaviours
pwn.isPasswordPwned = jest.fn((pwd) => {
return Promise.resolve(pwd !== goodPassword)
});
const onSubmit = jest.fn();

beforeEach(() => {
onSubmit.mockReset();
});
beforeEach(() => {
onSubmit.mockReset();
});

describe('password field', () => {

it('renders', () => {
it('should show warnings when password is pwned', async () => {
const wrapper = shallow(<UserRegistration/>);
expect(wrapper).toBeDefined();
await setFieldValuesAndUpdate(wrapper, username, pwnedPassword, pwnedPassword);

const inputField = wrapper.find('#passwordField input');
const errorIcon = wrapper.find('#passwordField .icon');

expect(inputField.hasClass('is-danger')).toBe(true);
expect(errorIcon.exists()).toBe(true);
});

it ('should hide warnings when password is blank', () => {
const wrapper = shallow(<UserRegistration/>);
setFieldValues(wrapper, username, '', '');

it('notifies caller of username and password', () => {
const wrapper = shallow(<UserRegistration onSubmit={onSubmit}/>);
setFieldValues(wrapper, username, goodPassword, goodPassword);
const inputField = wrapper.find('#passwordField input')
const errorIcon = wrapper.find('#passwordField .icon');

const submitButton = wrapper.find('button');
submitButton.simulate('click');
expect(inputField.hasClass('is-danger')).toBe(false);
expect(errorIcon.exists()).toBe(false);
});

expect(onSubmit).toBeCalledWith(username, goodPassword);
it ('should hide warnings when password is not pwned', async () => {
const wrapper = shallow(<UserRegistration/>);
await setFieldValuesAndUpdate(wrapper, username, goodPassword, goodPassword);

const inputField = wrapper.find('#passwordField input')
const errorIcon = wrapper.find('#passwordField .icon');

expect(inputField.hasClass('is-danger')).toBe(false);
expect(errorIcon.exists()).toBe(false);
});

});

describe('password confirmation field', () => {

it('shows error markers when password does not match confirmation', () => {
it('should show warnings when password does not match confirmation', () => {
const wrapper = shallow(<UserRegistration/>);
setFieldValues(wrapper, username, goodPassword, 'mismatch');

Expand All @@ -47,7 +67,7 @@ describe ('<UserRegistration/>', () => {
expect(errorIcon.exists()).toBe(true);
});

it('hides error marker when password does matches confirmation', () => {
it('should hide warnings when password does matches confirmation', () => {
const wrapper = shallow(<UserRegistration/>);
setFieldValues(wrapper, username, goodPassword, goodPassword);

Expand All @@ -58,43 +78,49 @@ describe ('<UserRegistration/>', () => {
expect(errorIcon.exists()).toBe(false);
});

it('shows error marker when password is pwned', async () => {
const wrapper = shallow(<UserRegistration/>);
await setFieldValuesAndUpdate(wrapper, username, pwnedPassword, pwnedPassword);
});

const inputField = wrapper.find('#passwordField input');
const errorIcon = wrapper.find('#passwordField .icon');
describe('submit button', () => {

expect(inputField.hasClass('is-danger')).toBe(true);
expect(errorIcon.exists()).toBe(true);
it ('should disable submit when username is blank', () => {
const wrapper = shallow(<UserRegistration onSubmit={onSubmit}/>);
setFieldValues(wrapper, '', goodPassword, goodPassword);

const submitButton = wrapper.find('button');
expect(submitButton.prop('disabled')).toBeTruthy();

// Try submitting anyway
submitButton.simulate('click');
expect(onSubmit).not.toBeCalled();
});

it ('hides error marker when password is blank', () => {
const wrapper = shallow(<UserRegistration/>);
it('should disable submit when password and confirmation are blank', () => {
const wrapper = shallow(<UserRegistration onSubmit={onSubmit}/>);
setFieldValues(wrapper, username, '', '');

const inputField = wrapper.find('#passwordField input')
const errorIcon = wrapper.find('#passwordField .icon');
const submitButton = wrapper.find('button');
expect(submitButton.prop('disabled')).toBeTruthy();

expect(inputField.hasClass('is-danger')).toBe(false);
expect(errorIcon.exists()).toBe(false);
// Try submitting anyway
submitButton.simulate('click');
expect(onSubmit).not.toBeCalled();
});

it ('hides error marker when password is not pwned', async () => {
const wrapper = shallow(<UserRegistration/>);
await setFieldValuesAndUpdate(wrapper, username, goodPassword, goodPassword);
it('should disable submit when password does not match confirmation', () => {
const wrapper = shallow(<UserRegistration onSubmit={onSubmit}/>);
setFieldValues(wrapper, username, goodPassword, 'mismatch');

const inputField = wrapper.find('#passwordField input')
const errorIcon = wrapper.find('#passwordField .icon');
const submitButton = wrapper.find('button');
expect(submitButton.prop('disabled')).toBeTruthy();

expect(inputField.hasClass('is-danger')).toBe(false);
expect(errorIcon.exists()).toBe(false);
// Try submitting anyway
submitButton.simulate('click');
expect(onSubmit).not.toBeCalled();
});


it('disables submit when password does not match confirmation', () => {
it('should disable submit when password is pwned', async () => {
const wrapper = shallow(<UserRegistration onSubmit={onSubmit}/>);
setFieldValues(wrapper, username, goodPassword, 'mismatch');
await setFieldValuesAndUpdate(wrapper, username, pwnedPassword, pwnedPassword);

const submitButton = wrapper.find('button');
expect(submitButton.prop('disabled')).toBeTruthy();
Expand All @@ -104,8 +130,7 @@ describe ('<UserRegistration/>', () => {
expect(onSubmit).not.toBeCalled();
});


it('enables submit when password matches confirmation', () => {
it('should enable submit when all fields are valid', () => {
const wrapper = shallow(<UserRegistration onSubmit={onSubmit}/>);
setFieldValues(wrapper, username, goodPassword, goodPassword);

Expand All @@ -116,36 +141,38 @@ describe ('<UserRegistration/>', () => {
expect(onSubmit).toBeCalled();
});

});

describe ('callbacks', () => {

it('disables submit when password and confirmation are blank', () => {
it('should notify caller of username and password', () => {
const wrapper = shallow(<UserRegistration onSubmit={onSubmit}/>);
setFieldValues(wrapper, username, '', '');
setFieldValues(wrapper, username, goodPassword, goodPassword);

const submitButton = wrapper.find('button');
expect(submitButton.prop('disabled')).toBeTruthy();

// Try submitting anyway
submitButton.simulate('click');
expect(onSubmit).not.toBeCalled();

expect(onSubmit).toBeCalledWith(username, goodPassword);
});

function setFieldValues(wrapper, username, password, confirm) {
const usernameField = wrapper.find('#usernameField input');
const passwordField = wrapper.find('#passwordField input');
const confirmField = wrapper.find('#confirmField input');
});

usernameField.simulate('change', stubEvent(usernameField, username));
passwordField.simulate('change', stubEvent(passwordField, password));
confirmField.simulate('change', stubEvent(confirmField, confirm));
}
function setFieldValues(wrapper, username, password, confirm) {
const usernameField = wrapper.find('#usernameField input');
const passwordField = wrapper.find('#passwordField input');
const confirmField = wrapper.find('#confirmField input');

usernameField.simulate('change', stubEvent(usernameField, username));
passwordField.simulate('change', stubEvent(passwordField, password));
confirmField.simulate('change', stubEvent(confirmField, confirm));
}

async function setFieldValuesAndUpdate(wrapper, username, password, confirm) {
setFieldValues(wrapper, username, password, confirm);
await flushPromises();
wrapper.update();
}
});

async function setFieldValuesAndUpdate(wrapper, username, password, confirm) {
setFieldValues(wrapper, username, password, confirm);
await flushPromises();
wrapper.update();
}

/**
* Stubbed event object suitable for event simulatrion.
Expand Down

0 comments on commit b5959e6

Please sign in to comment.