diff --git a/src/app/[lang]/internal/page.test.tsx b/src/app/[lang]/internal/page.test.tsx new file mode 100644 index 000000000..a49590d99 --- /dev/null +++ b/src/app/[lang]/internal/page.test.tsx @@ -0,0 +1,38 @@ +import { render, within } from '@testing-library/react'; +import { describe, expect, it } from 'vitest'; + +import InternalPage, { generateMetadata, generateStaticParams } from './page'; + +describe('/[lang]/internal page', () => { + it('generates locale params for internal test pages', () => { + expect(generateStaticParams()).toEqual([{ lang: 'en' }, { lang: 'ja' }, { lang: 'ko' }]); + }); + + it('renders the Korean internal page title and description only', async () => { + const container = document.createElement('div'); + const result = render(await InternalPage({ params: Promise.resolve({ lang: 'ko' }) }), { + baseElement: container, + container, + }); + + expect(within(result.container).getByRole('heading', { level: 1, name: '내부 페이지' })).toBeTruthy(); + expect( + within(result.container).getByText('검토와 구현 참고를 위해 유지 중인 내부 컴포넌트 및 페이지 예시 목록입니다.'), + ).toBeTruthy(); + expect(within(result.container).queryByRole('list')).not.toBeInTheDocument(); + }); + + it('uses the same copy for route metadata', async () => { + await expect(generateMetadata({ params: Promise.resolve({ lang: 'ko' }) })).resolves.toMatchObject({ + description: '검토와 구현 참고를 위해 유지 중인 내부 컴포넌트 및 페이지 예시 목록입니다.', + title: '내부 페이지', + }); + }); + + it('falls back to English metadata when static generation omits params', async () => { + await expect(generateMetadata({})).resolves.toMatchObject({ + description: 'A list of internal component and page examples maintained for review and implementation reference.', + title: 'Internal Pages', + }); + }); +}); diff --git a/src/app/[lang]/internal/page.tsx b/src/app/[lang]/internal/page.tsx new file mode 100644 index 000000000..b5e94accd --- /dev/null +++ b/src/app/[lang]/internal/page.tsx @@ -0,0 +1,94 @@ +import type { Metadata } from 'next'; + +type InternalPageParams = { + lang: string; +}; + +type InternalPageProps = { + params?: Promise; +}; + +type InternalPageCopy = { + description: string; + title: string; +}; + +const internalPageCopy: Record = { + en: { + description: 'A list of internal component and page examples maintained for review and implementation reference.', + title: 'Internal Pages', + }, + ja: { + description: 'レビューと実装参考のために維持している内部コンポーネントおよびページ例の一覧です。', + title: '内部ページ', + }, + ko: { + description: '검토와 구현 참고를 위해 유지 중인 내부 컴포넌트 및 페이지 예시 목록입니다.', + title: '내부 페이지', + }, +}; + +const locales = Object.keys(internalPageCopy); + +function getInternalPageCopy(lang: string) { + return internalPageCopy[lang] ?? internalPageCopy.en; +} + +async function getInternalPageLang(params: InternalPageProps['params']) { + const resolvedParams = await params; + + return resolvedParams?.lang ?? 'en'; +} + +export function generateStaticParams() { + return locales.map(lang => ({ lang })); +} + +export async function generateMetadata({ params }: InternalPageProps): Promise { + const lang = await getInternalPageLang(params); + const copy = getInternalPageCopy(lang); + + return { + description: copy.description, + title: copy.title, + }; +} + +export default async function InternalPage({ params }: InternalPageProps) { + const lang = await getInternalPageLang(params); + const copy = getInternalPageCopy(lang); + + return ( +
+

+ {copy.title} +

+

+ {copy.description} +

+
+ ); +}