-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(password reset): user should be able to reset their password (#37)
• Created an email confirmation form • Created a password reset form [Finishes #165273526]
- Loading branch information
1 parent
3e08557
commit da27459
Showing
9 changed files
with
177 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 26 additions & 6 deletions
32
src/components/EmailConfirmationForm/EmailConfirmationForm.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,41 @@ | ||
// react libraries | ||
import React from 'react'; | ||
|
||
// third party libraries | ||
import { shallow } from 'enzyme'; | ||
|
||
// components | ||
import EmailConfirmationForm from '.'; | ||
|
||
describe('EmailConfirmation Component', () => { | ||
const props = { | ||
backdropId: 'id', | ||
closeModal: () => { }, | ||
}; | ||
|
||
it('should render without exploding', () => { | ||
const wrapper = shallow(<EmailConfirmationForm {...props} />); | ||
expect(wrapper.length).toBe(1); | ||
}); | ||
|
||
// it('should call start logout on button click', () => { | ||
// const mockLogout = jest.fn(); | ||
// const wrapper = shallow(<EmailConfirmationForm startLogout={mockLogout} />); | ||
// wrapper.find('button').at(0).simulate('click'); | ||
// expect(mockLogout).toHaveBeenCalled(); | ||
// }); | ||
it('should render an error', () => { | ||
const wrapper = shallow(<EmailConfirmationForm />); | ||
wrapper.setProps({ isConfirmEmailError: true }); | ||
|
||
expect(wrapper.find('small').length).toBe(1); | ||
}); | ||
|
||
it('should render a success message', () => { | ||
const wrapper = shallow(<EmailConfirmationForm />); | ||
wrapper.setProps({ isConfirmEmailSuccess: true }); | ||
|
||
expect(wrapper.find('small').length).toBe(1); | ||
}); | ||
|
||
it('should render a loader while sending a message', () => { | ||
const wrapper = shallow(<EmailConfirmationForm />); | ||
wrapper.setProps({ isLoading: true }); | ||
|
||
expect(wrapper.find('.signupForm__loader').length).toBe(1); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,11 +13,16 @@ jest.mock('axios'); | |
|
||
const middlewares = [thunk]; | ||
const mockStore = configureMockStore(middlewares); | ||
const store = mockStore(); | ||
let store; | ||
|
||
const mockData = { status: 'OK' }; | ||
const email = '[email protected]'; | ||
|
||
beforeEach(() => { | ||
store = mockStore(); | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('Should send an email', async () => { | ||
mockAxios.post.mockImplementationOnce(() => Promise.resolve({ data: mockData })); | ||
|
||
|
@@ -31,3 +36,17 @@ it('Should send an email', async () => { | |
expect(store.getActions()).toEqual(expectedActions); | ||
expect(mockAxios.post).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('Should send an email', async () => { | ||
mockAxios.post.mockRejectedValueOnce(); | ||
|
||
const expectedActions = [ | ||
{ type: CONFIRM_EMAIL_START }, | ||
{ type: CONFIRM_EMAIL_FAILURE, error: undefined }, | ||
]; | ||
|
||
await store.dispatch(confirmEmailActions(email)); | ||
|
||
expect(store.getActions()).toEqual(expectedActions); | ||
expect(mockAxios.post).toHaveBeenCalledTimes(1); | ||
}); |
69 changes: 69 additions & 0 deletions
69
src/store/actions/resetPassword/resetPasswordActions.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// third party libraries | ||
import mockAxios from 'axios'; | ||
import configureMockStore from 'redux-mock-store'; | ||
import thunk from 'redux-thunk'; | ||
|
||
// thunks | ||
import resetPassword from 'store/actions/resetPassword'; | ||
import { | ||
PASSWORD_RESET_START, | ||
PASSWORD_RESET_SUCCESS, | ||
PASSWORD_RESET_FAILURE, | ||
TOKEN_RESET_FAILURE, | ||
} from 'store/actions/passwordResetTypes'; | ||
|
||
jest.mock('axios'); | ||
|
||
const middlewares = [thunk]; | ||
const mockStore = configureMockStore(middlewares); | ||
let store; | ||
|
||
const mockData = { status: 'OK' }; | ||
const password = 'Pa$$word123'; | ||
|
||
beforeEach(() => { | ||
store = mockStore(); | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('Should reset the password', async () => { | ||
mockAxios.post.mockResolvedValue({ data: mockData }); | ||
|
||
const expectedActions = [ | ||
{ type: PASSWORD_RESET_START }, | ||
{ type: PASSWORD_RESET_SUCCESS }, | ||
]; | ||
|
||
await store.dispatch(resetPassword(password)); | ||
|
||
expect(store.getActions()).toEqual(expectedActions); | ||
expect(mockAxios.post).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('Should dispatch the password error action on failure', async () => { | ||
mockAxios.post.mockRejectedValue({ response: { data: { errors: { password: [] } } } }); | ||
|
||
const expectedActions = [ | ||
{ type: PASSWORD_RESET_START }, | ||
{ type: PASSWORD_RESET_FAILURE, error: [] }, | ||
]; | ||
|
||
await store.dispatch(resetPassword(password)); | ||
|
||
expect(store.getActions()).toEqual(expectedActions); | ||
expect(mockAxios.post).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it('Should dispatch the token error action on failure', async () => { | ||
mockAxios.post.mockRejectedValue({ response: { data: { error: 'Invalid token' } } }); | ||
|
||
const expectedActions = [ | ||
{ type: PASSWORD_RESET_START }, | ||
{ type: TOKEN_RESET_FAILURE, error: ['Invalid token'] }, | ||
]; | ||
|
||
await store.dispatch(resetPassword(password)); | ||
|
||
expect(store.getActions()).toEqual(expectedActions); | ||
expect(mockAxios.post).toHaveBeenCalledTimes(1); | ||
}); |
23 changes: 17 additions & 6 deletions
23
src/store/reducers/passwordResetReducer/PassowdResetReducer.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,47 @@ | ||
import { | ||
PASSWORD_RESET_START, | ||
PASSWORD_RESET_SUCCESS, | ||
PASSWORD_RESET_FAILURE | ||
PASSWORD_RESET_FAILURE, | ||
TOKEN_RESET_FAILURE, | ||
} from 'store/actions/passwordResetTypes'; | ||
|
||
import passwordResetReducer from '.'; | ||
|
||
describe('cpassowd reset Reducer', () => { | ||
describe('Password reset Reducer', () => { | ||
it('Should return the initial state', () => { | ||
const newState = passwordResetReducer(undefined, {}); | ||
expect(newState.isLoading).toBe(false); | ||
expect(newState.isPassordResetSuccess).toBe(false); | ||
expect(newState.isPasswordResetError).toBe(false); | ||
}); | ||
|
||
it('Should start loading', () => { | ||
it('Should indicate the start of loading', () => { | ||
const newState = passwordResetReducer(undefined, { type: PASSWORD_RESET_START }); | ||
expect(newState.isLoading).toBe(true); | ||
expect(newState.isPassordResetSuccess).toBe(false); | ||
expect(newState.isPasswordResetError).toBe(false); | ||
}); | ||
|
||
it('Should set successfuly have reset the password', () => { | ||
it('Should indicate a successful reset of the password', () => { | ||
const newState = passwordResetReducer(undefined, { type: PASSWORD_RESET_SUCCESS }); | ||
expect(newState.isLoading).toBe(false); | ||
expect(newState.isPassordResetSuccess).toBe(true); | ||
expect(newState.isPasswordResetError).toBe(false); | ||
}); | ||
|
||
it('Should have failed', () => { | ||
const newState = passwordResetReducer(undefined, { type: PASSWORD_RESET_FAILURE }); | ||
it('Should indicate failure in reseting the password due to a password error', () => { | ||
const newState = passwordResetReducer(undefined, { type: PASSWORD_RESET_FAILURE, error: ['Invalid password'] }); | ||
expect(newState.isLoading).toBe(false); | ||
expect(newState.isPassordResetSuccess).toBe(false); | ||
expect(newState.isPasswordResetError).toBe(true); | ||
expect(newState.passwordErrors.length).toBe(1); | ||
}); | ||
|
||
it('Should indicate failure in reseting the password due to a token error', () => { | ||
const newState = passwordResetReducer(undefined, { type: TOKEN_RESET_FAILURE, error: ['Token error'] }); | ||
expect(newState.isLoading).toBe(false); | ||
expect(newState.isPassordResetSuccess).toBe(false); | ||
expect(newState.isPasswordResetError).toBe(true); | ||
expect(newState.tokenErrors.length).toBe(1); | ||
}); | ||
}); |