fix(*): 画布生成与邮件 - 合并 PR #423 并修复恢复关联和规格报价

保留 PR 原始提交,合并待测试文档双方内容。补齐摘要 nodeId 消费端,修复缺省质量的 <nil> 匹配,并移除报价面板按价格档篡改自动质量的行为。

验证:前端完整测试脚本 1139 项通过,生产构建通过;后端相关专项通过。全量后端存在 4 项基线可复现失败;另一次资源清理测试出现 SQLite 表锁,合并分支与基线单独重跑通过。未执行真实 SMTP、浏览器端到端或收费生成。
This commit is contained in:
ddCat committed 2026-09-06 04:44:16 +08:00
commit 8f4e2fca33
16 files changed
+441 -34

No files matched your search

@@ -61,6 +61,37 @@ func TestTaskClientContextRequiresCreatePageMetadata(t *testing.T) {
}
}
func TestTaskClientContextPreservesCanvasNodeID(t *testing.T) {
context := taskClientContext(`{"mode":"image","metadata":{"nodeId":"canvas-node-1","source":"canvas"}}`)
if context == nil || context.NodeID != "canvas-node-1" {
t.Fatalf("canvas node context was not preserved: %+v", context)
}
}
func TestTaskSummaryPreservesCanvasNodeWithoutExposingInput(t *testing.T) {
summary := taskSummaryForOutput(model.Task{
ID: "task-1", ProjectID: "project-1", Type: "canvas_image",
InputJSON: `{"metadata":{"nodeId":"node-1"},"config":{"apiKey":"private-test-value"}}`,
})
encoded, err := json.Marshal(summary)
if err != nil {
t.Fatal(err)
}
var output map[string]any
if err := json.Unmarshal(encoded, &output); err != nil {
t.Fatal(err)
}
context, ok := output["clientContext"].(map[string]any)
if !ok || context["nodeId"] != "node-1" || len(context) != 1 {
t.Fatalf("summary lost safe canvas association: %#v", output)
}
for _, key := range []string{"inputJson", "config", "apiKey"} {
if _, exists := output[key]; exists {
t.Fatalf("summary leaked %s", key)
}
}
}
func TestTaskClientContextProjectsChapterOperations(t *testing.T) {
characters := taskClientContext(`{"metadata":{"domainProjectId":"project-1","chapterId":"chapter-1","operation":"chapter_character_breakdown"}}`)
if characters == nil || characters.DomainProjectID != "project-1" || characters.ChapterID != "chapter-1" || characters.ChapterOperation != "characters" {