diff --git a/frontend/src/test-utils/mockLocale.ts b/frontend/src/test-utils/mockLocale.ts index 2eb89ce60..e42b5af08 100644 --- a/frontend/src/test-utils/mockLocale.ts +++ b/frontend/src/test-utils/mockLocale.ts @@ -12,11 +12,31 @@ import { vi } from "vitest"; * Defaults to `en-GB` */ export const mockLocale = (defaultLocale = "en-GB"): void => { - const { DateTimeFormat } = Intl; + const OriginalDateTimeFormat = Intl.DateTimeFormat; + + // Vitest 4.x requires function/class implementations for spyOn mocks when + // mocking constructors. For built-in constructors like Intl.DateTimeFormat + // that have internal slots, we use a function that returns a new instance. + // This is valid JavaScript - when a constructor returns an object, that + // object becomes the instance (instead of `this`). + function MockDateTimeFormat( + this: unknown, + locales?: Intl.LocalesArgument, + options?: Intl.DateTimeFormatOptions, + ): Intl.DateTimeFormat { + // Apply default locale when no locale is specified + return new OriginalDateTimeFormat(locales || defaultLocale, options); + } + + // Inherit static methods from the original DateTimeFormat + Object.setPrototypeOf(MockDateTimeFormat, OriginalDateTimeFormat); + // Set up prototype chain so instanceof checks work correctly + Object.setPrototypeOf( + MockDateTimeFormat.prototype, + OriginalDateTimeFormat.prototype, + ); + vi.spyOn(Intl, "DateTimeFormat").mockImplementation( - ( - locales?: Intl.LocalesArgument, - options?: Intl.DateTimeFormatOptions | undefined, - ) => new DateTimeFormat(locales || defaultLocale, options), + MockDateTimeFormat as typeof Intl.DateTimeFormat, ); };