@@ -34,6 +34,7 @@ describe("runHttpRequest", () => {
3434 mockHeaders . append ( "Content-Type" , "application/json" ) ;
3535
3636 const mockResponse = {
37+ ok : true ,
3738 status : 200 ,
3839 headers : mockHeaders ,
3940 body : {
@@ -90,6 +91,7 @@ describe("runHttpRequest", () => {
9091 mockHeaders . append ( "Content-Type" , "application/json" ) ;
9192
9293 const mockResponse = {
94+ ok : true ,
9395 status : 200 ,
9496 headers : mockHeaders ,
9597 body : {
@@ -142,6 +144,7 @@ describe("runHttpRequest", () => {
142144 mockHeaders . append ( "Content-Type" , "application/json" ) ;
143145
144146 const mockResponse = {
147+ ok : true ,
145148 status : 200 ,
146149 headers : mockHeaders ,
147150 body : {
@@ -192,4 +195,53 @@ describe("runHttpRequest", () => {
192195 // Clean up
193196 subscription . unsubscribe ( ) ;
194197 } ) ;
198+
199+ it ( "should throw HTTP error on occurs" , async ( ) => {
200+ // Mock a 404 error response with JSON body
201+ const mockHeaders = new Headers ( ) ;
202+ mockHeaders . append ( "content-type" , "application/json" ) ;
203+
204+ const mockText = '{"message":"User not found"}' ;
205+
206+ const mockResponse = {
207+ ok : false ,
208+ status : 404 ,
209+ headers : mockHeaders ,
210+ // our error-path reads .text() (not streaming)
211+ text : jest . fn ( ) . mockResolvedValue ( mockText ) ,
212+ } as unknown as Response ;
213+
214+ // Override fetch for this test
215+ fetchMock . mockResolvedValue ( mockResponse ) ;
216+
217+ const observable = runHttpRequest ( "https://example.com/api" , { method : "GET" } ) ;
218+
219+ const nextSpy = jest . fn ( ) ;
220+
221+ await new Promise < void > ( ( resolve ) => {
222+ const sub = observable . subscribe ( {
223+ next : nextSpy ,
224+ error : ( err : any ) => {
225+ // error should carry status + parsed payload
226+ expect ( err ) . toBeInstanceOf ( Error ) ;
227+ expect ( err . status ) . toBe ( 404 ) ;
228+ expect ( err . payload ) . toEqual ( { message : "User not found" } ) ;
229+ // readable message is okay too (optional)
230+ expect ( err . message ) . toContain ( "HTTP 404" ) ;
231+ expect ( err . message ) . toContain ( "User not found" ) ;
232+ resolve ( ) ;
233+ sub . unsubscribe ( ) ;
234+ } ,
235+ complete : ( ) => {
236+ fail ( "Should not complete on HTTP error" ) ;
237+ } ,
238+ } ) ;
239+ } ) ;
240+
241+ // Should not have emitted any data events on error short-circuit
242+ expect ( nextSpy ) . not . toHaveBeenCalled ( ) ;
243+
244+ // Ensure we read the error body exactly once
245+ expect ( ( mockResponse as any ) . text ) . toHaveBeenCalledTimes ( 1 ) ;
246+ } ) ;
195247} ) ;
0 commit comments