@@ -10,17 +10,16 @@ const labelItem = {
1010
1111describe ( "label-open-issues helpers" , ( ) => {
1212 it ( "classifies items from OpenAI structured response text" , async ( ) => {
13- const response = {
14- ok : true ,
15- status : 200 ,
16- json : async ( ) => ( {
13+ const response = new Response (
14+ JSON . stringify ( {
1715 output_text : JSON . stringify ( {
1816 category : "bug" ,
1917 isSupport : true ,
2018 isSkillOnly : false ,
2119 } ) ,
2220 } ) ,
23- } as Response ;
21+ { status : 200 } ,
22+ ) ;
2423
2524 await expect (
2625 testing . classifyItem ( labelItem , "issue" , {
@@ -55,11 +54,7 @@ describe("label-open-issues helpers", () => {
5554 } ) ;
5655
5756 it ( "times out stalled OpenAI classification body reads" , async ( ) => {
58- const response = {
59- ok : true ,
60- status : 200 ,
61- json : ( ) => new Promise ( ( ) => { } ) ,
62- } as Response ;
57+ const response = new Response ( new ReadableStream ( { } ) , { status : 200 } ) ;
6358 const request = testing . classifyItem ( labelItem , "issue" , {
6459 apiKey : "test-key" ,
6560 model : "test-model" ,
@@ -96,6 +91,53 @@ describe("label-open-issues helpers", () => {
9691 expect ( message . length ) . toBeLessThan ( 4300 ) ;
9792 } ) ;
9893
94+ it ( "reads bounded OpenAI classification JSON responses" , async ( ) => {
95+ await expect (
96+ testing . readBoundedOpenAIJson ( new Response ( '{"output_text":"{}"}' ) , 1024 ) ,
97+ ) . resolves . toEqual ( { output_text : "{}" } ) ;
98+ } ) ;
99+
100+ it ( "rejects oversized OpenAI classification JSON responses by content length" , async ( ) => {
101+ let canceled = false ;
102+ const response = new Response (
103+ new ReadableStream ( {
104+ cancel ( ) {
105+ canceled = true ;
106+ } ,
107+ } ) ,
108+ {
109+ headers : {
110+ "content-length" : "1025" ,
111+ } ,
112+ } ,
113+ ) ;
114+
115+ await expect ( testing . readBoundedOpenAIJson ( response , 1024 ) ) . rejects . toMatchObject ( {
116+ code : "ETOOBIG" ,
117+ message : "OpenAI classification response body exceeded 1024 bytes" ,
118+ } ) ;
119+ expect ( canceled ) . toBe ( true ) ;
120+ } ) ;
121+
122+ it ( "rejects oversized streamed OpenAI classification JSON responses" , async ( ) => {
123+ const encoder = new TextEncoder ( ) ;
124+ const response = new Response (
125+ new ReadableStream ( {
126+ start ( controller ) {
127+ controller . enqueue ( encoder . encode ( '{"output_text":"' ) ) ;
128+ controller . enqueue ( encoder . encode ( "x" . repeat ( 1024 ) ) ) ;
129+ controller . enqueue ( encoder . encode ( '"}' ) ) ;
130+ controller . close ( ) ;
131+ } ,
132+ } ) ,
133+ ) ;
134+
135+ await expect ( testing . readBoundedOpenAIJson ( response , 1024 ) ) . rejects . toMatchObject ( {
136+ code : "ETOOBIG" ,
137+ message : "OpenAI classification response body exceeded 1024 bytes" ,
138+ } ) ;
139+ } ) ;
140+
99141 it ( "rejects invalid OpenAI classification timeout values" , ( ) => {
100142 expect ( testing . resolveOpenAITimeoutMs ( "250" ) ) . toBe ( 250 ) ;
101143 expect ( ( ) => testing . resolveOpenAITimeoutMs ( "slow" ) ) . toThrow (
0 commit comments