package service import ( "bytes" "context" "mime/multipart" "net/http/httptest" "strings" "testing" commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository" "gitlab.com/mbugroup/lti-api.git/internal/config" "gitlab.com/mbugroup/lti-api.git/internal/database" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" "gorm.io/gorm" ) func TestDocumentServiceUpload(t *testing.T) { if strings.TrimSpace(config.S3Bucket) == "" { t.Fatal("S3 bucket is not configured; set S3_* env vars to run this test") } ctx := context.Background() db := setupDocumentTestDB(t) repo := commonRepo.NewDocumentRepository(db) svc, err := NewDocumentServiceFromConfig(ctx, repo) if err != nil { t.Fatalf("failed to create document service from config: %v", err) } file := newTestFileHeader(t, "integration-proof.txt", "text/plain", []byte("document integration test")) userID := uint(100) results, err := svc.UploadDocuments(ctx, DocumentUploadRequest{ DocumentableType: "INVENTORY_TRANSFER", DocumentableID: 99, CreatedBy: &userID, Files: []DocumentFile{ {File: file, Type: "integration"}, }, }) if err != nil { t.Fatalf("upload to S3 failed: %v", err) } if len(results) != 1 { t.Fatalf("expected 1 uploaded document, got %d", len(results)) } doc := results[0].Document if doc.Path == "" { t.Fatalf("expected non-empty storage path") } if results[0].URL == "" { t.Fatalf("expected public URL for uploaded document") } t.Logf("uploaded document #%d to %s (path=%s)", doc.Id, results[0].URL, doc.Path) } func setupDocumentTestDB(t *testing.T) *gorm.DB { t.Helper() if strings.TrimSpace(config.DBHost) == "" || strings.TrimSpace(config.DBName) == "" { t.Fatal("database configuration missing; ensure DB_HOST and DB_NAME are set") } db := database.Connect(config.DBHost, config.DBName) if db == nil { t.Fatal("failed to create database connection") } if err := db.AutoMigrate(&entity.Document{}); err != nil { t.Fatalf("failed to migrate document table: %v", err) } return db } func newTestFileHeader(t *testing.T, filename, contentType string, data []byte) *multipart.FileHeader { t.Helper() body := &bytes.Buffer{} writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("documents", filename) if err != nil { t.Fatalf("failed to create form file: %v", err) } if _, err := part.Write(data); err != nil { t.Fatalf("failed to write file data: %v", err) } if err := writer.Close(); err != nil { t.Fatalf("failed to close writer: %v", err) } req := httptest.NewRequest("POST", "http://example.com/upload", body) req.Header.Set("Content-Type", writer.FormDataContentType()) _, fileHeader, err := req.FormFile("documents") if err != nil { t.Fatalf("failed to parse form file: %v", err) } fileHeader.Header.Set("Content-Type", contentType) return fileHeader }