Cover frontend middleware auth/locale logic, i18n config/routing/request/navigation, and vi/en message parity — 91 new tests across 6 files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
122 lines
3.7 KiB
TypeScript
122 lines
3.7 KiB
TypeScript
import { describe, expect, it, vi, beforeEach } from 'vitest';
|
|
|
|
// Mock the routing module
|
|
vi.mock('../routing', () => ({
|
|
routing: {
|
|
locales: ['vi', 'en'] as const,
|
|
defaultLocale: 'vi',
|
|
localePrefix: 'as-needed',
|
|
},
|
|
}));
|
|
|
|
// Track getRequestConfig calls
|
|
let capturedConfigFn: ((params: { requestLocale: Promise<string | undefined> }) => Promise<{
|
|
locale: string;
|
|
messages: Record<string, unknown>;
|
|
}>) | null = null;
|
|
|
|
vi.mock('next-intl/server', () => ({
|
|
getRequestConfig: (fn: typeof capturedConfigFn) => {
|
|
capturedConfigFn = fn;
|
|
return fn;
|
|
},
|
|
}));
|
|
|
|
// Provide message mocks
|
|
vi.mock('../../messages/vi.json', () => ({
|
|
default: {
|
|
common: { goodgo: 'GoodGo', loading: 'Đang tải...' },
|
|
metadata: { title: 'GoodGo — Nền tảng Bất động sản Việt Nam' },
|
|
},
|
|
}));
|
|
|
|
vi.mock('../../messages/en.json', () => ({
|
|
default: {
|
|
common: { goodgo: 'GoodGo', loading: 'Loading...' },
|
|
metadata: { title: 'GoodGo — Vietnam Real Estate Platform' },
|
|
},
|
|
}));
|
|
|
|
// Import triggers getRequestConfig, which captures the config function
|
|
await import('../request');
|
|
|
|
describe('i18n/request', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('captures a config function via getRequestConfig', () => {
|
|
expect(capturedConfigFn).toBeTypeOf('function');
|
|
});
|
|
|
|
describe('locale resolution', () => {
|
|
it('uses the requested locale when it is valid (vi)', async () => {
|
|
const result = await capturedConfigFn!({
|
|
requestLocale: Promise.resolve('vi'),
|
|
});
|
|
expect(result.locale).toBe('vi');
|
|
});
|
|
|
|
it('uses the requested locale when it is valid (en)', async () => {
|
|
const result = await capturedConfigFn!({
|
|
requestLocale: Promise.resolve('en'),
|
|
});
|
|
expect(result.locale).toBe('en');
|
|
});
|
|
|
|
it('falls back to default locale (vi) when requestLocale is undefined', async () => {
|
|
const result = await capturedConfigFn!({
|
|
requestLocale: Promise.resolve(undefined),
|
|
});
|
|
expect(result.locale).toBe('vi');
|
|
});
|
|
|
|
it('falls back to default locale (vi) when requestLocale is empty string', async () => {
|
|
const result = await capturedConfigFn!({
|
|
requestLocale: Promise.resolve(''),
|
|
});
|
|
expect(result.locale).toBe('vi');
|
|
});
|
|
|
|
it('falls back to default locale (vi) for an invalid locale', async () => {
|
|
const result = await capturedConfigFn!({
|
|
requestLocale: Promise.resolve('fr'),
|
|
});
|
|
expect(result.locale).toBe('vi');
|
|
});
|
|
|
|
it('falls back to default locale (vi) for another invalid locale', async () => {
|
|
const result = await capturedConfigFn!({
|
|
requestLocale: Promise.resolve('ja'),
|
|
});
|
|
expect(result.locale).toBe('vi');
|
|
});
|
|
});
|
|
|
|
describe('message loading', () => {
|
|
it('loads Vietnamese messages for vi locale', async () => {
|
|
const result = await capturedConfigFn!({
|
|
requestLocale: Promise.resolve('vi'),
|
|
});
|
|
expect(result.messages).toBeDefined();
|
|
expect((result.messages as Record<string, Record<string, string>>).common.loading).toBe('Đang tải...');
|
|
});
|
|
|
|
it('loads English messages for en locale', async () => {
|
|
const result = await capturedConfigFn!({
|
|
requestLocale: Promise.resolve('en'),
|
|
});
|
|
expect(result.messages).toBeDefined();
|
|
expect((result.messages as Record<string, Record<string, string>>).common.loading).toBe('Loading...');
|
|
});
|
|
|
|
it('loads Vietnamese messages when falling back from invalid locale', async () => {
|
|
const result = await capturedConfigFn!({
|
|
requestLocale: Promise.resolve('fr'),
|
|
});
|
|
expect(result.locale).toBe('vi');
|
|
expect((result.messages as Record<string, Record<string, string>>).common.loading).toBe('Đang tải...');
|
|
});
|
|
});
|
|
});
|