The Hero server component awaited getMessages(locale) which called Directus with a 2-second timeout. On testing.dk0.dev (or when Directus is unreachable), this blocked the entire Hero render for ~2s → LCP 3.0s / 2320ms rendering delay. Changes: - Hero.tsx: remove getMessages() call entirely; use t() for all strings - messages/en.json + de.json: add hero.badge, hero.line1, hero.line2 keys - lib/i18n-loader.ts: invert lookup order — JSON first, Directus only as override for keys absent from JSON. Previously Directus was tried first for every key, causing ~49 parallel network requests per page load in HomePageServer (aboutT + projectsT + contactT + footerT translations). Now all JSON-backed keys return instantly without any network I/O. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
import { render, screen } from '@testing-library/react';
|
|
import Hero from '@/app/components/Hero';
|
|
|
|
// Mock next-intl/server
|
|
jest.mock('next-intl/server', () => ({
|
|
getTranslations: () => Promise.resolve((key: string) => {
|
|
const messages: Record<string, string> = {
|
|
badge: 'Student & Self-Hoster',
|
|
line1: 'Building',
|
|
line2: 'Stuff.',
|
|
description: 'Dennis is a student and passionate self-hoster.',
|
|
ctaWork: 'View My Work',
|
|
ctaContact: 'Get in touch',
|
|
};
|
|
return messages[key] || key;
|
|
}),
|
|
}));
|
|
|
|
// Mock next/image
|
|
interface ImageProps {
|
|
src: string;
|
|
alt: string;
|
|
fill?: boolean;
|
|
priority?: boolean;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
jest.mock('next/image', () => ({
|
|
__esModule: true,
|
|
default: ({ src, alt, fill, priority, ...props }: ImageProps) => (
|
|
// eslint-disable-next-line @next/next/no-img-element
|
|
<img
|
|
src={src}
|
|
alt={alt}
|
|
data-fill={fill?.toString()}
|
|
data-priority={priority?.toString()}
|
|
{...props}
|
|
/>
|
|
),
|
|
}));
|
|
|
|
describe('Hero', () => {
|
|
it('renders the hero section correctly', async () => {
|
|
const HeroResolved = await Hero({ locale: 'en' });
|
|
render(HeroResolved);
|
|
|
|
// Check for the main headlines (defaults in Hero.tsx)
|
|
expect(screen.getByText('Building')).toBeInTheDocument();
|
|
expect(screen.getByText('Stuff.')).toBeInTheDocument();
|
|
|
|
// Check for the description from our mock
|
|
expect(screen.getByText(/Dennis is a student/i)).toBeInTheDocument();
|
|
|
|
// Check for the image
|
|
expect(screen.getByAltText('Dennis Konkol')).toBeInTheDocument();
|
|
|
|
// Check for CTA
|
|
expect(screen.getByText('View My Work')).toBeInTheDocument();
|
|
});
|
|
});
|