You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
4.0 KiB
134 lines
4.0 KiB
import { describe, expect, it } from "vitest";
|
|
import {
|
|
buildPopiserverPriceQuoteRequest,
|
|
getQuotedPointAmount,
|
|
} from "@/utils/composerPricing";
|
|
import type { SelectedModel } from "@/types";
|
|
import type { GenerationNodeConfig } from "@/utils/generationConfig";
|
|
import type { ComposerPricingContext } from "@/utils/composerPricingContext";
|
|
|
|
function model(overrides: Partial<SelectedModel> = {}): SelectedModel {
|
|
return {
|
|
provider: "popiserver",
|
|
modelId: "popi-image",
|
|
displayName: "Popi Image",
|
|
capabilities: ["text-to-image"],
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function draft(overrides: Partial<GenerationNodeConfig> = {}): GenerationNodeConfig {
|
|
return {
|
|
prompt: "prompt",
|
|
selectedModel: model(),
|
|
inputImages: [],
|
|
imageCount: 1,
|
|
referenceSubjectList: [],
|
|
parameters: {},
|
|
extraTaskParams: {},
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function context(overrides: Partial<ComposerPricingContext> & { config?: GenerationNodeConfig } = {}): ComposerPricingContext {
|
|
return {
|
|
config: overrides.config ?? draft(),
|
|
capability: overrides.capability ?? "image",
|
|
media: overrides.media ?? {},
|
|
inputVideoDurationSeconds: overrides.inputVideoDurationSeconds ?? 0,
|
|
};
|
|
}
|
|
|
|
describe("composerPricing", () => {
|
|
it("builds PopiServer estimate payloads with provider model aliases", () => {
|
|
const request = buildPopiserverPriceQuoteRequest(context({
|
|
inputVideoDurationSeconds: 12,
|
|
config: draft({
|
|
selectedModel: model({
|
|
modelId: "123",
|
|
displayName: "Token billed video",
|
|
billingMethod: 2,
|
|
aiModelCode: "video-code",
|
|
aiModelCodeAlias: "video-alias",
|
|
}),
|
|
parameters: { duration: 8 },
|
|
}),
|
|
}));
|
|
|
|
expect(request).toEqual({
|
|
source: "estimate",
|
|
payload: {
|
|
model_name: "video-alias",
|
|
estimation_type: "auto",
|
|
parameters: {
|
|
duration: 8,
|
|
inputPrompt: "prompt",
|
|
input_video_duration_seconds: 12,
|
|
},
|
|
imageCount: 1,
|
|
input_video_duration_seconds: 12,
|
|
},
|
|
});
|
|
});
|
|
|
|
it("skips task price quote requests for llm and Seedance estimates", () => {
|
|
expect(buildPopiserverPriceQuoteRequest(context({
|
|
capability: "llm",
|
|
config: draft(),
|
|
}))).toBeNull();
|
|
expect(buildPopiserverPriceQuoteRequest(context({
|
|
capability: "video",
|
|
config: draft({
|
|
selectedModel: model({ displayName: "Seedance" }),
|
|
}),
|
|
}))).toMatchObject({ source: "estimate" });
|
|
});
|
|
|
|
it("uses PopiServer estimate only for billingMethod 2 or Seedance models", () => {
|
|
expect(buildPopiserverPriceQuoteRequest(context({ config: draft({
|
|
selectedModel: model({ billingMethod: 2 }),
|
|
}) }))).toMatchObject({ source: "estimate" });
|
|
expect(buildPopiserverPriceQuoteRequest(context({ config: draft({
|
|
selectedModel: model({
|
|
billingMethod: 1,
|
|
aiModelId: 32,
|
|
aiModelCode: "image-code",
|
|
type: 1,
|
|
subType: 101,
|
|
}),
|
|
}) }))).toMatchObject({ source: "task-price" });
|
|
expect(buildPopiserverPriceQuoteRequest(context({
|
|
capability: "video",
|
|
config: draft({
|
|
selectedModel: model({
|
|
displayName: "Seedance Pro",
|
|
billingMethod: 1,
|
|
}),
|
|
}),
|
|
}))).toMatchObject({ source: "estimate" });
|
|
});
|
|
|
|
it("builds unified PopiServer quote requests", () => {
|
|
const estimateContext = context({ config: draft({
|
|
selectedModel: model({ billingMethod: 2 }),
|
|
}) });
|
|
|
|
expect(buildPopiserverPriceQuoteRequest(estimateContext)).toMatchObject({
|
|
source: "estimate",
|
|
payload: {
|
|
estimation_type: "auto",
|
|
},
|
|
});
|
|
expect(buildPopiserverPriceQuoteRequest(context({ config: draft({
|
|
selectedModel: model({
|
|
billingMethod: 1,
|
|
aiModelId: 32,
|
|
}),
|
|
}) }))).toMatchObject({
|
|
source: "task-price",
|
|
});
|
|
expect(buildPopiserverPriceQuoteRequest(context())).toBeNull();
|
|
expect(getQuotedPointAmount({ data: { points: "36" } })).toBe(36);
|
|
expect(getQuotedPointAmount({ data: { points: "bad" } })).toBeNull();
|
|
});
|
|
});
|
|
|