Remove deprecated middleware and update component tests for branding and auth enhancements

- Deleted `middleware.disabled.ts` as it is no longer needed.
- Refactored `HeroSection` and `HomePage` tests to align with updated branding and messaging.
- Modified `DemoCredentialsModal` to support auto-filled demo credentials in login links.
- Mocked `ThemeToggle`, `LocaleSwitcher`, and `DemoCredentialsModal` in relevant tests.
- Updated admin tests to use `QueryClientProvider` and refactored API mocks for `AdminPage`.
- Replaced test assertions for stats section and badges with new branding content.
This commit is contained in:
Felipe Cardoso
2025-11-24 15:04:49 +01:00
parent acfe59c8b3
commit 13abd159fa
8 changed files with 131 additions and 112 deletions

View File

@@ -32,11 +32,15 @@ jest.mock('@/lib/api/hooks/useAuth', () => ({
useLogin: () => mockUseLogin(),
}));
// Mock router
// Mock router
jest.mock('next/navigation', () => ({
useRouter: () => ({
push: jest.fn(),
}),
useSearchParams: () => ({
get: jest.fn(),
}),
}));
// Mock auth store

View File

@@ -156,10 +156,16 @@ describe('DemoCredentialsModal', () => {
render(<DemoCredentialsModal open={true} onClose={mockOnClose} />);
const loginAsUserLink = screen.getByRole('link', { name: /login as user/i });
expect(loginAsUserLink).toHaveAttribute('href', '/login');
expect(loginAsUserLink).toHaveAttribute(
'href',
'/login?email=demo@example.com&password=Demo123!'
);
const loginAsAdminLink = screen.getByRole('link', { name: /login as admin/i });
expect(loginAsAdminLink).toHaveAttribute('href', '/login');
expect(loginAsAdminLink).toHaveAttribute(
'href',
'/login?email=admin@example.com&password=Admin123!'
);
});
it('calls onClose when login link is clicked', () => {

View File

@@ -27,6 +27,24 @@ jest.mock('@/components/home/DemoCredentialsModal', () => ({
) : null,
}));
// Mock auth hooks
jest.mock('@/lib/api/hooks/useAuth', () => ({
useIsAuthenticated: jest.fn(() => false),
useLogout: jest.fn(() => ({
mutate: jest.fn(),
})),
}));
// Mock Theme components
jest.mock('@/components/theme', () => ({
ThemeToggle: () => <div data-testid="theme-toggle">Theme Toggle</div>,
}));
// Mock LocaleSwitcher
jest.mock('@/components/i18n', () => ({
LocaleSwitcher: () => <div data-testid="locale-switcher">Locale Switcher</div>,
}));
describe('Header', () => {
it('renders logo', () => {
render(
@@ -38,7 +56,6 @@ describe('Header', () => {
);
expect(screen.getByText('PragmaStack')).toBeInTheDocument();
expect(screen.getByText('Template')).toBeInTheDocument();
});
it('logo links to homepage', () => {
@@ -50,7 +67,7 @@ describe('Header', () => {
/>
);
const logoLink = screen.getByRole('link', { name: /pragmastack template/i });
const logoLink = screen.getByRole('link', { name: /PragmaStack/i });
expect(logoLink).toHaveAttribute('href', '/');
});

View File

@@ -47,8 +47,8 @@ describe('HeroSection', () => {
);
expect(screen.getByText('MIT Licensed')).toBeInTheDocument();
expect(screen.getAllByText('97% Test Coverage')[0]).toBeInTheDocument();
expect(screen.getByText('Production Ready')).toBeInTheDocument();
expect(screen.getByText('Comprehensive Tests')).toBeInTheDocument();
expect(screen.getByText('Pragmatic by Design')).toBeInTheDocument();
});
it('renders main headline', () => {
@@ -60,8 +60,8 @@ describe('HeroSection', () => {
/>
);
expect(screen.getAllByText(/Everything You Need to Build/i)[0]).toBeInTheDocument();
expect(screen.getAllByText(/Modern Web Applications/i)[0]).toBeInTheDocument();
expect(screen.getByText(/The Pragmatic/i)).toBeInTheDocument();
expect(screen.getByText(/Full-Stack Template/i)).toBeInTheDocument();
});
it('renders subheadline with key messaging', () => {
@@ -73,7 +73,7 @@ describe('HeroSection', () => {
/>
);
expect(screen.getByText(/Production-ready FastAPI \+ Next.js template/i)).toBeInTheDocument();
expect(screen.getByText(/Opinionated, secure, and production-ready/i)).toBeInTheDocument();
expect(screen.getByText(/Start building features on day one/i)).toBeInTheDocument();
});
@@ -118,26 +118,6 @@ describe('HeroSection', () => {
expect(componentsLink).toHaveAttribute('href', '/dev');
});
it('displays test coverage stats', () => {
render(
<HeroSection
onOpenDemoModal={function (): void {
throw new Error('Function not implemented.');
}}
/>
);
const coverageTexts = screen.getAllByText('97%');
expect(coverageTexts.length).toBeGreaterThan(0);
const testCountTexts = screen.getAllByText('743');
expect(testCountTexts.length).toBeGreaterThan(0);
expect(screen.getAllByText(/Passing Tests/i)[0]).toBeInTheDocument();
expect(screen.getByText('0')).toBeInTheDocument();
expect(screen.getByText(/Flaky Tests/i)).toBeInTheDocument();
});
it('calls onOpenDemoModal when Try Live Demo button is clicked', () => {
const mockOnOpenDemoModal = jest.fn();
render(<HeroSection onOpenDemoModal={mockOnOpenDemoModal} />);

View File

@@ -35,21 +35,25 @@ describe('StatsSection', () => {
it('renders all stat cards', () => {
render(<StatsSection />);
expect(screen.getByText('Test Coverage')).toBeInTheDocument();
expect(screen.getByText('Passing Tests')).toBeInTheDocument();
expect(screen.getByText('Flaky Tests')).toBeInTheDocument();
expect(screen.getByText('API Endpoints')).toBeInTheDocument();
expect(screen.getByText('Open Source')).toBeInTheDocument();
expect(screen.getByText('Type Safe')).toBeInTheDocument();
expect(screen.getByText('Doc Guides')).toBeInTheDocument();
expect(screen.getByText('Magic')).toBeInTheDocument();
});
it('displays stat descriptions', () => {
render(<StatsSection />);
expect(
screen.getByText(/Comprehensive testing across backend and frontend/i)
screen.getByText(/MIT Licensed. No hidden costs or vendor lock-in/i)
).toBeInTheDocument();
expect(
screen.getByText(/End-to-end type safety with TypeScript & Pydantic/i)
).toBeInTheDocument();
expect(screen.getByText(/Comprehensive documentation for every feature/i)).toBeInTheDocument();
expect(
screen.getByText(/Explicit is better than implicit. No hidden logic/i)
).toBeInTheDocument();
expect(screen.getByText(/Backend, frontend unit, and E2E tests/i)).toBeInTheDocument();
expect(screen.getByText(/Production-stable test suite/i)).toBeInTheDocument();
expect(screen.getByText(/Fully documented with OpenAPI/i)).toBeInTheDocument();
});
it('renders animated counters with correct suffixes', () => {
@@ -69,7 +73,7 @@ describe('StatsSection', () => {
// After animation, we should see the final values
// The component should eventually show the stat values
const statsSection = screen.getByText('Test Coverage').parentElement;
const statsSection = screen.getByText('Open Source').parentElement;
expect(statsSection).toBeInTheDocument();
});
@@ -78,17 +82,17 @@ describe('StatsSection', () => {
// Icons are rendered via lucide-react components
// We can verify the stat cards are rendered with proper structure
const testCoverageCard = screen.getByText('Test Coverage').closest('div');
expect(testCoverageCard).toBeInTheDocument();
const openSourceCard = screen.getByText('Open Source').closest('div');
expect(openSourceCard).toBeInTheDocument();
const passingTestsCard = screen.getByText('Passing Tests').closest('div');
expect(passingTestsCard).toBeInTheDocument();
const typeSafeCard = screen.getByText('Type Safe').closest('div');
expect(typeSafeCard).toBeInTheDocument();
const flakyTestsCard = screen.getByText('Flaky Tests').closest('div');
expect(flakyTestsCard).toBeInTheDocument();
const docGuidesCard = screen.getByText('Doc Guides').closest('div');
expect(docGuidesCard).toBeInTheDocument();
const apiEndpointsCard = screen.getByText('API Endpoints').closest('div');
expect(apiEndpointsCard).toBeInTheDocument();
const magicCard = screen.getByText('Magic').closest('div');
expect(magicCard).toBeInTheDocument();
});
describe('Accessibility', () => {
@@ -102,7 +106,7 @@ describe('StatsSection', () => {
it('has descriptive labels for stats', () => {
render(<StatsSection />);
const statLabels = ['Test Coverage', 'Passing Tests', 'Flaky Tests', 'API Endpoints'];
const statLabels = ['Open Source', 'Type Safe', 'Doc Guides', 'Magic'];
statLabels.forEach((label) => {
expect(screen.getByText(label)).toBeInTheDocument();