feat: Implement User Authentication and Fix Frontend Startup
- Implemented Issue #9: User Authentication & Authorization - Added User model fields (FailedLoginAttempts, LockedUntil, LastLogin) - Created AuthService with JWT support, bcrypt hashing, and account lockout - Added AuthMiddleware and AuthHandler - Registered auth routes in backend - Created AuthContext and RequireAuth component in frontend - Implemented Login page and integrated with backend - Fixed 'Blank Page' issue in local Docker environment - Added QueryClientProvider to main.tsx - Installed missing lucide-react dependency - Fixed TypeScript linting errors in SetupGuard.tsx - Updated docker-entrypoint.sh to use 127.0.0.1 for reliable Caddy checks - Verified with local Docker build
This commit is contained in:
61
frontend/src/pages/__tests__/Setup.test.tsx
Normal file
61
frontend/src/pages/__tests__/Setup.test.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import Setup from '../Setup';
|
||||
import * as setupApi from '../../api/setup';
|
||||
|
||||
// Mock the API module
|
||||
vi.mock('../../api/setup', () => ({
|
||||
getSetupStatus: vi.fn(),
|
||||
performSetup: vi.fn(),
|
||||
}));
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const renderWithProviders = (ui: React.ReactNode) => {
|
||||
return render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<MemoryRouter>
|
||||
{ui}
|
||||
</MemoryRouter>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
};
|
||||
|
||||
describe('Setup Page', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
queryClient.clear();
|
||||
});
|
||||
|
||||
it('renders setup form when setup is required', async () => {
|
||||
vi.mocked(setupApi.getSetupStatus).mockResolvedValue({ setupRequired: true });
|
||||
|
||||
renderWithProviders(<Setup />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Welcome to CPM+')).toBeTruthy();
|
||||
});
|
||||
|
||||
expect(screen.getByLabelText('Name')).toBeTruthy();
|
||||
expect(screen.getByLabelText('Email Address')).toBeTruthy();
|
||||
expect(screen.getByLabelText('Password')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('does not render form when setup is not required', async () => {
|
||||
vi.mocked(setupApi.getSetupStatus).mockResolvedValue({ setupRequired: false });
|
||||
|
||||
renderWithProviders(<Setup />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('Welcome to CPM+')).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user