3bdc27f4de
Continue finishing the parts of the text extraction plan * add missing fields
833 lines
27 KiB
Go
833 lines
27 KiB
Go
package queryapi_test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
queryapi "queryorchestration/api/queryAPI"
|
|
"queryorchestration/internal/database/repository"
|
|
"queryorchestration/internal/fieldextraction"
|
|
"queryorchestration/internal/serviceconfig"
|
|
"queryorchestration/internal/test"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
"github.com/labstack/echo/v4"
|
|
openapi_types "github.com/oapi-codegen/runtime/types"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type FieldExtractionsTestConfig struct {
|
|
serviceconfig.BaseConfig
|
|
}
|
|
|
|
func (c *FieldExtractionsTestConfig) GetBackgroundRunner() any { return nil }
|
|
|
|
func setupFieldExtractionsTestController(t *testing.T) (*queryapi.Controllers, *FieldExtractionsTestConfig, uuid.UUID, string) {
|
|
t.Helper()
|
|
cfg := &FieldExtractionsTestConfig{}
|
|
test.CreateDB(t, cfg)
|
|
|
|
// Create services
|
|
fieldExtractionSvc := fieldextraction.New(cfg)
|
|
|
|
services := &queryapi.Services{
|
|
FieldExtraction: fieldExtractionSvc,
|
|
}
|
|
|
|
// Create test client and document with unique IDs
|
|
ctx := t.Context()
|
|
uniqueID := uuid.New().String()[:8]
|
|
clientID := fmt.Sprintf("test-client-%s", uniqueID)
|
|
err := cfg.GetDBQueries().CreateClient(ctx, &repository.CreateClientParams{
|
|
Clientid: clientID,
|
|
Name: "Test Client",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
filename := "test.pdf"
|
|
documentID, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("testhash-%s", uniqueID), // Unique hash per test
|
|
Filename: &filename,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
ctrl := queryapi.NewControllers(services, nil)
|
|
|
|
return ctrl, cfg, documentID, clientID
|
|
}
|
|
|
|
func TestCreateFieldExtraction_Success(t *testing.T) {
|
|
ctrl, _, documentID, _ := setupFieldExtractionsTestController(t)
|
|
|
|
// Create request body
|
|
reqBody := queryapi.FieldExtractionRequest{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
CreatedBy: openapi_types.Email("test@example.com"),
|
|
SingleFields: queryapi.SingleFields{
|
|
FileName: ptr("test.pdf"),
|
|
ContractTitle: ptr("Test Contract"),
|
|
ClientName: ptr("Test Client Inc"),
|
|
},
|
|
ArrayFields: []queryapi.ArrayFieldItem{
|
|
{
|
|
ExhibitTitle: ptr("Exhibit A"),
|
|
ExhibitPage: ptr("1"),
|
|
ReimbProvTin: ptr("123456789"),
|
|
},
|
|
{
|
|
ExhibitTitle: ptr("Exhibit B"),
|
|
ExhibitPage: ptr("2"),
|
|
ReimbProvTin: ptr("987654321"),
|
|
},
|
|
},
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/field-extractions", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFieldExtraction(c)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusCreated, rec.Code)
|
|
|
|
// Parse response
|
|
var resp queryapi.FieldExtractionResponse
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, documentID, uuid.UUID(resp.DocumentId))
|
|
assert.Equal(t, int32(1), resp.Version) // First version is 1
|
|
assert.Equal(t, "test@example.com", string(resp.CreatedBy))
|
|
assert.Equal(t, "test.pdf", *resp.SingleFields.FileName)
|
|
assert.Equal(t, "Test Contract", *resp.SingleFields.ContractTitle)
|
|
assert.Len(t, resp.ArrayFields, 2)
|
|
assert.Equal(t, "Exhibit A", *resp.ArrayFields[0].ExhibitTitle)
|
|
assert.Equal(t, "Exhibit B", *resp.ArrayFields[1].ExhibitTitle)
|
|
}
|
|
|
|
func TestCreateFieldExtraction_InvalidRequest(t *testing.T) {
|
|
ctrl, _, _, _ := setupFieldExtractionsTestController(t)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/field-extractions", bytes.NewReader([]byte("invalid json")))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err := ctrl.CreateFieldExtraction(c)
|
|
// Handler returns an echo.HTTPError which should be treated as an error
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestCreateFieldExtraction_MissingDocumentID(t *testing.T) {
|
|
ctrl, _, _, _ := setupFieldExtractionsTestController(t)
|
|
|
|
reqBody := queryapi.FieldExtractionRequest{
|
|
DocumentId: queryapi.DocumentID(uuid.Nil),
|
|
CreatedBy: openapi_types.Email("test@example.com"),
|
|
SingleFields: queryapi.SingleFields{
|
|
FileName: ptr("test.pdf"),
|
|
},
|
|
ArrayFields: []queryapi.ArrayFieldItem{},
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/field-extractions", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFieldExtraction(c)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestCreateFieldExtraction_MissingCreatedBy(t *testing.T) {
|
|
// Use a simple controller without database since we're just testing validation
|
|
ctrl := &queryapi.Controllers{}
|
|
|
|
// Use a valid document ID but empty createdBy
|
|
documentID := uuid.New()
|
|
body := []byte(fmt.Sprintf(`{
|
|
"documentId": "%s",
|
|
"createdBy": "",
|
|
"singleFields": {"fileName": "test.pdf"},
|
|
"arrayFields": []
|
|
}`, documentID))
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/field-extractions", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err := ctrl.CreateFieldExtraction(c)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestGetCurrentFieldExtraction_Success(t *testing.T) {
|
|
ctrl, cfg, documentID, _ := setupFieldExtractionsTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// First create a field extraction using the service directly
|
|
svc := fieldextraction.New(cfg)
|
|
filename := "test.pdf"
|
|
contractTitle := "Test Contract"
|
|
_, err := svc.CreateFieldExtraction(ctx, &fieldextraction.CreateFieldExtractionInput{
|
|
DocumentID: documentID,
|
|
SingleFields: &repository.AddFieldExtractionParams{
|
|
Documentid: documentID,
|
|
Filename: &filename,
|
|
Contracttitle: &contractTitle,
|
|
Createdby: "user@example.com",
|
|
},
|
|
ArrayFields: []*repository.AddFieldExtractionArrayFieldParams{},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Now test the API
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/field-extractions?documentId=%s", documentID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetCurrentFieldExtractionParams{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
}
|
|
|
|
err = ctrl.GetCurrentFieldExtraction(c, params)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
// Parse response
|
|
var resp queryapi.FieldExtractionResponse
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, documentID, uuid.UUID(resp.DocumentId))
|
|
assert.Equal(t, int32(1), resp.Version)
|
|
assert.Equal(t, "user@example.com", string(resp.CreatedBy))
|
|
assert.Equal(t, "Test Contract", *resp.SingleFields.ContractTitle)
|
|
}
|
|
|
|
func TestGetCurrentFieldExtraction_NotFound(t *testing.T) {
|
|
ctrl, _, _, _ := setupFieldExtractionsTestController(t)
|
|
|
|
// Use a random document ID that doesn't have any extractions
|
|
randomDocID := uuid.New()
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/field-extractions?documentId=%s", randomDocID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetCurrentFieldExtractionParams{
|
|
DocumentId: queryapi.DocumentID(randomDocID),
|
|
}
|
|
|
|
err := ctrl.GetCurrentFieldExtraction(c, params)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusNotFound, httpErr.Code)
|
|
}
|
|
|
|
func TestGetCurrentFieldExtraction_InvalidDocumentID(t *testing.T) {
|
|
ctrl, _, _, _ := setupFieldExtractionsTestController(t)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, "/field-extractions?documentId=", nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetCurrentFieldExtractionParams{
|
|
DocumentId: queryapi.DocumentID(uuid.Nil),
|
|
}
|
|
|
|
err := ctrl.GetCurrentFieldExtraction(c, params)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestGetFieldExtractionHistory_Success(t *testing.T) {
|
|
ctrl, cfg, documentID, _ := setupFieldExtractionsTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create multiple versions
|
|
svc := fieldextraction.New(cfg)
|
|
filename := "test.pdf"
|
|
|
|
for i := 1; i <= 3; i++ {
|
|
contractTitle := fmt.Sprintf("Contract Version %d", i)
|
|
_, err := svc.CreateFieldExtraction(ctx, &fieldextraction.CreateFieldExtractionInput{
|
|
DocumentID: documentID,
|
|
SingleFields: &repository.AddFieldExtractionParams{
|
|
Documentid: documentID,
|
|
Filename: &filename,
|
|
Contracttitle: &contractTitle,
|
|
Createdby: fmt.Sprintf("user%d@example.com", i),
|
|
},
|
|
ArrayFields: []*repository.AddFieldExtractionArrayFieldParams{},
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// Now test the API
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/field-extractions/history?documentId=%s", documentID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetFieldExtractionHistoryParams{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
}
|
|
|
|
err := ctrl.GetFieldExtractionHistory(c, params)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
// Parse response
|
|
var resp struct {
|
|
Versions []queryapi.FieldExtractionVersion `json:"versions"`
|
|
}
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
// Should have 3 versions, most recent first
|
|
assert.Len(t, resp.Versions, 3)
|
|
assert.Equal(t, int32(3), resp.Versions[0].Version)
|
|
assert.Equal(t, "user3@example.com", string(resp.Versions[0].CreatedBy))
|
|
assert.Equal(t, int32(2), resp.Versions[1].Version)
|
|
assert.Equal(t, "user2@example.com", string(resp.Versions[1].CreatedBy))
|
|
assert.Equal(t, int32(1), resp.Versions[2].Version)
|
|
assert.Equal(t, "user1@example.com", string(resp.Versions[2].CreatedBy))
|
|
}
|
|
|
|
func TestGetFieldExtractionHistory_NoHistory(t *testing.T) {
|
|
ctrl, cfg, _, clientID := setupFieldExtractionsTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create a new document with no extractions
|
|
filename := "nohistory.pdf"
|
|
newDocID, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: "nohistoryhash",
|
|
Filename: &filename,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/field-extractions/history?documentId=%s", newDocID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetFieldExtractionHistoryParams{
|
|
DocumentId: queryapi.DocumentID(newDocID),
|
|
}
|
|
|
|
err = ctrl.GetFieldExtractionHistory(c, params)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
// Parse response
|
|
var resp struct {
|
|
Versions []queryapi.FieldExtractionVersion `json:"versions"`
|
|
}
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, resp.Versions, 0)
|
|
}
|
|
|
|
func TestGetFieldExtractionHistory_InvalidDocumentID(t *testing.T) {
|
|
ctrl, _, _, _ := setupFieldExtractionsTestController(t)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, "/field-extractions/history?documentId=", nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetFieldExtractionHistoryParams{
|
|
DocumentId: queryapi.DocumentID(uuid.Nil),
|
|
}
|
|
|
|
err := ctrl.GetFieldExtractionHistory(c, params)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestCreateFieldExtraction_WithDates(t *testing.T) {
|
|
ctrl, _, documentID, _ := setupFieldExtractionsTestController(t)
|
|
|
|
effectiveDate := openapi_types.Date{Time: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)}
|
|
terminationDate := openapi_types.Date{Time: time.Date(2025, 12, 31, 0, 0, 0, 0, time.UTC)}
|
|
reimbEffectiveDate := openapi_types.Date{Time: time.Date(2024, 6, 1, 0, 0, 0, 0, time.UTC)}
|
|
|
|
reqBody := queryapi.FieldExtractionRequest{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
CreatedBy: openapi_types.Email("test@example.com"),
|
|
SingleFields: queryapi.SingleFields{
|
|
FileName: ptr("contract.pdf"),
|
|
ContractTitle: ptr("Test Contract with Dates"),
|
|
AareteDerivedEffectiveDt: &effectiveDate,
|
|
AareteDerivedTerminationDt: &terminationDate,
|
|
},
|
|
ArrayFields: []queryapi.ArrayFieldItem{
|
|
{
|
|
ExhibitTitle: ptr("Exhibit A"),
|
|
ReimbEffectiveDt: &reimbEffectiveDate,
|
|
},
|
|
},
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/field-extractions", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFieldExtraction(c)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusCreated, rec.Code)
|
|
|
|
// Parse response
|
|
var resp queryapi.FieldExtractionResponse
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
// Verify dates are returned correctly
|
|
require.NotNil(t, resp.SingleFields.AareteDerivedEffectiveDt)
|
|
assert.Equal(t, 2024, resp.SingleFields.AareteDerivedEffectiveDt.Year())
|
|
assert.Equal(t, time.January, resp.SingleFields.AareteDerivedEffectiveDt.Month())
|
|
assert.Equal(t, 1, resp.SingleFields.AareteDerivedEffectiveDt.Day())
|
|
|
|
require.NotNil(t, resp.SingleFields.AareteDerivedTerminationDt)
|
|
assert.Equal(t, 2025, resp.SingleFields.AareteDerivedTerminationDt.Year())
|
|
assert.Equal(t, time.December, resp.SingleFields.AareteDerivedTerminationDt.Month())
|
|
assert.Equal(t, 31, resp.SingleFields.AareteDerivedTerminationDt.Day())
|
|
|
|
require.NotNil(t, resp.ArrayFields[0].ReimbEffectiveDt)
|
|
assert.Equal(t, 2024, resp.ArrayFields[0].ReimbEffectiveDt.Year())
|
|
assert.Equal(t, time.June, resp.ArrayFields[0].ReimbEffectiveDt.Month())
|
|
}
|
|
|
|
func TestCreateFieldExtraction_WithNumericFields(t *testing.T) {
|
|
ctrl, _, documentID, _ := setupFieldExtractionsTestController(t)
|
|
|
|
reimbPctRate := 10.5
|
|
reimbFeeRate := 150.75
|
|
grouperBaseRate := 1000.00
|
|
|
|
reqBody := queryapi.FieldExtractionRequest{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
CreatedBy: openapi_types.Email("test@example.com"),
|
|
SingleFields: queryapi.SingleFields{
|
|
FileName: ptr("numeric_test.pdf"),
|
|
},
|
|
ArrayFields: []queryapi.ArrayFieldItem{
|
|
{
|
|
ExhibitTitle: ptr("Exhibit A"),
|
|
ReimbPctRate: &reimbPctRate,
|
|
ReimbFeeRate: &reimbFeeRate,
|
|
GrouperBaseRate: &grouperBaseRate,
|
|
},
|
|
},
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/field-extractions", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFieldExtraction(c)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusCreated, rec.Code)
|
|
|
|
// Parse response
|
|
var resp queryapi.FieldExtractionResponse
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
// Verify numeric fields
|
|
require.Len(t, resp.ArrayFields, 1)
|
|
require.NotNil(t, resp.ArrayFields[0].ReimbPctRate)
|
|
assert.InDelta(t, 10.5, *resp.ArrayFields[0].ReimbPctRate, 0.001)
|
|
require.NotNil(t, resp.ArrayFields[0].ReimbFeeRate)
|
|
assert.InDelta(t, 150.75, *resp.ArrayFields[0].ReimbFeeRate, 0.001)
|
|
require.NotNil(t, resp.ArrayFields[0].GrouperBaseRate)
|
|
assert.InDelta(t, 1000.00, *resp.ArrayFields[0].GrouperBaseRate, 0.001)
|
|
}
|
|
|
|
func TestCreateFieldExtraction_EmptyArrayFields(t *testing.T) {
|
|
ctrl, _, documentID, _ := setupFieldExtractionsTestController(t)
|
|
|
|
reqBody := queryapi.FieldExtractionRequest{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
CreatedBy: openapi_types.Email("test@example.com"),
|
|
SingleFields: queryapi.SingleFields{
|
|
FileName: ptr("simple.pdf"),
|
|
ContractTitle: ptr("Simple Contract"),
|
|
},
|
|
ArrayFields: []queryapi.ArrayFieldItem{},
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/field-extractions", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFieldExtraction(c)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusCreated, rec.Code)
|
|
|
|
// Parse response
|
|
var resp queryapi.FieldExtractionResponse
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, resp.ArrayFields, 0)
|
|
}
|
|
|
|
func TestCreateFieldExtraction_LargeArrayFields(t *testing.T) {
|
|
ctrl, _, documentID, _ := setupFieldExtractionsTestController(t)
|
|
|
|
// Create 100 array field items
|
|
arrayFields := make([]queryapi.ArrayFieldItem, 100)
|
|
for i := range arrayFields {
|
|
title := fmt.Sprintf("Exhibit %d", i)
|
|
page := fmt.Sprintf("%d", i+1)
|
|
arrayFields[i] = queryapi.ArrayFieldItem{
|
|
ExhibitTitle: &title,
|
|
ExhibitPage: &page,
|
|
}
|
|
}
|
|
|
|
reqBody := queryapi.FieldExtractionRequest{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
CreatedBy: openapi_types.Email("test@example.com"),
|
|
SingleFields: queryapi.SingleFields{
|
|
FileName: ptr("large_array.pdf"),
|
|
ContractTitle: ptr("Large Array Contract"),
|
|
},
|
|
ArrayFields: arrayFields,
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/field-extractions", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFieldExtraction(c)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusCreated, rec.Code)
|
|
|
|
// Parse response
|
|
var resp queryapi.FieldExtractionResponse
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, resp.ArrayFields, 100)
|
|
assert.Equal(t, "Exhibit 0", *resp.ArrayFields[0].ExhibitTitle)
|
|
assert.Equal(t, "Exhibit 99", *resp.ArrayFields[99].ExhibitTitle)
|
|
}
|
|
|
|
func TestCreateFieldExtraction_VersionIncrement(t *testing.T) {
|
|
ctrl, cfg, documentID, _ := setupFieldExtractionsTestController(t)
|
|
|
|
// Create first version via API
|
|
reqBody := queryapi.FieldExtractionRequest{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
CreatedBy: openapi_types.Email("user1@example.com"),
|
|
SingleFields: queryapi.SingleFields{
|
|
ContractTitle: ptr("Version 1"),
|
|
},
|
|
ArrayFields: []queryapi.ArrayFieldItem{},
|
|
}
|
|
|
|
body, _ := json.Marshal(reqBody)
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/field-extractions", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err := ctrl.CreateFieldExtraction(c)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusCreated, rec.Code)
|
|
|
|
var resp1 queryapi.FieldExtractionResponse
|
|
_ = json.Unmarshal(rec.Body.Bytes(), &resp1)
|
|
assert.Equal(t, int32(1), resp1.Version)
|
|
|
|
// Create second version
|
|
reqBody.CreatedBy = openapi_types.Email("user2@example.com")
|
|
reqBody.SingleFields.ContractTitle = ptr("Version 2")
|
|
body, _ = json.Marshal(reqBody)
|
|
|
|
req = httptest.NewRequest(http.MethodPost, "/field-extractions", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec = httptest.NewRecorder()
|
|
c = e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFieldExtraction(c)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusCreated, rec.Code)
|
|
|
|
var resp2 queryapi.FieldExtractionResponse
|
|
_ = json.Unmarshal(rec.Body.Bytes(), &resp2)
|
|
assert.Equal(t, int32(2), resp2.Version)
|
|
|
|
// GetCurrentFieldExtraction should return version 2
|
|
req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("/field-extractions?documentId=%s", documentID), nil)
|
|
rec = httptest.NewRecorder()
|
|
c = e.NewContext(req, rec)
|
|
|
|
_ = cfg // Keep cfg used for test context
|
|
|
|
params := queryapi.GetCurrentFieldExtractionParams{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
}
|
|
err = ctrl.GetCurrentFieldExtraction(c, params)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var currentResp queryapi.FieldExtractionResponse
|
|
_ = json.Unmarshal(rec.Body.Bytes(), ¤tResp)
|
|
assert.Equal(t, int32(2), currentResp.Version)
|
|
assert.Equal(t, "Version 2", *currentResp.SingleFields.ContractTitle)
|
|
}
|
|
|
|
func TestGetFieldExtractionByVersion_Success(t *testing.T) {
|
|
ctrl, cfg, documentID, _ := setupFieldExtractionsTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create multiple versions with dates for coverage
|
|
svc := fieldextraction.New(cfg)
|
|
filename := "test.pdf"
|
|
|
|
for i := 1; i <= 3; i++ {
|
|
contractTitle := fmt.Sprintf("Contract Version %d", i)
|
|
clientName := fmt.Sprintf("Client %d", i)
|
|
// Include dates to test date conversion coverage
|
|
effectiveDate := pgtype.Date{Time: time.Date(2024, 1, i, 0, 0, 0, 0, time.UTC), Valid: true}
|
|
terminationDate := pgtype.Date{Time: time.Date(2024, 12, i, 0, 0, 0, 0, time.UTC), Valid: true}
|
|
_, err := svc.CreateFieldExtraction(ctx, &fieldextraction.CreateFieldExtractionInput{
|
|
DocumentID: documentID,
|
|
SingleFields: &repository.AddFieldExtractionParams{
|
|
Documentid: documentID,
|
|
Filename: &filename,
|
|
Contracttitle: &contractTitle,
|
|
Clientname: &clientName,
|
|
Aaretederivedeffectivedt: effectiveDate,
|
|
Aaretederivedterminationdt: terminationDate,
|
|
Createdby: fmt.Sprintf("user%d@example.com", i),
|
|
},
|
|
ArrayFields: []*repository.AddFieldExtractionArrayFieldParams{
|
|
{
|
|
Exhibittitle: ptr(fmt.Sprintf("Exhibit V%d", i)),
|
|
},
|
|
},
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// Test retrieving version 2
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/field-extractions/version?documentId=%s&version=2", documentID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetFieldExtractionByVersionParams{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
Version: 2,
|
|
}
|
|
|
|
err := ctrl.GetFieldExtractionByVersion(c, params)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
// Parse response
|
|
var resp queryapi.FieldExtractionResponse
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
// Verify we got version 2
|
|
assert.Equal(t, documentID, uuid.UUID(resp.DocumentId))
|
|
assert.Equal(t, int32(2), resp.Version)
|
|
assert.Equal(t, "user2@example.com", string(resp.CreatedBy))
|
|
assert.Equal(t, "Contract Version 2", *resp.SingleFields.ContractTitle)
|
|
assert.Equal(t, "Client 2", *resp.SingleFields.ClientName)
|
|
// Verify dates are returned correctly
|
|
require.NotNil(t, resp.SingleFields.AareteDerivedEffectiveDt, "Expected effective date in response")
|
|
require.NotNil(t, resp.SingleFields.AareteDerivedTerminationDt, "Expected termination date in response")
|
|
assert.Equal(t, 2024, resp.SingleFields.AareteDerivedEffectiveDt.Year())
|
|
assert.Equal(t, time.January, resp.SingleFields.AareteDerivedEffectiveDt.Month())
|
|
assert.Equal(t, 2, resp.SingleFields.AareteDerivedEffectiveDt.Day())
|
|
require.Len(t, resp.ArrayFields, 1)
|
|
assert.Equal(t, "Exhibit V2", *resp.ArrayFields[0].ExhibitTitle)
|
|
|
|
// Also test retrieving version 1
|
|
req = httptest.NewRequest(http.MethodGet, fmt.Sprintf("/field-extractions/version?documentId=%s&version=1", documentID), nil)
|
|
rec = httptest.NewRecorder()
|
|
c = e.NewContext(req, rec)
|
|
|
|
params.Version = 1
|
|
err = ctrl.GetFieldExtractionByVersion(c, params)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, int32(1), resp.Version)
|
|
assert.Equal(t, "Contract Version 1", *resp.SingleFields.ContractTitle)
|
|
assert.Equal(t, "Exhibit V1", *resp.ArrayFields[0].ExhibitTitle)
|
|
}
|
|
|
|
func TestGetFieldExtractionByVersion_NotFound(t *testing.T) {
|
|
ctrl, cfg, documentID, _ := setupFieldExtractionsTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create only one version
|
|
svc := fieldextraction.New(cfg)
|
|
filename := "test.pdf"
|
|
contractTitle := "Test Contract"
|
|
_, err := svc.CreateFieldExtraction(ctx, &fieldextraction.CreateFieldExtractionInput{
|
|
DocumentID: documentID,
|
|
SingleFields: &repository.AddFieldExtractionParams{
|
|
Documentid: documentID,
|
|
Filename: &filename,
|
|
Contracttitle: &contractTitle,
|
|
Createdby: "user@example.com",
|
|
},
|
|
ArrayFields: []*repository.AddFieldExtractionArrayFieldParams{},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Try to get version 5 (which doesn't exist)
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/field-extractions/version?documentId=%s&version=5", documentID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetFieldExtractionByVersionParams{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
Version: 5,
|
|
}
|
|
|
|
err = ctrl.GetFieldExtractionByVersion(c, params)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusNotFound, httpErr.Code)
|
|
}
|
|
|
|
func TestGetFieldExtractionByVersion_InvalidDocumentID(t *testing.T) {
|
|
ctrl, _, _, _ := setupFieldExtractionsTestController(t)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, "/field-extractions/version?documentId=&version=1", nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetFieldExtractionByVersionParams{
|
|
DocumentId: queryapi.DocumentID(uuid.Nil),
|
|
Version: 1,
|
|
}
|
|
|
|
err := ctrl.GetFieldExtractionByVersion(c, params)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestGetFieldExtractionByVersion_InvalidVersion(t *testing.T) {
|
|
ctrl, _, documentID, _ := setupFieldExtractionsTestController(t)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/field-extractions/version?documentId=%s&version=0", documentID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetFieldExtractionByVersionParams{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
Version: 0, // Invalid: version must be >= 1
|
|
}
|
|
|
|
err := ctrl.GetFieldExtractionByVersion(c, params)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestGetFieldExtractionByVersion_NoExtractions(t *testing.T) {
|
|
ctrl, _, documentID, _ := setupFieldExtractionsTestController(t)
|
|
|
|
// Document exists but has no field extractions
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/field-extractions/version?documentId=%s&version=1", documentID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
params := queryapi.GetFieldExtractionByVersionParams{
|
|
DocumentId: queryapi.DocumentID(documentID),
|
|
Version: 1,
|
|
}
|
|
|
|
err := ctrl.GetFieldExtractionByVersion(c, params)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusNotFound, httpErr.Code)
|
|
}
|
|
|
|
// Helper function to create string pointer
|
|
func ptr(s string) *string {
|
|
return &s
|
|
}
|