63 lines
3.1 KiB
Python
63 lines
3.1 KiB
Python
"""Dify attachment compatibility and per-outlet fault isolation regressions."""
|
|
import asyncio
|
|
import base64
|
|
import json
|
|
from unittest import TestCase
|
|
import httpx
|
|
import model_gateway as gw
|
|
from test_model_gateway import _client, _outlet
|
|
|
|
PNG = base64.b64encode(b'\x89PNG\r\n\x1a\nsynthetic').decode()
|
|
|
|
class DifyMediaAudit(TestCase):
|
|
def exercise(self, *, status=200, legacy=False, extra=None):
|
|
requests=[]
|
|
async def run():
|
|
def handler(request):
|
|
requests.append(request)
|
|
if request.url.path.endswith('/files/upload'):
|
|
return httpx.Response(status,json={'id':'synthetic-file'})
|
|
return httpx.Response(200,json={'answer':'synthetic-ok'})
|
|
messages=[{'role':'system','content':'系统测试'}, {'role':'user','content':[
|
|
{'type':'text','text':'图上写了什么?'},
|
|
{'type':'image_url','image_url':{'url':'data:image/png;base64,'+PNG}}]}]
|
|
if extra:messages[-1]['content'].append(extra)
|
|
async with _client(handler) as client:
|
|
outlet=_outlet(kind='dify')
|
|
result=await gw.call_outlet(client,outlet,messages,image_b64=PNG if legacy else '')
|
|
return result,outlet
|
|
result,outlet=asyncio.run(run())
|
|
return result,outlet,requests
|
|
|
|
def test_inline_image_uploaded_and_referenced_with_matching_user(self):
|
|
result,_,requests=self.exercise()
|
|
self.assertEqual(result['text'],'synthetic-ok')
|
|
self.assertEqual(len(requests),2)
|
|
self.assertTrue(requests[0].url.path.endswith('/files/upload'))
|
|
body=json.loads(requests[1].content)
|
|
self.assertEqual(body['files'][0]['upload_file_id'],'synthetic-file')
|
|
self.assertIn(('\r\n\r\n'+body['user']+'\r\n').encode(), requests[0].content)
|
|
self.assertNotIn(PNG,body['query'])
|
|
|
|
def test_legacy_and_inline_same_image_uploads_once(self):
|
|
_,_,requests=self.exercise(legacy=True)
|
|
self.assertEqual(sum(r.url.path.endswith('/files/upload') for r in requests),1)
|
|
|
|
def test_failed_upload_is_outlet_failure_not_uncaught_gateway_exception(self):
|
|
result,outlet,requests=self.exercise(status=400,legacy=True)
|
|
self.assertFalse(result['text'])
|
|
self.assertIn('400',result['error'])
|
|
self.assertEqual(outlet.breaker.failures,1)
|
|
self.assertEqual(len(requests),1)
|
|
|
|
def test_remote_image_url_is_forwarded_as_attachment_not_downloaded(self):
|
|
_,_,requests=self.exercise(extra={'type':'image_url','image_url':{'url':'https://images.example/test.jpg'}})
|
|
body=json.loads(requests[-1].content)
|
|
self.assertEqual(body['files'][1],{'type':'image','transfer_method':'remote_url','url':'https://images.example/test.jpg'})
|
|
|
|
def test_jpeg_attachment_keeps_mime_type(self):
|
|
_,_,requests=self.exercise(extra={'type':'image_url','image_url':{'url':'data:image/jpeg;base64,'+PNG}})
|
|
upload=[r for r in requests if r.url.path.endswith('/files/upload')]
|
|
self.assertEqual(len(upload),2)
|
|
self.assertIn(b'Content-Type: image/jpeg',upload[1].content)
|