mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 16:42:15 +01:00
389 lines
18 KiB
Go
389 lines
18 KiB
Go
package api
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/thecodingmachine/gotenberg/internal/app/api/pkg/handler"
|
|
"github.com/thecodingmachine/gotenberg/internal/app/api/pkg/middleware"
|
|
"github.com/thecodingmachine/gotenberg/internal/app/api/pkg/resource"
|
|
"github.com/thecodingmachine/gotenberg/internal/pkg/config"
|
|
"github.com/thecodingmachine/gotenberg/test"
|
|
)
|
|
|
|
func TestPing(t *testing.T) {
|
|
endpoint := handler.PingEndpoint
|
|
config, err := config.FromEnv()
|
|
assert.Nil(t, err)
|
|
srv := New(config)
|
|
// should be OK.
|
|
req := httptest.NewRequest(http.MethodGet, endpoint, nil)
|
|
test.AssertStatusCode(t, http.StatusOK, srv, req)
|
|
}
|
|
|
|
func TestMerge(t *testing.T) {
|
|
os.Setenv(middleware.TestingTraceEnvVar, "1")
|
|
endpoint := handler.MergeEndpoint
|
|
config, err := config.FromEnv()
|
|
assert.Nil(t, err)
|
|
srv := New(config)
|
|
// should be OK.
|
|
body, contentType := test.PDFTestMultipartForm(t, nil)
|
|
req := httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusOK, srv, req)
|
|
// bad request.
|
|
body, contentType = test.PDFTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
// timeout.
|
|
body, contentType = test.PDFTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "0"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusRequestTimeout, srv, req)
|
|
// should have no more resources.
|
|
test.AssertDirectoryEmpty(t, middleware.TestsTracePrefix)
|
|
err = os.RemoveAll(middleware.TestsTracePrefix)
|
|
assert.Nil(t, err)
|
|
os.Unsetenv(middleware.TestingTraceEnvVar)
|
|
}
|
|
|
|
func TestHTML(t *testing.T) {
|
|
os.Setenv(middleware.TestingTraceEnvVar, "1")
|
|
endpoint := fmt.Sprintf("%s%s", handler.ConvertGroupEndpoint, handler.HTMLEndpoint)
|
|
config, err := config.FromEnv()
|
|
assert.Nil(t, err)
|
|
srv := New(config)
|
|
// should be OK.
|
|
body, contentType := test.HTMLTestMultipartForm(t, nil)
|
|
req := httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusOK, srv, req)
|
|
// bad request.
|
|
body, contentType = test.HTMLTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.HTMLTestMultipartForm(t, map[string]string{resource.WaitDelayFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.HTMLTestMultipartForm(t, map[string]string{resource.PaperWidthFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.HTMLTestMultipartForm(t, map[string]string{resource.PaperHeightFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.HTMLTestMultipartForm(t, map[string]string{resource.MarginTopFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.HTMLTestMultipartForm(t, map[string]string{resource.MarginBottomFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.HTMLTestMultipartForm(t, map[string]string{resource.MarginLeftFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.HTMLTestMultipartForm(t, map[string]string{resource.MarginRightFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.HTMLTestMultipartForm(t, map[string]string{resource.LandscapeFormField: "not a bool"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
// timeout.
|
|
body, contentType = test.HTMLTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "0"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusRequestTimeout, srv, req)
|
|
// should have no more resources.
|
|
test.AssertDirectoryEmpty(t, middleware.TestsTracePrefix)
|
|
err = os.RemoveAll(middleware.TestsTracePrefix)
|
|
assert.Nil(t, err)
|
|
os.Unsetenv(middleware.TestingTraceEnvVar)
|
|
}
|
|
|
|
func TestMarkdown(t *testing.T) {
|
|
os.Setenv(middleware.TestingTraceEnvVar, "1")
|
|
endpoint := fmt.Sprintf("%s%s", handler.ConvertGroupEndpoint, handler.MarkdownEndpoint)
|
|
config, err := config.FromEnv()
|
|
assert.Nil(t, err)
|
|
srv := New(config)
|
|
// should be OK.
|
|
body, contentType := test.MarkdownTestMultipartForm(t, nil)
|
|
req := httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusOK, srv, req)
|
|
// bad request.
|
|
body, contentType = test.MarkdownTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.MarkdownTestMultipartForm(t, map[string]string{resource.WaitDelayFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.MarkdownTestMultipartForm(t, map[string]string{resource.PaperWidthFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.MarkdownTestMultipartForm(t, map[string]string{resource.PaperHeightFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.MarkdownTestMultipartForm(t, map[string]string{resource.MarginTopFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.MarkdownTestMultipartForm(t, map[string]string{resource.MarginBottomFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.MarkdownTestMultipartForm(t, map[string]string{resource.MarginLeftFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.MarkdownTestMultipartForm(t, map[string]string{resource.MarginRightFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.MarkdownTestMultipartForm(t, map[string]string{resource.LandscapeFormField: "not a bool"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
// timeout.
|
|
body, contentType = test.MarkdownTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "0"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusRequestTimeout, srv, req)
|
|
// should have no more resources.
|
|
test.AssertDirectoryEmpty(t, middleware.TestsTracePrefix)
|
|
err = os.RemoveAll(middleware.TestsTracePrefix)
|
|
assert.Nil(t, err)
|
|
os.Unsetenv(middleware.TestingTraceEnvVar)
|
|
}
|
|
|
|
func TestURL(t *testing.T) {
|
|
os.Setenv(middleware.TestingTraceEnvVar, "1")
|
|
endpoint := fmt.Sprintf("%s%s", handler.ConvertGroupEndpoint, handler.URLEndpoint)
|
|
config, err := config.FromEnv()
|
|
assert.Nil(t, err)
|
|
srv := New(config)
|
|
// should be OK.
|
|
body, contentType := test.URLTestMultipartForm(t, nil)
|
|
req := httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusOK, srv, req)
|
|
// bad request.
|
|
body, contentType = test.URLTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.URLTestMultipartForm(t, map[string]string{resource.WaitDelayFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.URLTestMultipartForm(t, map[string]string{resource.PaperWidthFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.URLTestMultipartForm(t, map[string]string{resource.PaperHeightFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.URLTestMultipartForm(t, map[string]string{resource.MarginTopFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.URLTestMultipartForm(t, map[string]string{resource.MarginBottomFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.URLTestMultipartForm(t, map[string]string{resource.MarginLeftFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.URLTestMultipartForm(t, map[string]string{resource.MarginRightFormField: "not a float"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
body, contentType = test.URLTestMultipartForm(t, map[string]string{resource.LandscapeFormField: "not a bool"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusBadRequest, srv, req)
|
|
// timeout.
|
|
body, contentType = test.URLTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "0"})
|
|
req = httptest.NewRequest(http.MethodPost, endpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusRequestTimeout, srv, req)
|
|
// should have no more resources.
|
|
test.AssertDirectoryEmpty(t, middleware.TestsTracePrefix)
|
|
err = os.RemoveAll(middleware.TestsTracePrefix)
|
|
assert.Nil(t, err)
|
|
os.Unsetenv(middleware.TestingTraceEnvVar)
|
|
}
|
|
|
|
func TestConcurrent(t *testing.T) {
|
|
const concurrentRequests int = 4
|
|
os.Setenv(middleware.TestingTraceEnvVar, "1")
|
|
config, err := config.FromEnv()
|
|
assert.Nil(t, err)
|
|
srv := New(config)
|
|
// Merge.
|
|
test.AssertConcurrent(
|
|
t,
|
|
func() error {
|
|
body, contentType := test.PDFTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "120"})
|
|
req := httptest.NewRequest(http.MethodPost, handler.MergeEndpoint, body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
rec := httptest.NewRecorder()
|
|
srv.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
return fmt.Errorf("wrong status code: want '%d' got '%d'", http.StatusOK, rec.Code)
|
|
}
|
|
return nil
|
|
},
|
|
concurrentRequests,
|
|
)
|
|
// HTML.
|
|
test.AssertConcurrent(
|
|
t,
|
|
func() error {
|
|
body, contentType := test.HTMLTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "120"})
|
|
req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", handler.ConvertGroupEndpoint, handler.HTMLEndpoint), body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
rec := httptest.NewRecorder()
|
|
srv.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
return fmt.Errorf("wrong status code: want '%d' got '%d'", http.StatusOK, rec.Code)
|
|
}
|
|
return nil
|
|
},
|
|
concurrentRequests,
|
|
)
|
|
// Markdown.
|
|
test.AssertConcurrent(
|
|
t,
|
|
func() error {
|
|
body, contentType := test.MarkdownTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "120"})
|
|
req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", handler.ConvertGroupEndpoint, handler.MarkdownEndpoint), body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
rec := httptest.NewRecorder()
|
|
srv.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
return fmt.Errorf("wrong status code: want '%d' got '%d'", http.StatusOK, rec.Code)
|
|
}
|
|
return nil
|
|
},
|
|
concurrentRequests,
|
|
)
|
|
// URL.
|
|
test.AssertConcurrent(
|
|
t,
|
|
func() error {
|
|
body, contentType := test.URLTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "120"})
|
|
req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", handler.ConvertGroupEndpoint, handler.URLEndpoint), body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
rec := httptest.NewRecorder()
|
|
srv.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
return fmt.Errorf("wrong status code: want '%d' got '%d'", http.StatusOK, rec.Code)
|
|
}
|
|
return nil
|
|
},
|
|
concurrentRequests,
|
|
)
|
|
// Office.
|
|
test.AssertConcurrent(
|
|
t,
|
|
func() error {
|
|
body, contentType := test.OfficeTestMultipartForm(t, map[string]string{resource.WaitTimeoutFormField: "120"})
|
|
req := httptest.NewRequest(http.MethodPost, fmt.Sprintf("%s%s", handler.ConvertGroupEndpoint, handler.OfficeEndpoint), body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
rec := httptest.NewRecorder()
|
|
srv.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
return fmt.Errorf("wrong status code: want '%d' got '%d'", http.StatusOK, rec.Code)
|
|
}
|
|
return nil
|
|
},
|
|
concurrentRequests,
|
|
)
|
|
// should have no more resources.
|
|
test.AssertDirectoryEmpty(t, middleware.TestsTracePrefix)
|
|
err = os.RemoveAll(middleware.TestsTracePrefix)
|
|
assert.Nil(t, err)
|
|
os.Unsetenv(middleware.TestingTraceEnvVar)
|
|
}
|
|
|
|
func TestWebhook(t *testing.T) {
|
|
status := make(chan error, 2)
|
|
rcv := echo.New()
|
|
rcv.POST("/foo", func(c echo.Context) error {
|
|
if c.Request().Header.Get("Content-type") != "application/pdf" {
|
|
status <- fmt.Errorf("wrong Content-type: got '%s' want '%s'", c.Request().Header.Get("Content-type"), "application/pdf")
|
|
return nil
|
|
}
|
|
body, err := ioutil.ReadAll(c.Request().Body)
|
|
if err != nil {
|
|
status <- err
|
|
return nil
|
|
}
|
|
if body == nil || len(body) == 0 {
|
|
status <- errors.New("empty body")
|
|
return nil
|
|
}
|
|
status <- nil
|
|
return nil
|
|
})
|
|
go func() {
|
|
rcv.Start(":3001")
|
|
}()
|
|
os.Setenv(middleware.TestingTraceEnvVar, "1")
|
|
config, err := config.FromEnv()
|
|
assert.Nil(t, err)
|
|
srv := New(config)
|
|
body, contentType := test.PDFTestMultipartForm(t, map[string]string{resource.WebhookURLFormField: "http://localhost:3001/foo"})
|
|
req := httptest.NewRequest(http.MethodPost, "/merge", body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
test.AssertStatusCode(t, http.StatusOK, srv, req)
|
|
err = <-status
|
|
assert.NoError(t, err)
|
|
// should have no more resources.
|
|
test.AssertDirectoryEmpty(t, middleware.TestsTracePrefix)
|
|
err = os.RemoveAll(middleware.TestsTracePrefix)
|
|
assert.Nil(t, err)
|
|
os.Unsetenv(middleware.TestingTraceEnvVar)
|
|
}
|
|
|
|
func TestResultFilename(t *testing.T) {
|
|
os.Setenv(middleware.TestingTraceEnvVar, "1")
|
|
config, err := config.FromEnv()
|
|
assert.Nil(t, err)
|
|
srv := New(config)
|
|
body, contentType := test.PDFTestMultipartForm(t, map[string]string{resource.ResultFilenameFormField: "foo.pdf"})
|
|
req := httptest.NewRequest(http.MethodPost, "/merge", body)
|
|
req.Header.Set(echo.HeaderContentType, contentType)
|
|
rec := httptest.NewRecorder()
|
|
srv.ServeHTTP(rec, req)
|
|
assert.Equal(t, "attachment; filename=\"foo.pdf\"", rec.Header().Get("Content-Disposition"))
|
|
// should have no more resources.
|
|
test.AssertDirectoryEmpty(t, middleware.TestsTracePrefix)
|
|
err = os.RemoveAll(middleware.TestsTracePrefix)
|
|
assert.Nil(t, err)
|
|
os.Unsetenv(middleware.TestingTraceEnvVar)
|
|
}
|