fix(media): 对齐 EasyAI 媒体响应与转存策略
统一媒体异步提交和轮询响应,扩展 /ai/result 到当前用户的 Gateway 媒体任务,并保持既有 Gateway 字段兼容。\n\n启用转存但无可用渠道时回退到 24 小时本地静态资源;关闭转存时保留图片、音频等上游 Base64 字段。同步更新文件上传兼容结构、OpenAPI、管理端说明和回归测试。\n\n验证:cd apps/api && env -u AI_GATEWAY_TEST_DATABASE_URL go test ./... -count=1;gofmt -l 无输出;pnpm nx run web:typecheck。
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
package httpapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
|
||||
)
|
||||
|
||||
func TestOptionalTaskIdempotencyKeyRejectsMultipleValues(t *testing.T) {
|
||||
@@ -29,3 +33,29 @@ func TestTaskIdempotencyRequestHashIsCanonical(t *testing.T) {
|
||||
t.Fatal("async response semantics must be part of the request hash")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteIdempotentAsyncTaskReplayKeepsEasyAICompatibilityFields(t *testing.T) {
|
||||
t.Parallel()
|
||||
task := store.GatewayTask{
|
||||
ID: "async-replay-1",
|
||||
Kind: "images.generations",
|
||||
Status: "queued",
|
||||
AsyncMode: true,
|
||||
}
|
||||
recorder := httptest.NewRecorder()
|
||||
|
||||
writeIdempotentTaskReplay(recorder, task, true)
|
||||
|
||||
if recorder.Code != http.StatusAccepted ||
|
||||
recorder.Header().Get("Idempotent-Replayed") != "true" ||
|
||||
recorder.Header().Get("X-Gateway-Task-Id") != task.ID {
|
||||
t.Fatalf("unexpected replay status/headers: code=%d headers=%v", recorder.Code, recorder.Header())
|
||||
}
|
||||
var got map[string]any
|
||||
if err := json.NewDecoder(recorder.Body).Decode(&got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got["status"] != "submitted" || got["task_id"] != task.ID || got["taskId"] != task.ID {
|
||||
t.Fatalf("unexpected replay body: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user