@@ -152,6 +152,43 @@ def test_generate_images_openai_with_url_response(self):
152152 "https://cdn.example.com/generated/abc.png?sig=1" ,
153153 )
154154
155+ def test_generate_images_openai_skips_b64_json_with_invalid_image (self ):
156+ """
157+ 兼容层返回 200 但 body 不是可解码图片(如伪装成 JSON 的 HTML 错误页)
158+ 时,必须按素材源约定返回空列表让上层跳过该关键词,而不是让解码
159+ 异常中断整个任务。
160+ """
161+ fake_content = b"<html><body>gateway degraded</body></html>"
162+ response = _image_response (
163+ {"data" : [{"b64_json" : base64 .b64encode (fake_content ).decode ("ascii" )}]}
164+ )
165+
166+ with patch ("app.services.material.requests.post" , return_value = response ):
167+ results = material .generate_images_openai (
168+ "sunrise over mountains" , minimum_duration = 5 , save_dir = self .save_dir
169+ )
170+
171+ self .assertEqual (results , [])
172+ self .assertEqual (os .listdir (self .save_dir ), [])
173+
174+ def test_generate_images_openai_skips_url_download_with_invalid_content (self ):
175+ """临时 URL 下载到 200 的非图片内容时同样走跳过路径。"""
176+ response = _image_response (
177+ {"data" : [{"url" : "https://cdn.example.com/generated/abc.png?sig=1" }]}
178+ )
179+ download = _download_response (b"\x89 PNG\r \n \x1a \n not-really-a-png" )
180+
181+ with (
182+ patch ("app.services.material.requests.post" , return_value = response ),
183+ patch ("app.services.material.requests.get" , return_value = download ),
184+ ):
185+ results = material .generate_images_openai (
186+ "city at night" , minimum_duration = 3 , save_dir = self .save_dir
187+ )
188+
189+ self .assertEqual (results , [])
190+ self .assertEqual (os .listdir (self .save_dir ), [])
191+
155192 # ------------------------------------------------------------------
156193 # 退避重试与 key 轮换
157194 # ------------------------------------------------------------------
0 commit comments