feat: harden support, localize knowledge and add operator availability [skip ci]
Source-only publication of reviewed commit 64e96a7f423673dc29ad56485be9fc79bce8af1c.
Passed in isolation: focused frontend/backend tests, race checks, TypeScript typecheck, lint, Go compilation, Flowgram build, and deterministic SDK build/tests.
Not accepted as a production release: Next.js export/native assembly remains blocked by environment memory limits; browser interaction and MySQL staging acceptance remain unverified. No production server, database/schema, runtime configuration, deployment, release tag, or workflow execution was performed.
Expected source tree: 0a4a7528e9.
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
// Modified in the independent AgentDesk fork: localized knowledge workflows and safe display errors.
|
||||
package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"agent-desk/internal/models"
|
||||
@@ -18,7 +20,7 @@ import (
|
||||
)
|
||||
|
||||
func TestKnowledgeFAQExcelTemplateContainsExpectedHeaders(t *testing.T) {
|
||||
file, err := KnowledgeFAQService.BuildKnowledgeFAQImportTemplate()
|
||||
file, err := KnowledgeFAQService.BuildKnowledgeFAQImportTemplate("zh-CN")
|
||||
if err != nil {
|
||||
t.Fatalf("BuildKnowledgeFAQImportTemplate() error = %v", err)
|
||||
}
|
||||
@@ -247,3 +249,82 @@ func stubKnowledgeFAQImportIndex(t *testing.T) func() {
|
||||
indexKnowledgeFAQAfterImport = original
|
||||
}
|
||||
}
|
||||
|
||||
func TestKnowledgeFAQExcelLocalizedTemplatesRoundTrip(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
locale string
|
||||
headers []string
|
||||
question string
|
||||
}{
|
||||
{"en-US", []string{"Primary question", "Answer", "Similar questions", "Notes"}, "How do I reset my password?"},
|
||||
{"ru-RU", []string{"Основной вопрос", "Ответ", "Похожие вопросы", "Примечания"}, "Как сбросить пароль?"},
|
||||
{"zh-CN", []string{"标准问题", "答案", "相似问", "备注"}, "如何重置密码?"},
|
||||
} {
|
||||
t.Run(tc.locale, func(t *testing.T) {
|
||||
file, err := KnowledgeFAQService.BuildKnowledgeFAQImportTemplate(tc.locale)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
workbook, err := excelize.OpenReader(bytes.NewReader(file.Data))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer workbook.Close()
|
||||
table, err := workbook.GetRows("FAQ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(table[0], tc.headers) || table[1][0] != tc.question {
|
||||
t.Fatalf("wrong template: %#v", table)
|
||||
}
|
||||
rows, result, err := parseKnowledgeFAQImportRows(bytes.NewReader(file.Data), tc.locale)
|
||||
if err != nil || result.Failed != 0 || len(rows) != 1 || rows[0].Question != tc.question {
|
||||
t.Fatalf("round trip = %+v, %+v, %v", rows, result, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestKnowledgeFAQExcelImportAcceptsLegacyAndRussianHeaders(t *testing.T) {
|
||||
for _, headers := range [][]string{
|
||||
{"question", "answer", "similarQuestions", "remark"},
|
||||
{"标准问题", "答案", "相似问", "备注"},
|
||||
{"\ufeffОсновной вопрос", "ОТВЕТ", "Похожие вопросы", "Примечания"},
|
||||
{"Вопрос", "Ответ"},
|
||||
} {
|
||||
question, answer := " Author question 原文 ", "\n Answer 回答:原文\nnext "
|
||||
data := buildKnowledgeFAQExcelWorkbook(t, [][]string{headers, {question, answer}})
|
||||
rows, result, err := parseKnowledgeFAQImportRows(bytes.NewReader(data), "ru-RU")
|
||||
if err != nil || result.Failed != 0 || len(rows) != 1 {
|
||||
t.Fatalf("parse %v = %+v, %v", headers, result, err)
|
||||
}
|
||||
if rows[0].Question != question || rows[0].Answer != answer {
|
||||
t.Fatalf("authored data modified: %+v", rows[0])
|
||||
}
|
||||
if len(rows[0].SimilarQuestions) != 0 || rows[0].Remark != "" {
|
||||
t.Fatalf("missing optional columns copied question: %+v", rows[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestKnowledgeFAQExcelLocalizedExportPreservesRows(t *testing.T) {
|
||||
setupKnowledgeFAQExcelTestDB(t)
|
||||
kb := createKnowledgeFAQExcelTestBase(t, enums.StatusOk)
|
||||
item := &models.KnowledgeFAQ{KnowledgeBaseID: kb.ID, Question: " Original 问题 ", Answer: "\nОтвет <tag>原文</tag> ", SimilarQuestions: `[" same question ","相似问"]`, Remark: " Notes 原文 ", Status: enums.StatusOk}
|
||||
if err := repositories.KnowledgeFAQRepository.Create(sqls.DB(), item); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, locale := range []string{"en-US", "ru-RU"} {
|
||||
file, err := KnowledgeFAQService.ExportKnowledgeFAQs(kb.ID, locale)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rows, result, err := parseKnowledgeFAQImportRows(bytes.NewReader(file.Data), locale)
|
||||
if err != nil || result.Failed != 0 || len(rows) != 1 {
|
||||
t.Fatalf("export round trip: %+v, %v", result, err)
|
||||
}
|
||||
if rows[0].Question != item.Question || rows[0].Answer != item.Answer || rows[0].Remark != item.Remark || !reflect.DeepEqual(rows[0].SimilarQuestions, []string{" same question ", "相似问"}) {
|
||||
t.Fatalf("row changed: %+v", rows[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user