-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #58 from kkkkkSE/feat/manage-account
[feat] 비밀번호 변경 페이지 구현 및 테스트 코드 작성
- Loading branch information
Showing
11 changed files
with
547 additions
and
14 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { fireEvent, screen, waitFor } from '@testing-library/react'; | ||
|
||
import { render } from '../../test-helper'; | ||
|
||
import PasswordChangeForm from './PasswordChangeForm'; | ||
|
||
const context = describe; | ||
|
||
const store = { | ||
changePassword: jest.fn(), | ||
}; | ||
|
||
jest.mock('../../hooks/usePasswordChangeFormStore', () => () => [{}, store]); | ||
|
||
describe('<PasswordChangeForm />', () => { | ||
it('render change password form', () => { | ||
render(<PasswordChangeForm />); | ||
|
||
screen.getByLabelText(/새 비밀번호/); | ||
|
||
screen.getByRole('button', { name: /변경하기/ }); | ||
}); | ||
|
||
context('when submitting form', () => { | ||
it('execute changePassword function in store', async () => { | ||
render(<PasswordChangeForm />); | ||
|
||
fireEvent.submit(screen.getByTestId('password-change-form')); | ||
|
||
await waitFor(() => { | ||
expect(store.changePassword).toHaveBeenCalled(); | ||
}); | ||
}); | ||
}); | ||
}); |
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,86 @@ | ||
import { Controller, useForm } from 'react-hook-form'; | ||
|
||
import useLoginUserStore from '../../hooks/useLoginUserStore'; | ||
import usePasswordChangeFormStore from '../../hooks/usePasswordChangeFormStore'; | ||
|
||
import OperationButtons from '../ui/OperationButtons'; | ||
import ErrorMessage from '../ui/ErrorMessage'; | ||
|
||
import TextBox from '../ui/TextBox'; | ||
|
||
export default function PasswordChangeForm() { | ||
const [{ userType }] = useLoginUserStore(); | ||
|
||
const [{ errorMessage }, store] = usePasswordChangeFormStore(); | ||
|
||
interface FormValues { | ||
password: string; | ||
newPassword: string; | ||
confirmNewPassword: string; | ||
} | ||
|
||
const { control, handleSubmit } = useForm<FormValues>(); | ||
|
||
const onSubmit = (data: FormValues) => { | ||
store.changePassword({ | ||
type: userType, | ||
...data, | ||
}); | ||
}; | ||
|
||
return ( | ||
<form | ||
onSubmit={handleSubmit(onSubmit)} | ||
data-testid="password-change-form" | ||
> | ||
<Controller | ||
control={control} | ||
name="password" | ||
render={({ field: { value, onChange } }) => ( | ||
<TextBox | ||
type="password" | ||
label="기존 비밀번호" | ||
value={value} | ||
onChange={onChange} | ||
/> | ||
)} | ||
/> | ||
|
||
<Controller | ||
control={control} | ||
name="newPassword" | ||
render={({ field: { value, onChange } }) => ( | ||
<TextBox | ||
type="password" | ||
label="새 비밀번호" | ||
placeholder="8~40자 영문, 숫자 포함" | ||
value={value} | ||
onChange={onChange} | ||
/> | ||
)} | ||
/> | ||
|
||
<Controller | ||
control={control} | ||
name="confirmNewPassword" | ||
render={({ field: { value, onChange } }) => ( | ||
<TextBox | ||
type="password" | ||
label="비밀번호 확인" | ||
value={value} | ||
onChange={onChange} | ||
/> | ||
)} | ||
/> | ||
|
||
<OperationButtons | ||
primaryName="변경하기" | ||
primaryType="submit" | ||
/> | ||
|
||
{errorMessage && ( | ||
<ErrorMessage>{errorMessage}</ErrorMessage> | ||
)} | ||
</form> | ||
); | ||
} |
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,13 @@ | ||
import { container } from 'tsyringe'; | ||
|
||
import { useStore } from 'usestore-ts'; | ||
|
||
import PasswordChangeFormStore from '../stores/PasswordChangeFormStore'; | ||
|
||
const usePasswordChangeFormStore = () => { | ||
const store = container.resolve(PasswordChangeFormStore); | ||
|
||
return useStore(store); | ||
}; | ||
|
||
export default usePasswordChangeFormStore; |
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,76 @@ | ||
import { Link } from 'react-router-dom'; | ||
|
||
import styled from 'styled-components'; | ||
|
||
import ContentLayout from '../components/layout/ContentLayout'; | ||
|
||
import passwordIcon from '../assets/image/icon/password-icon.png'; | ||
import withdrawalIcon from '../assets/image/icon/withdrawal-icon.png'; | ||
|
||
export default function AccountPage() { | ||
return ( | ||
<ContentLayout | ||
pageHeader="계정 관리" | ||
testId="account-management" | ||
> | ||
<ContainerList> | ||
<li> | ||
<Link to="change-password"> | ||
<img src={passwordIcon} alt="" /> | ||
<span>비밀번호 변경</span> | ||
</Link> | ||
</li> | ||
<li> | ||
<Link to="delete-password"> | ||
<img src={withdrawalIcon} alt="" /> | ||
<span>계정 탈퇴</span> | ||
</Link> | ||
</li> | ||
</ContainerList> | ||
</ContentLayout> | ||
); | ||
} | ||
|
||
const ContainerList = styled.ul` | ||
li { | ||
padding: 1rem 1.4rem; | ||
margin-bottom: .4rem; | ||
border-radius: 1rem; | ||
cursor: pointer; | ||
:hover { | ||
background-color: ${(props) => props.theme.colors.gray2.default}; | ||
} | ||
> a { | ||
display: flex; | ||
align-items: center; | ||
flex-wrap: nowrap; | ||
width: 100%; | ||
} | ||
img { | ||
width: 3rem; | ||
margin-right: 2rem; | ||
} | ||
span { | ||
${(props) => props.theme.texts.bold.subTitle} | ||
} | ||
} | ||
@media screen and (${(props) => props.theme.breakPoint.mobile}){ | ||
li { | ||
padding: 1rem 1.2rem; | ||
img { | ||
width: 2.6rem; | ||
margin-right: 1.4rem; | ||
} | ||
span { | ||
${(props) => props.theme.texts.bold.boldText} | ||
} | ||
} | ||
} | ||
`; |
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,37 @@ | ||
import { useEffect } from 'react'; | ||
|
||
import { useNavigate } from 'react-router-dom'; | ||
|
||
import usePasswordChangeFormStore from '../hooks/usePasswordChangeFormStore'; | ||
|
||
import { STATIC_ROUTES } from '../constants/routes'; | ||
|
||
import ContentLayout from '../components/layout/ContentLayout'; | ||
import PasswordChangeForm from '../components/account/PasswordChangeForm'; | ||
|
||
export default function PasswordChangePage() { | ||
const navigate = useNavigate(); | ||
|
||
const [{ done }, store] = usePasswordChangeFormStore(); | ||
|
||
useEffect(() => { | ||
store.reset(); | ||
}, []); | ||
|
||
useEffect(() => { | ||
if (done) { | ||
store.reset(); | ||
|
||
navigate(STATIC_ROUTES.ACCOUNT); | ||
} | ||
}, [done]); | ||
|
||
return ( | ||
<ContentLayout | ||
pageHeader="비밀번호 변경" | ||
testId="password-change" | ||
> | ||
<PasswordChangeForm /> | ||
</ContentLayout> | ||
); | ||
} |
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
Oops, something went wrong.