@@ -87,6 +87,136 @@ describe('content extraction helpers', () => {
8787 expect ( ( ) => extractAllUserContent ( bad ) ) . toThrow ( ) ;
8888 } ) ;
8989
90+ test ( 'extractAllUserContent converts input_file with data URL' , ( ) => {
91+ const userContent : protocol . UserMessageItem [ 'content' ] = [
92+ {
93+ type : 'input_file' ,
94+ file : 'data:application/pdf;base64,JVBER...' ,
95+ filename : 'document.pdf' ,
96+ } ,
97+ ] ;
98+ const converted = extractAllUserContent ( userContent ) ;
99+ expect ( converted ) . toEqual ( [
100+ {
101+ type : 'file' ,
102+ file : {
103+ file_data : 'data:application/pdf;base64,JVBER...' ,
104+ filename : 'document.pdf' ,
105+ } ,
106+ } ,
107+ ] ) ;
108+ } ) ;
109+
110+ test ( 'extractAllUserContent throws on https URL (not supported in Chat Completions)' , ( ) => {
111+ const userContent : protocol . UserMessageItem [ 'content' ] = [
112+ {
113+ type : 'input_file' ,
114+ file : 'https://example.com/document.pdf' ,
115+ } ,
116+ ] ;
117+ expect ( ( ) => extractAllUserContent ( userContent ) ) . toThrow (
118+ / C h a t C o m p l e t i o n s o n l y s u p p o r t s d a t a U R L s / ,
119+ ) ;
120+ } ) ;
121+
122+ test ( 'extractAllUserContent converts input_file with file ID object' , ( ) => {
123+ const userContent : protocol . UserMessageItem [ 'content' ] = [
124+ {
125+ type : 'input_file' ,
126+ file : { id : 'file-abc123' } ,
127+ } ,
128+ ] ;
129+ const converted = extractAllUserContent ( userContent ) ;
130+ expect ( converted ) . toEqual ( [
131+ {
132+ type : 'file' ,
133+ file : {
134+ file_id : 'file-abc123' ,
135+ } ,
136+ } ,
137+ ] ) ;
138+ } ) ;
139+
140+ test ( 'extractAllUserContent throws on file URL object (not supported in Chat Completions)' , ( ) => {
141+ const userContent : protocol . UserMessageItem [ 'content' ] = [
142+ {
143+ type : 'input_file' ,
144+ file : { url : 'https://example.com/document.pdf' } ,
145+ } ,
146+ ] ;
147+ expect ( ( ) => extractAllUserContent ( userContent ) ) . toThrow (
148+ / r e q u i r e s a d a t a U R L o r f i l e I D / ,
149+ ) ;
150+ } ) ;
151+
152+ test ( 'extractAllUserContent gets filename from providerData' , ( ) => {
153+ const userContent : protocol . UserMessageItem [ 'content' ] = [
154+ {
155+ type : 'input_file' ,
156+ file : 'data:application/pdf;base64,JVBER...' ,
157+ providerData : {
158+ filename : 'from-provider.pdf' ,
159+ } ,
160+ } ,
161+ ] ;
162+ const converted = extractAllUserContent ( userContent ) ;
163+ expect ( converted ) . toEqual ( [
164+ {
165+ type : 'file' ,
166+ file : {
167+ file_data : 'data:application/pdf;base64,JVBER...' ,
168+ filename : 'from-provider.pdf' ,
169+ } ,
170+ } ,
171+ ] ) ;
172+ } ) ;
173+
174+ test ( 'extractAllUserContent prefers content filename over providerData' , ( ) => {
175+ const userContent : protocol . UserMessageItem [ 'content' ] = [
176+ {
177+ type : 'input_file' ,
178+ file : 'data:application/pdf;base64,JVBER...' ,
179+ filename : 'content-filename.pdf' ,
180+ providerData : {
181+ filename : 'from-provider.pdf' ,
182+ } ,
183+ } ,
184+ ] ;
185+ const converted = extractAllUserContent ( userContent ) ;
186+ expect ( converted ) . toEqual ( [
187+ {
188+ type : 'file' ,
189+ file : {
190+ file_data : 'data:application/pdf;base64,JVBER...' ,
191+ filename : 'content-filename.pdf' ,
192+ } ,
193+ } ,
194+ ] ) ;
195+ } ) ;
196+
197+ test ( 'extractAllUserContent throws on unsupported file string format' , ( ) => {
198+ const userContent : protocol . UserMessageItem [ 'content' ] = [
199+ {
200+ type : 'input_file' ,
201+ file : 'not-a-valid-url-or-data' ,
202+ } ,
203+ ] ;
204+ expect ( ( ) => extractAllUserContent ( userContent ) ) . toThrow (
205+ / u s e a n o b j e c t w i t h t h e i d p r o p e r t y / ,
206+ ) ;
207+ } ) ;
208+
209+ test ( 'extractAllUserContent throws when file is missing' , ( ) => {
210+ const userContent : protocol . UserMessageItem [ 'content' ] = [
211+ {
212+ type : 'input_file' ,
213+ } ,
214+ ] ;
215+ expect ( ( ) => extractAllUserContent ( userContent ) ) . toThrow (
216+ / r e q u i r e s a d a t a U R L o r f i l e I D / ,
217+ ) ;
218+ } ) ;
219+
90220 test ( 'extractAllAssistantContent converts supported entries and ignores images/audio' , ( ) => {
91221 const assistantContent : protocol . AssistantMessageItem [ 'content' ] = [
92222 { type : 'output_text' , text : 'hi' , providerData : { b : 2 } } ,
0 commit comments