-
Notifications
You must be signed in to change notification settings - Fork 272
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add redirection to previous page after login (#560)
* feat: redirection after login * feat: redirection after login with otp * feat: redirect on oauth
- Loading branch information
Showing
9 changed files
with
96 additions
and
21 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
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 |
---|---|---|
|
@@ -12,11 +12,13 @@ import { authSinginMutation } from '../loginForm.graphql'; | |
|
||
jest.mock('@sb/webapp-core/services/analytics'); | ||
|
||
const mockSearch = '?redirect=%2Fen%2Fprofile'; | ||
const mockNavigate = jest.fn(); | ||
jest.mock('react-router-dom', () => { | ||
return { | ||
...jest.requireActual<NodeModule>('react-router-dom'), | ||
useNavigate: () => mockNavigate, | ||
useLocation: () => ({ search: mockSearch }), | ||
}; | ||
}); | ||
const Component = () => <LoginForm />; | ||
|
@@ -34,14 +36,42 @@ describe('LoginForm: Component', () => { | |
|
||
const getEmailInput = async () => await screen.findByLabelText(/email/i); | ||
const getPasswordInput = async () => await screen.findByLabelText(/password/i); | ||
const clickLoginButton = async () => userEvent.click(await screen.findByRole('button', { name: /log in/i })); | ||
const clickLoginButton = async () => await userEvent.click(await screen.findByRole('button', { name: /log in/i })); | ||
const user = currentUserFactory({ | ||
firstName: 'Jack', | ||
lastName: 'White', | ||
email: '[email protected]', | ||
|
||
roles: [Role.USER], | ||
}); | ||
|
||
it('should redirect with searchParams if otp available', async () => { | ||
const refreshQueryMock = fillCommonQueryWithUser(user); | ||
const requestMock = composeMockedQueryResult(authSinginMutation, { | ||
variables: mockCredentials, | ||
data: { | ||
tokenAuth: { | ||
access: 'access-token', | ||
refresh: 'refresh-token', | ||
otpAuthToken: 'otpAuthToken', | ||
}, | ||
}, | ||
}); | ||
|
||
const { waitForApolloMocks } = render(<Component />, { | ||
apolloMocks: [requestMock, refreshQueryMock], | ||
}); | ||
await waitForApolloMocks(); | ||
|
||
await userEvent.type(await getEmailInput(), mockCredentials.input.email); | ||
await userEvent.type(await getPasswordInput(), mockCredentials.input.password); | ||
|
||
await clickLoginButton(); | ||
|
||
expect(trackEvent).not.toHaveBeenCalled(); | ||
expect(mockNavigate).toHaveBeenCalledWith({ pathname: '/en/auth/validate-otp', search: mockSearch }); | ||
}); | ||
|
||
it('should call login action when submitted', async () => { | ||
const refreshQueryMock = fillCommonQueryWithUser(user); | ||
const requestMock = composeMockedQueryResult(authSinginMutation, { | ||
|
@@ -65,7 +95,6 @@ describe('LoginForm: Component', () => { | |
await waitForApolloMocks(); | ||
|
||
expect(trackEvent).toHaveBeenCalledWith('auth', 'log-in'); | ||
expect(await mockNavigate).toHaveBeenCalledWith(`/en`); | ||
}); | ||
|
||
it('should show error if required value is missing', async () => { | ||
|
@@ -76,7 +105,6 @@ describe('LoginForm: Component', () => { | |
await clickLoginButton(); | ||
|
||
expect(await screen.findByText('Password is required')).toBeInTheDocument(); | ||
expect(await mockNavigate).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should show generic form error if action throws error', async () => { | ||
|
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
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
17 changes: 17 additions & 0 deletions
17
packages/webapp/src/shared/components/routes/authRoute/authRoute.hook.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,17 @@ | ||
import { useGenerateLocalePath, useLocale } from '@sb/webapp-core/hooks'; | ||
import { createSearchParams, useLocation } from 'react-router-dom'; | ||
|
||
export const useGenerateRedirectSearchParams = () => { | ||
const generateLocalePath = useGenerateLocalePath(); | ||
const locale = useLocale(); | ||
const { pathname } = useLocation(); | ||
|
||
const generateRedirectSearchParams = () => { | ||
const re = new RegExp(`/${locale}/?`); | ||
const pathnameWithoutLocale = pathname.replace(re, ''); | ||
const redirect = generateLocalePath(pathnameWithoutLocale); | ||
return pathnameWithoutLocale ? createSearchParams({ redirect }).toString() : undefined; | ||
}; | ||
|
||
return generateRedirectSearchParams; | ||
}; |