@@ -75,6 +75,19 @@ describe('UIUC-api/downloadConvoHistoryUser', () => {
7575 expect ( res4 . status ) . toHaveBeenCalledWith ( 400 )
7676 } )
7777
78+ it ( 'returns 400 when projectName is not a string' , async ( ) => {
79+ const res = createWritableRes ( )
80+ await handler (
81+ createMockReq ( {
82+ method : 'GET' ,
83+ query : { projectName : [ 'CS101' ] } ,
84+ user : { email : 'a@b.com' } ,
85+ } ) as any ,
86+ res as any ,
87+ )
88+ expect ( res . status ) . toHaveBeenCalledWith ( 400 )
89+ } )
90+
7891 it ( 'streams backend response to res on success' , async ( ) => {
7992 const fetchSpy = vi
8093 . spyOn ( globalThis , 'fetch' )
@@ -94,4 +107,115 @@ describe('UIUC-api/downloadConvoHistoryUser', () => {
94107 expect ( res . end ) . toHaveBeenCalled ( )
95108 fetchSpy . mockRestore ( )
96109 } )
110+
111+ it ( 'propagates backend non-ok status codes' , async ( ) => {
112+ const fetchSpy = vi . spyOn ( globalThis , 'fetch' ) . mockResolvedValueOnce (
113+ new Response ( 'nope' , {
114+ status : 502 ,
115+ statusText : 'Bad Gateway' ,
116+ headers : { 'content-type' : 'application/json' } ,
117+ } ) ,
118+ )
119+
120+ const res = createWritableRes ( )
121+ await handler (
122+ createMockReq ( {
123+ method : 'GET' ,
124+ query : { projectName : 'CS101' } ,
125+ user : { email : 'a@b.com' } ,
126+ } ) as any ,
127+ res as any ,
128+ )
129+
130+ expect ( res . status ) . toHaveBeenCalledWith ( 502 )
131+ expect ( res . json ) . toHaveBeenCalledWith (
132+ expect . objectContaining ( {
133+ error : expect . stringContaining ( 'Backend error' ) ,
134+ } ) ,
135+ )
136+ fetchSpy . mockRestore ( )
137+ } )
138+
139+ it ( 'returns 500 when backend response has no body' , async ( ) => {
140+ const fetchSpy = vi . spyOn ( globalThis , 'fetch' ) . mockResolvedValueOnce (
141+ new Response ( null , {
142+ status : 200 ,
143+ headers : { 'content-type' : 'application/zip' } ,
144+ } ) ,
145+ )
146+
147+ const res = createWritableRes ( )
148+ await handler (
149+ createMockReq ( {
150+ method : 'GET' ,
151+ query : { projectName : 'CS101' } ,
152+ user : { email : 'a@b.com' } ,
153+ } ) as any ,
154+ res as any ,
155+ )
156+ expect ( res . status ) . toHaveBeenCalledWith ( 500 )
157+ expect ( res . json ) . toHaveBeenCalledWith (
158+ expect . objectContaining ( { error : 'No response body received' } ) ,
159+ )
160+ fetchSpy . mockRestore ( )
161+ } )
162+
163+ it ( 'returns 504 on TimeoutError and 408 on AbortError' , async ( ) => {
164+ const timeoutErr = Object . assign ( new Error ( 'took too long' ) , {
165+ name : 'TimeoutError' ,
166+ } )
167+ const abortErr = Object . assign ( new Error ( 'aborted' ) , { name : 'AbortError' } )
168+
169+ const fetchSpy = vi
170+ . spyOn ( globalThis , 'fetch' )
171+ . mockRejectedValueOnce ( timeoutErr )
172+ . mockRejectedValueOnce ( abortErr )
173+
174+ const res1 = createWritableRes ( )
175+ await handler (
176+ createMockReq ( {
177+ method : 'GET' ,
178+ query : { projectName : 'CS101' } ,
179+ user : { email : 'a@b.com' } ,
180+ } ) as any ,
181+ res1 as any ,
182+ )
183+ expect ( res1 . status ) . toHaveBeenCalledWith ( 504 )
184+
185+ const res2 = createWritableRes ( )
186+ await handler (
187+ createMockReq ( {
188+ method : 'GET' ,
189+ query : { projectName : 'CS101' } ,
190+ user : { email : 'a@b.com' } ,
191+ } ) as any ,
192+ res2 as any ,
193+ )
194+ expect ( res2 . status ) . toHaveBeenCalledWith ( 408 )
195+
196+ fetchSpy . mockRestore ( )
197+ } )
198+
199+ it ( 'returns 500 on generic errors' , async ( ) => {
200+ const fetchSpy = vi
201+ . spyOn ( globalThis , 'fetch' )
202+ . mockRejectedValueOnce ( new Error ( 'boom' ) )
203+
204+ const res = createWritableRes ( )
205+ await handler (
206+ createMockReq ( {
207+ method : 'GET' ,
208+ query : { projectName : 'CS101' } ,
209+ user : { email : 'a@b.com' } ,
210+ } ) as any ,
211+ res as any ,
212+ )
213+ expect ( res . status ) . toHaveBeenCalledWith ( 500 )
214+ expect ( res . json ) . toHaveBeenCalledWith (
215+ expect . objectContaining ( {
216+ error : 'Internal server error while exporting documents' ,
217+ } ) ,
218+ )
219+ fetchSpy . mockRestore ( )
220+ } )
97221} )
0 commit comments