mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
546 lines
12 KiB
Go
546 lines
12 KiB
Go
package libreoffice
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"testing"
|
|
|
|
"github.com/gotenberg/gotenberg/v7/pkg/gotenberg"
|
|
"github.com/gotenberg/gotenberg/v7/pkg/modules/api"
|
|
"github.com/gotenberg/gotenberg/v7/pkg/modules/libreoffice/unoconv"
|
|
"github.com/labstack/echo/v4"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func TestConvertHandler(t *testing.T) {
|
|
for i, tc := range []struct {
|
|
ctx *api.MockContext
|
|
api unoconv.API
|
|
engine gotenberg.PDFEngine
|
|
expectErr bool
|
|
expectHTTPErr bool
|
|
expectHTTPStatus int
|
|
expectOutputPathsCount int
|
|
}{
|
|
{
|
|
ctx: &api.MockContext{Context: &api.Context{}},
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".foo",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
expectErr: true,
|
|
expectHTTPErr: true,
|
|
expectHTTPStatus: http.StatusBadRequest,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
})
|
|
ctx.SetValues(map[string][]string{
|
|
"nativePdfA1aFormat": {
|
|
"true",
|
|
},
|
|
"pdfFormat": {
|
|
"foo",
|
|
},
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
expectErr: true,
|
|
expectHTTPErr: true,
|
|
expectHTTPStatus: http.StatusBadRequest,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return unoconv.ErrMalformedPageRanges
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
expectErr: true,
|
|
expectHTTPErr: true,
|
|
expectHTTPStatus: http.StatusBadRequest,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return errors.New("foo")
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
"bar.docx": "/foo/bar.docx",
|
|
})
|
|
ctx.SetValues(map[string][]string{
|
|
"merge": {
|
|
"true",
|
|
},
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return nil
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
engine: func() gotenberg.PDFEngine {
|
|
return &ProtoPDFEngine{
|
|
merge: func(_ context.Context, _ *zap.Logger, _ []string, _ string) error {
|
|
return errors.New("foo")
|
|
},
|
|
}
|
|
}(),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
"bar.docx": "/foo/bar.docx",
|
|
})
|
|
ctx.SetValues(map[string][]string{
|
|
"merge": {
|
|
"true",
|
|
},
|
|
"pdfFormat": {
|
|
"foo",
|
|
},
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return nil
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
engine: func() gotenberg.PDFEngine {
|
|
return &ProtoPDFEngine{
|
|
merge: func(_ context.Context, _ *zap.Logger, _ []string, _ string) error {
|
|
return nil
|
|
},
|
|
convert: func(_ context.Context, _ *zap.Logger, _, _, _ string) error {
|
|
return gotenberg.ErrPDFFormatNotAvailable
|
|
},
|
|
}
|
|
}(),
|
|
expectErr: true,
|
|
expectHTTPErr: true,
|
|
expectHTTPStatus: http.StatusBadRequest,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
"bar.docx": "/foo/bar.docx",
|
|
})
|
|
ctx.SetValues(map[string][]string{
|
|
"merge": {
|
|
"true",
|
|
},
|
|
"pdfFormat": {
|
|
"foo",
|
|
},
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return nil
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
engine: func() gotenberg.PDFEngine {
|
|
return &ProtoPDFEngine{
|
|
merge: func(_ context.Context, _ *zap.Logger, _ []string, _ string) error {
|
|
return nil
|
|
},
|
|
convert: func(_ context.Context, _ *zap.Logger, _, _, _ string) error {
|
|
return errors.New("foo")
|
|
},
|
|
}
|
|
}(),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetCancelled(true)
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
"bar.docx": "/foo/bar.docx",
|
|
})
|
|
ctx.SetValues(map[string][]string{
|
|
"merge": {
|
|
"true",
|
|
},
|
|
"pdfFormat": {
|
|
"foo",
|
|
},
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return nil
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
engine: func() gotenberg.PDFEngine {
|
|
return &ProtoPDFEngine{
|
|
merge: func(_ context.Context, _ *zap.Logger, _ []string, _ string) error {
|
|
return nil
|
|
},
|
|
convert: func(_ context.Context, _ *zap.Logger, _, _, _ string) error {
|
|
return nil
|
|
},
|
|
}
|
|
}(),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
"bar.docx": "/foo/bar.docx",
|
|
})
|
|
ctx.SetValues(map[string][]string{
|
|
"merge": {
|
|
"true",
|
|
},
|
|
"pdfFormat": {
|
|
"foo",
|
|
},
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return nil
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
engine: func() gotenberg.PDFEngine {
|
|
return &ProtoPDFEngine{
|
|
merge: func(_ context.Context, _ *zap.Logger, _ []string, _ string) error {
|
|
return nil
|
|
},
|
|
convert: func(_ context.Context, _ *zap.Logger, _, _, _ string) error {
|
|
return nil
|
|
},
|
|
}
|
|
}(),
|
|
expectOutputPathsCount: 1,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
})
|
|
ctx.SetValues(map[string][]string{
|
|
"pdfFormat": {
|
|
"foo",
|
|
},
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return nil
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
engine: func() gotenberg.PDFEngine {
|
|
return &ProtoPDFEngine{
|
|
merge: func(_ context.Context, _ *zap.Logger, _ []string, _ string) error {
|
|
return nil
|
|
},
|
|
convert: func(_ context.Context, _ *zap.Logger, _, _, _ string) error {
|
|
return gotenberg.ErrPDFFormatNotAvailable
|
|
},
|
|
}
|
|
}(),
|
|
expectErr: true,
|
|
expectHTTPErr: true,
|
|
expectHTTPStatus: http.StatusBadRequest,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
"bar.docx": "/foo/bar.docx",
|
|
})
|
|
ctx.SetValues(map[string][]string{
|
|
"pdfFormat": {
|
|
"foo",
|
|
},
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return nil
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
engine: func() gotenberg.PDFEngine {
|
|
return &ProtoPDFEngine{
|
|
merge: func(_ context.Context, _ *zap.Logger, _ []string, _ string) error {
|
|
return nil
|
|
},
|
|
convert: func(_ context.Context, _ *zap.Logger, _, _, _ string) error {
|
|
return errors.New("foo")
|
|
},
|
|
}
|
|
}(),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetCancelled(true)
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
"bar.docx": "/foo/bar.docx",
|
|
})
|
|
ctx.SetValues(map[string][]string{
|
|
"pdfFormat": {
|
|
"foo",
|
|
},
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return nil
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
engine: func() gotenberg.PDFEngine {
|
|
return &ProtoPDFEngine{
|
|
merge: func(_ context.Context, _ *zap.Logger, _ []string, _ string) error {
|
|
return nil
|
|
},
|
|
convert: func(_ context.Context, _ *zap.Logger, _, _, _ string) error {
|
|
return nil
|
|
},
|
|
}
|
|
}(),
|
|
expectErr: true,
|
|
},
|
|
{
|
|
ctx: func() *api.MockContext {
|
|
ctx := &api.MockContext{Context: &api.Context{}}
|
|
|
|
ctx.SetFiles(map[string]string{
|
|
"foo.docx": "/foo/foo.docx",
|
|
"bar.docx": "/foo/bar.docx",
|
|
})
|
|
ctx.SetValues(map[string][]string{
|
|
"pdfFormat": {
|
|
"foo",
|
|
},
|
|
})
|
|
|
|
return ctx
|
|
}(),
|
|
api: func() unoconv.API {
|
|
unoconvAPI := struct{ ProtoUnoconvAPI }{}
|
|
unoconvAPI.pdf = func(_ context.Context, _ *zap.Logger, _, _ string, _ unoconv.Options) error {
|
|
return nil
|
|
}
|
|
unoconvAPI.extensions = func() []string {
|
|
return []string{
|
|
".docx",
|
|
}
|
|
}
|
|
|
|
return unoconvAPI
|
|
}(),
|
|
engine: func() gotenberg.PDFEngine {
|
|
return &ProtoPDFEngine{
|
|
merge: func(_ context.Context, _ *zap.Logger, _ []string, _ string) error {
|
|
return nil
|
|
},
|
|
convert: func(_ context.Context, _ *zap.Logger, _, _, _ string) error {
|
|
return nil
|
|
},
|
|
}
|
|
}(),
|
|
expectOutputPathsCount: 2,
|
|
},
|
|
} {
|
|
c := echo.New().NewContext(nil, nil)
|
|
c.Set("context", tc.ctx.Context)
|
|
|
|
err := convertRoute(tc.api, tc.engine).Handler(c)
|
|
|
|
if tc.expectErr && err == nil {
|
|
t.Errorf("test %d: expected error but got: %v", i, err)
|
|
}
|
|
|
|
if !tc.expectErr && err != nil {
|
|
t.Errorf("test %d: expected no error but got: %v", i, err)
|
|
}
|
|
|
|
var httpErr api.HTTPError
|
|
isHTTPErr := errors.As(err, &httpErr)
|
|
|
|
if tc.expectHTTPErr && !isHTTPErr {
|
|
t.Errorf("test %d: expected HTTP error but got: %v", i, err)
|
|
}
|
|
|
|
if !tc.expectHTTPErr && isHTTPErr {
|
|
t.Errorf("test %d: expected no HTTP error but got one: %v", i, httpErr)
|
|
}
|
|
|
|
if err != nil && tc.expectHTTPErr && isHTTPErr {
|
|
status, _ := httpErr.HTTPError()
|
|
if status != tc.expectHTTPStatus {
|
|
t.Errorf("test %d: expected %d HTTP status code but got %d", i, tc.expectHTTPStatus, status)
|
|
}
|
|
}
|
|
|
|
if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) {
|
|
t.Errorf("test %d: expected %d output paths but got %d", i, tc.expectOutputPathsCount, len(tc.ctx.OutputPaths()))
|
|
}
|
|
}
|
|
}
|