mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-17 12:42:16 +01:00
feat(pdfengines): one flag per PDF engine method for a more granular selection of PDF engines
This commit is contained in:
8
Makefile
8
Makefile
@@ -72,6 +72,10 @@ LOG_LEVEL=info
|
|||||||
LOG_FORMAT=auto
|
LOG_FORMAT=auto
|
||||||
LOG_FIELDS_PREFIX=
|
LOG_FIELDS_PREFIX=
|
||||||
PDFENGINES_ENGINES=
|
PDFENGINES_ENGINES=
|
||||||
|
PDFENGINES_MERGE_ENGINES=qpdf,pdfcpu,pdftk
|
||||||
|
PDFENGINES_CONVERT_ENGINES=libreoffice-pdfengine
|
||||||
|
PDFENGINES_READ_METADATA_ENGINES=exiftool
|
||||||
|
PDFENGINES_WRITE_METADATA_ENGINES=exiftool
|
||||||
PDFENGINES_DISABLE_ROUTES=false
|
PDFENGINES_DISABLE_ROUTES=false
|
||||||
PROMETHEUS_NAMESPACE=gotenberg
|
PROMETHEUS_NAMESPACE=gotenberg
|
||||||
PROMETHEUS_COLLECT_INTERVAL=1s
|
PROMETHEUS_COLLECT_INTERVAL=1s
|
||||||
@@ -136,6 +140,10 @@ run: ## Start a Gotenberg container
|
|||||||
--log-format=$(LOG_FORMAT) \
|
--log-format=$(LOG_FORMAT) \
|
||||||
--log-fields-prefix=$(LOG_FIELDS_PREFIX) \
|
--log-fields-prefix=$(LOG_FIELDS_PREFIX) \
|
||||||
--pdfengines-engines=$(PDFENGINES_ENGINES) \
|
--pdfengines-engines=$(PDFENGINES_ENGINES) \
|
||||||
|
--pdfengines-merge-engines=$(PDFENGINES_MERGE_ENGINES) \
|
||||||
|
--pdfengines-convert-engines=$(PDFENGINES_CONVERT_ENGINES) \
|
||||||
|
--pdfengines-read-metadata-engines=$(PDFENGINES_READ_METADATA_ENGINES) \
|
||||||
|
--pdfengines-write-metadata-engines=$(PDFENGINES_WRITE_METADATA_ENGINES) \
|
||||||
--pdfengines-disable-routes=$(PDFENGINES_DISABLE_ROUTES) \
|
--pdfengines-disable-routes=$(PDFENGINES_DISABLE_ROUTES) \
|
||||||
--prometheus-namespace=$(PROMETHEUS_NAMESPACE) \
|
--prometheus-namespace=$(PROMETHEUS_NAMESPACE) \
|
||||||
--prometheus-collect-interval=$(PROMETHEUS_COLLECT_INTERVAL) \
|
--prometheus-collect-interval=$(PROMETHEUS_COLLECT_INTERVAL) \
|
||||||
|
|||||||
@@ -12,12 +12,23 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type multiPdfEngines struct {
|
type multiPdfEngines struct {
|
||||||
engines []gotenberg.PdfEngine
|
mergeEngines []gotenberg.PdfEngine
|
||||||
|
convertEngines []gotenberg.PdfEngine
|
||||||
|
readMedataEngines []gotenberg.PdfEngine
|
||||||
|
writeMedataEngines []gotenberg.PdfEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMultiPdfEngines(engines ...gotenberg.PdfEngine) *multiPdfEngines {
|
func newMultiPdfEngines(
|
||||||
|
mergeEngines,
|
||||||
|
convertEngines,
|
||||||
|
readMetadataEngines,
|
||||||
|
writeMedataEngines []gotenberg.PdfEngine,
|
||||||
|
) *multiPdfEngines {
|
||||||
return &multiPdfEngines{
|
return &multiPdfEngines{
|
||||||
engines: engines,
|
mergeEngines: mergeEngines,
|
||||||
|
convertEngines: convertEngines,
|
||||||
|
readMedataEngines: readMetadataEngines,
|
||||||
|
writeMedataEngines: writeMedataEngines,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +38,7 @@ func (multi *multiPdfEngines) Merge(ctx context.Context, logger *zap.Logger, inp
|
|||||||
var err error
|
var err error
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
|
|
||||||
for _, engine := range multi.engines {
|
for _, engine := range multi.mergeEngines {
|
||||||
go func(engine gotenberg.PdfEngine) {
|
go func(engine gotenberg.PdfEngine) {
|
||||||
errChan <- engine.Merge(ctx, logger, inputPaths, outputPath)
|
errChan <- engine.Merge(ctx, logger, inputPaths, outputPath)
|
||||||
}(engine)
|
}(engine)
|
||||||
@@ -52,7 +63,7 @@ func (multi *multiPdfEngines) Convert(ctx context.Context, logger *zap.Logger, f
|
|||||||
var err error
|
var err error
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
|
|
||||||
for _, engine := range multi.engines {
|
for _, engine := range multi.convertEngines {
|
||||||
go func(engine gotenberg.PdfEngine) {
|
go func(engine gotenberg.PdfEngine) {
|
||||||
errChan <- engine.Convert(ctx, logger, formats, inputPath, outputPath)
|
errChan <- engine.Convert(ctx, logger, formats, inputPath, outputPath)
|
||||||
}(engine)
|
}(engine)
|
||||||
@@ -80,16 +91,16 @@ func (multi *multiPdfEngines) ReadMetadata(ctx context.Context, logger *zap.Logg
|
|||||||
var err error
|
var err error
|
||||||
var mu sync.Mutex // to safely append errors.
|
var mu sync.Mutex // to safely append errors.
|
||||||
|
|
||||||
resultChan := make(chan readMetadataResult, len(multi.engines))
|
resultChan := make(chan readMetadataResult, len(multi.readMedataEngines))
|
||||||
|
|
||||||
for _, engine := range multi.engines {
|
for _, engine := range multi.readMedataEngines {
|
||||||
go func(engine gotenberg.PdfEngine) {
|
go func(engine gotenberg.PdfEngine) {
|
||||||
metadata, err := engine.ReadMetadata(ctx, logger, inputPath)
|
metadata, err := engine.ReadMetadata(ctx, logger, inputPath)
|
||||||
resultChan <- readMetadataResult{metadata: metadata, err: err}
|
resultChan <- readMetadataResult{metadata: metadata, err: err}
|
||||||
}(engine)
|
}(engine)
|
||||||
}
|
}
|
||||||
|
|
||||||
for range multi.engines {
|
for range multi.readMedataEngines {
|
||||||
select {
|
select {
|
||||||
case result := <-resultChan:
|
case result := <-resultChan:
|
||||||
if result.err != nil {
|
if result.err != nil {
|
||||||
@@ -111,7 +122,7 @@ func (multi *multiPdfEngines) WriteMetadata(ctx context.Context, logger *zap.Log
|
|||||||
var err error
|
var err error
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
|
|
||||||
for _, engine := range multi.engines {
|
for _, engine := range multi.writeMedataEngines {
|
||||||
go func(engine gotenberg.PdfEngine) {
|
go func(engine gotenberg.PdfEngine) {
|
||||||
errChan <- engine.WriteMetadata(ctx, logger, metadata, inputPath)
|
errChan <- engine.WriteMetadata(ctx, logger, metadata, inputPath)
|
||||||
}(engine)
|
}(engine)
|
||||||
|
|||||||
@@ -20,11 +20,16 @@ func TestMultiPdfEngines_Merge(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "nominal behavior",
|
scenario: "nominal behavior",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
[]gotenberg.PdfEngine{
|
||||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
&gotenberg.PdfEngineMock{
|
||||||
return nil
|
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
expectError: false,
|
expectError: false,
|
||||||
@@ -32,16 +37,21 @@ func TestMultiPdfEngines_Merge(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "at least one engine does not return an error",
|
scenario: "at least one engine does not return an error",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
[]gotenberg.PdfEngine{
|
||||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
&gotenberg.PdfEngineMock{
|
||||||
return errors.New("foo")
|
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||||
},
|
return errors.New("foo")
|
||||||
},
|
},
|
||||||
&gotenberg.PdfEngineMock{
|
},
|
||||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
&gotenberg.PdfEngineMock{
|
||||||
return nil
|
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
expectError: false,
|
expectError: false,
|
||||||
@@ -49,16 +59,21 @@ func TestMultiPdfEngines_Merge(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "all engines return an error",
|
scenario: "all engines return an error",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
[]gotenberg.PdfEngine{
|
||||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
&gotenberg.PdfEngineMock{
|
||||||
return errors.New("foo")
|
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||||
},
|
return errors.New("foo")
|
||||||
},
|
},
|
||||||
&gotenberg.PdfEngineMock{
|
},
|
||||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
&gotenberg.PdfEngineMock{
|
||||||
return errors.New("foo")
|
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||||
|
return errors.New("foo")
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
expectError: true,
|
expectError: true,
|
||||||
@@ -66,11 +81,16 @@ func TestMultiPdfEngines_Merge(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "context expired",
|
scenario: "context expired",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
[]gotenberg.PdfEngine{
|
||||||
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
&gotenberg.PdfEngineMock{
|
||||||
return nil
|
MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: func() context.Context {
|
ctx: func() context.Context {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
@@ -105,43 +125,58 @@ func TestMultiPdfEngines_Convert(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "nominal behavior",
|
scenario: "nominal behavior",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
[]gotenberg.PdfEngine{
|
||||||
return nil
|
&gotenberg.PdfEngineMock{
|
||||||
|
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: "at least one engine does not return an error",
|
scenario: "at least one engine does not return an error",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
[]gotenberg.PdfEngine{
|
||||||
return errors.New("foo")
|
&gotenberg.PdfEngineMock{
|
||||||
},
|
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
},
|
return errors.New("foo")
|
||||||
&gotenberg.PdfEngineMock{
|
},
|
||||||
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
},
|
||||||
return nil
|
&gotenberg.PdfEngineMock{
|
||||||
|
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: "all engines return an error",
|
scenario: "all engines return an error",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
[]gotenberg.PdfEngine{
|
||||||
return errors.New("foo")
|
&gotenberg.PdfEngineMock{
|
||||||
},
|
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
},
|
return errors.New("foo")
|
||||||
&gotenberg.PdfEngineMock{
|
},
|
||||||
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
},
|
||||||
return errors.New("foo")
|
&gotenberg.PdfEngineMock{
|
||||||
|
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
|
return errors.New("foo")
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
expectError: true,
|
expectError: true,
|
||||||
@@ -149,11 +184,16 @@ func TestMultiPdfEngines_Convert(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "context expired",
|
scenario: "context expired",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
[]gotenberg.PdfEngine{
|
||||||
return nil
|
&gotenberg.PdfEngineMock{
|
||||||
|
ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: func() context.Context {
|
ctx: func() context.Context {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
@@ -188,43 +228,58 @@ func TestMultiPdfEngines_ReadMetadata(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "nominal behavior",
|
scenario: "nominal behavior",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
nil,
|
||||||
return make(map[string]interface{}), nil
|
[]gotenberg.PdfEngine{
|
||||||
|
&gotenberg.PdfEngineMock{
|
||||||
|
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
||||||
|
return make(map[string]interface{}), nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: "at least one engine does not return an error",
|
scenario: "at least one engine does not return an error",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
nil,
|
||||||
return nil, errors.New("foo")
|
[]gotenberg.PdfEngine{
|
||||||
},
|
&gotenberg.PdfEngineMock{
|
||||||
},
|
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
||||||
&gotenberg.PdfEngineMock{
|
return nil, errors.New("foo")
|
||||||
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
},
|
||||||
return make(map[string]interface{}), nil
|
},
|
||||||
|
&gotenberg.PdfEngineMock{
|
||||||
|
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
||||||
|
return make(map[string]interface{}), nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: "all engines return an error",
|
scenario: "all engines return an error",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
nil,
|
||||||
return nil, errors.New("foo")
|
[]gotenberg.PdfEngine{
|
||||||
},
|
&gotenberg.PdfEngineMock{
|
||||||
},
|
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
||||||
&gotenberg.PdfEngineMock{
|
return nil, errors.New("foo")
|
||||||
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
},
|
||||||
return nil, errors.New("foo")
|
},
|
||||||
|
&gotenberg.PdfEngineMock{
|
||||||
|
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
||||||
|
return nil, errors.New("foo")
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
expectError: true,
|
expectError: true,
|
||||||
@@ -232,11 +287,16 @@ func TestMultiPdfEngines_ReadMetadata(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "context expired",
|
scenario: "context expired",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
nil,
|
||||||
return make(map[string]interface{}), nil
|
[]gotenberg.PdfEngine{
|
||||||
|
&gotenberg.PdfEngineMock{
|
||||||
|
ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) {
|
||||||
|
return make(map[string]interface{}), nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
nil,
|
||||||
),
|
),
|
||||||
ctx: func() context.Context {
|
ctx: func() context.Context {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
@@ -271,9 +331,14 @@ func TestMultiPdfEngines_WriteMetadata(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "nominal behavior",
|
scenario: "nominal behavior",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
nil,
|
||||||
return nil
|
nil,
|
||||||
|
[]gotenberg.PdfEngine{
|
||||||
|
&gotenberg.PdfEngineMock{
|
||||||
|
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -282,14 +347,19 @@ func TestMultiPdfEngines_WriteMetadata(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "at least one engine does not return an error",
|
scenario: "at least one engine does not return an error",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
nil,
|
||||||
return errors.New("foo")
|
nil,
|
||||||
|
[]gotenberg.PdfEngine{
|
||||||
|
&gotenberg.PdfEngineMock{
|
||||||
|
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
||||||
|
return errors.New("foo")
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
&gotenberg.PdfEngineMock{
|
||||||
&gotenberg.PdfEngineMock{
|
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
||||||
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
return nil
|
||||||
return nil
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -298,14 +368,19 @@ func TestMultiPdfEngines_WriteMetadata(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "all engines return an error",
|
scenario: "all engines return an error",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
nil,
|
||||||
return errors.New("foo")
|
nil,
|
||||||
|
[]gotenberg.PdfEngine{
|
||||||
|
&gotenberg.PdfEngineMock{
|
||||||
|
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
||||||
|
return errors.New("foo")
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
&gotenberg.PdfEngineMock{
|
||||||
&gotenberg.PdfEngineMock{
|
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
||||||
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
return errors.New("foo")
|
||||||
return errors.New("foo")
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -315,9 +390,14 @@ func TestMultiPdfEngines_WriteMetadata(t *testing.T) {
|
|||||||
{
|
{
|
||||||
scenario: "context expired",
|
scenario: "context expired",
|
||||||
engine: newMultiPdfEngines(
|
engine: newMultiPdfEngines(
|
||||||
&gotenberg.PdfEngineMock{
|
nil,
|
||||||
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
nil,
|
||||||
return nil
|
nil,
|
||||||
|
[]gotenberg.PdfEngine{
|
||||||
|
&gotenberg.PdfEngineMock{
|
||||||
|
WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -27,9 +27,12 @@ func init() {
|
|||||||
// the [api.Router] interface to expose relevant PDF processing routes if
|
// the [api.Router] interface to expose relevant PDF processing routes if
|
||||||
// enabled.
|
// enabled.
|
||||||
type PdfEngines struct {
|
type PdfEngines struct {
|
||||||
names []string
|
mergeNames []string
|
||||||
engines []gotenberg.PdfEngine
|
convertNames []string
|
||||||
disableRoutes bool
|
readMetadataNames []string
|
||||||
|
writeMedataNames []string
|
||||||
|
engines []gotenberg.PdfEngine
|
||||||
|
disableRoutes bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Descriptor returns a PdfEngines' module descriptor.
|
// Descriptor returns a PdfEngines' module descriptor.
|
||||||
@@ -38,9 +41,18 @@ func (mod *PdfEngines) Descriptor() gotenberg.ModuleDescriptor {
|
|||||||
ID: "pdfengines",
|
ID: "pdfengines",
|
||||||
FlagSet: func() *flag.FlagSet {
|
FlagSet: func() *flag.FlagSet {
|
||||||
fs := flag.NewFlagSet("pdfengines", flag.ExitOnError)
|
fs := flag.NewFlagSet("pdfengines", flag.ExitOnError)
|
||||||
fs.StringSlice("pdfengines-engines", make([]string, 0), "Set the PDF engines and their order - all by default")
|
fs.StringSlice("pdfengines-merge-engines", []string{"qpdf", "pdfcpu", "pdftk"}, "Set the PDF engines and their order for the merge feature")
|
||||||
|
fs.StringSlice("pdfengines-convert-engines", []string{"libreoffice-pdfengine"}, "Set the PDF engines and their order for the convert feature")
|
||||||
|
fs.StringSlice("pdfengines-read-metadata-engines", []string{"exiftool"}, "Set the PDF engines and their order for the read metadata feature")
|
||||||
|
fs.StringSlice("pdfengines-write-metadata-engines", []string{"exiftool"}, "Set the PDF engines and their order for the write metadata feature")
|
||||||
fs.Bool("pdfengines-disable-routes", false, "Disable the routes")
|
fs.Bool("pdfengines-disable-routes", false, "Disable the routes")
|
||||||
|
|
||||||
|
fs.StringSlice("pdfengines-engines", make([]string, 0), "Set the default PDF engines and their default order - all by default")
|
||||||
|
err := fs.MarkDeprecated("pdfengines-engines", "use other flags for a more granular selection of PDF engines per method")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
return fs
|
return fs
|
||||||
}(),
|
}(),
|
||||||
New: func() gotenberg.Module { return new(PdfEngines) },
|
New: func() gotenberg.Module { return new(PdfEngines) },
|
||||||
@@ -51,7 +63,10 @@ func (mod *PdfEngines) Descriptor() gotenberg.ModuleDescriptor {
|
|||||||
// selected by the user thanks to the "engines" flag.
|
// selected by the user thanks to the "engines" flag.
|
||||||
func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error {
|
func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error {
|
||||||
flags := ctx.ParsedFlags()
|
flags := ctx.ParsedFlags()
|
||||||
names := flags.MustStringSlice("pdfengines-engines")
|
mergeNames := flags.MustStringSlice("pdfengines-merge-engines")
|
||||||
|
convertNames := flags.MustStringSlice("pdfengines-convert-engines")
|
||||||
|
readMetadataNames := flags.MustStringSlice("pdfengines-read-metadata-engines")
|
||||||
|
writeMetadataNames := flags.MustStringSlice("pdfengines-write-metadata-engines")
|
||||||
mod.disableRoutes = flags.MustBool("pdfengines-disable-routes")
|
mod.disableRoutes = flags.MustBool("pdfengines-disable-routes")
|
||||||
|
|
||||||
engines, err := ctx.Modules(new(gotenberg.PdfEngine))
|
engines, err := ctx.Modules(new(gotenberg.PdfEngine))
|
||||||
@@ -65,26 +80,37 @@ func (mod *PdfEngines) Provision(ctx *gotenberg.Context) error {
|
|||||||
mod.engines[i] = engine.(gotenberg.PdfEngine)
|
mod.engines[i] = engine.(gotenberg.PdfEngine)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(names) > 0 {
|
defaultNames := make([]string, len(mod.engines))
|
||||||
// Selection from user.
|
for i, engine := range mod.engines {
|
||||||
mod.names = names
|
defaultNames[i] = engine.(gotenberg.Module).Descriptor().ID
|
||||||
|
|
||||||
// Example in case of deprecated module name.
|
|
||||||
//for i, name := range names {
|
|
||||||
// if name == "unoconv-pdfengine" || name == "uno-pdfengine" {
|
|
||||||
// logger.Warn(fmt.Sprintf("%s is deprecated; prefer libreoffice-pdfengine instead", name))
|
|
||||||
// mod.names[i] = "libreoffice-pdfengine"
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// No selection from user, use all PDF engines available.
|
// Example in case of deprecated module name.
|
||||||
mod.names = make([]string, len(mod.engines))
|
//for i, name := range defaultNames {
|
||||||
|
// if name == "unoconv-pdfengine" || name == "uno-pdfengine" {
|
||||||
|
// logger.Warn(fmt.Sprintf("%s is deprecated; prefer libreoffice-pdfengine instead", name))
|
||||||
|
// mod.defaultNames[i] = "libreoffice-pdfengine"
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
for i, engine := range mod.engines {
|
mod.mergeNames = defaultNames
|
||||||
mod.names[i] = engine.(gotenberg.Module).Descriptor().ID
|
if len(mergeNames) > 0 {
|
||||||
|
mod.mergeNames = mergeNames
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.convertNames = defaultNames
|
||||||
|
if len(convertNames) > 0 {
|
||||||
|
mod.convertNames = convertNames
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.readMetadataNames = defaultNames
|
||||||
|
if len(readMetadataNames) > 0 {
|
||||||
|
mod.readMetadataNames = readMetadataNames
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.writeMedataNames = defaultNames
|
||||||
|
if len(writeMetadataNames) > 0 {
|
||||||
|
mod.writeMedataNames = writeMetadataNames
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -105,22 +131,40 @@ func (mod *PdfEngines) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nonExistingEngines := make([]string, 0)
|
nonExistingEngines := make([]string, 0)
|
||||||
|
findNonExistingEngines := func(names []string) {
|
||||||
|
for _, name := range names {
|
||||||
|
engineExists := false
|
||||||
|
|
||||||
for _, name := range mod.names {
|
for _, engine := range mod.engines {
|
||||||
engineExists := false
|
if name == engine.(gotenberg.Module).Descriptor().ID {
|
||||||
|
engineExists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, engine := range mod.engines {
|
if engineExists {
|
||||||
if name == engine.(gotenberg.Module).Descriptor().ID {
|
continue
|
||||||
engineExists = true
|
}
|
||||||
break
|
|
||||||
|
alreadyInSlice := false
|
||||||
|
for _, engine := range nonExistingEngines {
|
||||||
|
if engine == name {
|
||||||
|
alreadyInSlice = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !alreadyInSlice {
|
||||||
|
nonExistingEngines = append(nonExistingEngines, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !engineExists {
|
|
||||||
nonExistingEngines = append(nonExistingEngines, name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findNonExistingEngines(mod.mergeNames)
|
||||||
|
findNonExistingEngines(mod.convertNames)
|
||||||
|
findNonExistingEngines(mod.readMetadataNames)
|
||||||
|
findNonExistingEngines(mod.writeMedataNames)
|
||||||
|
|
||||||
if len(nonExistingEngines) == 0 {
|
if len(nonExistingEngines) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -132,24 +176,35 @@ func (mod *PdfEngines) Validate() error {
|
|||||||
// modules.
|
// modules.
|
||||||
func (mod *PdfEngines) SystemMessages() []string {
|
func (mod *PdfEngines) SystemMessages() []string {
|
||||||
return []string{
|
return []string{
|
||||||
strings.Join(mod.names[:], " "),
|
fmt.Sprintf("merge engines - %s", strings.Join(mod.mergeNames[:], " ")),
|
||||||
|
fmt.Sprintf("convert engines - %s", strings.Join(mod.convertNames[:], " ")),
|
||||||
|
fmt.Sprintf("read metadata engines - %s", strings.Join(mod.readMetadataNames[:], " ")),
|
||||||
|
fmt.Sprintf("write medata engines - %s", strings.Join(mod.writeMedataNames[:], " ")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PdfEngine returns a [gotenberg.PdfEngine].
|
// PdfEngine returns a [gotenberg.PdfEngine].
|
||||||
func (mod *PdfEngines) PdfEngine() (gotenberg.PdfEngine, error) {
|
func (mod *PdfEngines) PdfEngine() (gotenberg.PdfEngine, error) {
|
||||||
engines := make([]gotenberg.PdfEngine, len(mod.names))
|
engines := func(names []string) []gotenberg.PdfEngine {
|
||||||
|
list := make([]gotenberg.PdfEngine, len(names))
|
||||||
for i, name := range mod.names {
|
for i, name := range names {
|
||||||
for _, engine := range mod.engines {
|
for _, engine := range mod.engines {
|
||||||
if name == engine.(gotenberg.Module).Descriptor().ID {
|
if name == engine.(gotenberg.Module).Descriptor().ID {
|
||||||
engines[i] = engine
|
list[i] = engine
|
||||||
break
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
return newMultiPdfEngines(engines...), nil
|
return newMultiPdfEngines(
|
||||||
|
engines(mod.mergeNames),
|
||||||
|
engines(mod.convertNames),
|
||||||
|
engines(mod.readMetadataNames),
|
||||||
|
engines(mod.writeMedataNames),
|
||||||
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routes returns the HTTP routes.
|
// Routes returns the HTTP routes.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package pdfengines
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -22,10 +23,13 @@ func TestPdfEngines_Descriptor(t *testing.T) {
|
|||||||
|
|
||||||
func TestPdfEngines_Provision(t *testing.T) {
|
func TestPdfEngines_Provision(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
scenario string
|
scenario string
|
||||||
ctx *gotenberg.Context
|
ctx *gotenberg.Context
|
||||||
expectedPdfEngines []string
|
expectedMergePdfEngines []string
|
||||||
expectError bool
|
expectedConvertPdfEngines []string
|
||||||
|
expectedReadMetadataPdfEngines []string
|
||||||
|
expectedWriteMetadataPdfEngines []string
|
||||||
|
expectError bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
scenario: "no selection from user",
|
scenario: "no selection from user",
|
||||||
@@ -61,8 +65,11 @@ func TestPdfEngines_Provision(t *testing.T) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}(),
|
}(),
|
||||||
expectedPdfEngines: []string{"bar"},
|
expectedMergePdfEngines: []string{"qpdf", "pdfcpu", "pdftk"},
|
||||||
expectError: false,
|
expectedConvertPdfEngines: []string{"libreoffice-pdfengine"},
|
||||||
|
expectedReadMetadataPdfEngines: []string{"exiftool"},
|
||||||
|
expectedWriteMetadataPdfEngines: []string{"exiftool"},
|
||||||
|
expectError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: "selection from user",
|
scenario: "selection from user",
|
||||||
@@ -100,7 +107,7 @@ func TestPdfEngines_Provision(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fs := new(PdfEngines).Descriptor().FlagSet
|
fs := new(PdfEngines).Descriptor().FlagSet
|
||||||
err := fs.Parse([]string{"--pdfengines-engines=b", "--pdfengines-engines=a"})
|
err := fs.Parse([]string{"--pdfengines-merge-engines=b", "--pdfengines-convert-engines=b", "--pdfengines-read-metadata-engines=a", "--pdfengines-write-metadata-engines=a"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected no error but got: %v", err)
|
t.Fatalf("expected no error but got: %v", err)
|
||||||
}
|
}
|
||||||
@@ -116,8 +123,12 @@ func TestPdfEngines_Provision(t *testing.T) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}(),
|
}(),
|
||||||
expectedPdfEngines: []string{"b", "a"},
|
|
||||||
expectError: false,
|
expectedMergePdfEngines: []string{"b"},
|
||||||
|
expectedConvertPdfEngines: []string{"b"},
|
||||||
|
expectedReadMetadataPdfEngines: []string{"a"},
|
||||||
|
expectedWriteMetadataPdfEngines: []string{"a"},
|
||||||
|
expectError: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
scenario: "no valid PDF engine",
|
scenario: "no valid PDF engine",
|
||||||
@@ -167,13 +178,43 @@ func TestPdfEngines_Provision(t *testing.T) {
|
|||||||
t.Fatal("expected error but got none")
|
t.Fatal("expected error but got none")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tc.expectedPdfEngines) != len(mod.names) {
|
if len(tc.expectedMergePdfEngines) != len(mod.mergeNames) {
|
||||||
t.Fatalf("expected %d names but got %d", len(tc.expectedPdfEngines), len(mod.names))
|
t.Fatalf("expected %d merge names but got %d", len(tc.expectedMergePdfEngines), len(mod.mergeNames))
|
||||||
}
|
}
|
||||||
|
|
||||||
for index, name := range mod.names {
|
if len(tc.expectedConvertPdfEngines) != len(mod.convertNames) {
|
||||||
if name != tc.expectedPdfEngines[index] {
|
t.Fatalf("expected %d convert names but got %d", len(tc.expectedConvertPdfEngines), len(mod.convertNames))
|
||||||
t.Fatalf("expected scenario at index %d to be %s, but got: %s", index, name, tc.expectedPdfEngines[index])
|
}
|
||||||
|
|
||||||
|
if len(tc.expectedReadMetadataPdfEngines) != len(mod.readMetadataNames) {
|
||||||
|
t.Fatalf("expected %d read metadata names but got %d", len(tc.expectedReadMetadataPdfEngines), len(mod.readMetadataNames))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(tc.expectedWriteMetadataPdfEngines) != len(mod.writeMedataNames) {
|
||||||
|
t.Fatalf("expected %d write metadata names but got %d", len(tc.expectedWriteMetadataPdfEngines), len(mod.writeMedataNames))
|
||||||
|
}
|
||||||
|
|
||||||
|
for index, name := range mod.mergeNames {
|
||||||
|
if name != tc.expectedMergePdfEngines[index] {
|
||||||
|
t.Fatalf("expected merge name at index %d to be %s, but got: %s", index, name, tc.expectedMergePdfEngines[index])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for index, name := range mod.convertNames {
|
||||||
|
if name != tc.expectedConvertPdfEngines[index] {
|
||||||
|
t.Fatalf("expected convert name at index %d to be %s, but got: %s", index, name, tc.expectedConvertPdfEngines[index])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for index, name := range mod.readMetadataNames {
|
||||||
|
if name != tc.expectedReadMetadataPdfEngines[index] {
|
||||||
|
t.Fatalf("expected read metadata name at index %d to be %s, but got: %s", index, name, tc.expectedReadMetadataPdfEngines[index])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for index, name := range mod.writeMedataNames {
|
||||||
|
if name != tc.expectedWriteMetadataPdfEngines[index] {
|
||||||
|
t.Fatalf("expected write metadat name at index %d to be %s, but got: %s", index, name, tc.expectedWriteMetadataPdfEngines[index])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -239,8 +280,11 @@ func TestPdfEngines_Validate(t *testing.T) {
|
|||||||
} {
|
} {
|
||||||
t.Run(tc.scenario, func(t *testing.T) {
|
t.Run(tc.scenario, func(t *testing.T) {
|
||||||
mod := PdfEngines{
|
mod := PdfEngines{
|
||||||
names: tc.names,
|
mergeNames: tc.names,
|
||||||
engines: tc.engines,
|
convertNames: tc.names,
|
||||||
|
readMetadataNames: tc.names,
|
||||||
|
writeMedataNames: tc.names,
|
||||||
|
engines: tc.engines,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := mod.Validate()
|
err := mod.Validate()
|
||||||
@@ -258,22 +302,36 @@ func TestPdfEngines_Validate(t *testing.T) {
|
|||||||
|
|
||||||
func TestPdfEngines_SystemMessages(t *testing.T) {
|
func TestPdfEngines_SystemMessages(t *testing.T) {
|
||||||
mod := new(PdfEngines)
|
mod := new(PdfEngines)
|
||||||
mod.names = []string{"foo", "bar"}
|
mod.mergeNames = []string{"foo", "bar"}
|
||||||
|
mod.convertNames = []string{"foo", "bar"}
|
||||||
|
mod.readMetadataNames = []string{"foo", "bar"}
|
||||||
|
mod.writeMedataNames = []string{"foo", "bar"}
|
||||||
|
|
||||||
messages := mod.SystemMessages()
|
messages := mod.SystemMessages()
|
||||||
if len(messages) != 1 {
|
if len(messages) != 4 {
|
||||||
t.Errorf("expected one and only one message, but got %d", len(messages))
|
t.Errorf("expected one and only one message, but got %d", len(messages))
|
||||||
}
|
}
|
||||||
|
|
||||||
expect := strings.Join(mod.names[:], " ")
|
expect := []string{
|
||||||
if messages[0] != expect {
|
fmt.Sprintf("merge engines - %s", strings.Join(mod.mergeNames[:], " ")),
|
||||||
t.Errorf("expected message '%s', but got '%s'", expect, messages[0])
|
fmt.Sprintf("convert engines - %s", strings.Join(mod.convertNames[:], " ")),
|
||||||
|
fmt.Sprintf("read metadata engines - %s", strings.Join(mod.readMetadataNames[:], " ")),
|
||||||
|
fmt.Sprintf("write medata engines - %s", strings.Join(mod.writeMedataNames[:], " ")),
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, message := range messages {
|
||||||
|
if message != expect[i] {
|
||||||
|
t.Errorf("expected message at index %d to be %s, but got %s", i, message, expect[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPdfEngines_PdfEngine(t *testing.T) {
|
func TestPdfEngines_PdfEngine(t *testing.T) {
|
||||||
mod := PdfEngines{
|
mod := PdfEngines{
|
||||||
names: []string{"foo", "bar"},
|
mergeNames: []string{"foo", "bar"},
|
||||||
|
convertNames: []string{"foo", "bar"},
|
||||||
|
readMetadataNames: []string{"foo", "bar"},
|
||||||
|
writeMedataNames: []string{"foo", "bar"},
|
||||||
engines: func() []gotenberg.PdfEngine {
|
engines: func() []gotenberg.PdfEngine {
|
||||||
engine1 := &struct {
|
engine1 := &struct {
|
||||||
gotenberg.ModuleMock
|
gotenberg.ModuleMock
|
||||||
|
|||||||
Reference in New Issue
Block a user