Skip to content

Commit 2bacd1c

Browse files
committed
Update scripts/bootstrap unit test
1 parent 83f5d66 commit 2bacd1c

1 file changed

Lines changed: 111 additions & 25 deletions

File tree

‎src/components/scripts/bootstrap/__tests__/index.spec.ts‎

Lines changed: 111 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1-
// @vitest-environment happy-dom
1+
// @vitest-environment jsdom
22
/**
33
* Unit tests for AppBootstrap
44
* Tests initialization of state management on page load
55
*/
6-
import { describe, it, expect, beforeEach, vi } from 'vitest'
6+
import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest'
77
import { AppBootstrap } from '@components/scripts/bootstrap'
88
import { addScriptBreadcrumb, ClientScriptError } from '@components/scripts/errors'
99
import { TestError } from '@test/errors'
1010

11+
vi.mock('@components/scripts/errors', async () => {
12+
const actual = await vi.importActual<typeof import('@components/scripts/errors')>(
13+
'@components/scripts/errors'
14+
)
15+
16+
return {
17+
...actual,
18+
addScriptBreadcrumb: vi.fn(),
19+
handleScriptError: vi.fn(),
20+
}
21+
})
22+
1123
// Mock the store initialization functions
1224
vi.mock('@components/scripts/store', () => ({
1325
initConsentFromCookies: vi.fn(),
@@ -18,30 +30,76 @@ vi.mock('@components/scripts/store', () => ({
1830
},
1931
}))
2032

21-
// Mock Sentry breadcrumb function
22-
vi.mock('@components/scripts/errors', () => ({
23-
addScriptBreadcrumb: vi.fn(),
24-
handleScriptError: vi.fn(),
33+
vi.mock('@components/scripts/sentry/client', () => ({
34+
SentryBootstrap: {
35+
init: vi.fn(),
36+
},
37+
}))
38+
39+
const mockEnvironmentClient = vi.hoisted(() => ({
40+
getPackageRelease: vi.fn().mockReturnValue('test-release'),
41+
getPrivacyPolicyVersion: vi.fn().mockReturnValue('1.0.0'),
42+
isProd: vi.fn().mockReturnValue(false),
43+
isDev: vi.fn().mockReturnValue(true),
44+
isE2eTest: vi.fn().mockReturnValue(false),
45+
isTest: vi.fn().mockReturnValue(false),
46+
isUnitTest: vi.fn().mockReturnValue(true),
2547
}))
2648

49+
vi.mock('@components/scripts/utils/environmentClient', () => mockEnvironmentClient)
50+
2751
// Import the mocked functions after setting up mocks
2852
import {
2953
initConsentFromCookies,
3054
initConsentSideEffects,
3155
addViewTransitionThemeInitListener,
3256
} from '@components/scripts/store'
57+
import { SentryBootstrap } from '@components/scripts/sentry/client'
58+
59+
type TestWindow = Window & {
60+
isPlaywrightControlled?: boolean
61+
environmentClientSnapshot?: {
62+
isUnitTest: boolean
63+
isTest: boolean
64+
isE2eTest: boolean
65+
isDev: boolean
66+
isProd: boolean
67+
packageRelease: string
68+
privacyPolicyVersion: string
69+
}
70+
}
71+
72+
const testWindow = window as TestWindow
73+
const consoleInfoSpy = vi.spyOn(console, 'info').mockImplementation(() => {})
74+
75+
const mockSuccessfulInit = () => {
76+
vi.mocked(addViewTransitionThemeInitListener).mockReturnValue(undefined)
77+
vi.mocked(initConsentFromCookies).mockReturnValue(undefined)
78+
vi.mocked(initConsentSideEffects).mockReturnValue(undefined)
79+
}
3380

3481
describe('AppBootstrap', () => {
3582
beforeEach(() => {
3683
vi.clearAllMocks()
84+
mockSuccessfulInit()
85+
delete testWindow.isPlaywrightControlled
86+
delete testWindow.environmentClientSnapshot
87+
mockEnvironmentClient.isProd.mockReturnValue(false)
88+
mockEnvironmentClient.isDev.mockReturnValue(true)
89+
mockEnvironmentClient.isE2eTest.mockReturnValue(false)
90+
mockEnvironmentClient.isTest.mockReturnValue(false)
91+
mockEnvironmentClient.isUnitTest.mockReturnValue(true)
92+
mockEnvironmentClient.getPackageRelease.mockReturnValue('test-release')
93+
mockEnvironmentClient.getPrivacyPolicyVersion.mockReturnValue('1.0.0')
94+
consoleInfoSpy.mockClear()
95+
})
96+
97+
afterAll(() => {
98+
consoleInfoSpy.mockRestore()
3799
})
38100

39101
describe('Successful initialization', () => {
40102
it('should call addViewTransitionThemeInitListener, initConsentFromCookies and initialize side effects', () => {
41-
vi.mocked(addViewTransitionThemeInitListener).mockReturnValue(undefined)
42-
vi.mocked(initConsentFromCookies).mockReturnValue(undefined)
43-
vi.mocked(initConsentSideEffects).mockReturnValue(undefined)
44-
45103
AppBootstrap.init()
46104

47105
expect(addViewTransitionThemeInitListener).toHaveBeenCalledTimes(1)
@@ -50,10 +108,6 @@ describe('AppBootstrap', () => {
50108
})
51109

52110
it('should add breadcrumbs for successful initialization', () => {
53-
vi.mocked(addViewTransitionThemeInitListener).mockReturnValue(undefined)
54-
vi.mocked(initConsentFromCookies).mockReturnValue(undefined)
55-
vi.mocked(initConsentSideEffects).mockReturnValue(undefined)
56-
57111
AppBootstrap.init()
58112

59113
expect(addScriptBreadcrumb).toHaveBeenCalledWith({
@@ -75,10 +129,6 @@ describe('AppBootstrap', () => {
75129
})
76130

77131
it('should not throw error when initialization succeeds', () => {
78-
vi.mocked(addViewTransitionThemeInitListener).mockReturnValue(undefined)
79-
vi.mocked(initConsentFromCookies).mockReturnValue(undefined)
80-
vi.mocked(initConsentSideEffects).mockReturnValue(undefined)
81-
82132
expect(() => AppBootstrap.init()).not.toThrow()
83133
})
84134
})
@@ -122,11 +172,9 @@ describe('AppBootstrap', () => {
122172
})
123173

124174
it('should not call side effects when initConsentFromCookies fails', () => {
125-
vi.mocked(addViewTransitionThemeInitListener).mockReturnValue(undefined)
126175
vi.mocked(initConsentFromCookies).mockImplementation(() => {
127176
throw new TestError('Cookie initialization failed')
128177
})
129-
vi.mocked(initConsentSideEffects).mockReturnValue(undefined)
130178

131179
try {
132180
AppBootstrap.init()
@@ -138,7 +186,6 @@ describe('AppBootstrap', () => {
138186
})
139187

140188
it('should wrap non-Error objects in ClientScriptError', () => {
141-
vi.mocked(addViewTransitionThemeInitListener).mockReturnValue(undefined)
142189
vi.mocked(initConsentFromCookies).mockImplementation(() => {
143190
throw 'String error'
144191
})
@@ -155,10 +202,6 @@ describe('AppBootstrap', () => {
155202

156203
describe('Integration scenarios', () => {
157204
it('should successfully initialize on repeated calls', () => {
158-
vi.mocked(addViewTransitionThemeInitListener).mockReturnValue(undefined)
159-
vi.mocked(initConsentFromCookies).mockReturnValue(undefined)
160-
vi.mocked(initConsentSideEffects).mockReturnValue(undefined)
161-
162205
AppBootstrap.init()
163206
AppBootstrap.init()
164207

@@ -167,4 +210,47 @@ describe('AppBootstrap', () => {
167210
expect(initConsentSideEffects).toHaveBeenCalledTimes(2)
168211
})
169212
})
213+
214+
describe('Runtime integrations', () => {
215+
it('should write the environment snapshot when Playwright controls the window', () => {
216+
testWindow.isPlaywrightControlled = true
217+
mockEnvironmentClient.isUnitTest.mockReturnValue(false)
218+
mockEnvironmentClient.isTest.mockReturnValue(true)
219+
mockEnvironmentClient.isE2eTest.mockReturnValue(true)
220+
mockEnvironmentClient.isDev.mockReturnValue(false)
221+
mockEnvironmentClient.isProd.mockReturnValue(true)
222+
mockEnvironmentClient.getPackageRelease.mockReturnValue('2024.10.0')
223+
mockEnvironmentClient.getPrivacyPolicyVersion.mockReturnValue('3.1.4')
224+
225+
AppBootstrap.init()
226+
227+
expect(testWindow.environmentClientSnapshot).toEqual({
228+
isUnitTest: false,
229+
isTest: true,
230+
isE2eTest: true,
231+
isDev: false,
232+
isProd: true,
233+
packageRelease: '2024.10.0',
234+
privacyPolicyVersion: '3.1.4',
235+
})
236+
})
237+
238+
it('should initialize Sentry in production builds', () => {
239+
mockEnvironmentClient.isProd.mockReturnValue(true)
240+
241+
AppBootstrap.init()
242+
243+
expect(SentryBootstrap.init).toHaveBeenCalledTimes(1)
244+
expect(consoleInfoSpy).not.toHaveBeenCalled()
245+
})
246+
247+
it('should log when Sentry stays disabled outside production', () => {
248+
mockEnvironmentClient.isProd.mockReturnValue(false)
249+
250+
AppBootstrap.init()
251+
252+
expect(SentryBootstrap.init).not.toHaveBeenCalled()
253+
expect(consoleInfoSpy).toHaveBeenCalledWith('🔧 Sentry disabled in development mode')
254+
})
255+
})
170256
})

0 commit comments

Comments
 (0)