117 lines
3.4 KiB
TypeScript
117 lines
3.4 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import {
|
|
isImageGenerationModelDescriptor,
|
|
isStillImageGenerationModelDescriptor,
|
|
isVideoModelDescriptor,
|
|
} from "@/lib/ai/model-classification";
|
|
import { getStyleProModelAvailability } from "@/lib/style-pro/model-availability";
|
|
import type { AiProvider } from "@/lib/db/schema";
|
|
|
|
function styleProEntry(overrides?: {
|
|
providerType?: AiProvider["type"];
|
|
modelId?: string;
|
|
supportsVision?: boolean;
|
|
healthStatus?: "healthy" | "degraded" | "auto_disabled";
|
|
healthAutoDisabledAt?: Date | null;
|
|
healthObservationStartedAt?: Date | null;
|
|
}) {
|
|
return {
|
|
model: {
|
|
displayName: "Test Image Model",
|
|
modelId: overrides?.modelId || "test-image-model",
|
|
supportsVision: overrides?.supportsVision ?? true,
|
|
capabilities: null,
|
|
defaultParams: null,
|
|
isEnabled: true,
|
|
healthStatus: overrides?.healthStatus || "healthy",
|
|
healthAutoDisabledAt: overrides?.healthAutoDisabledAt || null,
|
|
healthObservationStartedAt:
|
|
overrides?.healthObservationStartedAt || null,
|
|
},
|
|
provider: {
|
|
type: overrides?.providerType || "openai-image",
|
|
},
|
|
};
|
|
}
|
|
|
|
test.describe("model classification", () => {
|
|
test("keeps multi-reference BananaImage models classified as image models", () => {
|
|
const descriptor = {
|
|
providerType: "bananaimage",
|
|
modelId: "gemini-3-pro-image-preview",
|
|
capabilities: {
|
|
supportedModes: [
|
|
"text-to-image",
|
|
"image-to-image",
|
|
"reference-images",
|
|
],
|
|
},
|
|
supportsImageGen: true,
|
|
};
|
|
|
|
expect(isVideoModelDescriptor(descriptor)).toBe(false);
|
|
expect(isImageGenerationModelDescriptor(descriptor)).toBe(true);
|
|
});
|
|
|
|
test("still recognizes explicit video generation modes", () => {
|
|
expect(
|
|
isVideoModelDescriptor({
|
|
providerType: "custom",
|
|
modelId: "custom-video-model",
|
|
capabilities: { supportedModes: ["text-to-video"] },
|
|
})
|
|
).toBe(true);
|
|
});
|
|
|
|
test("uses one image-only rule for canvas and Style Pro model pools", () => {
|
|
expect(
|
|
isStillImageGenerationModelDescriptor({
|
|
providerType: "ruxa-image",
|
|
modelId: "google/nano-banana-2",
|
|
supportsImageGen: true,
|
|
})
|
|
).toBe(true);
|
|
|
|
expect(
|
|
isStillImageGenerationModelDescriptor({
|
|
providerType: "ruxa-video",
|
|
modelId: "kling-video",
|
|
supportsImageGen: true,
|
|
})
|
|
).toBe(false);
|
|
});
|
|
|
|
test("prevents reference-incompatible models from being selected in Style Pro", () => {
|
|
const availability = getStyleProModelAvailability(
|
|
styleProEntry({ supportsVision: false })
|
|
);
|
|
|
|
expect(availability.selectable).toBe(false);
|
|
expect(availability.availabilityLabel).toBe("仅文生图");
|
|
});
|
|
|
|
test("temporarily disables degraded models in Style Pro", () => {
|
|
const availability = getStyleProModelAvailability(
|
|
styleProEntry({
|
|
healthStatus: "degraded",
|
|
healthObservationStartedAt: new Date(),
|
|
})
|
|
);
|
|
|
|
expect(availability.selectable).toBe(false);
|
|
expect(availability.availabilityLabel).toBe("暂不可用");
|
|
});
|
|
|
|
test("keeps known reference-capable BFL models selectable", () => {
|
|
const availability = getStyleProModelAvailability(
|
|
styleProEntry({
|
|
providerType: "bfl-image",
|
|
modelId: "flux-2-klein-4b",
|
|
supportsVision: false,
|
|
})
|
|
);
|
|
|
|
expect(availability.selectable).toBe(true);
|
|
});
|
|
});
|