mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-16 12:22:17 +01:00
test: add integration tests
This commit is contained in:
@@ -1,817 +0,0 @@
|
||||
package libreoffice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/gotenberg/gotenberg/v8/pkg/gotenberg"
|
||||
"github.com/gotenberg/gotenberg/v8/pkg/modules/api"
|
||||
libreofficeapi "github.com/gotenberg/gotenberg/v8/pkg/modules/libreoffice/api"
|
||||
)
|
||||
|
||||
func TestConvertRoute(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
scenario string
|
||||
ctx *api.ContextMock
|
||||
libreOffice libreofficeapi.Uno
|
||||
engine gotenberg.PdfEngine
|
||||
expectOptions libreofficeapi.Options
|
||||
expectError bool
|
||||
expectHttpError bool
|
||||
expectHttpStatus int
|
||||
expectOutputPathsCount int
|
||||
expectOutputPaths []string
|
||||
}{
|
||||
{
|
||||
scenario: "missing at least one mandatory file",
|
||||
ctx: &api.ContextMock{Context: new(api.Context)},
|
||||
libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
}},
|
||||
expectError: true,
|
||||
expectHttpError: true,
|
||||
expectHttpStatus: http.StatusBadRequest,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "invalid quality form field (not an integer)",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"quality": {
|
||||
"foo",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
}},
|
||||
expectError: true,
|
||||
expectHttpError: true,
|
||||
expectHttpStatus: http.StatusBadRequest,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "invalid quality form field (< 1)",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"quality": {
|
||||
"0",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
}},
|
||||
expectError: true,
|
||||
expectHttpError: true,
|
||||
expectHttpStatus: http.StatusBadRequest,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "invalid quality form field (> 100)",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"quality": {
|
||||
"101",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
}},
|
||||
expectError: true,
|
||||
expectHttpError: true,
|
||||
expectHttpStatus: http.StatusBadRequest,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "invalid maxImageResolution form field (not an integer)",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"maxImageResolution": {
|
||||
"foo",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
}},
|
||||
expectError: true,
|
||||
expectHttpError: true,
|
||||
expectHttpStatus: http.StatusBadRequest,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "invalid maxImageResolution form field (not in range)",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"maxImageResolution": {
|
||||
"1",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
}},
|
||||
expectError: true,
|
||||
expectHttpError: true,
|
||||
expectHttpStatus: http.StatusBadRequest,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "invalid metadata form field",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"metadata": {
|
||||
"foo",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
}},
|
||||
expectError: true,
|
||||
expectHttpError: true,
|
||||
expectHttpStatus: http.StatusBadRequest,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "ErrPdfFormatNotSupported (nativePdfFormats)",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return libreofficeapi.ErrInvalidPdfFormats
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectHttpError: true,
|
||||
expectHttpStatus: http.StatusBadRequest,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "ErrUnoException",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"nativePageRanges": {
|
||||
"foo",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return libreofficeapi.ErrUnoException
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectHttpError: true,
|
||||
expectHttpStatus: http.StatusBadRequest,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "ErrRuntimeException",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"password": {
|
||||
"invalid",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return libreofficeapi.ErrRuntimeException
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectHttpError: true,
|
||||
expectHttpStatus: http.StatusBadRequest,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "error from LibreOffice",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return errors.New("foo")
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "PDF engine merge error",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
"document2.docx": "/document2.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"merge": {
|
||||
"true",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
engine: &gotenberg.PdfEngineMock{
|
||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||
return errors.New("foo")
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "PDF engine split error",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"splitMode": {
|
||||
gotenberg.SplitModeIntervals,
|
||||
},
|
||||
"splitSpan": {
|
||||
"1",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
engine: &gotenberg.PdfEngineMock{
|
||||
SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) {
|
||||
return nil, errors.New("foo")
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "PDF engine convert error",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"pdfa": {
|
||||
gotenberg.PdfA1b,
|
||||
},
|
||||
"nativePdfFormats": {
|
||||
"false",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
engine: &gotenberg.PdfEngineMock{
|
||||
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||
return errors.New("foo")
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "PDF engine write metadata error",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"metadata": {
|
||||
"{\"Creator\": \"foo\", \"Producer\": \"bar\" }",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
engine: &gotenberg.PdfEngineMock{
|
||||
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
||||
return errors.New("foo")
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "PDF engine flatten error",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"flatten": {
|
||||
"true",
|
||||
},
|
||||
})
|
||||
ctx.SetCancelled(true)
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
engine: &gotenberg.PdfEngineMock{
|
||||
FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error {
|
||||
return errors.New("foo")
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "cannot add output paths",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetCancelled(true)
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 0,
|
||||
},
|
||||
{
|
||||
scenario: "success (single file)",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
"document2.docx": "/document2.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"quality": {
|
||||
"100",
|
||||
},
|
||||
"maxImageResolution": {
|
||||
"1200",
|
||||
},
|
||||
"merge": {
|
||||
"true",
|
||||
},
|
||||
"pdfa": {
|
||||
gotenberg.PdfA1b,
|
||||
},
|
||||
"pdfua": {
|
||||
"true",
|
||||
},
|
||||
"nativePdfFormats": {
|
||||
"false",
|
||||
},
|
||||
"metadata": {
|
||||
"{\"Creator\": \"foo\", \"Producer\": \"bar\" }",
|
||||
},
|
||||
"flatten": {
|
||||
"true",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
engine: &gotenberg.PdfEngineMock{
|
||||
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||
return nil
|
||||
},
|
||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||
return nil
|
||||
},
|
||||
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
||||
return nil
|
||||
},
|
||||
FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 1,
|
||||
},
|
||||
{
|
||||
scenario: "success (many files)",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
"document2.docx": "/document2.docx",
|
||||
"document2.doc": "/document2.doc",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"pdfa": {
|
||||
gotenberg.PdfA1b,
|
||||
},
|
||||
"pdfua": {
|
||||
"true",
|
||||
},
|
||||
"nativePdfFormats": {
|
||||
"false",
|
||||
},
|
||||
"metadata": {
|
||||
"{\"Creator\": \"foo\", \"Producer\": \"bar\" }",
|
||||
},
|
||||
"flatten": {
|
||||
"true",
|
||||
},
|
||||
})
|
||||
ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error {
|
||||
return nil
|
||||
}})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx", ".doc"}
|
||||
},
|
||||
},
|
||||
engine: &gotenberg.PdfEngineMock{
|
||||
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||
return nil
|
||||
},
|
||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||
return nil
|
||||
},
|
||||
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
||||
return nil
|
||||
},
|
||||
FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 3,
|
||||
expectOutputPaths: []string{"/document.docx.pdf", "/document2.docx.pdf", "/document2.doc.pdf"},
|
||||
},
|
||||
{
|
||||
scenario: "success with native PDF/A & PDF/UA",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"pdfa": {
|
||||
gotenberg.PdfA1b,
|
||||
},
|
||||
"pdfua": {
|
||||
"true",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 1,
|
||||
},
|
||||
{
|
||||
scenario: "success with split (many files)",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
"document2.docx": "/document2.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"splitMode": {
|
||||
gotenberg.SplitModeIntervals,
|
||||
},
|
||||
"splitSpan": {
|
||||
"1",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
engine: &gotenberg.PdfEngineMock{
|
||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||
return nil
|
||||
},
|
||||
SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) {
|
||||
inputPathNoExt := inputPath[:len(inputPath)-len(filepath.Ext(inputPath))]
|
||||
filenameNoExt := filepath.Base(inputPathNoExt)
|
||||
return []string{
|
||||
fmt.Sprintf(
|
||||
"%s/%s_%d.pdf",
|
||||
outputDirPath, filenameNoExt, 0,
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"%s/%s_%d.pdf",
|
||||
outputDirPath, filenameNoExt, 1,
|
||||
),
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 4,
|
||||
expectOutputPaths: []string{"/document_docx/document.docx_0.pdf", "/document_docx/document.docx_1.pdf", "/document2_docx/document2.docx_0.pdf", "/document2_docx/document2.docx_1.pdf"},
|
||||
},
|
||||
{
|
||||
scenario: "success with merge and split",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
"document2.docx": "/document2.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"merge": {
|
||||
"true",
|
||||
},
|
||||
"splitMode": {
|
||||
gotenberg.SplitModeIntervals,
|
||||
},
|
||||
"splitSpan": {
|
||||
"1",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
engine: &gotenberg.PdfEngineMock{
|
||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||
return nil
|
||||
},
|
||||
SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) {
|
||||
inputPathNoExt := inputPath[:len(inputPath)-len(filepath.Ext(inputPath))]
|
||||
filenameNoExt := filepath.Base(inputPathNoExt)
|
||||
return []string{
|
||||
fmt.Sprintf(
|
||||
"%s/%s_%d.pdf",
|
||||
outputDirPath, filenameNoExt, 0,
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"%s/%s_%d.pdf",
|
||||
outputDirPath, filenameNoExt, 1,
|
||||
),
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 2,
|
||||
},
|
||||
{
|
||||
scenario: "success with split and native PDF/A & PDF/UA (many files)",
|
||||
ctx: func() *api.ContextMock {
|
||||
ctx := &api.ContextMock{Context: new(api.Context)}
|
||||
ctx.SetFiles(map[string]string{
|
||||
"document.docx": "/document.docx",
|
||||
"document2.docx": "/document2.docx",
|
||||
})
|
||||
ctx.SetValues(map[string][]string{
|
||||
"splitMode": {
|
||||
gotenberg.SplitModeIntervals,
|
||||
},
|
||||
"splitSpan": {
|
||||
"1",
|
||||
},
|
||||
"pdfa": {
|
||||
gotenberg.PdfA1b,
|
||||
},
|
||||
"pdfua": {
|
||||
"true",
|
||||
},
|
||||
})
|
||||
return ctx
|
||||
}(),
|
||||
libreOffice: &libreofficeapi.ApiMock{
|
||||
PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error {
|
||||
return nil
|
||||
},
|
||||
ExtensionsMock: func() []string {
|
||||
return []string{".docx"}
|
||||
},
|
||||
},
|
||||
engine: &gotenberg.PdfEngineMock{
|
||||
SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) {
|
||||
inputPathNoExt := inputPath[:len(inputPath)-len(filepath.Ext(inputPath))]
|
||||
filenameNoExt := filepath.Base(inputPathNoExt)
|
||||
return []string{
|
||||
fmt.Sprintf(
|
||||
"%s/%s_%d.pdf",
|
||||
outputDirPath, filenameNoExt, 0,
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"%s/%s_%d.pdf",
|
||||
outputDirPath, filenameNoExt, 1,
|
||||
),
|
||||
}, nil
|
||||
},
|
||||
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
expectError: false,
|
||||
expectHttpError: false,
|
||||
expectOutputPathsCount: 4,
|
||||
expectOutputPaths: []string{"/document_docx/document.docx_0.pdf", "/document_docx/document.docx_1.pdf", "/document2_docx/document2.docx_0.pdf", "/document2_docx/document2.docx_1.pdf"},
|
||||
},
|
||||
} {
|
||||
t.Run(tc.scenario, func(t *testing.T) {
|
||||
tc.ctx.SetLogger(zap.NewNop())
|
||||
tc.ctx.SetMkdirAll(&gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error {
|
||||
return nil
|
||||
}})
|
||||
tc.ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error {
|
||||
return nil
|
||||
}})
|
||||
c := echo.New().NewContext(nil, nil)
|
||||
c.Set("context", tc.ctx.Context)
|
||||
|
||||
err := convertRoute(tc.libreOffice, tc.engine).Handler(c)
|
||||
|
||||
if tc.expectError && err == nil {
|
||||
t.Fatal("expected error but got none", err)
|
||||
}
|
||||
|
||||
if !tc.expectError && err != nil {
|
||||
t.Fatalf("expected no error but got: %v", err)
|
||||
}
|
||||
|
||||
var httpErr api.HttpError
|
||||
isHttpError := errors.As(err, &httpErr)
|
||||
|
||||
if tc.expectHttpError && !isHttpError {
|
||||
t.Errorf("expected an HTTP error but got: %v", err)
|
||||
}
|
||||
|
||||
if !tc.expectHttpError && isHttpError {
|
||||
t.Errorf("expected no HTTP error but got one: %v", httpErr)
|
||||
}
|
||||
|
||||
if err != nil && tc.expectHttpError && isHttpError {
|
||||
status, _ := httpErr.HttpError()
|
||||
if status != tc.expectHttpStatus {
|
||||
t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status)
|
||||
}
|
||||
}
|
||||
|
||||
if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) {
|
||||
t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths()))
|
||||
}
|
||||
|
||||
for _, path := range tc.expectOutputPaths {
|
||||
if !slices.Contains(tc.ctx.OutputPaths(), path) {
|
||||
t.Errorf("expected '%s' in output paths %v", path, tc.ctx.OutputPaths())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user