Files
query-orchestration/internal/document/batch/outcome/reporter_test.go
T
Jay Brown aafe7d5b5f Merged in feature/batch-status (pull request #215)
Implement and test the batch status feature

* working
2026-03-12 18:53:42 +00:00

151 lines
4.8 KiB
Go

// Package outcome_test contains integration tests for the batch outcome reporter.
// Tests use real database via testcontainers (no mocks).
package outcome_test
import (
"testing"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/document/batch/outcome"
"queryorchestration/internal/serviceconfig"
"queryorchestration/internal/test"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type TestConfig struct {
serviceconfig.BaseConfig
}
// createBatchWithOutcome is a helper that creates a client, batch, and inserts
// a submitted outcome row. Returns the batchID and the unique clientID used.
func createBatchWithOutcome(t *testing.T, cfg *TestConfig, clientPrefix, filename string) (uuid.UUID, string) {
t.Helper()
ctx := t.Context()
// Use a unique clientID to avoid collisions when tests share the DB
clientID := clientPrefix + "_" + uuid.New().String()[:8]
err := cfg.GetDBQueries().CreateClient(ctx, &repository.CreateClientParams{
Clientid: clientID,
Name: "Test Client " + clientID,
})
require.NoError(t, err)
batchID, err := cfg.GetDBQueries().CreateBatchUpload(ctx, &repository.CreateBatchUploadParams{
ClientID: clientID,
OriginalFilename: "test.zip",
TotalDocuments: 5,
})
require.NoError(t, err)
err = cfg.GetDBQueries().InsertBatchDocumentOutcome(ctx, &repository.InsertBatchDocumentOutcomeParams{
BatchID: batchID,
Filename: filename,
Column3: repository.BatchOutcomeStatusSubmitted,
})
require.NoError(t, err)
return batchID, clientID
}
// TestResolve_SetsDocumentIDAndOutcome inserts a submitted row, resolves it
// with a document_id, and verifies the update took effect.
func TestResolve_SetsDocumentIDAndOutcome(t *testing.T) {
cfg := &TestConfig{}
test.CreateDB(t, cfg)
ctx := t.Context()
filename := "invoice.pdf"
batchID, clientID := createBatchWithOutcome(t, cfg, "test_resolve_sets", filename)
// Create a real document so FK constraint is satisfied
docID, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
Clientid: clientID,
Hash: "hash_resolve_test",
BatchID: &batchID,
})
require.NoError(t, err)
reporter := outcome.New(cfg.GetDBQueries())
err = reporter.Resolve(ctx, &batchID, filename, docID,
repository.BatchOutcomeStatusInitComplete, nil)
require.NoError(t, err)
// Verify the row was updated
rows, err := cfg.GetDBQueries().ListBatchDocumentOutcomes(ctx, batchID)
require.NoError(t, err)
require.Len(t, rows, 1)
assert.Equal(t, repository.BatchOutcomeStatusInitComplete, rows[0].Outcome)
require.NotNil(t, rows[0].DocumentID)
assert.Equal(t, docID, *rows[0].DocumentID)
}
// TestResolve_NoOpForNilBatchID verifies that calling Resolve with a nil batchID
// returns no error and makes no DB changes.
func TestResolve_NoOpForNilBatchID(t *testing.T) {
cfg := &TestConfig{}
test.CreateDB(t, cfg)
ctx := t.Context()
reporter := outcome.New(cfg.GetDBQueries())
// Call with nil batchID -- should be a no-op
err := reporter.Resolve(ctx, nil, "anything.pdf", uuid.New(),
repository.BatchOutcomeStatusInitComplete, nil)
require.NoError(t, err)
}
// TestUpdate_UpdatesOutcomeByDocumentID inserts a resolved row (with document_id),
// then updates it to sync_complete and verifies.
func TestUpdate_UpdatesOutcomeByDocumentID(t *testing.T) {
cfg := &TestConfig{}
test.CreateDB(t, cfg)
ctx := t.Context()
filename := "receipt.pdf"
batchID, clientID := createBatchWithOutcome(t, cfg, "test_update_docid", filename)
// Create a real document so FK constraint is satisfied
docID, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
Clientid: clientID,
Hash: "hash_update_test",
BatchID: &batchID,
})
require.NoError(t, err)
reporter := outcome.New(cfg.GetDBQueries())
// Resolve first (set document_id and advance to init_complete)
err = reporter.Resolve(ctx, &batchID, filename, docID,
repository.BatchOutcomeStatusInitComplete, nil)
require.NoError(t, err)
// Now update to sync_complete
err = reporter.Update(ctx, docID, repository.BatchOutcomeStatusSyncComplete, nil)
require.NoError(t, err)
// Verify the outcome was advanced
rows, err := cfg.GetDBQueries().ListBatchDocumentOutcomes(ctx, batchID)
require.NoError(t, err)
require.Len(t, rows, 1)
assert.Equal(t, repository.BatchOutcomeStatusSyncComplete, rows[0].Outcome)
}
// TestUpdate_NoOpForNonBatchDocument verifies that calling Update for a
// document_id that has no outcome row produces no error (0 rows affected).
func TestUpdate_NoOpForNonBatchDocument(t *testing.T) {
cfg := &TestConfig{}
test.CreateDB(t, cfg)
ctx := t.Context()
reporter := outcome.New(cfg.GetDBQueries())
// Call Update with a random document_id that has no outcome row
err := reporter.Update(ctx, uuid.New(), repository.BatchOutcomeStatusSyncComplete, nil)
require.NoError(t, err)
}