-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvitest.setup.ts
More file actions
129 lines (118 loc) · 4.53 KB
/
vitest.setup.ts
File metadata and controls
129 lines (118 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* Copyright 2026 Salesforce, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import '@testing-library/jest-dom';
import { cleanup } from '@testing-library/react';
import { afterEach, beforeAll, vi } from 'vitest';
import { mockConfig } from '@/test-utils/config';
import i18next from 'i18next';
import { initReactI18next } from 'react-i18next';
import resources from '@/locales';
// Clear engagement-related PUBLIC__ env vars before any modules load
// The engagement config is protected from env var overrides, so these must be cleared
// to prevent defineConfig from throwing during module initialization
for (const key of Object.keys(process.env)) {
if (key.startsWith('PUBLIC__') && key.toLowerCase().includes('engagement')) {
delete process.env[key];
}
}
// Set window.__APP_CONFIG__ before any modules are imported
// This ensures getConfig() works during module initialization in tests where it is used before the config provider is rendered.
// to initialize AuthContext for hydration.
(window as Window & { __APP_CONFIG__: typeof mockConfig }).__APP_CONFIG__ = mockConfig;
// Initialize i18next for tests that use components with useTranslation
// This runs before all tests but individual tests can reinitialize as needed
beforeAll(() => {
if (!i18next.isInitialized) {
void i18next.use(initReactI18next).init({
lng: 'en-US',
fallbackLng: 'en-US',
resources,
interpolation: {
escapeValue: false,
},
});
}
});
// Mock getI18nextInstance to return an i18next instance for server actions
// Individual tests can override this if needed
vi.mock('@/middlewares/i18next', async () => {
const actual = await vi.importActual('@/middlewares/i18next');
// Create a simple mock i18next that has the t function with proper namespaces
const mockI18next = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
t: (key: string, options?: any) => {
// Handle namespace:key format
if (key.includes(':')) {
const [ns, ...keyParts] = key.split(':');
const keyPath = keyParts.join(':'); // rejoin in case there are multiple colons
// Navigate nested object using dot notation
const keys = keyPath.split('.');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let value: any = resources['en-US'][ns as keyof (typeof resources)['en-US']];
for (const k of keys) {
if (value && typeof value === 'object') {
value = value[k];
} else {
break;
}
}
if (typeof value === 'string' && options) {
// Simple interpolation for {{variable}} syntax
return value.replace(/\{\{(\w+)\}\}/g, (_, prop) => options[prop] || `{{${prop}}}`);
}
return value || key;
}
return key;
},
language: 'en-US',
};
return {
...actual,
getI18nextInstance: () => mockI18next,
getLocale: () => 'en-US',
};
});
afterEach(() => {
cleanup();
});
// Mock window.matchMedia for required components
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: vi.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: vi.fn(),
removeListener: vi.fn(),
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
})),
});
global.ResizeObserver = vi.fn().mockImplementation(() => ({
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn(),
}));
// Mock IntersectionObserver for carousel components
global.IntersectionObserver = vi.fn().mockImplementation((_callback) => ({
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn(),
root: null,
rootMargin: '',
thresholds: [],
}));