review(front): refacto url-manager (#8861)
Replace https://github.com/twentyhq/twenty/pull/8855
This commit is contained in:
@ -30,8 +30,8 @@ import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { useReadCaptchaToken } from '@/captcha/hooks/useReadCaptchaToken';
|
||||
import { signInUpModeState } from '@/auth/states/signInUpModeState';
|
||||
import { useRequestFreshCaptchaToken } from '@/captcha/hooks/useRequestFreshCaptchaToken';
|
||||
import { useUrlManager } from '@/url-manager/hooks/useUrlManager';
|
||||
import { SignInUpMode } from '@/auth/types/signInUpMode';
|
||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||
|
||||
const StyledContentContainer = styled(motion.div)`
|
||||
margin-bottom: ${({ theme }) => theme.spacing(8)};
|
||||
@ -53,8 +53,7 @@ export const SignInUpGlobalScopeForm = () => {
|
||||
const { signInWithMicrosoft } = useSignInWithMicrosoft();
|
||||
const { checkUserExists } = useAuth();
|
||||
const { readCaptchaToken } = useReadCaptchaToken();
|
||||
const { redirectToWorkspace } = useUrlManager();
|
||||
|
||||
const { redirectToWorkspaceDomain } = useRedirectToWorkspaceDomain();
|
||||
const setSignInUpStep = useSetRecoilState(signInUpStepState);
|
||||
const [signInUpMode, setSignInUpMode] = useRecoilState(signInUpModeState);
|
||||
|
||||
@ -97,7 +96,7 @@ export const SignInUpGlobalScopeForm = () => {
|
||||
isDefined(data?.checkUserExists.availableWorkspaces) &&
|
||||
data.checkUserExists.availableWorkspaces.length >= 1
|
||||
) {
|
||||
return redirectToWorkspace(
|
||||
return redirectToWorkspaceDomain(
|
||||
data?.checkUserExists.availableWorkspaces[0].subdomain,
|
||||
pathname,
|
||||
{
|
||||
|
||||
@ -0,0 +1,72 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { useEmailPasswordResetLinkMutation } from '~/generated/graphql';
|
||||
import { useHandleResetPassword } from '@/auth/sign-in-up/hooks/useHandleResetPassword';
|
||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||
|
||||
// Mocks
|
||||
jest.mock('@/ui/feedback/snack-bar-manager/hooks/useSnackBar');
|
||||
jest.mock('~/generated/graphql');
|
||||
|
||||
describe('useHandleResetPassword', () => {
|
||||
const enqueueSnackBarMock = jest.fn();
|
||||
const emailPasswordResetLinkMock = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
(useSnackBar as jest.Mock).mockReturnValue({
|
||||
enqueueSnackBar: enqueueSnackBarMock,
|
||||
});
|
||||
(useEmailPasswordResetLinkMutation as jest.Mock).mockReturnValue([
|
||||
emailPasswordResetLinkMock,
|
||||
]);
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should show error message if email is invalid', async () => {
|
||||
const { result } = renderHook(() => useHandleResetPassword());
|
||||
await act(() => result.current.handleResetPassword('')());
|
||||
|
||||
expect(enqueueSnackBarMock).toHaveBeenCalledWith('Invalid email', {
|
||||
variant: SnackBarVariant.Error,
|
||||
});
|
||||
});
|
||||
|
||||
it('should show success message if password reset link is sent', async () => {
|
||||
emailPasswordResetLinkMock.mockResolvedValue({
|
||||
data: { emailPasswordResetLink: { success: true } },
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useHandleResetPassword());
|
||||
await act(() => result.current.handleResetPassword('test@example.com')());
|
||||
|
||||
expect(enqueueSnackBarMock).toHaveBeenCalledWith(
|
||||
'Password reset link has been sent to the email',
|
||||
{ variant: SnackBarVariant.Success },
|
||||
);
|
||||
});
|
||||
|
||||
it('should show error message if sending reset link fails', async () => {
|
||||
emailPasswordResetLinkMock.mockResolvedValue({
|
||||
data: { emailPasswordResetLink: { success: false } },
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useHandleResetPassword());
|
||||
await act(() => result.current.handleResetPassword('test@example.com')());
|
||||
|
||||
expect(enqueueSnackBarMock).toHaveBeenCalledWith('There was some issue', {
|
||||
variant: SnackBarVariant.Error,
|
||||
});
|
||||
});
|
||||
|
||||
it('should show error message in case of request error', async () => {
|
||||
const errorMessage = 'Network Error';
|
||||
emailPasswordResetLinkMock.mockRejectedValue(new Error(errorMessage));
|
||||
|
||||
const { result } = renderHook(() => useHandleResetPassword());
|
||||
await act(() => result.current.handleResetPassword('test@example.com')());
|
||||
|
||||
expect(enqueueSnackBarMock).toHaveBeenCalledWith(errorMessage, {
|
||||
variant: SnackBarVariant.Error,
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,73 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { useGetAuthorizationUrlMutation } from '~/generated/graphql';
|
||||
import { useSSO } from '@/auth/sign-in-up/hooks/useSSO';
|
||||
|
||||
// Mock dependencies
|
||||
jest.mock('@/ui/feedback/snack-bar-manager/hooks/useSnackBar');
|
||||
jest.mock('~/generated/graphql');
|
||||
|
||||
// Helpers
|
||||
const mockEnqueueSnackBar = jest.fn();
|
||||
const mockGetAuthorizationUrlMutation = jest.fn();
|
||||
|
||||
// Mock return values
|
||||
(useSnackBar as jest.Mock).mockReturnValue({
|
||||
enqueueSnackBar: mockEnqueueSnackBar,
|
||||
});
|
||||
(useGetAuthorizationUrlMutation as jest.Mock).mockReturnValue([
|
||||
mockGetAuthorizationUrlMutation,
|
||||
]);
|
||||
|
||||
describe('useSSO', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should call getAuthorizationUrlForSSO with correct parameters', async () => {
|
||||
const { result } = renderHook(() => useSSO());
|
||||
const identityProviderId = 'test-id';
|
||||
|
||||
mockGetAuthorizationUrlMutation.mockResolvedValueOnce({
|
||||
data: {
|
||||
getAuthorizationUrl: {
|
||||
authorizationURL: 'http://example.com',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await result.current.getAuthorizationUrlForSSO({ identityProviderId });
|
||||
|
||||
expect(mockGetAuthorizationUrlMutation).toHaveBeenCalledWith({
|
||||
variables: { input: { identityProviderId } },
|
||||
});
|
||||
});
|
||||
|
||||
it('should enqueue error snackbar when URL retrieval fails', async () => {
|
||||
const { result } = renderHook(() => useSSO());
|
||||
const identityProviderId = 'test-id';
|
||||
|
||||
mockGetAuthorizationUrlMutation.mockResolvedValueOnce({
|
||||
errors: [{ message: 'Error message' }],
|
||||
});
|
||||
|
||||
await result.current.redirectToSSOLoginPage(identityProviderId);
|
||||
|
||||
expect(mockEnqueueSnackBar).toHaveBeenCalledWith('Error message', {
|
||||
variant: 'error',
|
||||
});
|
||||
});
|
||||
|
||||
it('should enqueue default error snackbar when error message is not provided', async () => {
|
||||
const { result } = renderHook(() => useSSO());
|
||||
const identityProviderId = 'test-id';
|
||||
|
||||
mockGetAuthorizationUrlMutation.mockResolvedValueOnce({ errors: [{}] });
|
||||
|
||||
await result.current.redirectToSSOLoginPage(identityProviderId);
|
||||
|
||||
expect(mockEnqueueSnackBar).toHaveBeenCalledWith('Unknown error', {
|
||||
variant: 'error',
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,55 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { useSignInWithGoogle } from '@/auth/sign-in-up/hooks/useSignInWithGoogle';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
useParams: jest.fn(),
|
||||
useSearchParams: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@/auth/hooks/useAuth', () => ({
|
||||
useAuth: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('useSignInWithGoogle', () => {
|
||||
it('should call signInWithGoogle with correct params', () => {
|
||||
const signInWithGoogleMock = jest.fn();
|
||||
const mockUseParams = { workspaceInviteHash: 'testHash' };
|
||||
const mockSearchParams = new URLSearchParams('inviteToken=testToken');
|
||||
|
||||
(useParams as jest.Mock).mockReturnValue(mockUseParams);
|
||||
(useSearchParams as jest.Mock).mockReturnValue([mockSearchParams]);
|
||||
(useAuth as jest.Mock).mockReturnValue({
|
||||
signInWithGoogle: signInWithGoogleMock,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSignInWithGoogle());
|
||||
result.current.signInWithGoogle();
|
||||
|
||||
expect(signInWithGoogleMock).toHaveBeenCalledWith({
|
||||
workspaceInviteHash: 'testHash',
|
||||
workspacePersonalInviteToken: 'testToken',
|
||||
});
|
||||
});
|
||||
|
||||
it('should call signInWithGoogle with undefined invite token if not present', () => {
|
||||
const signInWithGoogleMock = jest.fn();
|
||||
const mockUseParams = { workspaceInviteHash: 'testHash' };
|
||||
const mockSearchParams = new URLSearchParams();
|
||||
|
||||
(useParams as jest.Mock).mockReturnValue(mockUseParams);
|
||||
(useSearchParams as jest.Mock).mockReturnValue([mockSearchParams]);
|
||||
(useAuth as jest.Mock).mockReturnValue({
|
||||
signInWithGoogle: signInWithGoogleMock,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSignInWithGoogle());
|
||||
result.current.signInWithGoogle();
|
||||
|
||||
expect(signInWithGoogleMock).toHaveBeenCalledWith({
|
||||
workspaceInviteHash: 'testHash',
|
||||
workspacePersonalInviteToken: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,60 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { useSignInWithMicrosoft } from '@/auth/sign-in-up/hooks/useSignInWithMicrosoft';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
useParams: jest.fn(),
|
||||
useSearchParams: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@/auth/hooks/useAuth', () => ({
|
||||
useAuth: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('useSignInWithMicrosoft', () => {
|
||||
it('should call signInWithMicrosoft with the correct parameters', () => {
|
||||
const workspaceInviteHashMock = 'testHash';
|
||||
const inviteTokenMock = 'testToken';
|
||||
const signInWithMicrosoftMock = jest.fn();
|
||||
|
||||
(useParams as jest.Mock).mockReturnValue({
|
||||
workspaceInviteHash: workspaceInviteHashMock,
|
||||
});
|
||||
(useSearchParams as jest.Mock).mockReturnValue([
|
||||
new URLSearchParams(`inviteToken=${inviteTokenMock}`),
|
||||
]);
|
||||
(useAuth as jest.Mock).mockReturnValue({
|
||||
signInWithMicrosoft: signInWithMicrosoftMock,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSignInWithMicrosoft());
|
||||
result.current.signInWithMicrosoft();
|
||||
|
||||
expect(signInWithMicrosoftMock).toHaveBeenCalledWith({
|
||||
workspaceInviteHash: workspaceInviteHashMock,
|
||||
workspacePersonalInviteToken: inviteTokenMock,
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle missing inviteToken gracefully', () => {
|
||||
const workspaceInviteHashMock = 'testHash';
|
||||
const signInWithMicrosoftMock = jest.fn();
|
||||
|
||||
(useParams as jest.Mock).mockReturnValue({
|
||||
workspaceInviteHash: workspaceInviteHashMock,
|
||||
});
|
||||
(useSearchParams as jest.Mock).mockReturnValue([new URLSearchParams('')]);
|
||||
(useAuth as jest.Mock).mockReturnValue({
|
||||
signInWithMicrosoft: signInWithMicrosoftMock,
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useSignInWithMicrosoft());
|
||||
result.current.signInWithMicrosoft();
|
||||
|
||||
expect(signInWithMicrosoftMock).toHaveBeenCalledWith({
|
||||
workspaceInviteHash: workspaceInviteHashMock,
|
||||
workspacePersonalInviteToken: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user