-
Notifications
You must be signed in to change notification settings - Fork 1
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 #219 from uh-dcm/tests
test: add more tests
- Loading branch information
Showing
12 changed files
with
752 additions
and
0 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,91 @@ | ||
import React from 'react'; | ||
import { render, screen, fireEvent, waitFor } from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import { describe, it, expect, vi, beforeEach } from 'vitest'; | ||
import Errors from '@/features/errors/Errors'; | ||
import * as logRecords from '@/features/errors/log-records'; | ||
import { toast } from 'sonner'; | ||
|
||
vi.mock('@/features/errors/log-records', () => ({ | ||
getLogRecords: vi.fn(), | ||
clearLogRecords: vi.fn(), | ||
})); | ||
|
||
vi.mock('sonner', () => ({ | ||
toast: { | ||
success: vi.fn(), | ||
error: vi.fn(), | ||
}, | ||
})); | ||
|
||
vi.mock('@/components/page-layout', () => ({ | ||
PageLayout: ({ children }: { children: React.ReactNode }) => <div>{children}</div>, | ||
})); | ||
|
||
describe('Errors Component', () => { | ||
beforeEach(() => { | ||
vi.clearAllMocks(); | ||
}); | ||
|
||
it('renders error log correctly', async () => { | ||
vi.mocked(logRecords.getLogRecords).mockResolvedValue(['Error 1', 'Error 2']); | ||
render(<Errors />); | ||
|
||
await waitFor(() => { | ||
expect(screen.getByText('Error log')).toBeInTheDocument(); | ||
expect(screen.getByText('Error 1')).toBeInTheDocument(); | ||
expect(screen.getByText('Error 2')).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
it('handles empty error log', async () => { | ||
vi.mocked(logRecords.getLogRecords).mockResolvedValue([]); | ||
render(<Errors />); | ||
|
||
await waitFor(() => { | ||
expect(screen.getByText('No error log.')).toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
it('clears error log', async () => { | ||
vi.mocked(logRecords.getLogRecords).mockResolvedValue(['Error 1']); | ||
vi.mocked(logRecords.clearLogRecords).mockResolvedValue(); | ||
|
||
render(<Errors />); | ||
|
||
await waitFor(() => { | ||
expect(screen.getByText('Error 1')).toBeInTheDocument(); | ||
}); | ||
|
||
fireEvent.click(screen.getByRole('button', { name: 'Clear Log' })); | ||
|
||
const confirmButtons = screen.getAllByRole('button', { name: 'Clear Log' }); | ||
fireEvent.click(confirmButtons[confirmButtons.length - 1]); | ||
|
||
await waitFor(() => { | ||
expect(logRecords.clearLogRecords).toHaveBeenCalled(); | ||
expect(toast.success).toHaveBeenCalledWith('Log cleared successfully'); | ||
}); | ||
}); | ||
|
||
it('handles clear log error', async () => { | ||
vi.mocked(logRecords.getLogRecords).mockResolvedValue(['Error 1']); | ||
vi.mocked(logRecords.clearLogRecords).mockRejectedValue(new Error('Clear failed')); | ||
|
||
render(<Errors />); | ||
|
||
await waitFor(() => { | ||
expect(screen.getByText('Error 1')).toBeInTheDocument(); | ||
}); | ||
|
||
fireEvent.click(screen.getByRole('button', { name: 'Clear Log' })); | ||
|
||
const confirmButtons = screen.getAllByRole('button', { name: 'Clear Log' }); | ||
fireEvent.click(confirmButtons[confirmButtons.length - 1]); | ||
|
||
await waitFor(() => { | ||
expect(logRecords.clearLogRecords).toHaveBeenCalled(); | ||
expect(toast.error).toHaveBeenCalledWith('Failed to clear log'); | ||
}); | ||
}); | ||
}); |
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,89 @@ | ||
import { render, screen, fireEvent, waitFor } from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import { describe, it, expect, vi, beforeEach } from 'vitest'; | ||
import Login from '@/features/user/Login'; | ||
import * as authFunctions from '@/services/authfunctions'; | ||
import { toast } from 'sonner'; | ||
|
||
vi.mock('@/services/authfunctions', () => ({ | ||
loginUser: vi.fn(), | ||
})); | ||
|
||
vi.mock('sonner', () => ({ | ||
toast: { | ||
error: vi.fn(), | ||
success: vi.fn(), | ||
}, | ||
})); | ||
|
||
describe('Login Component', () => { | ||
const mockOnLoginSuccess = vi.fn(); | ||
|
||
beforeEach(() => { | ||
vi.clearAllMocks(); | ||
}); | ||
|
||
it('renders login form correctly', () => { | ||
render(<Login onLoginSuccess={mockOnLoginSuccess} />); | ||
|
||
expect(screen.getByAltText('News Article Collector Logo')).toBeInTheDocument(); | ||
expect(screen.getByText('News Article Collector')).toBeInTheDocument(); | ||
expect(screen.getByPlaceholderText('Enter your password')).toBeInTheDocument(); | ||
expect(screen.getByRole('button', { name: 'Log in' })).toBeInTheDocument(); | ||
}); | ||
|
||
it('handles successful login', async () => { | ||
const mockLoginResponse = { access_token: 'mock-token' }; | ||
vi.mocked(authFunctions.loginUser).mockResolvedValue(mockLoginResponse); | ||
|
||
render(<Login onLoginSuccess={mockOnLoginSuccess} />); | ||
|
||
const passwordInput = screen.getByPlaceholderText('Enter your password'); | ||
const loginButton = screen.getByRole('button', { name: 'Log in' }); | ||
|
||
fireEvent.change(passwordInput, { target: { value: 'testpassword' } }); | ||
fireEvent.click(loginButton); | ||
|
||
await waitFor(() => { | ||
expect(authFunctions.loginUser).toHaveBeenCalledWith('testpassword'); | ||
expect(toast.success).toHaveBeenCalledWith('Login successful!'); | ||
expect(mockOnLoginSuccess).toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
it('handles login failure', async () => { | ||
vi.mocked(authFunctions.loginUser).mockResolvedValue(null); | ||
|
||
render(<Login onLoginSuccess={mockOnLoginSuccess} />); | ||
|
||
const passwordInput = screen.getByPlaceholderText('Enter your password'); | ||
const loginButton = screen.getByRole('button', { name: 'Log in' }); | ||
|
||
fireEvent.change(passwordInput, { target: { value: 'wrongpassword' } }); | ||
fireEvent.click(loginButton); | ||
|
||
await waitFor(() => { | ||
expect(authFunctions.loginUser).toHaveBeenCalledWith('wrongpassword'); | ||
expect(toast.error).toHaveBeenCalledWith('Failed to login'); | ||
expect(mockOnLoginSuccess).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
it('handles login error', async () => { | ||
vi.mocked(authFunctions.loginUser).mockRejectedValue(new Error('Network error')); | ||
|
||
render(<Login onLoginSuccess={mockOnLoginSuccess} />); | ||
|
||
const passwordInput = screen.getByPlaceholderText('Enter your password'); | ||
const loginButton = screen.getByRole('button', { name: 'Log in' }); | ||
|
||
fireEvent.change(passwordInput, { target: { value: 'testpassword' } }); | ||
fireEvent.click(loginButton); | ||
|
||
await waitFor(() => { | ||
expect(authFunctions.loginUser).toHaveBeenCalledWith('testpassword'); | ||
expect(toast.error).toHaveBeenCalledWith('Login failed: Network error'); | ||
expect(mockOnLoginSuccess).not.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,90 @@ | ||
import { render, screen, fireEvent, waitFor } from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import { describe, it, expect, vi, beforeEach } from 'vitest'; | ||
import { BrowserRouter } from 'react-router-dom'; | ||
import Register from '@/features/user/Register'; | ||
import * as authFunctions from '@/services/authfunctions'; | ||
import { toast } from 'sonner'; | ||
|
||
vi.mock('@/services/authfunctions', () => ({ | ||
registerUser: vi.fn(), | ||
})); | ||
|
||
vi.mock('sonner', () => ({ | ||
toast: { | ||
error: vi.fn(), | ||
success: vi.fn(), | ||
warning: vi.fn(), | ||
}, | ||
})); | ||
|
||
describe('Register Component', () => { | ||
const mockOnRegistrationSuccess = vi.fn(); | ||
|
||
beforeEach(() => { | ||
vi.clearAllMocks(); | ||
}); | ||
|
||
const renderRegister = () => { | ||
return render( | ||
<BrowserRouter> | ||
<Register onRegistrationSuccess={mockOnRegistrationSuccess} /> | ||
</BrowserRouter> | ||
); | ||
}; | ||
|
||
it('renders register form correctly', () => { | ||
renderRegister(); | ||
expect(screen.getByAltText('News Article Collector Logo')).toBeInTheDocument(); | ||
expect(screen.getByText('News Article Collector')).toBeInTheDocument(); | ||
expect(screen.getByPlaceholderText('Enter your email')).toBeInTheDocument(); | ||
expect(screen.getByPlaceholderText('Enter your password')).toBeInTheDocument(); | ||
expect(screen.getByRole('button', { name: 'Register' })).toBeInTheDocument(); | ||
}); | ||
|
||
it('handles successful registration', async () => { | ||
vi.mocked(authFunctions.registerUser).mockResolvedValue({ success: true, data: {}, emailSent: true }); | ||
renderRegister(); | ||
|
||
fireEvent.change(screen.getByPlaceholderText('Enter your email'), { target: { value: 'test@example.com' } }); | ||
fireEvent.change(screen.getByPlaceholderText('Enter your password'), { target: { value: 'password123' } }); | ||
fireEvent.click(screen.getByRole('button', { name: 'Register' })); | ||
|
||
await waitFor(() => { | ||
expect(authFunctions.registerUser).toHaveBeenCalledWith('test@example.com', 'password123', false); | ||
expect(toast.success).toHaveBeenCalledWith('Registration successful!'); | ||
expect(mockOnRegistrationSuccess).toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
it('handles registration failure', async () => { | ||
vi.mocked(authFunctions.registerUser).mockResolvedValue({ success: false, error: 'Registration failed' }); | ||
renderRegister(); | ||
|
||
fireEvent.change(screen.getByPlaceholderText('Enter your email'), { target: { value: 'test@example.com' } }); | ||
fireEvent.change(screen.getByPlaceholderText('Enter your password'), { target: { value: 'password123' } }); | ||
fireEvent.click(screen.getByRole('button', { name: 'Register' })); | ||
|
||
await waitFor(() => { | ||
expect(authFunctions.registerUser).toHaveBeenCalledWith('test@example.com', 'password123', false); | ||
expect(toast.error).toHaveBeenCalledWith('Failed to register: Registration failed'); | ||
expect(mockOnRegistrationSuccess).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
it('handles registration with email sending issue', async () => { | ||
vi.mocked(authFunctions.registerUser).mockResolvedValue({ success: true, data: {}, emailSent: false }); | ||
renderRegister(); | ||
|
||
fireEvent.change(screen.getByPlaceholderText('Enter your email'), { target: { value: 'test@example.com' } }); | ||
fireEvent.change(screen.getByPlaceholderText('Enter your password'), { target: { value: 'password123' } }); | ||
fireEvent.click(screen.getByRole('button', { name: 'Register' })); | ||
|
||
await waitFor(() => { | ||
expect(authFunctions.registerUser).toHaveBeenCalledWith('test@example.com', 'password123', false); | ||
expect(toast.success).toHaveBeenCalledWith('Registration successful!'); | ||
expect(toast.warning).toHaveBeenCalledWith('Registration successful, but there was an issue sending the confirmation email. You can still use the app.', { duration: 10000 }); | ||
expect(mockOnRegistrationSuccess).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,74 @@ | ||
import { render, screen, waitFor } from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import { describe, it, expect, vi, beforeEach } from 'vitest'; | ||
import { MemoryRouter, Route, Routes } from 'react-router-dom'; | ||
import ReregisterValidator from '@/features/user/ReregisterValidator'; | ||
import * as authFunctions from '@/services/authfunctions'; | ||
import { toast } from 'sonner'; | ||
|
||
vi.mock('@/services/authfunctions', () => ({ | ||
validateReregisterToken: vi.fn(), | ||
})); | ||
|
||
vi.mock('sonner', () => ({ | ||
toast: { | ||
error: vi.fn(), | ||
custom: vi.fn(), | ||
}, | ||
})); | ||
|
||
describe('ReregisterValidator Component', () => { | ||
const mockOnValidationComplete = vi.fn(); | ||
|
||
beforeEach(() => { | ||
vi.clearAllMocks(); | ||
}); | ||
|
||
const renderReregisterValidator = (token: string) => { | ||
return render( | ||
<MemoryRouter initialEntries={[`/reregister/${token}`]}> | ||
<Routes> | ||
<Route path="/reregister/:token" element={<ReregisterValidator onValidationComplete={mockOnValidationComplete} />} /> | ||
</Routes> | ||
</MemoryRouter> | ||
); | ||
}; | ||
|
||
it('displays loading message while validating', () => { | ||
renderReregisterValidator('valid-token'); | ||
expect(screen.getByText('Validating reregistration token...')).toBeInTheDocument(); | ||
}); | ||
|
||
it('handles valid token', async () => { | ||
vi.mocked(authFunctions.validateReregisterToken).mockResolvedValue({ valid: true }); | ||
renderReregisterValidator('valid-token'); | ||
|
||
await waitFor(() => { | ||
expect(authFunctions.validateReregisterToken).toHaveBeenCalledWith('valid-token'); | ||
expect(toast.custom).toHaveBeenCalled(); | ||
expect(mockOnValidationComplete).toHaveBeenCalledWith(true); | ||
}); | ||
}); | ||
|
||
it('handles invalid token', async () => { | ||
vi.mocked(authFunctions.validateReregisterToken).mockResolvedValue({ valid: false }); | ||
renderReregisterValidator('invalid-token'); | ||
|
||
await waitFor(() => { | ||
expect(authFunctions.validateReregisterToken).toHaveBeenCalledWith('invalid-token'); | ||
expect(toast.error).toHaveBeenCalledWith('Invalid or expired token'); | ||
expect(mockOnValidationComplete).toHaveBeenCalledWith(false); | ||
}); | ||
}); | ||
|
||
it('handles validation error', async () => { | ||
vi.mocked(authFunctions.validateReregisterToken).mockRejectedValue(new Error('Validation failed')); | ||
renderReregisterValidator('error-token'); | ||
|
||
await waitFor(() => { | ||
expect(authFunctions.validateReregisterToken).toHaveBeenCalledWith('error-token'); | ||
expect(toast.error).toHaveBeenCalledWith('An error occurred when validating the token. Did it expire already?'); | ||
expect(mockOnValidationComplete).toHaveBeenCalledWith(false); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.