-
Notifications
You must be signed in to change notification settings - Fork 298
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: refactor inverstor password manager component
- Loading branch information
1 parent
51d367f
commit 7301ff9
Showing
5 changed files
with
176 additions
and
39 deletions.
There are no files selected for viewing
138 changes: 138 additions & 0 deletions
138
...cfd/src/Containers/investor-password-manager/__tests__/investor-password-manager.spec.tsx
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,138 @@ | ||
import React from 'react'; | ||
import { screen, render, waitFor, fireEvent } from '@testing-library/react'; | ||
import InvestorPasswordManager from '../investor-password-manager'; | ||
import { localize } from '@deriv/translations'; | ||
|
||
type TValidLengthOptions = { | ||
min?: number; | ||
max?: number; | ||
}; | ||
|
||
jest.mock('@deriv/shared/src/services/ws-methods', () => ({ | ||
__esModule: true, | ||
default: 'mockedDefaultExport', | ||
WS: { | ||
verifyEmail: jest.fn(() => Promise.resolve()), | ||
}, | ||
})); | ||
|
||
const validLengthMock = (value = '', options: TValidLengthOptions) => | ||
(options.min ? value.length >= options.min : true) && (options.max ? value.length <= options.max : true); | ||
|
||
const mock_errors = { | ||
password: () => localize('Password should have lower and uppercase English letters with numbers.'), | ||
repeated_chars_are_easy: () => localize('Repeats like "aaa" are easy to guess'), | ||
repeated_patterns_are_easy: () => localize('Repeats like "abcabcabc" are only slightly harder to guess than "abc"'), | ||
recent_years_are_easy: () => localize('Recent years are easy to guess'), | ||
}; | ||
|
||
jest.mock('@deriv/shared/src/utils/validation/declarative-validation-rules.ts', () => ({ | ||
getErrorMessages: jest.fn(() => ({ | ||
password_warnings: mock_errors, | ||
})), | ||
validLength: jest.fn((value, options) => validLengthMock(value, options)), | ||
})); | ||
|
||
describe('<InvestorPasswordManager> ', () => { | ||
const mock_props = { | ||
error_message_investor: 'Forgot your password? Please reset your password.', | ||
is_submit_success_investor: false, | ||
multi_step_ref: { current: { goNextStep: jest.fn(), goPrevStep: jest.fn() } }, | ||
onSubmit: jest.fn(), | ||
setPasswordType: jest.fn(() => 'investor'), | ||
toggleModal: jest.fn(), | ||
validatePassword: jest.fn(), | ||
}; | ||
|
||
it('should render the correct texts ', async () => { | ||
render(<InvestorPasswordManager {...mock_props} />); | ||
expect(await screen.findByText(/new investor password/i)).toBeInTheDocument(); | ||
expect( | ||
screen.getByText( | ||
/use this password to grant viewing access to another user. While they may view your trading account, they will not be able to trade or take any other actions/i | ||
) | ||
).toBeInTheDocument(); | ||
expect( | ||
screen.getByText( | ||
/if this is the first time you try to create a password, or you have forgotten your password, please reset it/i | ||
) | ||
).toBeInTheDocument(); | ||
expect(screen.getByText(/current investor password/i)).toBeInTheDocument(); | ||
expect(screen.getByText(/new investor password/i)).toBeInTheDocument(); | ||
}); | ||
|
||
it('should fill the password field and trigger the appropriate error message for repeated password pattern', async () => { | ||
render(<InvestorPasswordManager {...mock_props} />); | ||
expect(await screen.findByText(/new investor password/i)).toBeInTheDocument(); | ||
const new_investor = screen.getByLabelText(/new investor password/i); | ||
await waitFor(() => { | ||
fireEvent.change(new_investor, { target: { value: 'abcabcabc' } }); | ||
}); | ||
expect( | ||
await screen.findByText(/repeats like "abcabcabc" are only slightly harder to guess than "abc"/i) | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it('should fill the password field and trigger the appropriate error message for repeated characters', async () => { | ||
render(<InvestorPasswordManager {...mock_props} />); | ||
expect(await screen.findByText(/new investor password/i)).toBeInTheDocument(); | ||
const new_investor = screen.getByLabelText(/new investor password/i); | ||
await waitFor(() => { | ||
fireEvent.change(new_investor, { target: { value: 'aaaaa' } }); | ||
}); | ||
expect(await screen.findByText(/repeats like "aaa" are easy to guess/i)).toBeInTheDocument(); | ||
}); | ||
|
||
it('should fill the password field and trigger the appropriate error message for using recent years', async () => { | ||
render(<InvestorPasswordManager {...mock_props} />); | ||
expect(await screen.findByText(/new investor password/i)).toBeInTheDocument(); | ||
const new_investor = screen.getByLabelText(/new investor password/i); | ||
await waitFor(() => { | ||
fireEvent.change(new_investor, { target: { value: '1996' } }); | ||
}); | ||
|
||
expect(await screen.findByText(/recent years are easy to guess/i)).toBeInTheDocument(); | ||
}); | ||
|
||
it('should fill the password field and trigger the appropriate message for strong and valid password', async () => { | ||
render(<InvestorPasswordManager {...mock_props} />); | ||
expect(await screen.findByText(/new investor password/i)).toBeInTheDocument(); | ||
const new_investor = screen.getByLabelText(/new investor password/i); | ||
await waitFor(() => { | ||
fireEvent.change(new_investor, { target: { value: 'Qzzxcc!lopi1' } }); | ||
expect( | ||
screen.getAllByText( | ||
/strong passwords contain at least 8 characters, combine uppercase and lowercase letters and numbers/i | ||
)[0] | ||
).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
it('should fill the password fields and trigger the appropriate message and enable the change password button', async () => { | ||
const mockOnSubmit = jest.fn(); | ||
render(<InvestorPasswordManager {...mock_props} onSubmit={mockOnSubmit} />); | ||
expect(await screen.findByText(/new investor password/i)).toBeInTheDocument(); | ||
const current_investor = screen.getByLabelText(/current investor password/i); | ||
const new_investor = screen.getByLabelText(/new investor password/i); | ||
const change_investor_password_btn = screen.getByText(/change investor password/i); | ||
await waitFor(() => { | ||
fireEvent.change(current_investor, { target: { value: 'Testing1234' } }); | ||
fireEvent.change(new_investor, { target: { value: 'Qzzxcc!lopi1' } }); | ||
expect( | ||
screen.getAllByText( | ||
/strong passwords contain at least 8 characters, combine uppercase and lowercase letters and numbers/i | ||
)[0] | ||
).toBeInTheDocument(); | ||
expect(change_investor_password_btn).toBeEnabled(); | ||
fireEvent.click(change_investor_password_btn); | ||
expect(screen.getByTestId('dt_error_message_investor')).toBeInTheDocument(); | ||
expect(mockOnSubmit).toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
it('should render success message if the user clicks on create or reset investor passwords', async () => { | ||
render(<InvestorPasswordManager {...mock_props} is_submit_success_investor={true} />); | ||
expect(screen.getByText(/your investor password has been changed/i)).toBeInTheDocument(); | ||
expect(screen.getByRole('button', { name: /ok/i })).toBeInTheDocument(); | ||
}); | ||
}); |
22 changes: 22 additions & 0 deletions
22
packages/cfd/src/Containers/investor-password-manager/cfd-password-success-message.tsx
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,22 @@ | ||
import React from 'react'; | ||
import { Text, Button, Icon } from '@deriv/components'; | ||
import { localize, Localize } from '@deriv/translations'; | ||
import { TCFDPasswordSuccessMessage } from '../props.types'; | ||
|
||
const CFDPasswordSuccessMessage = ({ toggleModal, is_investor }: TCFDPasswordSuccessMessage) => ( | ||
<div className='cfd-password-manager__success'> | ||
<Icon icon='IcPasswordUpdated' size={128} /> | ||
<Text as='p' size='xxs' align='center'> | ||
{is_investor ? ( | ||
<Localize i18n_default_text='Your investor password has been changed.' /> | ||
) : ( | ||
<Localize i18n_default_text='Your password has been changed.' /> | ||
)} | ||
</Text> | ||
<Button onClick={toggleModal} className='cfd-password-manager__success-btn' primary large> | ||
<p className='dc-btn__text'>{localize('OK')}</p> | ||
</Button> | ||
</div> | ||
); | ||
|
||
export default CFDPasswordSuccessMessage; |
3 changes: 3 additions & 0 deletions
3
packages/cfd/src/Containers/investor-password-manager/index.ts
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,3 @@ | ||
import InvestorPasswordManager from './investor-password-manager'; | ||
|
||
export default InvestorPasswordManager; |
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