Merged in feature/add-deletes (pull request #214)
support delete for client, document and folder * support delete for client, document and folder * remove batch cancel conflict not used Approved-by: Jacob Mathison
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
package document_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/document"
|
||||
"queryorchestration/internal/fieldextraction"
|
||||
"queryorchestration/internal/harddelete"
|
||||
"queryorchestration/internal/test"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// createTestDocumentWithDeps creates a document with entries, cleans, and field extractions.
|
||||
// Returns the document ID for use in delete tests.
|
||||
func createTestDocumentWithDeps(t *testing.T, cfg *TestConfig, clientID string, folderID *uuid.UUID, hash string) uuid.UUID {
|
||||
t.Helper()
|
||||
ctx := t.Context()
|
||||
q := cfg.GetDBQueries()
|
||||
|
||||
filename := hash + ".pdf"
|
||||
docID, err := q.CreateDocument(ctx, &repository.CreateDocumentParams{
|
||||
Clientid: clientID,
|
||||
Hash: hash,
|
||||
Filename: &filename,
|
||||
Folderid: folderID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add a document entry (S3 reference)
|
||||
err = q.AddDocumentEntry(ctx, &repository.AddDocumentEntryParams{
|
||||
Documentid: docID,
|
||||
Bucket: "test-bucket",
|
||||
Key: "test-key/" + hash,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add a document clean (must satisfy location_xor_fail constraint)
|
||||
cleanBucket := "clean-bucket"
|
||||
cleanKey := "clean-key/" + hash
|
||||
cleanHash := "cleanhash-" + hash
|
||||
cleanID, err := q.AddDocumentClean(ctx, &repository.AddDocumentCleanParams{
|
||||
Documentid: docID,
|
||||
Bucket: &cleanBucket,
|
||||
Key: &cleanKey,
|
||||
Hash: &cleanHash,
|
||||
Mimetype: repository.NullCleanmimetype{
|
||||
Cleanmimetype: repository.CleanmimetypeApplicationPdf,
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add a clean entry
|
||||
err = q.AddDocumentCleanEntry(ctx, &repository.AddDocumentCleanEntryParams{
|
||||
Cleanid: cleanID,
|
||||
Version: 1,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Add field extraction
|
||||
fieldSvc := fieldextraction.New(cfg)
|
||||
contractTitle := "Test Contract " + hash
|
||||
input := &fieldextraction.CreateFieldExtractionInput{
|
||||
DocumentID: docID,
|
||||
SingleFields: &repository.AddFieldExtractionParams{
|
||||
Documentid: docID,
|
||||
Filename: &filename,
|
||||
Contracttitle: &contractTitle,
|
||||
Createdby: "testuser",
|
||||
},
|
||||
ArrayFields: []*repository.AddFieldExtractionArrayFieldParams{},
|
||||
}
|
||||
_, err = fieldSvc.CreateFieldExtraction(ctx, input)
|
||||
require.NoError(t, err)
|
||||
|
||||
return docID
|
||||
}
|
||||
|
||||
func TestHardDeleteDocument(t *testing.T) {
|
||||
ctx := t.Context()
|
||||
cfg := &TestConfig{}
|
||||
test.CreateDB(t, cfg)
|
||||
|
||||
clientID := "test-doc-delete"
|
||||
test.CreateTestClient(t, cfg, clientID, "Test Doc Delete")
|
||||
|
||||
svc := document.New(cfg)
|
||||
|
||||
t.Run("deletes document and all dependent rows", func(t *testing.T) {
|
||||
q := cfg.GetDBQueries()
|
||||
|
||||
rootFolder, err := q.GetFolderByPath(ctx, &repository.GetFolderByPathParams{
|
||||
Clientid: clientID,
|
||||
Path: "/",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
docID := createTestDocumentWithDeps(t, cfg, clientID, &rootFolder.ID, "delete-cascade-test")
|
||||
|
||||
// Verify document and deps exist before delete
|
||||
_, err = q.GetDocumentSummary(ctx, docID)
|
||||
require.NoError(t, err)
|
||||
|
||||
s3Rows, err := q.CollectDocumentS3Paths(ctx, docID)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, s3Rows, 1)
|
||||
|
||||
// Delete the document
|
||||
s3Paths, err := svc.HardDelete(ctx, docID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify S3 paths returned
|
||||
assert.Len(t, s3Paths, 1)
|
||||
assert.Equal(t, "test-bucket", s3Paths[0].Bucket)
|
||||
assert.Equal(t, "test-key/delete-cascade-test", s3Paths[0].Key)
|
||||
assert.Equal(t, docID, s3Paths[0].DocumentID)
|
||||
|
||||
// Verify document is gone
|
||||
_, err = q.GetDocumentSummary(ctx, docID)
|
||||
require.Error(t, err)
|
||||
|
||||
// Verify document entries are gone
|
||||
s3Rows, err = q.CollectDocumentS3Paths(ctx, docID)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, s3Rows)
|
||||
|
||||
// Verify field extractions are gone
|
||||
extractions, err := q.GetFieldExtractionsByDocumentID(ctx, docID)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, extractions)
|
||||
})
|
||||
|
||||
t.Run("returns NotFoundError for non-existent document", func(t *testing.T) {
|
||||
fakeID := uuid.New()
|
||||
_, err := svc.HardDelete(ctx, fakeID)
|
||||
require.Error(t, err)
|
||||
|
||||
var notFoundErr *harddelete.NotFoundError
|
||||
assert.True(t, errors.As(err, ¬FoundErr))
|
||||
})
|
||||
|
||||
t.Run("returns empty S3 paths when document has no entries", func(t *testing.T) {
|
||||
q := cfg.GetDBQueries()
|
||||
|
||||
// Create a document with no entries
|
||||
docID, err := q.CreateDocument(ctx, &repository.CreateDocumentParams{
|
||||
Clientid: clientID,
|
||||
Hash: "no-entries-test",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
s3Paths, err := svc.HardDelete(ctx, docID)
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, s3Paths)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user