Skip to content

Commit 67a4357

Browse files
committed
Refactor and README.md changes
1 parent 38cee47 commit 67a4357

File tree

9 files changed

+87
-88
lines changed

9 files changed

+87
-88
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ React Firebase Admin is our in-house admin dashboard boilerplate, used in many o
8888
- [Format.js](https://formatjs.io/) (★ 11.7k) libraries for internationalization (see [docs](https://formatjs.io/docs/basic-internationalization-principles)).
8989
- [date-fns](https://date-fns.org/) (★ 22.3k) date utility library (see [docs](https://date-fns.org/docs/Getting-Started)).
9090
- [cross-env](https://github.com/kentcdodds/cross-env) (★ 4.9k) run scripts that set and use environment variables across platforms (see [docs](https://www.npmjs.com/package/cross-env)).
91+
- [React Hook Form](https://github.com/react-hook-form/react-hook-form) (★ 14.6k) Performant, flexible and extensible forms with easy to use validation.
92+
- [yup](https://github.com/jquense/yup) (★ 11k) schema builder for value parsing and validation.
9193

9294
### Unit Testing
9395

src/components/UserForm/index.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const UserForm = ({ isEditing, isProfile, user, onSubmitHandler, schema }) => {
3636
setValue('file', null);
3737
}
3838
return () => dispatch(usersCleanUp());
39-
}, [dispatch, success]);
39+
}, [dispatch, success, setValue]);
4040

4141
const invalidEmailMessage = useFormatMessage('UserForm.invalidEmail');
4242

src/pages/Login/index.jsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* eslint-disable no-nested-ternary */
21
import React, { useEffect } from 'react';
32
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
43
import { Redirect, Link } from 'react-router-dom';
@@ -155,17 +154,18 @@ const Login = () => {
155154
ref={register}
156155
/>
157156
</div>
158-
{isEmailLink ? (
159-
errors.password ? (
160-
<ErrorMessage text={unsafePasswordMessage} />
161-
) : (
162-
isValidPassword && (
163-
<p className="is-success">{safePasswordMessage}</p>
164-
)
165-
)
157+
{errors.password ? (
158+
<ErrorMessage
159+
text={
160+
isEmailLink
161+
? unsafePasswordMessage
162+
: invalidPasswordMessage
163+
}
164+
/>
166165
) : (
167-
errors.password && (
168-
<ErrorMessage text={invalidPasswordMessage} />
166+
isEmailLink &&
167+
isValidPassword && (
168+
<p className="is-success">{safePasswordMessage}</p>
169169
)
170170
)}
171171
</div>

src/pages/Profile/ChangePassword/ChangePassword.test.js

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,67 +26,69 @@ describe('<ChangePassword /> rendering', () => {
2626
expect(component.asFragment()).toMatchSnapshot();
2727
});
2828

29-
it('should display an error message when the current and new password are equal', () => {
29+
it('should display an error message when the current and new password are equal', async () => {
3030
const { component } = renderWithProviders(<ChangePassword />)({
3131
auth: {
3232
userData: {},
3333
},
3434
});
3535

36-
fireEvent.input(component.container.querySelector('input[name=current]'), {
36+
fireEvent.input(component.getByTestId('current'), {
3737
target: {
3838
value: 'oldpassword',
3939
},
4040
});
4141

42-
fireEvent.input(component.container.querySelector('input[name=new]'), {
42+
fireEvent.input(component.getByTestId('new'), {
4343
target: {
4444
value: 'oldpassword',
4545
},
4646
});
4747

48-
expect(component.container.querySelector('.error')).toBeTruthy();
48+
await (() =>
49+
expect(
50+
component.getByText(
51+
'The new password and the current one cannot be the same'
52+
)
53+
).toBeTruthy());
4954
});
5055

51-
it('should display a message informing the user that the new password is secure', () => {
56+
it('should display a message informing the user that the new password is secure', async () => {
5257
const { component } = renderWithProviders(<ChangePassword />)({
5358
auth: {
5459
userData: {},
5560
},
5661
});
5762

58-
fireEvent.input(component.container.querySelector('input[name=new]'), {
63+
fireEvent.input(component.getByTestId('new'), {
5964
target: {
6065
value: 'newSecurePassword',
6166
},
6267
});
6368

64-
expect(component.container.querySelector('p.is-success')).toBeTruthy();
69+
await (() => expect(component.getByText('Safe password')).toBeTruthy());
6570
});
6671

67-
it('should display a message informing the user that the new and confirmation passwords match', () => {
72+
it('should display a message informing the user that the new and confirmation passwords match', async () => {
6873
const { component } = renderWithProviders(<ChangePassword />)({
6974
auth: {
7075
userData: {},
7176
},
7277
});
7378

74-
fireEvent.input(component.container.querySelector('input[name=new]'), {
79+
fireEvent.input(component.getByTestId('new'), {
7580
target: {
7681
value: 'newSecurePassword!',
7782
},
7883
});
7984

80-
fireEvent.input(
81-
component.container.querySelector('input[name=confirmation]'),
82-
{
83-
target: {
84-
value: 'newSecurePassword!',
85-
},
86-
}
87-
);
85+
fireEvent.input(component.getByTestId('confirmation'), {
86+
target: {
87+
value: 'newSecurePassword!',
88+
},
89+
});
8890

89-
expect(component.container.querySelector('p.is-success')).toBeTruthy();
91+
await (() => expect(component.getByText('Passwords match')).toBeTruthy());
9092
});
9193

9294
it('should display the button loading when loading', () => {
@@ -117,31 +119,25 @@ describe('<ChangePassword /> actions', () => {
117119
},
118120
});
119121

120-
fireEvent.input(component.container.querySelector('input[name=current]'), {
122+
fireEvent.input(component.getByTestId('current'), {
121123
target: {
122124
value: 'oldpassword',
123125
},
124126
});
125127

126-
fireEvent.input(
127-
component.container.querySelector('input[name=confirmation]'),
128-
{
129-
target: {
130-
value: 'newpassword',
131-
},
132-
}
133-
);
134-
135-
fireEvent.input(
136-
component.container.querySelector('input[name=confirmation]'),
137-
{
138-
target: {
139-
value: 'newpassword',
140-
},
141-
}
142-
);
143-
144-
fireEvent.submit(component.container.querySelector('form'));
128+
fireEvent.input(component.getByTestId('new'), {
129+
target: {
130+
value: 'newpassword',
131+
},
132+
});
133+
134+
fireEvent.input(component.getByTestId('confirmation'), {
135+
target: {
136+
value: 'newpassword',
137+
},
138+
});
139+
140+
fireEvent.click(component.getByRole('button'));
145141

146142
await (() => expect(actions.changeUserPassword).toBeCalledTimes(1));
147143

src/pages/Profile/ChangePassword/__snapshots__/ChangePassword.test.js.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ exports[`<ChangePassword /> rendering should render without crashing 1`] = `
4848
>
4949
<input
5050
class="input"
51+
data-testid="current"
5152
name="current"
5253
type="password"
5354
/>
@@ -79,6 +80,7 @@ exports[`<ChangePassword /> rendering should render without crashing 1`] = `
7980
>
8081
<input
8182
class="input"
83+
data-testid="new"
8284
name="new"
8385
type="password"
8486
/>
@@ -109,6 +111,7 @@ exports[`<ChangePassword /> rendering should render without crashing 1`] = `
109111
>
110112
<input
111113
class="input"
114+
data-testid="confirmation"
112115
name="confirmation"
113116
type="password"
114117
/>

src/pages/Profile/ChangePassword/index.jsx

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const ChangePasswordCard = () => {
3535
const dispatch = useDispatch();
3636

3737
const { register, handleSubmit, watch, setValue, errors } = useForm({
38+
mode: 'onChange',
3839
defaultValues: {
3940
current: '',
4041
new: '',
@@ -53,14 +54,8 @@ const ChangePasswordCard = () => {
5354
}, [dispatch, changedPassword]);
5455

5556
const newPassword = watch('new');
56-
const currentPassword = watch('current');
5757
const confirmationPassword = watch('confirmation');
5858

59-
const isNewPasswordSecure = newPassword && newPassword.length >= 6;
60-
61-
const isCurrentPasswordInvalid =
62-
currentPassword && currentPassword.length < 6;
63-
6459
const invalidPasswordMessage = useFormatMessage(
6560
`ChangePassword.invalidPassword`
6661
);
@@ -71,11 +66,6 @@ const ChangePasswordCard = () => {
7166
`ChangePassword.insecurePassword`
7267
);
7368

74-
const insecurePasswordError = <ErrorMessage text={insecurePasswordMessage} />;
75-
76-
const newPasswordsAreEqual =
77-
newPassword && confirmationPassword && newPassword === confirmationPassword;
78-
7969
const passwordsMatchMessagge = useFormatMessage(
8070
`ChangePassword.matchPassword`
8171
);
@@ -84,15 +74,8 @@ const ChangePasswordCard = () => {
8474
`ChangePassword.notMatchPassword`
8575
);
8676

87-
const notMatchPasswordError = <ErrorMessage text={notMatchPasswordMessage} />;
88-
89-
const currentAndNewPasswordsEqual =
90-
newPassword && currentPassword === newPassword;
91-
9277
const samePasswordMessage = useFormatMessage(`ChangePassword.samePassword`);
9378

94-
const samePasswordError = <ErrorMessage text={samePasswordMessage} />;
95-
9679
const onSubmitHandler = ({ current, confirmation }) => {
9780
dispatch(changeUserPassword(current, confirmation));
9881
};
@@ -119,18 +102,18 @@ const ChangePasswordCard = () => {
119102
<div className="field">
120103
<div className="control">
121104
<input
105+
data-testid="current"
122106
className={classNames('input', {
123-
'is-danger': isCurrentPasswordInvalid,
107+
'is-danger': errors.current,
124108
})}
125109
type="password"
126110
name="current"
127111
ref={register}
128112
/>
129113
</div>
130-
{isCurrentPasswordInvalid ||
131-
(errors.current && (
132-
<ErrorMessage text={invalidPasswordMessage} />
133-
))}
114+
{errors.current && (
115+
<ErrorMessage text={invalidPasswordMessage} />
116+
)}
134117
</div>
135118
</div>
136119
</div>
@@ -145,20 +128,29 @@ const ChangePasswordCard = () => {
145128
<div className="field">
146129
<div className="control">
147130
<input
131+
data-testid="new"
148132
className={classNames(
149133
`input`,
150-
{ 'is-success': isNewPasswordSecure },
151-
{ 'is-danger': newPassword && !isNewPasswordSecure }
134+
{ 'is-success': newPassword && !errors.new },
135+
{ 'is-danger': errors.new }
152136
)}
153137
type="password"
154138
name="new"
155139
ref={register}
156140
/>
157141
</div>
158-
{isNewPasswordSecure ? (
159-
<p className="is-success">{safePasswordMessage}</p>
142+
{errors.new ? (
143+
<ErrorMessage
144+
text={
145+
newPassword.length < 6
146+
? insecurePasswordMessage
147+
: samePasswordMessage
148+
}
149+
/>
160150
) : (
161-
newPassword && insecurePasswordError
151+
newPassword && (
152+
<p className="is-success">{safePasswordMessage}</p>
153+
)
162154
)}
163155
</div>
164156
</div>
@@ -174,23 +166,28 @@ const ChangePasswordCard = () => {
174166
<div className="field">
175167
<div className="control">
176168
<input
169+
data-testid="confirmation"
177170
className={classNames(
178171
`input`,
179-
{ 'is-success': newPasswordsAreEqual },
180172
{
181-
'is-danger':
182-
confirmationPassword && !newPasswordsAreEqual,
173+
'is-success':
174+
confirmationPassword && !errors.confirmation,
175+
},
176+
{
177+
'is-danger': errors.confirmation,
183178
}
184179
)}
185180
type="password"
186181
name="confirmation"
187182
ref={register}
188183
/>
189184
</div>
190-
{newPasswordsAreEqual ? (
191-
<p className="is-success">{passwordsMatchMessagge}</p>
185+
{errors.confirmation ? (
186+
<ErrorMessage text={notMatchPasswordMessage} />
192187
) : (
193-
confirmationPassword && notMatchPasswordError
188+
confirmationPassword && (
189+
<p className="is-success">{passwordsMatchMessagge}</p>
190+
)
194191
)}
195192
</div>
196193
</div>
@@ -207,7 +204,6 @@ const ChangePasswordCard = () => {
207204
{useFormatMessage(`ChangePassword.submits`)}
208205
</button>
209206
</div>
210-
{currentAndNewPasswordsEqual && samePasswordError}
211207
</div>
212208
</div>
213209
</div>

src/pages/Profile/__snapshots__/Profile.test.js.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ exports[`<Profile /> rendering should render without crashing 1`] = `
408408
>
409409
<input
410410
class="input"
411+
data-testid="current"
411412
name="current"
412413
type="password"
413414
/>
@@ -439,6 +440,7 @@ exports[`<Profile /> rendering should render without crashing 1`] = `
439440
>
440441
<input
441442
class="input"
443+
data-testid="new"
442444
name="new"
443445
type="password"
444446
/>
@@ -469,6 +471,7 @@ exports[`<Profile /> rendering should render without crashing 1`] = `
469471
>
470472
<input
471473
class="input"
474+
data-testid="confirmation"
472475
name="confirmation"
473476
type="password"
474477
/>

0 commit comments

Comments
 (0)