@@ -250,41 +250,103 @@ describe("bot/handlers/document", () => {
250250 } ) ;
251251 } ) ;
252252
253- describe ( "unsupported file types " , ( ) => {
254- it ( "ignores unsupported MIME types silently " , async ( ) => {
253+ describe ( "image files " , ( ) => {
254+ it ( "downloads and sends image documents when model supports images " , async ( ) => {
255255 const { ctx, replyMock } = createDocumentContext ( {
256256 document : {
257- file_id : "zip -file-id" ,
258- file_unique_id : "zip -unique-id" ,
259- file_name : "archive.zip " ,
260- mime_type : "application/zip " ,
257+ file_id : "image -file-id" ,
258+ file_unique_id : "image -unique-id" ,
259+ file_name : "photo.png " ,
260+ mime_type : "image/png " ,
261261 file_size : 5000 ,
262262 } ,
263+ caption : "Describe this image" ,
263264 } ) ;
264265 const { deps, processPromptMock, downloadMock } = createDocumentDeps ( ) ;
265266
266267 await handleDocumentMessage ( ctx , deps ) ;
267268
268- expect ( replyMock ) . not . toHaveBeenCalled ( ) ;
269+ expect ( replyMock ) . toHaveBeenCalledWith ( t ( "bot.file_downloading" ) ) ;
270+ expect ( downloadMock ) . toHaveBeenCalled ( ) ;
271+ expect ( processPromptMock ) . toHaveBeenCalledWith (
272+ ctx ,
273+ "Describe this image" ,
274+ deps ,
275+ expect . arrayContaining ( [
276+ expect . objectContaining ( {
277+ type : "file" ,
278+ mime : "image/png" ,
279+ filename : "photo.png" ,
280+ url : expect . stringMatching ( / ^ d a t a : i m a g e \/ p n g ; b a s e 6 4 , / ) ,
281+ } ) ,
282+ ] ) ,
283+ ) ;
284+ } ) ;
285+
286+ it ( "shows error when model does not support images" , async ( ) => {
287+ const { ctx, replyMock } = createDocumentContext ( {
288+ document : {
289+ file_id : "image-file-id" ,
290+ file_unique_id : "image-unique-id" ,
291+ file_name : "photo.png" ,
292+ mime_type : "image/png" ,
293+ file_size : 5000 ,
294+ } ,
295+ } ) ;
296+ const { deps, processPromptMock, downloadMock } = createDocumentDeps ( {
297+ getModelCapabilities : vi . fn ( ) . mockResolvedValue ( {
298+ input : { image : false } ,
299+ } ) ,
300+ } ) ;
301+
302+ await handleDocumentMessage ( ctx , deps ) ;
303+
304+ expect ( replyMock ) . toHaveBeenCalledWith ( t ( "bot.photo_model_no_image" ) ) ;
269305 expect ( downloadMock ) . not . toHaveBeenCalled ( ) ;
270306 expect ( processPromptMock ) . not . toHaveBeenCalled ( ) ;
271307 } ) ;
272308
273- it ( "ignores image files " , async ( ) => {
274- const { ctx, replyMock } = createDocumentContext ( {
309+ it ( "sends caption-only when model does not support images but caption exists " , async ( ) => {
310+ const { ctx } = createDocumentContext ( {
275311 document : {
276312 file_id : "image-file-id" ,
277313 file_unique_id : "image-unique-id" ,
278314 file_name : "photo.png" ,
279315 mime_type : "image/png" ,
280316 file_size : 5000 ,
281317 } ,
318+ caption : "Describe this image" ,
319+ } ) ;
320+ const { deps, processPromptMock, downloadMock } = createDocumentDeps ( {
321+ getModelCapabilities : vi . fn ( ) . mockResolvedValue ( {
322+ input : { image : false } ,
323+ } ) ,
282324 } ) ;
283- const { deps, processPromptMock } = createDocumentDeps ( ) ;
284325
285326 await handleDocumentMessage ( ctx , deps ) ;
286327
287- expect ( replyMock ) . not . toHaveBeenCalled ( ) ;
328+ expect ( downloadMock ) . not . toHaveBeenCalled ( ) ;
329+ expect ( processPromptMock ) . toHaveBeenCalledWith ( ctx , "Describe this image" , deps ) ;
330+ } ) ;
331+ } ) ;
332+
333+ describe ( "unsupported file types" , ( ) => {
334+ it ( "shows error for unsupported MIME types" , async ( ) => {
335+ const { ctx, replyMock } = createDocumentContext ( {
336+ document : {
337+ file_id : "zip-file-id" ,
338+ file_unique_id : "zip-unique-id" ,
339+ file_name : "archive.zip" ,
340+ mime_type : "application/zip" ,
341+ file_size : 5000 ,
342+ } ,
343+ } ) ;
344+ const { deps, processPromptMock, downloadMock } = createDocumentDeps ( ) ;
345+
346+ await handleDocumentMessage ( ctx , deps ) ;
347+
348+ expect ( replyMock ) . toHaveBeenCalledWith ( t ( "bot.file_type_unsupported" ) ) ;
349+ expect ( downloadMock ) . not . toHaveBeenCalled ( ) ;
288350 expect ( processPromptMock ) . not . toHaveBeenCalled ( ) ;
289351 } ) ;
290352 } ) ;
0 commit comments