package service import ( "fmt" "strings" "testing" ) func TestValidateImageTaskRejectsOversizedGrokPromptByUTF8Bytes(t *testing.T) { prompt := strings.Repeat("中", 4001) input := canvasGenerationInput{ Mode: "image", Prompt: prompt, Config: providerConfig{InterfaceType: "grok-image", Model: "grok-imagine-image-quality"}, } err := validateImageTask(DefaultImageCapabilityConfig("grok-image", "grok-imagine-image-quality"), input) if err == nil { t.Fatal("validateImageTask() error = nil") } wantBytes := fmt.Sprintf("%d UTF-8 字节", len(prompt)) if !strings.Contains(err.Error(), wantBytes) || !strings.Contains(err.Error(), "8000") || !strings.Contains(err.Error(), "连线文本") { t.Fatalf("validateImageTask() error = %q", err) } } func TestValidateImageTaskDoesNotApplyQualityPromptLimitToGrokLite(t *testing.T) { prompt := strings.Repeat("中", 4001) input := canvasGenerationInput{ Mode: "image", Prompt: prompt, Config: providerConfig{InterfaceType: "grok-image", Model: "grok-imagine-image"}, } if err := validateImageTask(DefaultImageCapabilityConfig("grok-image", "grok-imagine-image"), input); err != nil { t.Fatalf("validateImageTask() error = %q", err) } } func TestValidateImageTaskEnforcesGPTImage2CustomSizeLimits(t *testing.T) { profile := DefaultImageCapabilityConfig("openai-image", "gpt-image-2") profile.Size.AllowCustom = true valid := canvasGenerationInput{Mode: "image", Config: providerConfig{InterfaceType: "openai-image", Model: "gpt-image-2", Size: "3840x1920"}} if err := validateImageTask(profile, valid); err != nil { t.Fatalf("validateImageTask(valid) error = %v", err) } tests := map[string]string{ "4096x2048": "最长边", "3840x2161": "16 的倍数", "3840x1024": "宽高比", "640x640": "总像素", } for size, want := range tests { t.Run(size, func(t *testing.T) { input := canvasGenerationInput{Mode: "image", Config: providerConfig{InterfaceType: "openai-image", Model: "gpt-image-2", Size: size}} err := validateImageTask(profile, input) if err == nil || !strings.Contains(err.Error(), want) { t.Fatalf("validateImageTask(%s) error = %v, want %q", size, err, want) } }) } } func TestDefaultVideoCapabilityUsesProtocolSpecificResolutionTiers(t *testing.T) { tests := map[string][]string{ "newapi-channel-2": {"480p", "720p", "1080p", "1440p", "2160p"}, "volcengine-ark-video": {"480p", "720p", "1080p"}, "volcengine-jimeng-video": {"720p"}, "gemini-veo": {"720p", "1080p"}, } for protocol, want := range tests { t.Run(protocol, func(t *testing.T) { profile := DefaultModelCapabilityConfigForModel(protocol, "") if profile == nil || profile.Video == nil { t.Fatalf("DefaultModelCapabilityConfigForModel(%q) video profile = nil", protocol) } if fmt.Sprint(profile.Video.Resolutions) != fmt.Sprint(want) { t.Fatalf("resolutions = %v, want %v", profile.Video.Resolutions, want) } }) } } func TestNormalizeResolutionSupportsCommonAliases(t *testing.T) { tests := map[string]string{ "1440": "1440p", "1440p": "1440p", "2K": "1440p", "4K": "2160p", "768P": "768p", } for input, want := range tests { if got := normalizeResolution(input); got != want { t.Fatalf("normalizeResolution(%q) = %q, want %q", input, got, want) } } }