138 lines
4.0 KiB
Go
138 lines
4.0 KiB
Go
package questiontable
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type answerRewriterStub struct {
|
|
rewritten string
|
|
err error
|
|
}
|
|
|
|
func (s answerRewriterStub) Rewrite(ctx context.Context, content string) (string, error) {
|
|
return s.rewritten, s.err
|
|
}
|
|
|
|
func TestRunOnceRewritesAnswerBeforeInsert(t *testing.T) {
|
|
repo := newStubRepo()
|
|
inserter := newStubInserter()
|
|
inserter.recordID = "rec-rewrite-1"
|
|
repo.claimFn = func(ctx context.Context, limit int, maxAttempts int, staleBefore time.Time) ([]PendingExport, error) {
|
|
return []PendingExport{
|
|
{
|
|
ExportID: "exp-rewrite",
|
|
Row: Row{
|
|
Question: "机械臂如何学习使用呢",
|
|
Answer: "原始答案含[[3](#_Toc1)]和",
|
|
|
|
AskedTime: time.Now(),
|
|
AskerName: "张三",
|
|
AskerUnionID: "union-z",
|
|
TriggerPerson: "张三",
|
|
Department: "研发部",
|
|
Region: "华东",
|
|
QuestionImageURLs: []string{"https://weknora-api.example/i/001"},
|
|
},
|
|
Attempts: 0,
|
|
},
|
|
}, nil
|
|
}
|
|
rw := answerRewriterStub{rewritten: "转换后答案[3]", err: nil}
|
|
d, err := NewDispatcher(repo, inserter, &DispatcherOptions{Rewriter: rw})
|
|
if err != nil {
|
|
t.Fatalf("NewDispatcher: %v", err)
|
|
}
|
|
|
|
stats, err := d.RunOnce(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("RunOnce: %v", err)
|
|
}
|
|
if stats.Claimed != 1 || stats.Exported != 1 || stats.Failed != 0 {
|
|
t.Fatalf("stats=%+v", stats)
|
|
}
|
|
if len(inserter.rows) != 1 {
|
|
t.Fatalf("rows=%d, want 1", len(inserter.rows))
|
|
}
|
|
row := inserter.rows[0]
|
|
if row.Answer != "转换后答案[3]" {
|
|
t.Fatalf("Answer=%q, want rewritten", row.Answer)
|
|
}
|
|
}
|
|
|
|
func TestRunOnceRewriterErrorFallsBackToOriginalAnswer(t *testing.T) {
|
|
repo := newStubRepo()
|
|
inserter := newStubInserter()
|
|
inserter.recordID = "rec-fallback-1"
|
|
repo.claimFn = func(ctx context.Context, limit int, maxAttempts int, staleBefore time.Time) ([]PendingExport, error) {
|
|
return []PendingExport{
|
|
{
|
|
ExportID: "exp-fallback",
|
|
Row: Row{
|
|
Question: "问题",
|
|
Answer: "原始答案",
|
|
AskedTime: time.Now(),
|
|
},
|
|
Attempts: 0,
|
|
},
|
|
}, nil
|
|
}
|
|
rw := answerRewriterStub{rewritten: "", err: context.DeadlineExceeded}
|
|
d, err := NewDispatcher(repo, inserter, &DispatcherOptions{Rewriter: rw})
|
|
if err != nil {
|
|
t.Fatalf("NewDispatcher: %v", err)
|
|
}
|
|
|
|
stats, err := d.RunOnce(context.Background())
|
|
if err != nil {
|
|
t.Fatalf("RunOnce: %v", err)
|
|
}
|
|
if stats.Failed != 0 || stats.Exported != 1 {
|
|
t.Fatalf("stats=%+v", stats)
|
|
}
|
|
if len(inserter.rows) != 1 || inserter.rows[0].Answer != "原始答案" {
|
|
t.Fatalf("rows=%+v, want fallback original answer", inserter.rows)
|
|
}
|
|
}
|
|
|
|
func TestRowToFieldsIncludesQuestionImageURLsAndImageMarker(t *testing.T) {
|
|
r := Row{
|
|
Question: "请描述并分析这张图片。",
|
|
Answer: "回答了。",
|
|
AskedTime: time.Now(),
|
|
AskerName: "张三",
|
|
AskerUnionID: "union-z",
|
|
TriggerPerson: "张三",
|
|
Department: "研发部",
|
|
Region: "华东",
|
|
QuestionImageURLs: []string{
|
|
"https://weknora-api.example/i/001",
|
|
"https://weknora-api.example/i/002",
|
|
},
|
|
}
|
|
|
|
fields := r.ToFields()
|
|
|
|
original, ok := fields[FieldOriginalQuestion].(string)
|
|
if !ok {
|
|
t.Fatalf("OriginalQuestion type=%T", fields[FieldOriginalQuestion])
|
|
}
|
|
if !strings.HasPrefix(original, "[图片]") {
|
|
t.Fatalf("OriginalQuestion=%q, want [图片] prefix", original)
|
|
}
|
|
// Image URLs must be rendered as markdown image syntax so the Notable cell
|
|
// previews them (same as the answer column), not as a plain-text link.
|
|
if !strings.Contains(original, "") ||
|
|
!strings.Contains(original, "") {
|
|
t.Fatalf("OriginalQuestion=%q, missing markdown image syntax", original)
|
|
}
|
|
|
|
// Without image URLs, no [图片] prefix.
|
|
plain := Row{Question: "普通问题", AskedTime: time.Now()}
|
|
if got := plain.ToFields()[FieldOriginalQuestion]; got != "普通问题" {
|
|
t.Fatalf("plain OriginalQuestion=%q, want unchanged", got)
|
|
}
|
|
}
|