package freedoc_test import ( "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "chat-agent-system/internal/docrevision" "chat-agent-system/internal/freedoc" ) func TestCreateDocument_ClientKeyIdempotentAndBootstrapsLedger(t *testing.T) { ctx := context.Background() rev := docrevision.NewService(nil) svc := freedoc.NewService(nil, nil) svc.SetDocRevision(rev) detail, err := svc.CreateDocument(ctx, 42, freedoc.CreateFreeformDocRequest{ ProjectID: 7, Title: "超声探头规格.pdf", ContentMarkdown: "# 超声探头规格\n\n上传正文基线\n", Space: "my_private", ClientKey: "doc-upload-1789263145197-0", }) require.NoError(t, err) require.NotNil(t, detail) assert.True(t, len(detail.Document.DocID) > 0) assert.True(t, detail.Document.DocID[:8] == "doc-free" || detail.Document.DocID[:9] == "doc-free-") require.NotNil(t, detail.Document.ClientKey) assert.Equal(t, "doc-upload-1789263145197-0", *detail.Document.ClientKey) assert.Equal(t, "freeform", detail.Document.GovernanceMode) // source_content_sha256 must remain content fingerprint — never client_key prefix assert.NotContains(t, detail.Document.SourceContentSHA256, "doc-upload") assert.NotContains(t, detail.Document.SourceContentSHA256, "client_key") assert.Len(t, detail.Document.SourceContentSHA256, 64) st, err := rev.GetRevisionState(ctx, detail.Document.DocID) require.NoError(t, err) assert.GreaterOrEqual(t, st.CurrentVersionNo, 1) again, err := svc.CreateDocument(ctx, 42, freedoc.CreateFreeformDocRequest{ ProjectID: 7, Title: "超声探头规格.pdf", ContentMarkdown: "# 超声探头规格\n\n上传正文基线\n", ClientKey: "doc-upload-1789263145197-0", }) require.NoError(t, err) assert.Equal(t, detail.Document.DocID, again.Document.DocID) otherUser, err := svc.CreateDocument(ctx, 99, freedoc.CreateFreeformDocRequest{ ProjectID: 7, Title: "他人同名键", ContentMarkdown: "# other\n", ClientKey: "doc-upload-1789263145197-0", }) require.NoError(t, err) assert.NotEqual(t, detail.Document.DocID, otherUser.Document.DocID) } func TestCreateDocument_RejectsEmptyContent(t *testing.T) { svc := freedoc.NewService(nil, nil) _, err := svc.CreateDocument(context.Background(), 1, freedoc.CreateFreeformDocRequest{ ProjectID: 1, Title: "x", ContentMarkdown: " ", }) assert.ErrorIs(t, err, freedoc.ErrInvalidParam) } func TestCreateDocument_RequiresProjectIDAndPrivateSpace(t *testing.T) { svc := freedoc.NewService(nil, nil) _, err := svc.CreateDocument(context.Background(), 1, freedoc.CreateFreeformDocRequest{ ProjectID: 0, Title: "x", ContentMarkdown: "# x\n", }) assert.ErrorIs(t, err, freedoc.ErrInvalidParam) assert.Contains(t, err.Error(), "project_id") _, err = svc.CreateDocument(context.Background(), 1, freedoc.CreateFreeformDocRequest{ ProjectID: 1, Title: "x", ContentMarkdown: "# x\n", Space: "project_shared", }) assert.ErrorIs(t, err, freedoc.ErrInvalidParam) assert.Contains(t, err.Error(), "my_private") }