Files
Agent-System/internal/freedoc/service_db_test.go
T
weichenandCursor 9c7d6d49b2 feat(freedoc): CreateDocument with client_key idempotency
Support direct freeform create for upload fact-source registration while
keeping source_content_sha256 as a content fingerprint only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 11:12:03 +00:00

95 lines
3.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package freedoc_test
import (
"context"
"fmt"
"testing"
"time"
"chat-agent-system/internal/config"
"chat-agent-system/internal/ctxmgr"
"chat-agent-system/internal/freedoc"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestFreeformDoc_DatabaseIntegration(t *testing.T) {
cfg, err := config.Load(".env")
if err != nil || cfg == nil || cfg.ContextDbHost == "" {
t.Skip("Skipping DB integration test: context DB not configured")
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
pool, err := pgxpool.New(ctx, cfg.ContextDSN())
if err != nil || pool.Ping(ctx) != nil {
t.Skipf("Skipping DB integration test: cannot connect to %s: %v", cfg.ContextDSN(), err)
}
defer pool.Close()
ctxMgr := ctxmgr.NewContextManager(pool, nil, ctxmgr.DefaultTimeDecayConfig())
service := freedoc.NewService(pool, ctxMgr)
sessionID := fmt.Sprintf("sess-db-freedoc-%d", time.Now().UnixNano())
msgID, err := ctxMgr.RecordUserMessageWithID(ctx, sessionID, 1, "assistant", "# 数据库持久化自由文档\n\n通过 PostgreSQL 完整事务落库并生成版本 1。", "consult", "main", nil)
require.NoError(t, err)
// 1. 创建私密文档
detail, isExisting, err := service.CreateFromMessage(ctx, 101, freedoc.CreateFromMessageRequest{
MessageID: msgID,
ProjectID: 1,
})
require.NoError(t, err)
assert.False(t, isExisting)
assert.Equal(t, "数据库持久化自由文档", detail.Document.Title)
assert.Equal(t, "my_private", detail.Document.Space)
docID := detail.Document.DocID
// 2. 数据库幂等性验证:再次调用返回同一 docID
detail2, isExisting2, err := service.CreateFromMessage(ctx, 101, freedoc.CreateFromMessageRequest{
MessageID: msgID,
ProjectID: 1,
})
require.NoError(t, err)
assert.True(t, isExisting2)
assert.Equal(t, docID, detail2.Document.DocID)
// 3. 读取与权限验证
readDoc, err := service.GetDocument(ctx, 101, docID)
require.NoError(t, err)
assert.Equal(t, docID, readDoc.Document.DocID)
assert.Contains(t, readDoc.Content, "通过 PostgreSQL 完整事务落库")
// 非本人访问私密文档必须被拒
_, err = service.GetDocument(ctx, 999, docID)
assert.ErrorIs(t, err, freedoc.ErrForbidden)
// 4. 版本迭代与乐观锁冲突验证
curVer := 1
newMarkdown := "修订后的正文内容(v2)"
updated, err := service.UpdateDocument(ctx, 101, docID, freedoc.UpdateFreeformDocRequest{
ContentMarkdown: &newMarkdown,
ExpectedVersion: &curVer,
})
require.NoError(t, err)
assert.Equal(t, 2, updated.Document.CurrentVersionID)
// 5. 共享到项目与撤回共享
shared, err := service.ShareDocument(ctx, 101, docID)
require.NoError(t, err)
assert.Equal(t, "project_shared", shared.Space)
unshared, err := service.UnshareDocument(ctx, 101, docID)
require.NoError(t, err)
assert.Equal(t, "my_private", unshared.Space)
// 6. 删除清理
err = service.DeleteDocument(ctx, 101, docID)
require.NoError(t, err)
_, err = service.GetDocument(ctx, 101, docID)
assert.ErrorIs(t, err, freedoc.ErrNotFound)
}