ebf47c6013
track file sizes for all documents in system * feature complete needs dev testing
776 lines
23 KiB
Go
776 lines
23 KiB
Go
package queryapi_test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
queryapi "queryorchestration/api/queryAPI"
|
|
"queryorchestration/internal/database/repository"
|
|
"queryorchestration/internal/folder"
|
|
"queryorchestration/internal/serviceconfig"
|
|
"queryorchestration/internal/test"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/labstack/echo/v4"
|
|
openapi_types "github.com/oapi-codegen/runtime/types"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type FoldersTestConfig struct {
|
|
serviceconfig.BaseConfig
|
|
}
|
|
|
|
func (c *FoldersTestConfig) GetBackgroundRunner() any { return nil }
|
|
|
|
func setupFoldersTestController(t *testing.T) (*queryapi.Controllers, *FoldersTestConfig, string) {
|
|
t.Helper()
|
|
cfg := &FoldersTestConfig{}
|
|
test.CreateDB(t, cfg)
|
|
|
|
// Create services
|
|
folderSvc := folder.New(cfg)
|
|
|
|
services := &queryapi.Services{
|
|
Folder: folderSvc,
|
|
}
|
|
|
|
// Create test client with unique ID
|
|
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: fmt.Sprintf("Test Client %s", uniqueID),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
ctrl := queryapi.NewControllers(services, nil)
|
|
|
|
return ctrl, cfg, clientID
|
|
}
|
|
|
|
func TestCreateFolder_Success(t *testing.T) {
|
|
ctrl, _, clientID := setupFoldersTestController(t)
|
|
|
|
reqBody := queryapi.FolderCreate{
|
|
Path: "/documents/contracts",
|
|
ClientId: queryapi.ClientID(clientID),
|
|
CreatedBy: openapi_types.Email("user@example.com"),
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/folders", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFolder(c)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusCreated, rec.Code)
|
|
|
|
// Parse response
|
|
var resp queryapi.Folder
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "/documents/contracts", resp.Path)
|
|
assert.Equal(t, clientID, string(resp.ClientId))
|
|
assert.Equal(t, "user@example.com", string(resp.CreatedBy))
|
|
assert.NotEqual(t, uuid.Nil, uuid.UUID(resp.Id))
|
|
}
|
|
|
|
func TestCreateFolder_WithParent(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create parent folder first
|
|
parentFolder, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/documents",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
reqBody := queryapi.FolderCreate{
|
|
Path: "/documents/contracts",
|
|
ClientId: queryapi.ClientID(clientID),
|
|
CreatedBy: openapi_types.Email("user@example.com"),
|
|
ParentId: (*openapi_types.UUID)(&parentFolder.ID),
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/folders", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFolder(c)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusCreated, rec.Code)
|
|
|
|
var resp queryapi.Folder
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
// Verify parent ID is set
|
|
assert.True(t, resp.ParentId.IsSpecified())
|
|
parentID, err := resp.ParentId.Get()
|
|
require.NoError(t, err)
|
|
assert.Equal(t, parentFolder.ID, uuid.UUID(parentID))
|
|
}
|
|
|
|
func TestCreateFolder_MissingPath(t *testing.T) {
|
|
ctrl, _, clientID := setupFoldersTestController(t)
|
|
|
|
reqBody := queryapi.FolderCreate{
|
|
Path: "",
|
|
ClientId: queryapi.ClientID(clientID),
|
|
CreatedBy: openapi_types.Email("user@example.com"),
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/folders", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFolder(c)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestCreateFolder_MissingClientId(t *testing.T) {
|
|
ctrl, _, _ := setupFoldersTestController(t)
|
|
|
|
reqBody := queryapi.FolderCreate{
|
|
Path: "/documents",
|
|
ClientId: "",
|
|
CreatedBy: openapi_types.Email("user@example.com"),
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/folders", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.CreateFolder(c)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestCreateFolder_MissingCreatedBy(t *testing.T) {
|
|
ctrl, _, clientID := setupFoldersTestController(t)
|
|
|
|
// Send raw JSON with empty createdBy field
|
|
body := []byte(fmt.Sprintf(`{"path":"/documents","clientId":"%s","createdBy":""}`, clientID))
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/folders", bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err := ctrl.CreateFolder(c)
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestRenameFolder_Success(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create folder first
|
|
folderRec, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/old-path",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
reqBody := queryapi.FolderRename{
|
|
Path: "/new-path",
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPatch, fmt.Sprintf("/folders/%s", folderRec.ID), bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.RenameFolder(c, openapi_types.UUID(folderRec.ID))
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusNoContent, rec.Code)
|
|
|
|
// Verify the folder was renamed
|
|
updatedFolder, err := cfg.GetDBQueries().GetFolderByID(ctx, folderRec.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "/new-path", updatedFolder.Path)
|
|
}
|
|
|
|
func TestRenameFolder_MissingPath(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create folder first
|
|
folderRec, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/old-path",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
reqBody := queryapi.FolderRename{
|
|
Path: "",
|
|
}
|
|
|
|
body, err := json.Marshal(reqBody)
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPatch, fmt.Sprintf("/folders/%s", folderRec.ID), bytes.NewReader(body))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.RenameFolder(c, openapi_types.UUID(folderRec.ID))
|
|
require.Error(t, err)
|
|
httpErr, ok := err.(*echo.HTTPError)
|
|
require.True(t, ok)
|
|
assert.Equal(t, http.StatusBadRequest, httpErr.Code)
|
|
}
|
|
|
|
func TestGetFolderDocuments_Success(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create folder
|
|
folderRec, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/documents",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Create documents in the folder
|
|
filename1 := "doc1.pdf"
|
|
docID1, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("hash1-%s", uuid.New().String()[:8]),
|
|
Filename: &filename1,
|
|
Folderid: &folderRec.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
filename2 := "doc2.pdf"
|
|
docID2, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("hash2-%s", uuid.New().String()[:8]),
|
|
Filename: &filename2,
|
|
Folderid: &folderRec.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/folders/%s/documents", folderRec.ID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.GetFolderDocuments(c, openapi_types.UUID(folderRec.ID), queryapi.GetFolderDocumentsParams{})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var resp struct {
|
|
Documents []queryapi.DocumentInFolder `json:"documents"`
|
|
}
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, resp.Documents, 2)
|
|
|
|
// Verify both documents are returned
|
|
docIDs := make(map[uuid.UUID]bool)
|
|
for _, doc := range resp.Documents {
|
|
docIDs[uuid.UUID(doc.Id)] = true
|
|
}
|
|
assert.True(t, docIDs[docID1])
|
|
assert.True(t, docIDs[docID2])
|
|
}
|
|
|
|
func TestGetFolderDocuments_EmptyFolder(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create folder with no documents
|
|
folderRec, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/empty-folder",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/folders/%s/documents", folderRec.ID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.GetFolderDocuments(c, openapi_types.UUID(folderRec.ID), queryapi.GetFolderDocumentsParams{})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var resp struct {
|
|
Documents []queryapi.DocumentInFolder `json:"documents"`
|
|
}
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, resp.Documents, 0)
|
|
}
|
|
|
|
// TestGetFolderDocuments_IncludesFileSize verifies that file sizes are returned
|
|
// in the folder documents response when documents have file_size_bytes set.
|
|
func TestGetFolderDocuments_IncludesFileSize(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create folder
|
|
folderRec, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/documents-with-sizes",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Create documents with file sizes
|
|
filename1 := "small-doc.pdf"
|
|
fileSize1 := int64(1024) // 1KB
|
|
docID1, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("sizehash1-%s", uuid.New().String()[:8]),
|
|
Filename: &filename1,
|
|
Folderid: &folderRec.ID,
|
|
FileSizeBytes: &fileSize1,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
filename2 := "large-doc.pdf"
|
|
fileSize2 := int64(5242880) // 5MB
|
|
docID2, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("sizehash2-%s", uuid.New().String()[:8]),
|
|
Filename: &filename2,
|
|
Folderid: &folderRec.ID,
|
|
FileSizeBytes: &fileSize2,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/folders/%s/documents", folderRec.ID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.GetFolderDocuments(c, openapi_types.UUID(folderRec.ID), queryapi.GetFolderDocumentsParams{})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var resp struct {
|
|
Documents []queryapi.DocumentInFolder `json:"documents"`
|
|
}
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Len(t, resp.Documents, 2)
|
|
|
|
// Build a map of document ID to file size for verification
|
|
docSizes := make(map[uuid.UUID]*int64)
|
|
for _, doc := range resp.Documents {
|
|
docSizes[uuid.UUID(doc.Id)] = doc.FileSizeBytes
|
|
}
|
|
|
|
// Verify file sizes are present and correct
|
|
require.NotNil(t, docSizes[docID1], "document 1 should have file size")
|
|
assert.Equal(t, fileSize1, *docSizes[docID1], "document 1 file size should be 1024")
|
|
|
|
require.NotNil(t, docSizes[docID2], "document 2 should have file size")
|
|
assert.Equal(t, fileSize2, *docSizes[docID2], "document 2 file size should be 5242880")
|
|
}
|
|
|
|
// TestGetFolderDocuments_NilFileSize verifies that documents without file sizes
|
|
// (legacy documents) return nil for fileSizeBytes.
|
|
func TestGetFolderDocuments_NilFileSize(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create folder
|
|
folderRec, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/documents-no-sizes",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Create document WITHOUT file size (simulating legacy document)
|
|
filename := "legacy-doc.pdf"
|
|
docID, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("legacyhash-%s", uuid.New().String()[:8]),
|
|
Filename: &filename,
|
|
Folderid: &folderRec.ID,
|
|
FileSizeBytes: nil, // No file size
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/folders/%s/documents", folderRec.ID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.GetFolderDocuments(c, openapi_types.UUID(folderRec.ID), queryapi.GetFolderDocumentsParams{})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var resp struct {
|
|
Documents []queryapi.DocumentInFolder `json:"documents"`
|
|
}
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, resp.Documents, 1)
|
|
|
|
// Verify file size is nil for the legacy document
|
|
assert.Equal(t, docID, uuid.UUID(resp.Documents[0].Id))
|
|
assert.Nil(t, resp.Documents[0].FileSizeBytes, "legacy document should have nil file size")
|
|
}
|
|
|
|
func TestGetFolderMetrics_Success(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create folder
|
|
folderRec, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/documents",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Create documents in the folder
|
|
filename1 := "doc1.pdf"
|
|
docID1, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("metricshash1-%s", uuid.New().String()[:8]),
|
|
Filename: &filename1,
|
|
Folderid: &folderRec.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
filename2 := "doc2.pdf"
|
|
docID2, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("metricshash2-%s", uuid.New().String()[:8]),
|
|
Filename: &filename2,
|
|
Folderid: &folderRec.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
filename3 := "doc3.pdf"
|
|
_, err = cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("metricshash3-%s", uuid.New().String()[:8]),
|
|
Filename: &filename3,
|
|
Folderid: &folderRec.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Apply labels to documents (using labels from the lookup table)
|
|
_, err = cfg.GetDBQueries().ApplyLabel(ctx, &repository.ApplyLabelParams{
|
|
Documentid: docID1,
|
|
Label: "Ingested",
|
|
Appliedby: "user@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = cfg.GetDBQueries().ApplyLabel(ctx, &repository.ApplyLabelParams{
|
|
Documentid: docID2,
|
|
Label: "Ingested",
|
|
Appliedby: "user@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = cfg.GetDBQueries().ApplyLabel(ctx, &repository.ApplyLabelParams{
|
|
Documentid: docID2,
|
|
Label: "OCR_Processed",
|
|
Appliedby: "user@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/folders/%s/metrics", folderRec.ID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.GetFolderMetrics(c, openapi_types.UUID(folderRec.ID))
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var resp queryapi.FolderMetrics
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, folderRec.ID, uuid.UUID(resp.FolderId))
|
|
assert.Equal(t, int32(3), resp.TotalDocuments)
|
|
assert.Equal(t, int32(2), resp.ByLabel["Ingested"])
|
|
assert.Equal(t, int32(1), resp.ByLabel["OCR_Processed"])
|
|
}
|
|
|
|
func TestGetFolderMetrics_EmptyFolder(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create folder with no documents
|
|
folderRec, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/empty-metrics",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/folders/%s/metrics", folderRec.ID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err = ctrl.GetFolderMetrics(c, openapi_types.UUID(folderRec.ID))
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var resp queryapi.FolderMetrics
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, int32(0), resp.TotalDocuments)
|
|
assert.Len(t, resp.ByLabel, 0)
|
|
}
|
|
|
|
func TestListClientFolders_Success(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create some folders for the client
|
|
folder1, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/folder1",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/folder1/subfolder",
|
|
Clientid: clientID,
|
|
Parentid: &folder1.ID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/folder2",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/client/%s/folders", clientID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
// Call with empty params (metrics=false by default)
|
|
err = ctrl.ListClientFolders(c, queryapi.ClientID(clientID), queryapi.ListClientFoldersParams{})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var resp queryapi.FolderList
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
// Should have 3 folders
|
|
assert.Len(t, resp.Folders, 3)
|
|
|
|
// Folders should be ordered by path
|
|
assert.Equal(t, "/folder1", resp.Folders[0].Path)
|
|
assert.Equal(t, "/folder1/subfolder", resp.Folders[1].Path)
|
|
assert.Equal(t, "/folder2", resp.Folders[2].Path)
|
|
|
|
// Metrics should not be specified when metrics=false
|
|
for _, f := range resp.Folders {
|
|
assert.False(t, f.Metrics.IsSpecified(), "metrics should not be specified when metrics param is false/omitted")
|
|
}
|
|
}
|
|
|
|
func TestListClientFolders_EmptyResult(t *testing.T) {
|
|
ctrl, _, clientID := setupFoldersTestController(t)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/client/%s/folders", clientID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
err := ctrl.ListClientFolders(c, queryapi.ClientID(clientID), queryapi.ListClientFoldersParams{})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var resp queryapi.FolderList
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
// Should have empty folders array
|
|
assert.Len(t, resp.Folders, 0)
|
|
}
|
|
|
|
func TestListClientFolders_WithMetrics(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create a folder
|
|
folderRec, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/metrics-folder",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Create documents in the folder
|
|
filename1 := "doc1.pdf"
|
|
docID1, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("listmetricshash1-%s", uuid.New().String()[:8]),
|
|
Filename: &filename1,
|
|
Folderid: &folderRec.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
filename2 := "doc2.pdf"
|
|
docID2, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{
|
|
Clientid: clientID,
|
|
Hash: fmt.Sprintf("listmetricshash2-%s", uuid.New().String()[:8]),
|
|
Filename: &filename2,
|
|
Folderid: &folderRec.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Apply labels
|
|
_, err = cfg.GetDBQueries().ApplyLabel(ctx, &repository.ApplyLabelParams{
|
|
Documentid: docID1,
|
|
Label: "Ingested",
|
|
Appliedby: "user@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = cfg.GetDBQueries().ApplyLabel(ctx, &repository.ApplyLabelParams{
|
|
Documentid: docID2,
|
|
Label: "Ingested",
|
|
Appliedby: "user@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = cfg.GetDBQueries().ApplyLabel(ctx, &repository.ApplyLabelParams{
|
|
Documentid: docID2,
|
|
Label: "OCR_Processed",
|
|
Appliedby: "user@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/client/%s/folders?metrics=true", clientID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
// Call with metrics=true
|
|
metricsTrue := true
|
|
err = ctrl.ListClientFolders(c, queryapi.ClientID(clientID), queryapi.ListClientFoldersParams{
|
|
Metrics: &metricsTrue,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var resp queryapi.FolderList
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
// Should have 1 folder
|
|
require.Len(t, resp.Folders, 1)
|
|
|
|
// Metrics should be populated
|
|
folder := resp.Folders[0]
|
|
assert.True(t, folder.Metrics.IsSpecified(), "metrics should be specified when metrics=true")
|
|
|
|
metricsVal, err := folder.Metrics.Get()
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int32(2), metricsVal.TotalDocuments)
|
|
assert.Equal(t, int32(2), metricsVal.ByLabel["Ingested"])
|
|
assert.Equal(t, int32(1), metricsVal.ByLabel["OCR_Processed"])
|
|
}
|
|
|
|
func TestListClientFolders_MetricsFalseExplicit(t *testing.T) {
|
|
ctrl, cfg, clientID := setupFoldersTestController(t)
|
|
ctx := t.Context()
|
|
|
|
// Create a folder
|
|
_, err := cfg.GetDBQueries().CreateFolder(ctx, &repository.CreateFolderParams{
|
|
Path: "/no-metrics-folder",
|
|
Clientid: clientID,
|
|
Createdby: "admin@example.com",
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("/client/%s/folders?metrics=false", clientID), nil)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
// Call with metrics=false explicitly
|
|
metricsFalse := false
|
|
err = ctrl.ListClientFolders(c, queryapi.ClientID(clientID), queryapi.ListClientFoldersParams{
|
|
Metrics: &metricsFalse,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, http.StatusOK, rec.Code)
|
|
|
|
var resp queryapi.FolderList
|
|
err = json.Unmarshal(rec.Body.Bytes(), &resp)
|
|
require.NoError(t, err)
|
|
|
|
// Should have 1 folder
|
|
require.Len(t, resp.Folders, 1)
|
|
|
|
// Metrics should NOT be specified
|
|
folder := resp.Folders[0]
|
|
assert.False(t, folder.Metrics.IsSpecified(), "metrics should not be specified when metrics=false")
|
|
}
|