Files
xinmi/internal/workbench/quality_settings_test.go
T
yawan f7fc992f57
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
2026-09-22 16:19:06 +08:00

73 lines
3.4 KiB
Go

package workbench
import (
"errors"
"reflect"
"strings"
"testing"
)
func TestQualitySettingsInvalidateApprovalWithoutChangingAcceptedText(t *testing.T) {
s, ctx, job, _ := generationHarness(t)
job.Action = "review-settings"
before := TaskData{Segments: []Segment{{ID: "a", Status: "accepted", Content: "原文\n必须保留。"}}, Review: "旧报告", Composed: "旧成稿", Quality: &QualityReport{Passed: true}}
r := &Resource{Kind: "content-tasks", Status: "needs_configuration", Data: asJSON(before)}
settings := &QualitySettings{Rules: "观点不能互相矛盾", Style: "面向初学者"}
if err := s.executeTask(ctx, job, r, ActionRequest{QualitySettings: settings}); err != nil {
t.Fatal(err)
}
after, _ := decode[TaskData](r.Data)
if after.QualitySettings != *settings || !reflect.DeepEqual(after.Segments, before.Segments) || after.Quality != nil || after.Review != "" || after.Composed != "" {
t.Fatalf("settings must invalidate old results while preserving originals: %+v", after)
}
if err := applyManualUpdate(r, resourceRequest{Name: r.Name, Data: asJSON(before)}); !errors.Is(err, ErrInvalid) {
t.Fatalf("manual update bypassed review-settings action: %v", err)
}
}
func TestReviewUsesSavedCriteriaAndBindsApprovalToTheirVersion(t *testing.T) {
s, ctx, job, model := generationHarness(t)
job.Action = "review"
model.output = `{"passed":true,"summary":"已检查指定要求","issues":[]}`
d := TaskData{AgentID: "author", QualitySettings: QualitySettings{Rules: "EXACT_CRITERIA", Style: "EXACT_STYLE"}, Segments: []Segment{{ID: "a", Status: "accepted", Content: "已采用正文"}}}
r := &Resource{Kind: "content-tasks", Data: asJSON(d)}
if err := s.executeTask(ctx, job, r, ActionRequest{}); err != nil {
t.Fatal(err)
}
after, _ := decode[TaskData](r.Data)
if len(model.messages) != 2 || !strings.Contains(model.messages[1].Content, "EXACT_CRITERIA") || !strings.Contains(model.messages[1].Content, "EXACT_STYLE") || after.Quality.SettingsHash != d.QualitySettings.hash() {
t.Fatal("review did not use or record current rules and style")
}
accepted, _ := acceptedManuscript(after)
if err := requireQuality(after, accepted); err != nil {
t.Fatal(err)
}
after.QualitySettings.Style = "new style"
if !errors.Is(requireQuality(after, accepted), ErrInvalid) {
t.Fatal("stale review accepted after criteria changed")
}
}
func TestCompositionPreservesShortAndLongTextWithoutDependencies(t *testing.T) {
for _, count := range []int{1, 5000} {
s, ctx, job, _ := generationHarness(t)
job.Action = "compose"
s.models, s.agents, s.knowledgeBases = nil, nil, nil
d := TaskData{FlowID: "deleted-flow", AgentID: "deleted-agent", Segments: []Segment{
{ID: "a", Title: "不得添加的标题", Status: "accepted", Content: " " + strings.Repeat("第一段。\n", count)},
{ID: "skip", Status: "skipped", Content: "跳过的正文"},
{ID: "c", Status: "accepted", Content: "下一段。 "},
}}
accepted, _ := acceptedManuscript(d)
d.Quality = &QualityReport{Passed: true, ManuscriptHash: manuscriptHash(accepted)}
r := &Resource{Kind: "content-tasks", Status: "needs_configuration", Data: asJSON(d)}
if err := s.executeTask(ctx, job, r, ActionRequest{}); err != nil {
t.Fatal(err)
}
after, _ := decode[TaskData](r.Data)
if after.Composed != d.Segments[0].Content+"\n\n"+d.Segments[2].Content || r.Status != "completed" {
t.Fatal("composition changed accepted text or canvas order")
}
}
}