package clients import ( "context" "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "github.com/easyai/easyai-ai-gateway/apps/api/internal/store" ) func TestKelingOmniPayloadPreservesCompatibleSettings(t *testing.T) { payload, cleanupIDs, err := (KelingClient{}).kelingOmniPayload(context.Background(), Request{ Kind: "videos.generations", ModelType: "omni_video", Body: map[string]any{ "prompt": "A product reveal", "duration": 3, "resolution": "720p", "aspect_ratio": "16:9", "audio": false, "watermark_info": map[string]any{"enabled": true}, "external_task_id": "external-1", }, Candidate: store.RuntimeModelCandidate{ Provider: "keling", ProviderModelName: "kling-video-o1", Capabilities: map[string]any{"omni_video": map[string]any{}}, }, }, "token") if err != nil { t.Fatalf("build compatible Omni payload: %v", err) } if len(cleanupIDs) != 0 || payload["model_name"] != "kling-video-o1" || payload["mode"] != "std" || payload["sound"] != "off" || payload["duration"] != "3" || payload["aspect_ratio"] != "16:9" || payload["external_task_id"] != "external-1" { t.Fatalf("unexpected compatible Omni payload: %+v", payload) } watermark, _ := payload["watermark_info"].(map[string]any) if watermark["enabled"] != true { t.Fatalf("watermark setting was not preserved: %+v", payload) } } func TestKelingOmniUpstreamModelNameSeparatesGatewayAliases(t *testing.T) { tests := map[string]string{ "kling-o1": "kling-video-o1", "kling-video-o1": "kling-video-o1", "kling-3.0-omni": "kling-v3-omni", "kling-v3-omni": "kling-v3-omni", } for configured, want := range tests { got := kelingOmniUpstreamModelName(store.RuntimeModelCandidate{ProviderModelName: configured}) if got != want { t.Fatalf("configured=%s got=%s want=%s", configured, got, want) } } } func TestKelingOmniRejectsGeneratedAudioForO1(t *testing.T) { _, _, err := (KelingClient{}).kelingOmniPayload(context.Background(), Request{ Body: map[string]any{ "prompt": "A beach", "duration": 5, "resolution": "1080p", "aspect_ratio": "9:16", "audio": true, }, Candidate: store.RuntimeModelCandidate{ProviderModelName: "kling-video-o1"}, }, "token") if err == nil || ErrorCode(err) != "invalid_parameter" { t.Fatalf("expected generated-audio rejection for O1, got %v", err) } } func TestKelingOmniResumeReturnsUpstreamFailureCodeAndModel(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet || r.URL.Path != "/videos/omni-video/remote-failed" { t.Fatalf("unexpected request %s %s", r.Method, r.URL.Path) } if r.Header.Get("Authorization") != "Bearer upstream-key" { t.Fatalf("unexpected Authorization header: %q", r.Header.Get("Authorization")) } _ = json.NewEncoder(w).Encode(map[string]any{ "code": 0, "request_id": "failure-request", "data": map[string]any{ "task_id": "remote-failed", "task_status": "failed", "task_status_msg": "content policy rejection", }, }) })) defer server.Close() _, err := (KelingClient{HTTPClient: server.Client()}).Run(context.Background(), Request{ Kind: "videos.generations", ModelType: "omni_video", RemoteTaskID: "remote-failed", RemoteTaskPayload: map[string]any{"endpoint": "/videos/omni-video"}, Candidate: store.RuntimeModelCandidate{ BaseURL: server.URL, Provider: "keling", ProviderModelName: "kling-v3-omni", Credentials: map[string]any{"apiKey": "upstream-key"}, PlatformConfig: map[string]any{ "kelingPollIntervalMs": 10, "kelingPollTimeoutSeconds": 1, }, }, }) if err == nil || ErrorCode(err) != "keling_task_failed" || !strings.Contains(err.Error(), "content policy rejection") { t.Fatalf("expected preserved Keling task failure, got code=%q err=%v", ErrorCode(err), err) } } func TestKelingOmniPayloadPreservesIntelligentMultiShot(t *testing.T) { payload, _, err := (KelingClient{}).kelingOmniPayload(context.Background(), Request{ Kind: "videos.generations", ModelType: "omni_video", Body: map[string]any{ "prompt": "Create three coherent shots", "duration": 5, "resolution": "1080p", "aspect_ratio": "9:16", "multi_shot": true, "shot_type": "intelligence", }, Candidate: store.RuntimeModelCandidate{ ProviderModelName: "kling-v3-omni", Capabilities: map[string]any{"omni_video": map[string]any{}}, }, }, "token") if err != nil { t.Fatalf("build intelligent multi-shot payload: %v", err) } if payload["multi_shot"] != true || payload["shot_type"] != "intelligence" || payload["prompt"] != "Create three coherent shots" { t.Fatalf("unexpected intelligent multi-shot payload: %+v", payload) } } func TestKelingVideoSuccessResultPreservesOfficialVideoMetadata(t *testing.T) { result := kelingVideoSuccessResult(Request{Candidate: store.RuntimeModelCandidate{ProviderModelName: "kling-video-o1"}}, "remote-1", map[string]any{ "data": map[string]any{ "task_result": map[string]any{ "videos": []any{map[string]any{ "id": "video-1", "url": "https://example.com/video.mp4", "watermark_url": "https://example.com/watermarked.mp4", "duration": "3", }}, }, }, }) data, _ := result["data"].([]any) video, _ := data[0].(map[string]any) if video["id"] != "video-1" || video["watermark_url"] != "https://example.com/watermarked.mp4" || video["duration"] != "3" { t.Fatalf("official video metadata was lost: %+v", video) } }