Files
query-orchestration/internal/document/text/processExtract_test.go
T
Michael McGuinness 81e7223560 Merged in feature/textextraction (pull request #110)
Text Extraction

* bases

* go

* splitting

* structure

* movetoasync

* movetoasync

* settinguptrigger

* reorder

* storevent

* standardisepollingvalidation

* unittests

* fixlint

* fixlint

* awscfg

* generatesample

* followthrough

* tests

* clena

* store

* externalidcleanup

* clientid

* local

* baseunittests

* putobjecttests

* tests
2025-04-02 18:50:03 +00:00

264 lines
7.1 KiB
Go

package documenttext
import (
"context"
"database/sql"
"fmt"
"io"
"strings"
"testing"
"queryorchestration/internal/database/repository"
objectstoremock "queryorchestration/mocks/objectstore"
queuemock "queryorchestration/mocks/queue"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/sqs"
"github.com/google/uuid"
"github.com/pashagolub/pgxmock/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)
func TestProcess(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
require.NoError(t, err)
cfg := &DocTextConfig{}
cfg.DBPool = pool
cfg.DBQueries = repository.New(pool)
cfg.QuerySyncURL = "querysync"
mockSQS := queuemock.NewMockSQSClient(t)
cfg.QueueClient = mockSQS
mockS3 := objectstoremock.NewMockS3Client(t)
cfg.StoreClient = mockS3
svc := Service{
cfg: cfg,
}
triggerId := uuid.MustParse("6ac21b2b-f36c-4ae7-a815-307d4a9bfe4d")
docId := uuid.MustParse("6ac21b2b-f36c-4ae7-a815-307d4a9bfe4a")
textractId := "hello"
textId := uuid.New()
cleanId := uuid.New()
hash := `"5d41402abc4b2a76b9719d911017c592"`
pool.ExpectQuery("name: GetDocumentTextTrigger :one").WithArgs(triggerId).WillReturnRows(
pgxmock.NewRows([]string{"id", "cleanId", "version", "textractJobId", "documentId"}).
AddRow(triggerId, cleanId, int64(123), &textractId, docId),
)
pool.ExpectBegin()
pool.ExpectQuery("name: GetDocumentTextExtractionByHash :one").WithArgs(cleanId, hash).WillReturnRows(
pgxmock.NewRows([]string{"id"}).
AddRow(textId),
)
pool.ExpectExec("name: AddDocumentTextEntry :exec").WithArgs(textId, triggerId, pgxmock.AnyArg()).
WillReturnResult(pgxmock.NewResult("", 1))
pool.ExpectCommit()
body := io.NopCloser(strings.NewReader("hello"))
mockS3.EXPECT().
GetObject(
mock.Anything,
mock.MatchedBy(func(in *s3.GetObjectInput) bool {
return *in.IfMatch == "hash"
}),
mock.Anything,
).
Return(&s3.GetObjectOutput{
Body: body,
}, nil)
mockSQS.EXPECT().
SendMessage(
mock.Anything,
mock.MatchedBy(func(in *sqs.SendMessageInput) bool {
return *in.QueueUrl == cfg.QuerySyncURL && *in.MessageBody == fmt.Sprintf("{\"id\":\"%s\"}", docId.String())
}),
mock.Anything,
).
Return(&sqs.SendMessageOutput{}, nil)
err = svc.Process(ctx, &ProcessParams{
Bucket: "bucket",
Key: "6ece4a77-702c-4cc9-8654-43c557e21658/text/textract/6ac21b2b-f36c-4ae7-a815-307d4a9bfe4d",
Hash: "hash",
})
assert.NoError(t, err)
}
func TestStoreTrigger(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
require.NoError(t, err)
cfg := &DocTextConfig{}
cfg.DBPool = pool
cfg.DBQueries = repository.New(pool)
cfg.QuerySyncURL = "querysync"
mockSQS := queuemock.NewMockSQSClient(t)
cfg.QueueClient = mockSQS
mockS3 := objectstoremock.NewMockS3Client(t)
cfg.StoreClient = mockS3
svc := Service{
cfg: cfg,
}
cleanId := uuid.New()
textId := uuid.New()
triggerId := uuid.New()
clientId := "hello"
bucket := "bucket"
t.Run("exists", func(t *testing.T) {
hash := `"5d41402abc4b2a76b9719d911017c592"`
pool.ExpectBegin()
pool.ExpectQuery("name: GetDocumentTextExtractionByHash :one").WithArgs(cleanId, hash).WillReturnRows(
pgxmock.NewRows([]string{"id"}).
AddRow(textId),
)
pool.ExpectExec("name: AddDocumentTextEntry :exec").WithArgs(textId, triggerId, pgxmock.AnyArg()).
WillReturnResult(pgxmock.NewResult("", 1))
pool.ExpectCommit()
text := strings.NewReader("hello")
err = svc.storeProcess(ctx, text, &repository.GetDocumentTextTriggerRow{
ID: triggerId,
Cleanid: cleanId,
}, &ProcessParams{
Bucket: bucket,
})
require.NoError(t, err)
})
t.Run("not exists", func(t *testing.T) {
key := fmt.Sprintf("%s/text/out/%s", clientId, triggerId)
hash := `"09644372e99020106946045c6fd2d70b"`
pool.ExpectBegin()
pool.ExpectQuery("name: GetDocumentTextExtractionByHash :one").WithArgs(cleanId, hash).
WillReturnError(sql.ErrNoRows)
pool.ExpectQuery("name: AddDocumentText :one").WithArgs(bucket, key, hash).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).
AddRow(textId),
)
mockS3.EXPECT().
PutObject(
mock.Anything,
mock.MatchedBy(func(in *s3.PutObjectInput) bool {
bod, err := io.ReadAll(in.Body)
require.NoError(t, err)
return string(bod) == "byebye" && *in.Key == key && *in.Bucket == bucket
}),
mock.Anything,
).
Return(&s3.PutObjectOutput{}, nil)
pool.ExpectExec("name: AddDocumentTextEntry :exec").WithArgs(textId, triggerId, pgxmock.AnyArg()).
WillReturnResult(pgxmock.NewResult("", 1))
pool.ExpectCommit()
text := strings.NewReader("byebye")
err = svc.storeProcess(ctx, text, &repository.GetDocumentTextTriggerRow{
ID: triggerId,
Cleanid: cleanId,
}, &ProcessParams{
Bucket: bucket,
ClientID: clientId,
})
require.NoError(t, err)
})
}
func TestDuplicateReader(t *testing.T) {
original := strings.NewReader("hello")
readerOne, readerTwo, err := duplicateReader(original)
require.NoError(t, err)
contentOne, err := io.ReadAll(readerOne)
require.NoError(t, err)
assert.Equal(t, []byte("hello"), contentOne)
contentTwo, err := io.ReadAll(readerTwo)
require.NoError(t, err)
assert.Equal(t, []byte("hello"), contentTwo)
}
func TestProcessTrigger(t *testing.T) {
ctx := context.Background()
pool, err := pgxmock.NewPool()
require.NoError(t, err)
cfg := &DocTextConfig{}
cfg.DBPool = pool
cfg.DBQueries = repository.New(pool)
cfg.QuerySyncURL = "querysync"
mockSQS := queuemock.NewMockSQSClient(t)
cfg.QueueClient = mockSQS
mockS3 := objectstoremock.NewMockS3Client(t)
cfg.StoreClient = mockS3
svc := Service{
cfg: cfg,
}
cleanId := uuid.New()
textId := uuid.New()
triggerId := uuid.New()
clientId := "hello"
bucket := "bucket"
key := fmt.Sprintf("%s/text/out/%s", clientId, triggerId)
hash := `"5d41402abc4b2a76b9719d911017c592"`
pool.ExpectBegin()
pool.ExpectQuery("name: GetDocumentTextExtractionByHash :one").WithArgs(cleanId, hash).
WillReturnError(sql.ErrNoRows)
pool.ExpectQuery("name: AddDocumentText :one").WithArgs(bucket, key, hash).
WillReturnRows(
pgxmock.NewRows([]string{"id"}).
AddRow(textId),
)
body := io.NopCloser(strings.NewReader("hello"))
mockS3.EXPECT().
GetObject(
mock.Anything,
mock.MatchedBy(func(in *s3.GetObjectInput) bool {
return *in.Key == key && *in.Bucket == bucket && *in.IfMatch == hash
}),
mock.Anything,
).
Return(&s3.GetObjectOutput{
Body: body,
}, nil)
mockS3.EXPECT().
PutObject(
mock.Anything,
mock.MatchedBy(func(in *s3.PutObjectInput) bool {
bod, err := io.ReadAll(in.Body)
require.NoError(t, err)
return string(bod) == "hello" && *in.Key == key && *in.Bucket == bucket
}),
mock.Anything,
).
Return(&s3.PutObjectOutput{}, nil)
pool.ExpectExec("name: AddDocumentTextEntry :exec").WithArgs(textId, triggerId, pgxmock.AnyArg()).
WillReturnResult(pgxmock.NewResult("", 1))
pool.ExpectCommit()
err = svc.processTrigger(ctx, &repository.GetDocumentTextTriggerRow{
ID: triggerId,
Cleanid: cleanId,
}, &ProcessParams{
ClientID: clientId,
Bucket: bucket,
Key: key,
Hash: hash,
})
require.NoError(t, err)
}