| import reactRouter from 'react-router-dom'; |
| import userEvent from '@testing-library/user-event'; |
| import { getByTestId, render, waitFor } from 'test/layout-test-utils'; |
| import type { TStartupConfig } from 'librechat-data-provider'; |
| import * as endpointQueries from '~/data-provider/Endpoints/queries'; |
| import * as miscDataProvider from '~/data-provider/Misc/queries'; |
| import * as authMutations from '~/data-provider/Auth/mutations'; |
| import * as authQueries from '~/data-provider/Auth/queries'; |
| import AuthLayout from '~/components/Auth/AuthLayout'; |
| import Login from '~/components/Auth/Login'; |
|
|
| jest.mock('librechat-data-provider/react-query'); |
|
|
| const mockStartupConfig = { |
| isFetching: false, |
| isLoading: false, |
| isError: false, |
| data: { |
| socialLogins: ['google', 'facebook', 'openid', 'github', 'discord', 'saml'], |
| discordLoginEnabled: true, |
| facebookLoginEnabled: true, |
| githubLoginEnabled: true, |
| googleLoginEnabled: true, |
| openidLoginEnabled: true, |
| openidLabel: 'Test OpenID', |
| openidImageUrl: 'http://test-server.com', |
| samlLoginEnabled: true, |
| samlLabel: 'Test SAML', |
| samlImageUrl: 'http://test-server.com', |
| ldap: { |
| enabled: false, |
| }, |
| registrationEnabled: true, |
| emailLoginEnabled: true, |
| socialLoginEnabled: true, |
| serverDomain: 'mock-server', |
| }, |
| }; |
|
|
| const setup = ({ |
| useGetUserQueryReturnValue = { |
| isLoading: false, |
| isError: false, |
| data: {}, |
| }, |
| useLoginUserReturnValue = { |
| isLoading: false, |
| isError: false, |
| mutate: jest.fn(), |
| data: {}, |
| isSuccess: false, |
| }, |
| useRefreshTokenMutationReturnValue = { |
| isLoading: false, |
| isError: false, |
| mutate: jest.fn(), |
| data: { |
| token: 'mock-token', |
| user: {}, |
| }, |
| }, |
| useGetStartupConfigReturnValue = mockStartupConfig, |
| useGetBannerQueryReturnValue = { |
| isLoading: false, |
| isError: false, |
| data: {}, |
| }, |
| } = {}) => { |
| const mockUseLoginUser = jest |
| .spyOn(authMutations, 'useLoginUserMutation') |
| |
| .mockReturnValue(useLoginUserReturnValue); |
| const mockUseGetUserQuery = jest |
| .spyOn(authQueries, 'useGetUserQuery') |
| |
| .mockReturnValue(useGetUserQueryReturnValue); |
| const mockUseGetStartupConfig = jest |
| .spyOn(endpointQueries, 'useGetStartupConfig') |
| |
| .mockReturnValue(useGetStartupConfigReturnValue); |
| const mockUseRefreshTokenMutation = jest |
| .spyOn(authMutations, 'useRefreshTokenMutation') |
| |
| .mockReturnValue(useRefreshTokenMutationReturnValue); |
| const mockUseGetBannerQuery = jest |
| .spyOn(miscDataProvider, 'useGetBannerQuery') |
| |
| .mockReturnValue(useGetBannerQueryReturnValue); |
| const mockUseOutletContext = jest.spyOn(reactRouter, 'useOutletContext').mockReturnValue({ |
| startupConfig: useGetStartupConfigReturnValue.data, |
| }); |
| const renderResult = render( |
| <AuthLayout |
| startupConfig={useGetStartupConfigReturnValue.data as TStartupConfig} |
| isFetching={useGetStartupConfigReturnValue.isFetching} |
| error={null} |
| startupConfigError={null} |
| header={'Welcome back'} |
| pathname="login" |
| > |
| <Login /> |
| </AuthLayout>, |
| ); |
| return { |
| ...renderResult, |
| mockUseLoginUser, |
| mockUseGetUserQuery, |
| mockUseOutletContext, |
| mockUseGetStartupConfig, |
| mockUseRefreshTokenMutation, |
| mockUseGetBannerQuery, |
| }; |
| }; |
|
|
| jest.mock('react-router-dom', () => ({ |
| ...jest.requireActual('react-router-dom'), |
| useOutletContext: () => ({ |
| startupConfig: mockStartupConfig, |
| }), |
| })); |
|
|
| test('renders login form', () => { |
| const { getByLabelText, getByRole } = setup(); |
| expect(getByLabelText(/email/i)).toBeInTheDocument(); |
| expect(getByLabelText(/password/i)).toBeInTheDocument(); |
| expect(getByTestId(document.body, 'login-button')).toBeInTheDocument(); |
| expect(getByRole('link', { name: /Sign up/i })).toBeInTheDocument(); |
| expect(getByRole('link', { name: /Sign up/i })).toHaveAttribute('href', '/register'); |
| expect(getByRole('link', { name: /Continue with Google/i })).toBeInTheDocument(); |
| expect(getByRole('link', { name: /Continue with Google/i })).toHaveAttribute( |
| 'href', |
| 'mock-server/oauth/google', |
| ); |
| expect(getByRole('link', { name: /Continue with Facebook/i })).toBeInTheDocument(); |
| expect(getByRole('link', { name: /Continue with Facebook/i })).toHaveAttribute( |
| 'href', |
| 'mock-server/oauth/facebook', |
| ); |
| expect(getByRole('link', { name: /Continue with Github/i })).toBeInTheDocument(); |
| expect(getByRole('link', { name: /Continue with Github/i })).toHaveAttribute( |
| 'href', |
| 'mock-server/oauth/github', |
| ); |
| expect(getByRole('link', { name: /Continue with Discord/i })).toBeInTheDocument(); |
| expect(getByRole('link', { name: /Continue with Discord/i })).toHaveAttribute( |
| 'href', |
| 'mock-server/oauth/discord', |
| ); |
| expect(getByRole('link', { name: /Test SAML/i })).toBeInTheDocument(); |
| expect(getByRole('link', { name: /Test SAML/i })).toHaveAttribute( |
| 'href', |
| 'mock-server/oauth/saml', |
| ); |
| }); |
|
|
| test('calls loginUser.mutate on login', async () => { |
| const mutate = jest.fn(); |
| const { getByLabelText } = setup({ |
| |
| useLoginUserReturnValue: { |
| isLoading: false, |
| mutate: mutate, |
| isError: false, |
| }, |
| }); |
|
|
| const emailInput = getByLabelText(/email/i); |
| const passwordInput = getByLabelText(/password/i); |
| const submitButton = getByTestId(document.body, 'login-button'); |
|
|
| await userEvent.type(emailInput, 'test@test.com'); |
| await userEvent.type(passwordInput, 'password'); |
| await userEvent.click(submitButton); |
|
|
| waitFor(() => expect(mutate).toHaveBeenCalled()); |
| }); |
|
|
| test('Navigates to / on successful login', async () => { |
| const { getByLabelText, history } = setup({ |
| |
| useLoginUserReturnValue: { |
| isLoading: false, |
| mutate: jest.fn(), |
| isError: false, |
| isSuccess: true, |
| }, |
| useGetStartupConfigReturnValue: { |
| ...mockStartupConfig, |
| data: { |
| ...mockStartupConfig.data, |
| emailLoginEnabled: true, |
| registrationEnabled: true, |
| }, |
| }, |
| }); |
|
|
| const emailInput = getByLabelText(/email/i); |
| const passwordInput = getByLabelText(/password/i); |
| const submitButton = getByTestId(document.body, 'login-button'); |
|
|
| await userEvent.type(emailInput, 'test@test.com'); |
| await userEvent.type(passwordInput, 'password'); |
| await userEvent.click(submitButton); |
|
|
| waitFor(() => expect(history.location.pathname).toBe('/')); |
| }); |
|
|