11import * as fs from 'fs' ;
22import SentryCli from '@sentry/cli' ;
3- import glob from 'glob' ;
4- import type { ResolvedConfig } from 'vite' ;
3+ import { glob } from 'glob' ;
54import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest' ;
65import { sentryOnBuildEnd } from '../../../src/vite/buildEnd/handleOnBuildEnd' ;
76
87// Mock dependencies
98vi . mock ( '@sentry/cli' ) ;
10- vi . mock ( 'fs' ) ;
9+ vi . mock ( 'fs' , ( ) => ( {
10+ promises : {
11+ rm : vi . fn ( ) . mockResolvedValue ( undefined ) ,
12+ } ,
13+ } ) ) ;
1114vi . mock ( 'glob' ) ;
1215
1316describe ( 'sentryOnBuildEnd' , ( ) => {
@@ -16,6 +19,7 @@ describe('sentryOnBuildEnd', () => {
1619 new : vi . fn ( ) ,
1720 uploadSourceMaps : vi . fn ( ) ,
1821 } ,
22+ execute : vi . fn ( ) ,
1923 } ;
2024
2125 const defaultConfig = {
@@ -37,12 +41,12 @@ describe('sentryOnBuildEnd', () => {
3741 build : {
3842 sourcemap : true ,
3943 } ,
40- } as ResolvedConfig ,
41- sentryConfig : {
42- authToken : 'test-token ' ,
43- org : 'test-org ' ,
44- project : 'test-project' ,
45- debug : false ,
44+ sentryConfig : {
45+ authToken : 'test-token' ,
46+ org : 'test-org ' ,
47+ project : 'test-project ' ,
48+ debug : false ,
49+ } ,
4650 } ,
4751 } ;
4852
@@ -61,10 +65,13 @@ describe('sentryOnBuildEnd', () => {
6165 it ( 'should create a new Sentry release when release name is provided' , async ( ) => {
6266 const config = {
6367 ...defaultConfig ,
64- sentryConfig : {
65- ...defaultConfig . sentryConfig ,
66- release : {
67- name : 'v1.0.0' ,
68+ viteConfig : {
69+ ...defaultConfig . viteConfig ,
70+ sentryConfig : {
71+ ...defaultConfig . viteConfig . sentryConfig ,
72+ release : {
73+ name : 'v1.0.0' ,
74+ } ,
6875 } ,
6976 } ,
7077 } ;
@@ -77,10 +84,13 @@ describe('sentryOnBuildEnd', () => {
7784 it ( 'should upload source maps when enabled' , async ( ) => {
7885 const config = {
7986 ...defaultConfig ,
80- sentryConfig : {
81- ...defaultConfig . sentryConfig ,
82- sourceMapsUploadOptions : {
83- enabled : true ,
87+ viteConfig : {
88+ ...defaultConfig . viteConfig ,
89+ sentryConfig : {
90+ ...defaultConfig . viteConfig . sentryConfig ,
91+ sourceMapsUploadOptions : {
92+ enabled : true ,
93+ } ,
8494 } ,
8595 } ,
8696 } ;
@@ -95,10 +105,13 @@ describe('sentryOnBuildEnd', () => {
95105 it ( 'should not upload source maps when explicitly disabled' , async ( ) => {
96106 const config = {
97107 ...defaultConfig ,
98- sentryConfig : {
99- ...defaultConfig . sentryConfig ,
100- sourceMapsUploadOptions : {
101- enabled : false ,
108+ viteConfig : {
109+ ...defaultConfig . viteConfig ,
110+ sentryConfig : {
111+ ...defaultConfig . viteConfig . sentryConfig ,
112+ sourceMapsUploadOptions : {
113+ enabled : false ,
114+ } ,
102115 } ,
103116 } ,
104117 } ;
@@ -115,16 +128,18 @@ describe('sentryOnBuildEnd', () => {
115128 absolute : true ,
116129 nodir : true ,
117130 } ) ;
118- expect ( fs . promises . rm ) . toHaveBeenCalledTimes ( 2 ) ;
119131 } ) ;
120132
121133 it ( 'should delete custom files after upload when specified' , async ( ) => {
122134 const config = {
123135 ...defaultConfig ,
124- sentryConfig : {
125- ...defaultConfig . sentryConfig ,
126- sourceMapsUploadOptions : {
127- filesToDeleteAfterUpload : '/custom/**/*.map' ,
136+ viteConfig : {
137+ ...defaultConfig . viteConfig ,
138+ sentryConfig : {
139+ ...defaultConfig . viteConfig . sentryConfig ,
140+ sourceMapsUploadOptions : {
141+ filesToDeleteAfterUpload : '/custom/**/*.map' ,
142+ } ,
128143 } ,
129144 } ,
130145 } ;
@@ -143,10 +158,13 @@ describe('sentryOnBuildEnd', () => {
143158
144159 const config = {
145160 ...defaultConfig ,
146- sentryConfig : {
147- ...defaultConfig . sentryConfig ,
148- release : {
149- name : 'v1.0.0' ,
161+ viteConfig : {
162+ ...defaultConfig . viteConfig ,
163+ sentryConfig : {
164+ ...defaultConfig . viteConfig . sentryConfig ,
165+ release : {
166+ name : 'v1.0.0' ,
167+ } ,
150168 } ,
151169 } ,
152170 } ;
@@ -157,6 +175,35 @@ describe('sentryOnBuildEnd', () => {
157175 consoleSpy . mockRestore ( ) ;
158176 } ) ;
159177
178+ it ( 'should inject debug IDs before uploading source maps' , async ( ) => {
179+ const config = {
180+ ...defaultConfig ,
181+ viteConfig : {
182+ ...defaultConfig . viteConfig ,
183+ sentryConfig : {
184+ ...defaultConfig . viteConfig . sentryConfig ,
185+ sourceMapsUploadOptions : {
186+ enabled : true ,
187+ } ,
188+ } ,
189+ } ,
190+ } ;
191+
192+ await sentryOnBuildEnd ( config ) ;
193+
194+ expect ( mockSentryCliInstance . execute ) . toHaveBeenCalledWith ( [ 'sourcemaps' , 'inject' , '/build' ] , false ) ;
195+ } ) ;
196+
197+ it ( 'should handle errors during debug ID injection gracefully' , async ( ) => {
198+ const consoleSpy = vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
199+ mockSentryCliInstance . execute . mockRejectedValueOnce ( new Error ( 'Injection failed' ) ) ;
200+
201+ await sentryOnBuildEnd ( defaultConfig ) ;
202+
203+ expect ( consoleSpy ) . toHaveBeenCalledWith ( '[Sentry] Could not inject debug ids' , expect . any ( Error ) ) ;
204+ consoleSpy . mockRestore ( ) ;
205+ } ) ;
206+
160207 it ( 'should handle errors during source map upload gracefully' , async ( ) => {
161208 const consoleSpy = vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
162209 mockSentryCliInstance . releases . uploadSourceMaps . mockRejectedValueOnce ( new Error ( 'Upload failed' ) ) ;
@@ -172,9 +219,12 @@ describe('sentryOnBuildEnd', () => {
172219
173220 const config = {
174221 ...defaultConfig ,
175- sentryConfig : {
176- ...defaultConfig . sentryConfig ,
177- debug : true ,
222+ viteConfig : {
223+ ...defaultConfig . viteConfig ,
224+ sentryConfig : {
225+ ...defaultConfig . viteConfig . sentryConfig ,
226+ debug : true ,
227+ } ,
178228 } ,
179229 } ;
180230
0 commit comments