@@ -8,18 +8,24 @@ const fsAccessMock = vi.fn();
8
8
const fsCopyFileMock = vi . fn ( ) ;
9
9
const fsReadFile = vi . fn ( ) ;
10
10
const fsWriteFileMock = vi . fn ( ) ;
11
+ const fsMkdirMock = vi . fn ( ) ;
12
+ const fsReaddirMock = vi . fn ( ) ;
13
+ const fsExistsSyncMock = vi . fn ( ) ;
11
14
12
15
vi . mock ( 'fs' , async ( ) => {
13
16
const actual = await vi . importActual ( 'fs' ) ;
14
17
return {
15
18
...actual ,
19
+ existsSync : ( ...args : unknown [ ] ) => fsExistsSyncMock ( ...args ) ,
16
20
promises : {
17
21
// @ts -expect-error this exists
18
22
...actual . promises ,
19
23
access : ( ...args : unknown [ ] ) => fsAccessMock ( ...args ) ,
20
24
copyFile : ( ...args : unknown [ ] ) => fsCopyFileMock ( ...args ) ,
21
25
readFile : ( ...args : unknown [ ] ) => fsReadFile ( ...args ) ,
22
26
writeFile : ( ...args : unknown [ ] ) => fsWriteFileMock ( ...args ) ,
27
+ mkdir : ( ...args : unknown [ ] ) => fsMkdirMock ( ...args ) ,
28
+ readdir : ( ...args : unknown [ ] ) => fsReaddirMock ( ...args ) ,
23
29
} ,
24
30
} ;
25
31
} ) ;
@@ -30,6 +36,9 @@ beforeEach(() => {
30
36
31
37
describe ( 'addInstrumentationFileToBuild()' , ( ) => {
32
38
const nitroOptions : Nitro = {
39
+ hooks : {
40
+ hook : vi . fn ( ) ,
41
+ } ,
33
42
options : {
34
43
buildDir : '/path/to/buildDir' ,
35
44
output : {
@@ -39,40 +48,142 @@ describe('addInstrumentationFileToBuild()', () => {
39
48
} ,
40
49
} ;
41
50
51
+ const callNitroCloseHook = async ( ) => {
52
+ const hookCallback = nitroOptions . hooks . hook . mock . calls [ 0 ] [ 1 ] ;
53
+ await hookCallback ( ) ;
54
+ } ;
55
+
42
56
it ( 'adds `instrument.server.mjs` to the server output directory' , async ( ) => {
43
57
fsCopyFileMock . mockResolvedValueOnce ( true ) ;
44
58
await addInstrumentationFileToBuild ( nitroOptions ) ;
59
+
60
+ await callNitroCloseHook ( ) ;
61
+
45
62
expect ( fsCopyFileMock ) . toHaveBeenCalledWith (
46
63
'/path/to/buildDir/build/ssr/instrument.server.js' ,
47
64
'/path/to/serverDir/instrument.server.mjs' ,
48
65
) ;
49
- expect ( consoleLogSpy ) . toHaveBeenCalledWith (
50
- '[Sentry SolidStart withSentry] Successfully created /path/to/serverDir/instrument.server.mjs.' ,
51
- ) ;
52
66
} ) ;
53
67
54
- it ( 'warns when `instrument.server.js` can not be copied to the server output directory' , async ( ) => {
68
+ it ( 'warns when `instrument.server.js` cannot be copied to the server output directory' , async ( ) => {
55
69
const error = new Error ( 'Failed to copy file.' ) ;
56
70
fsCopyFileMock . mockRejectedValueOnce ( error ) ;
57
71
await addInstrumentationFileToBuild ( nitroOptions ) ;
72
+
73
+ await callNitroCloseHook ( ) ;
74
+
58
75
expect ( fsCopyFileMock ) . toHaveBeenCalledWith (
59
76
'/path/to/buildDir/build/ssr/instrument.server.js' ,
60
77
'/path/to/serverDir/instrument.server.mjs' ,
61
78
) ;
62
79
expect ( consoleWarnSpy ) . toHaveBeenCalledWith (
63
- '[Sentry SolidStart withSentry] Failed to create /path/to/serverDir/instrument.server.mjs .' ,
80
+ '[Sentry SolidStart withSentry] Failed to add instrumentation file to build .' ,
64
81
error ,
65
82
) ;
66
83
} ) ;
67
84
68
- it . each ( [ staticHostPresets ] ) ( "doesn't add `instrument.server.mjs` for static host `%s`" , async preset => {
69
- await addInstrumentationFileToBuild ( {
85
+ it . each ( staticHostPresets ) ( "doesn't add `instrument.server.mjs` for static host `%s`" , async preset => {
86
+ const staticNitroOptions = {
70
87
...nitroOptions ,
71
88
options : {
72
89
...nitroOptions . options ,
73
90
preset,
74
91
} ,
75
- } ) ;
92
+ } ;
93
+
94
+ await addInstrumentationFileToBuild ( staticNitroOptions ) ;
95
+
96
+ await callNitroCloseHook ( ) ;
97
+
76
98
expect ( fsCopyFileMock ) . not . toHaveBeenCalled ( ) ;
77
99
} ) ;
100
+
101
+ it ( 'creates assets directory if it does not exist' , async ( ) => {
102
+ fsExistsSyncMock . mockReturnValue ( false ) ;
103
+ fsMkdirMock . mockResolvedValueOnce ( true ) ;
104
+ fsCopyFileMock . mockResolvedValueOnce ( true ) ;
105
+ await addInstrumentationFileToBuild ( nitroOptions ) ;
106
+
107
+ await callNitroCloseHook ( ) ;
108
+
109
+ expect ( fsMkdirMock ) . toHaveBeenCalledWith ( '/path/to/serverDir/assets' , { recursive : true } ) ;
110
+ expect ( consoleLogSpy ) . toHaveBeenCalledWith (
111
+ '[Sentry SolidStart withSentry] Successfully created directory /path/to/serverDir/assets.' ,
112
+ ) ;
113
+ } ) ;
114
+
115
+ it ( 'does not create assets directory if it already exists' , async ( ) => {
116
+ fsExistsSyncMock . mockReturnValue ( true ) ;
117
+ await addInstrumentationFileToBuild ( nitroOptions ) ;
118
+
119
+ await callNitroCloseHook ( ) ;
120
+
121
+ expect ( fsMkdirMock ) . not . toHaveBeenCalled ( ) ;
122
+ } ) ;
123
+
124
+ it ( 'copies release injection file if available' , async ( ) => {
125
+ fsExistsSyncMock . mockReturnValue ( true ) ;
126
+ fsReaddirMock . mockResolvedValueOnce ( [ '_sentry-release-injection-file-test.js' ] ) ;
127
+ fsCopyFileMock . mockResolvedValueOnce ( true ) ;
128
+ await addInstrumentationFileToBuild ( nitroOptions ) ;
129
+
130
+ await callNitroCloseHook ( ) ;
131
+
132
+ expect ( fsCopyFileMock ) . toHaveBeenCalledWith (
133
+ '/path/to/buildDir/build/ssr/assets/_sentry-release-injection-file-test.js' ,
134
+ '/path/to/serverDir/assets/_sentry-release-injection-file-test.js' ,
135
+ ) ;
136
+ expect ( consoleLogSpy ) . toHaveBeenCalledWith (
137
+ '[Sentry SolidStart withSentry] Successfully created /path/to/serverDir/assets/_sentry-release-injection-file-test.js.' ,
138
+ ) ;
139
+ } ) ;
140
+
141
+ it ( 'warns when release injection file cannot be copied' , async ( ) => {
142
+ const error = new Error ( 'Failed to copy release injection file.' ) ;
143
+ fsExistsSyncMock . mockReturnValue ( true ) ;
144
+ fsReaddirMock . mockResolvedValueOnce ( [ '_sentry-release-injection-file-test.js' ] ) ;
145
+ fsCopyFileMock . mockRejectedValueOnce ( error ) ;
146
+ await addInstrumentationFileToBuild ( nitroOptions ) ;
147
+
148
+ await callNitroCloseHook ( ) ;
149
+
150
+ expect ( fsCopyFileMock ) . toHaveBeenCalledWith (
151
+ '/path/to/buildDir/build/ssr/assets/_sentry-release-injection-file-test.js' ,
152
+ '/path/to/serverDir/assets/_sentry-release-injection-file-test.js' ,
153
+ ) ;
154
+ expect ( consoleWarnSpy ) . toHaveBeenCalledWith (
155
+ '[Sentry SolidStart withSentry] Failed to copy release injection file.' ,
156
+ error ,
157
+ ) ;
158
+ } ) ;
159
+
160
+ it ( 'does not copy release injection file if not found' , async ( ) => {
161
+ fsExistsSyncMock . mockReturnValue ( true ) ;
162
+ fsReaddirMock . mockResolvedValueOnce ( [ ] ) ;
163
+ await addInstrumentationFileToBuild ( nitroOptions ) ;
164
+
165
+ await callNitroCloseHook ( ) ;
166
+
167
+ expect ( fsCopyFileMock ) . not . toHaveBeenCalledWith (
168
+ expect . stringContaining ( '_sentry-release-injection-file-' ) ,
169
+ expect . any ( String ) ,
170
+ ) ;
171
+ } ) ;
172
+
173
+ it ( 'warns when `instrument.server.js` is not found' , async ( ) => {
174
+ const error = new Error ( 'File not found' ) ;
175
+ fsCopyFileMock . mockRejectedValueOnce ( error ) ;
176
+ await addInstrumentationFileToBuild ( nitroOptions ) ;
177
+
178
+ await callNitroCloseHook ( ) ;
179
+
180
+ expect ( fsCopyFileMock ) . toHaveBeenCalledWith (
181
+ '/path/to/buildDir/build/ssr/instrument.server.js' ,
182
+ '/path/to/serverDir/instrument.server.mjs' ,
183
+ ) ;
184
+ expect ( consoleWarnSpy ) . toHaveBeenCalledWith (
185
+ '[Sentry SolidStart withSentry] Failed to add instrumentation file to build.' ,
186
+ error ,
187
+ ) ;
188
+ } ) ;
78
189
} ) ;
0 commit comments