fix(release): 正式版本 - 修复 SSRF 与 Quality checks,发布 v1.6.6.1

This commit is contained in:
ddcat666 committed 2026-10-13 12:55:30 +08:00
1 parent ede6cc1e70
commit ea6676f449
21 files changed
+1303 -338

No files matched your search

+13 -2
View File
@@ -1,7 +1,15 @@
import { describe, expect, test } from "bun:test";
import { defaultModelCapabilityConfig } from "../src/lib/model-capabilities";
import type { ModelProtocolDefinition } from "../src/lib/model-protocols";
import { changeChannelModelCapability, duplicateChannelModelValues, editorSectionForField, initialChannelModelValues, updateChannelModelUpstreamCapabilities, validateChannelModelPrices, validateChannelModelProtocol } from "../src/pages/admin/components/channel-model-editor-form";
import {
changeChannelModelCapability,
duplicateChannelModelValues,
editorSectionForField,
initialChannelModelValues,
updateChannelModelUpstreamCapabilities,
validateChannelModelPrices,
validateChannelModelProtocol,
} from "../src/pages/admin/components/channel-model-editor-form";
import { defaultPriceTier } from "../src/pages/admin/components/channel-model-price-tier-form";
import type { ChannelModel, ChannelModelPriceTier } from "../src/services/api/wallet";
@@ -84,7 +92,10 @@ describe("channel model editor drafts", () => {
capability: "video",
protocol: "video",
enabled: false,
priceTiers: [{ providerModelKey: "", unitPrice: 5 }, { providerModelKey: "vendor-video-hq", unitPrice: 8 }],
priceTiers: [
{ providerModelKey: "", unitPrice: 5 },
{ providerModelKey: "vendor-video-hq", unitPrice: 8 },
],
});
expect(draft.tags).not.toBe(item.tags);
});
+10 -3
View File
@@ -59,7 +59,10 @@ test("candidate rows do not disguise missing prices as zero", () => {
test("model rows preserve multiple promotional labels and colors without altering prices", () => {
const config = fixture();
config.channels[0].modelCosts![0].tags = [{ text: "限时特价", color: "purple" }, { text: "官方1折", color: "gold" }];
config.channels[0].modelCosts![0].tags = [
{ text: "限时特价", color: "purple" },
{ text: "官方1折", color: "gold" },
];
for (const theme of [canvasThemes.light, canvasThemes.dark]) {
const markup = renderToStaticMarkup(<ModelLabel config={config} model={config.model} capability="video" theme={theme} creationVariant showConfiguredModelName={false} showPrice showDescription />);
expect(markup).toContain('data-color="purple">限时特价');
@@ -68,7 +71,8 @@ test("model rows preserve multiple promotional labels and colors without alterin
}
config.channels[0].modelCosts![0].tags = [];
const markup = renderToStaticMarkup(<ModelLabel config={config} model={config.model} capability="video" theme={canvasThemes.light} showDescription />);
expect(markup).not.toContain('aria-label="模型标签"');
expect(markup).not.toContain("限时特价");
expect(markup).not.toContain("官方1折");
});
test("video capability tag is derived from limits and precedes editable model tags", () => {
@@ -76,7 +80,10 @@ test("video capability tag is derived from limits and precedes editable model ta
const cost = config.channels[0].modelCosts![0];
cost.capabilityConfig = defaultModelCapabilityConfig();
Object.assign(cost.capabilityConfig.video!.references, { maxImages: 30, maxVideos: 10, maxAudios: 10 });
cost.tags = [{ text: "限时特价", color: "purple" }, { text: "按次收费", color: "blue" }];
cost.tags = [
{ text: "限时特价", color: "purple" },
{ text: "按次收费", color: "blue" },
];
const markup = renderToStaticMarkup(<ModelLabel config={config} model={config.model} capability="video" theme={canvasThemes.light} creationVariant showConfiguredModelName={false} showPrice showDescription />);
+1 -1
View File
@@ -1,6 +1,6 @@
import { expect, test } from "bun:test";
import { defaultFeatureAvailability } from "./use-user-store";
import { defaultFeatureAvailability } from "../src/stores/use-user-store";
test("new workbench entries stay closed until the backend explicitly opens them", () => {
expect(defaultFeatureAvailability.imageWorkbenchEnabled).toBe(false);
+1 -1
View File
@@ -1,6 +1,6 @@
import { describe, expect, test } from "bun:test";
import { filterWorkbenchTools, workbenchTaskSnapshot } from "./image-workbench-page";
import { filterWorkbenchTools, workbenchTaskSnapshot } from "../src/pages/workbench/image-workbench-page";
import type { GenerationTask } from "@/services/api/task-center";
import type { WorkbenchTool } from "@/services/api/workbench";
+4 -5
View File
@@ -39,7 +39,7 @@ describe("workspace route loading", () => {
expect(router).toContain('{ path: "/create", element: deferred(<CreatePage />) }');
expect(router).toContain("<RequireAuth allowAnonymous={isGuestWorkspacePath(pathname)}>");
expect(router).toContain('{ path: "/assets", element: <RequireAuth>{deferred(<AssetsPage />)}</RequireAuth> }');
expect(router).toContain('{ path: "/canvas/:id", element: <RequireAuth><CanvasProjectPage /></RequireAuth> }');
expect(router).toMatch(/path: "\/canvas\/:id",\s+element: \(\s+<RequireAuth>\s+<CanvasProjectPage \/>\s+<\/RequireAuth>\s+\),/);
expect(router).not.toContain('path: "/home"');
expect(router).not.toContain("HomePage");
expect(navigation).toContain('{ ...toolItem("create", "/"), id: "home", title: "创作" }');
@@ -77,7 +77,6 @@ describe("workspace route loading", () => {
expect(detail).toContain("新建画布");
});
test("keeps project asset refresh scoped to the latest user and project", () => {
const editor = source("../src/pages/projects/detail/editor.tsx");
@@ -108,7 +107,7 @@ describe("workspace route loading", () => {
expect(projectDetail).toContain('import("@/services/user-data-sync")');
expect(projectDetail).not.toContain('import { createCanvasProjectWithRemoteSync } from "@/services/user-data-sync"');
expect(workflow).not.toContain('from "@/lib/video-poster"');
expect(workflow).toContain('if (playing) return <video');
expect(workflow).toContain("if (playing) return <video");
});
test("uses a quiet workspace skeleton for initial hydration", () => {
@@ -141,9 +140,9 @@ describe("workspace wallet entry", () => {
expect(router).not.toContain("WalletPage");
expect(router).not.toContain("loadWalletPage");
expect(modules).not.toContain("pages/wallet");
expect(host).toContain("pathname !== \"/wallet\"");
expect(host).toContain('pathname !== "/wallet"');
expect(host).toContain("openWorkspaceWallet");
expect(palette).toContain('run: () => openWorkspaceWallet()');
expect(palette).toContain("run: () => openWorkspaceWallet()");
expect(palette).not.toContain('"/wallet"');
expect(canvasTopBar).toContain("openWorkspaceWallet()");
expect(canvasTopBar).not.toContain('to="/wallet"');