deploy linting and first unit test maybe
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 11s
Some checks failed
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Failing after 11s
This commit is contained in:
@@ -48,6 +48,12 @@ jobs:
|
||||
- name: Install Dependencies
|
||||
run: npm ci # 'ci' is faster and safer for CI/CD than 'install'.
|
||||
|
||||
- name: Lint TypeScript Code
|
||||
run: npm run lint # Run the linter to check for code quality issues.
|
||||
|
||||
- name: Run Unit Tests
|
||||
run: npm test # Run the test suite to ensure code correctness.
|
||||
|
||||
# --- Backend Deployment ---
|
||||
- name: Deploy Supabase Edge Functions
|
||||
# Pass the access token as an environment variable directly to this step
|
||||
|
||||
72
components/LoginPage.test.tsx
Normal file
72
components/LoginPage.test.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import React from 'react';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { LoginPage } from './LoginPage';
|
||||
|
||||
describe('LoginPage Component', () => {
|
||||
it('should render the login form with default values', () => {
|
||||
render(<LoginPage onLogin={() => {}} error={null} />);
|
||||
|
||||
// Check for the main heading
|
||||
expect(screen.getByText('Sign in to Flyer Crawler')).not.toBeNull();
|
||||
|
||||
// Check that inputs have their default values
|
||||
expect(screen.getByLabelText('Email address')).toHaveValue('test@test.com');
|
||||
expect(screen.getByLabelText('Password')).toHaveValue('pass123');
|
||||
|
||||
// Check that the button is rendered
|
||||
expect(screen.getByRole('button', { name: 'Sign in' })).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should allow typing in email and password fields', () => {
|
||||
render(<LoginPage onLogin={() => {}} error={null} />);
|
||||
|
||||
const emailInput = screen.getByLabelText('Email address');
|
||||
const passwordInput = screen.getByLabelText('Password');
|
||||
|
||||
fireEvent.change(emailInput, { target: { value: 'new@email.com' } });
|
||||
fireEvent.change(passwordInput, { target: { value: 'newpassword' } });
|
||||
|
||||
expect(emailInput).toHaveValue('new@email.com');
|
||||
expect(passwordInput).toHaveValue('newpassword');
|
||||
});
|
||||
|
||||
it('should call onLogin with the correct credentials on submit', async () => {
|
||||
const handleLogin = vi.fn();
|
||||
render(<LoginPage onLogin={handleLogin} error={null} />);
|
||||
|
||||
const emailInput = screen.getByLabelText('Email address');
|
||||
const passwordInput = screen.getByLabelText('Password');
|
||||
const submitButton = screen.getByRole('button', { name: 'Sign in' });
|
||||
|
||||
// Change credentials
|
||||
fireEvent.change(emailInput, { target: { value: 'user@example.com' } });
|
||||
fireEvent.change(passwordInput, { target: { value: 'password123' } });
|
||||
|
||||
// Submit the form
|
||||
fireEvent.click(submitButton);
|
||||
|
||||
// The button should be disabled and show a loading state
|
||||
expect(submitButton).toBeDisabled();
|
||||
expect(screen.queryByText('Sign in')).toBeNull(); // Text is replaced by spinner
|
||||
|
||||
// Wait for the setTimeout in the component to fire
|
||||
await waitFor(() => {
|
||||
expect(handleLogin).toHaveBeenCalledWith('user@example.com', 'password123');
|
||||
});
|
||||
});
|
||||
|
||||
it('should display an error message when the error prop is provided', () => {
|
||||
const errorMessage = 'Invalid credentials, please try again.';
|
||||
render(<LoginPage onLogin={() => {}} error={errorMessage} />);
|
||||
|
||||
expect(screen.getByText(errorMessage)).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should not display an error message when the error prop is null', () => {
|
||||
render(<LoginPage onLogin={() => {}} error={null} />);
|
||||
|
||||
// The error container shouldn't even be in the DOM
|
||||
expect(screen.queryByText(/invalid/i)).toBeNull();
|
||||
});
|
||||
});
|
||||
2383
package-lock.json
generated
2383
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -6,7 +6,8 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
"preview": "vite preview",
|
||||
"test": "vitest run --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google/genai": "^1.28.0",
|
||||
@@ -18,12 +19,17 @@
|
||||
"supabase": "^2.54.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "^16.0.0",
|
||||
"@testing-library/jest-dom": "^6.4.8",
|
||||
"@types/node": "^22.14.0",
|
||||
"@vitejs/plugin-react": "^5.0.0",
|
||||
"@vitest/coverage-v8": "^2.0.4",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"jsdom": "^27.1.0",
|
||||
"postcss": "^8.4.40",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"typescript": "~5.8.2",
|
||||
"vite": "^6.2.0"
|
||||
"vite": "^6.2.0",
|
||||
"vitest": "^2.0.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
/// <reference types="vitest" />
|
||||
import path from 'path';
|
||||
import { defineConfig } from 'vite';
|
||||
import { defineConfig as defineViteConfig } from 'vite';
|
||||
import { defineConfig as defineVitestConfig } from 'vitest/config';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
export default defineConfig({
|
||||
const vitestConfig = defineVitestConfig({
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
setupFiles: ['./vitest.setup.ts'],
|
||||
},
|
||||
});
|
||||
|
||||
const viteConfig = defineViteConfig({
|
||||
plugins: [react()],
|
||||
server: {
|
||||
port: 3000,
|
||||
host: '0.0.0.0',
|
||||
},
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, '.'),
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export default { ...viteConfig, test: vitestConfig.test };
|
||||
|
||||
5
vitest.setup.ts
Normal file
5
vitest.setup.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// vitest.setup.ts
|
||||
import { expect } from 'vitest';
|
||||
import '@testing-library/jest-dom/vitest';
|
||||
|
||||
// You can add any other global setup here if needed.
|
||||
Reference in New Issue
Block a user