mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-12 02:12:15 +01:00
test: add integration tests
This commit is contained in:
2
test/integration/doc.go
Normal file
2
test/integration/doc.go
Normal file
@@ -0,0 +1,2 @@
|
||||
// Package integration contains everything related to integration testing.
|
||||
package integration
|
||||
852
test/integration/features/chromium_convert_html.feature
Normal file
852
test/integration/features/chromium_convert_html.feature
Normal file
@@ -0,0 +1,852 @@
|
||||
Feature: /forms/chromium/convert/html
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Default)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Single Page)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-12-html/index.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 12 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 12:
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-12-html/index.html | file |
|
||||
| singlePage | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
# page-break-after: always; tells the browser's print engine to force a page break after each element,
|
||||
# even when calculating a large enough paper height, Chromium's PDF rendering will still honor those page break
|
||||
# directives.
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Landscape)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should NOT be set to landscape orientation
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| landscape | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should be set to landscape orientation
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Native Page Ranges)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-12-html/index.html | file |
|
||||
| nativePageRanges | 2-3 | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Header & Footer)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-12-html/index.html | file |
|
||||
| files | testdata/header-footer-html/header.html | file |
|
||||
| files | testdata/header-footer-html/footer.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 12 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Pages 12
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
1 of 12
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 12:
|
||||
"""
|
||||
Pages 12
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 12:
|
||||
"""
|
||||
12 of 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Wait Delay)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| waitDelay | 2.5s | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Wait For Expression)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| waitForExpression | window.globalVar === 'ready' | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Emulated Media Type)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'print'.
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'screen'.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| emulatedMediaType | print | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'print'.
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'screen'.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| emulatedMediaType | screen | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'screen'.
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'print'.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Default Allow / Deny Lists)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| 'file:///etc/passwd' matches the expression from the denied list |
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Main URL does NOT match allowed list)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_ALLOW_LIST | ^file:(?!//\\/tmp/).* |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
Then the response status code should be 403
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Forbidden
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Main URL does match denied list)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_ALLOW_LIST | |
|
||||
| CHROMIUM_DENY_LIST | ^file:///tmp.* |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
Then the response status code should be 403
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Forbidden
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Request does not match the allowed list)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_ALLOW_LIST | ^file:///tmp.* |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| 'file:///etc/passwd' does not match the expression from the allowed list |
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (JavaScript Enabled)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
JavaScript is enabled.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (JavaScript Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_DISABLE_JAVASCRIPT | true |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
JavaScript is enabled.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Fail On Resource HTTP Status Codes)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| failOnResourceHttpStatusCodes | [499,599] | field |
|
||||
Then the response status code should be 409
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid HTTP status code from resources:
|
||||
https://httpstat.us/400 - 400: Bad Request
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Fail On Resource Loading Failed)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| failOnResourceLoadingFailed | true | field |
|
||||
Then the response status code should be 409
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
Chromium failed to load resources
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
resource Stylesheet: net::ERR_CONNECTION_REFUSED
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
resource Stylesheet: net::ERR_FILE_NOT_FOUND
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Fail On Console Exceptions)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-html/index.html | file |
|
||||
| failOnConsoleExceptions | true | field |
|
||||
Then the response status code should be 409
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
Chromium console exceptions
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
exception "Uncaught" (61:12): Error: Exception 1
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
exception "Uncaught" (65:12): Error: Exception 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Bad Request)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| singlePage | foo | field |
|
||||
| paperWidth | foo | field |
|
||||
| paperHeight | foo | field |
|
||||
| marginTop | foo | field |
|
||||
| marginBottom | foo | field |
|
||||
| marginLeft | foo | field |
|
||||
| marginRight | foo | field |
|
||||
| preferCssPageSize | foo | field |
|
||||
| generateDocumentOutline | foo | field |
|
||||
| printBackground | foo | field |
|
||||
| omitBackground | foo | field |
|
||||
| landscape | foo | field |
|
||||
| scale | foo | field |
|
||||
| waitDelay | foo | field |
|
||||
| emulatedMediaType | foo | field |
|
||||
| failOnHttpStatusCodes | foo | field |
|
||||
| failOnResourceHttpStatusCodes | foo | field |
|
||||
| failOnResourceLoadingFailed | foo | field |
|
||||
| failOnConsoleExceptions | foo | field |
|
||||
| skipNetworkIdleEvent | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'skipNetworkIdleEvent' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'failOnHttpStatusCodes' is invalid (got 'foo', resulting to unmarshal failOnHttpStatusCodes: invalid character 'o' in literal false (expecting 'a')); form field 'failOnResourceHttpStatusCodes' is invalid (got 'foo', resulting to unmarshal failOnResourceHttpStatusCodes: invalid character 'o' in literal false (expecting 'a')); form field 'failOnResourceLoadingFailed' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'failOnConsoleExceptions' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'waitDelay' is invalid (got 'foo', resulting to time: invalid duration "foo"); form field 'emulatedMediaType' is invalid (got 'foo', resulting to wrong value, expected either 'screen', 'print' or empty); form field 'omitBackground' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'landscape' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'printBackground' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'scale' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'singlePage' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'paperWidth' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'paperHeight' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginTop' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginBottom' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginLeft' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginRight' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'preferCssPageSize' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'generateDocumentOutline' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form file 'index.html' is required
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| omitBackground | true | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
omitBackground requires printBackground set to true
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| paperWidth | 0 | field |
|
||||
| paperHeight | 0 | field |
|
||||
| marginTop | 1000000 | field |
|
||||
| marginBottom | 1000000 | field |
|
||||
| marginLeft | 1000000 | field |
|
||||
| marginRight | 1000000 | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Chromium does not handle the provided settings; please check for aberrant form values
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| nativePageRanges | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Chromium does not handle the page ranges 'foo' (nativePageRanges)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| waitForExpression | undefined | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
The expression 'undefined' (waitForExpression) returned an exception or undefined
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| cookies | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'cookies' is invalid (got 'foo', resulting to unmarshal cookies: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| cookies | [{"name":"yummy_cookie","value":"choco"}] | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'cookies' is invalid (got '[{"name":"yummy_cookie","value":"choco"}]', resulting to cookie 0 must have its name, value and domain set)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| extraHttpHeaders | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'extraHttpHeaders' is invalid (got 'foo', resulting to unmarshal extraHttpHeaders: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| extraHttpHeaders | {"foo":"bar;scope;;"} | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'extraHttpHeaders' is invalid (got '{"foo":"bar;scope;;"}', resulting to invalid scope '' for header 'foo')
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| extraHttpHeaders | {"foo":"bar;scope=*."} | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'extraHttpHeaders' is invalid (got '{"foo":"bar;scope=*."}', resulting to invalid scope regex pattern for header 'foo': error parsing regexp: missing argument to repetition operator in `*.`)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| splitMode | foo | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitMode' is invalid (got 'foo', resulting to wrong value, expected either 'intervals' or 'pages')
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitSpan' is invalid (got 'foo', resulting to strconv.Atoi: parsing "foo": invalid syntax)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| pdfa | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| pdfua | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'pdfua' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| metadata | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'metadata' is invalid (got 'foo', resulting to unmarshal metadata: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Split Intervals)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-3-html/index.html | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
Then the "*_0.pdf" PDF should have 2 page(s)
|
||||
Then the "*_1.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "*_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "*_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Split Pages)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-3-html/index.html | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
Then the "*_0.pdf" PDF should have 1 page(s)
|
||||
Then the "*_1.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "*_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Split Pages & Unify)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-3-html/index.html | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
| splitUnify | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Split Many PDFs - Lot of Pages)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-12-html/index.html | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 1 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 12 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
| *_2.pdf |
|
||||
| *_3.pdf |
|
||||
| *_4.pdf |
|
||||
| *_5.pdf |
|
||||
| *_6.pdf |
|
||||
| *_7.pdf |
|
||||
| *_8.pdf |
|
||||
| *_9.pdf |
|
||||
| *_10.pdf |
|
||||
| *_11.pdf |
|
||||
Then the "*_0.pdf" PDF should have 1 page(s)
|
||||
Then the "*_11.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "*_11.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Split & PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-3-html/index.html | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
Then the "*_0.pdf" PDF should have 2 page(s)
|
||||
Then the "*_1.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "*_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "*_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Metadata)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| flatten | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be flatten
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (PDF/A-1b & PDF/UA-1 & Metadata & Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| flatten | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 7 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
Then the response PDF(s) should be flatten
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Routes Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_DISABLE_ROUTES | true |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| Gotenberg-Trace | forms_chromium_convert_html | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then the response header "Gotenberg-Trace" should be "forms_chromium_convert_html"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"forms_chromium_convert_html" |
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Download From)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| downloadFrom | [{"url":"http://host.docker.internal:%d/static/testdata/page-1-html/index.html","extraHttpHeaders":{"X-Foo":"bar"}}] | field |
|
||||
Then the response status code should be 200
|
||||
Then the file request header "X-Foo" should be "bar"
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Webhook)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a webhook server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
|
||||
| Gotenberg-Webhook-Error-Url | http://host.docker.internal:%d/webhook/error | header |
|
||||
Then the response status code should be 204
|
||||
When I wait for the asynchronous request to the webhook
|
||||
Then the webhook request header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the webhook request
|
||||
Then there should be the following file(s) in the webhook request:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/html (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: POST /foo/forms/chromium/convert/html (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "POST" request to Gotenberg at the "/foo/forms/chromium/convert/html" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-html/index.html | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
977
test/integration/features/chromium_convert_markdown.feature
Normal file
977
test/integration/features/chromium_convert_markdown.feature
Normal file
@@ -0,0 +1,977 @@
|
||||
Feature: /forms/chromium/convert/markdown
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Default)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Single Page)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-12-markdown/index.html | file |
|
||||
| files | testdata/pages-12-markdown/page_1.md | file |
|
||||
| files | testdata/pages-12-markdown/page_2.md | file |
|
||||
| files | testdata/pages-12-markdown/page_3.md | file |
|
||||
| files | testdata/pages-12-markdown/page_4.md | file |
|
||||
| files | testdata/pages-12-markdown/page_5.md | file |
|
||||
| files | testdata/pages-12-markdown/page_6.md | file |
|
||||
| files | testdata/pages-12-markdown/page_7.md | file |
|
||||
| files | testdata/pages-12-markdown/page_8.md | file |
|
||||
| files | testdata/pages-12-markdown/page_9.md | file |
|
||||
| files | testdata/pages-12-markdown/page_10.md | file |
|
||||
| files | testdata/pages-12-markdown/page_11.md | file |
|
||||
| files | testdata/pages-12-markdown/page_12.md | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 12 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 12:
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-12-markdown/index.html | file |
|
||||
| files | testdata/pages-12-markdown/page_1.md | file |
|
||||
| files | testdata/pages-12-markdown/page_2.md | file |
|
||||
| files | testdata/pages-12-markdown/page_3.md | file |
|
||||
| files | testdata/pages-12-markdown/page_4.md | file |
|
||||
| files | testdata/pages-12-markdown/page_5.md | file |
|
||||
| files | testdata/pages-12-markdown/page_6.md | file |
|
||||
| files | testdata/pages-12-markdown/page_7.md | file |
|
||||
| files | testdata/pages-12-markdown/page_8.md | file |
|
||||
| files | testdata/pages-12-markdown/page_9.md | file |
|
||||
| files | testdata/pages-12-markdown/page_10.md | file |
|
||||
| files | testdata/pages-12-markdown/page_11.md | file |
|
||||
| files | testdata/pages-12-markdown/page_12.md | file |
|
||||
| singlePage | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
# page-break-after: always; tells the browser's print engine to force a page break after each element,
|
||||
# even when calculating a large enough paper height, Chromium's PDF rendering will still honor those page break
|
||||
# directives.
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Landscape)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should NOT be set to landscape orientation
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| landscape | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should be set to landscape orientation
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Native Page Ranges)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-12-markdown/index.html | file |
|
||||
| files | testdata/pages-12-markdown/page_1.md | file |
|
||||
| files | testdata/pages-12-markdown/page_2.md | file |
|
||||
| files | testdata/pages-12-markdown/page_3.md | file |
|
||||
| files | testdata/pages-12-markdown/page_4.md | file |
|
||||
| files | testdata/pages-12-markdown/page_5.md | file |
|
||||
| files | testdata/pages-12-markdown/page_6.md | file |
|
||||
| files | testdata/pages-12-markdown/page_7.md | file |
|
||||
| files | testdata/pages-12-markdown/page_8.md | file |
|
||||
| files | testdata/pages-12-markdown/page_9.md | file |
|
||||
| files | testdata/pages-12-markdown/page_10.md | file |
|
||||
| files | testdata/pages-12-markdown/page_11.md | file |
|
||||
| files | testdata/pages-12-markdown/page_12.md | file |
|
||||
| nativePageRanges | 2-3 | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Header & Footer)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-12-markdown/index.html | file |
|
||||
| files | testdata/pages-12-markdown/page_1.md | file |
|
||||
| files | testdata/pages-12-markdown/page_2.md | file |
|
||||
| files | testdata/pages-12-markdown/page_3.md | file |
|
||||
| files | testdata/pages-12-markdown/page_4.md | file |
|
||||
| files | testdata/pages-12-markdown/page_5.md | file |
|
||||
| files | testdata/pages-12-markdown/page_6.md | file |
|
||||
| files | testdata/pages-12-markdown/page_7.md | file |
|
||||
| files | testdata/pages-12-markdown/page_8.md | file |
|
||||
| files | testdata/pages-12-markdown/page_9.md | file |
|
||||
| files | testdata/pages-12-markdown/page_10.md | file |
|
||||
| files | testdata/pages-12-markdown/page_11.md | file |
|
||||
| files | testdata/pages-12-markdown/page_12.md | file |
|
||||
| files | testdata/header-footer-html/header.html | file |
|
||||
| files | testdata/header-footer-html/footer.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 12 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Pages 12
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
1 of 12
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 12:
|
||||
"""
|
||||
Pages 12
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 12:
|
||||
"""
|
||||
12 of 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Wait Delay)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| waitDelay | 2.5s | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Wait For Expression)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| waitForExpression | window.globalVar === 'ready' | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Emulated Media Type)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'print'.
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'screen'.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| emulatedMediaType | print | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'print'.
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'screen'.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| emulatedMediaType | screen | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'screen'.
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'print'.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Default Allow / Deny Lists)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| 'file:///etc/passwd' matches the expression from the denied list |
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Main URL does NOT match allowed list)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_ALLOW_LIST | ^file:(?!//\\/tmp/).* |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
Then the response status code should be 403
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Forbidden
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Main URL does match denied list)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_ALLOW_LIST | |
|
||||
| CHROMIUM_DENY_LIST | ^file:///tmp.* |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
Then the response status code should be 403
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Forbidden
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Request does not match the allowed list)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_ALLOW_LIST | ^file:///tmp.* |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| 'file:///etc/passwd' does not match the expression from the allowed list |
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (JavaScript Enabled)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
JavaScript is enabled.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (JavaScript Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_DISABLE_JAVASCRIPT | true |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
JavaScript is enabled.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Fail On Resource HTTP Status Codes)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| failOnResourceHttpStatusCodes | [499,599] | field |
|
||||
Then the response status code should be 409
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid HTTP status code from resources:
|
||||
https://httpstat.us/400 - 400: Bad Request
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Fail On Resource Loading Failed)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| failOnResourceLoadingFailed | true | field |
|
||||
Then the response status code should be 409
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
Chromium failed to load resources
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
resource Stylesheet: net::ERR_CONNECTION_REFUSED
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
resource Stylesheet: net::ERR_FILE_NOT_FOUND
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Fail On Console Exceptions)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/feature-rich-markdown/index.html | file |
|
||||
| files | testdata/feature-rich-markdown/table.md | file |
|
||||
| failOnConsoleExceptions | true | field |
|
||||
Then the response status code should be 409
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
Chromium console exceptions
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
exception "Uncaught" (93:12): Error: Exception 1
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
exception "Uncaught" (97:12): Error: Exception 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Bad Request)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-3-markdown/index.html | file |
|
||||
| files | testdata/pages-3-markdown/page_1.md | file |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Markdown file(s) not found: 'page_2.md'; 'page_3.md'
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| singlePage | foo | field |
|
||||
| paperWidth | foo | field |
|
||||
| paperHeight | foo | field |
|
||||
| marginTop | foo | field |
|
||||
| marginBottom | foo | field |
|
||||
| marginLeft | foo | field |
|
||||
| marginRight | foo | field |
|
||||
| preferCssPageSize | foo | field |
|
||||
| generateDocumentOutline | foo | field |
|
||||
| printBackground | foo | field |
|
||||
| omitBackground | foo | field |
|
||||
| landscape | foo | field |
|
||||
| scale | foo | field |
|
||||
| waitDelay | foo | field |
|
||||
| emulatedMediaType | foo | field |
|
||||
| failOnHttpStatusCodes | foo | field |
|
||||
| failOnResourceHttpStatusCodes | foo | field |
|
||||
| failOnResourceLoadingFailed | foo | field |
|
||||
| failOnConsoleExceptions | foo | field |
|
||||
| skipNetworkIdleEvent | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'skipNetworkIdleEvent' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'failOnHttpStatusCodes' is invalid (got 'foo', resulting to unmarshal failOnHttpStatusCodes: invalid character 'o' in literal false (expecting 'a')); form field 'failOnResourceHttpStatusCodes' is invalid (got 'foo', resulting to unmarshal failOnResourceHttpStatusCodes: invalid character 'o' in literal false (expecting 'a')); form field 'failOnResourceLoadingFailed' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'failOnConsoleExceptions' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'waitDelay' is invalid (got 'foo', resulting to time: invalid duration "foo"); form field 'emulatedMediaType' is invalid (got 'foo', resulting to wrong value, expected either 'screen', 'print' or empty); form field 'omitBackground' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'landscape' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'printBackground' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'scale' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'singlePage' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'paperWidth' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'paperHeight' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginTop' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginBottom' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginLeft' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginRight' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'preferCssPageSize' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'generateDocumentOutline' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form file 'index.html' is required; no form file found for extensions: [.md]
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| omitBackground | true | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
omitBackground requires printBackground set to true
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| paperWidth | 0 | field |
|
||||
| paperHeight | 0 | field |
|
||||
| marginTop | 1000000 | field |
|
||||
| marginBottom | 1000000 | field |
|
||||
| marginLeft | 1000000 | field |
|
||||
| marginRight | 1000000 | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Chromium does not handle the provided settings; please check for aberrant form values
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| nativePageRanges | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Chromium does not handle the page ranges 'foo' (nativePageRanges)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| waitForExpression | undefined | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
The expression 'undefined' (waitForExpression) returned an exception or undefined
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| cookies | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'cookies' is invalid (got 'foo', resulting to unmarshal cookies: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| cookies | [{"name":"yummy_cookie","value":"choco"}] | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'cookies' is invalid (got '[{"name":"yummy_cookie","value":"choco"}]', resulting to cookie 0 must have its name, value and domain set)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| extraHttpHeaders | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'extraHttpHeaders' is invalid (got 'foo', resulting to unmarshal extraHttpHeaders: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| extraHttpHeaders | {"foo":"bar;scope;;"} | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'extraHttpHeaders' is invalid (got '{"foo":"bar;scope;;"}', resulting to invalid scope '' for header 'foo')
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| extraHttpHeaders | {"foo":"bar;scope=*."} | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'extraHttpHeaders' is invalid (got '{"foo":"bar;scope=*."}', resulting to invalid scope regex pattern for header 'foo': error parsing regexp: missing argument to repetition operator in `*.`)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| splitMode | foo | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitMode' is invalid (got 'foo', resulting to wrong value, expected either 'intervals' or 'pages')
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitSpan' is invalid (got 'foo', resulting to strconv.Atoi: parsing "foo": invalid syntax)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| pdfa | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| pdfua | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'pdfua' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| metadata | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'metadata' is invalid (got 'foo', resulting to unmarshal metadata: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Split Intervals)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-3-markdown/index.html | file |
|
||||
| files | testdata/pages-3-markdown/page_1.md | file |
|
||||
| files | testdata/pages-3-markdown/page_2.md | file |
|
||||
| files | testdata/pages-3-markdown/page_3.md | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
Then the "*_0.pdf" PDF should have 2 page(s)
|
||||
Then the "*_1.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "*_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "*_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Split Pages)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-3-markdown/index.html | file |
|
||||
| files | testdata/pages-3-markdown/page_1.md | file |
|
||||
| files | testdata/pages-3-markdown/page_2.md | file |
|
||||
| files | testdata/pages-3-markdown/page_3.md | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
Then the "*_0.pdf" PDF should have 1 page(s)
|
||||
Then the "*_1.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "*_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Split Pages & Unify)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-3-markdown/index.html | file |
|
||||
| files | testdata/pages-3-markdown/page_1.md | file |
|
||||
| files | testdata/pages-3-markdown/page_2.md | file |
|
||||
| files | testdata/pages-3-markdown/page_3.md | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
| splitUnify | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Split Many PDFs - Lot of Pages)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-12-markdown/index.html | file |
|
||||
| files | testdata/pages-12-markdown/page_1.md | file |
|
||||
| files | testdata/pages-12-markdown/page_2.md | file |
|
||||
| files | testdata/pages-12-markdown/page_3.md | file |
|
||||
| files | testdata/pages-12-markdown/page_4.md | file |
|
||||
| files | testdata/pages-12-markdown/page_5.md | file |
|
||||
| files | testdata/pages-12-markdown/page_6.md | file |
|
||||
| files | testdata/pages-12-markdown/page_7.md | file |
|
||||
| files | testdata/pages-12-markdown/page_8.md | file |
|
||||
| files | testdata/pages-12-markdown/page_9.md | file |
|
||||
| files | testdata/pages-12-markdown/page_10.md | file |
|
||||
| files | testdata/pages-12-markdown/page_11.md | file |
|
||||
| files | testdata/pages-12-markdown/page_12.md | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 1 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 12 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
| *_2.pdf |
|
||||
| *_3.pdf |
|
||||
| *_4.pdf |
|
||||
| *_5.pdf |
|
||||
| *_6.pdf |
|
||||
| *_7.pdf |
|
||||
| *_8.pdf |
|
||||
| *_9.pdf |
|
||||
| *_10.pdf |
|
||||
| *_11.pdf |
|
||||
Then the "*_0.pdf" PDF should have 1 page(s)
|
||||
Then the "*_11.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "*_11.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Split & PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages-3-markdown/index.html | file |
|
||||
| files | testdata/pages-3-markdown/page_1.md | file |
|
||||
| files | testdata/pages-3-markdown/page_2.md | file |
|
||||
| files | testdata/pages-3-markdown/page_3.md | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
Then the "*_0.pdf" PDF should have 2 page(s)
|
||||
Then the "*_1.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "*_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "*_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Metadata)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| flatten | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be flatten
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (PDF/A-1b & PDF/UA-1 & Metadata & Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| flatten | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 7 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
Then the response PDF(s) should be flatten
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Routes Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_DISABLE_ROUTES | true |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| Gotenberg-Trace | forms_chromium_convert_html | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then the response header "Gotenberg-Trace" should be "forms_chromium_convert_html"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"forms_chromium_convert_html" |
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Download From)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| downloadFrom | [{"url":"http://host.docker.internal:%d/static/testdata/page-1-markdown/index.html","extraHttpHeaders":{"X-Foo":"bar"}}] | field |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
Then the response status code should be 200
|
||||
Then the file request header "X-Foo" should be "bar"
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Webhook)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a webhook server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
|
||||
| Gotenberg-Webhook-Error-Url | http://host.docker.internal:%d/webhook/error | header |
|
||||
Then the response status code should be 204
|
||||
When I wait for the asynchronous request to the webhook
|
||||
Then the webhook request header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the webhook request
|
||||
Then there should be the following file(s) in the webhook request:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/markdown (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: POST /foo/forms/chromium/convert/markdown (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "POST" request to Gotenberg at the "/foo/forms/chromium/convert/markdown" endpoint with the following form data and header(s):
|
||||
| files | testdata/page-1-markdown/index.html | file |
|
||||
| files | testdata/page-1-markdown/page_1.md | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
929
test/integration/features/chromium_convert_url.feature
Normal file
929
test/integration/features/chromium_convert_url.feature
Normal file
@@ -0,0 +1,929 @@
|
||||
Feature: /forms/chromium/convert/url
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Default)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Single Page)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/pages-12-html/index.html | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 12 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 12:
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/pages-12-html/index.html | field |
|
||||
| singlePage | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
# page-break-after: always; tells the browser's print engine to force a page break after each element,
|
||||
# even when calculating a large enough paper height, Chromium's PDF rendering will still honor those page break
|
||||
# directives.
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Landscape)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should NOT be set to landscape orientation
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| landscape | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should be set to landscape orientation
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Native Page Ranges)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/pages-12-html/index.html | field |
|
||||
| nativePageRanges | 2-3 | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Header & Footer)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/pages-12-html/index.html | field |
|
||||
| files | testdata/header-footer-html/header.html | file |
|
||||
| files | testdata/header-footer-html/footer.html | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 12 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Pages 12
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
1 of 12
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 12:
|
||||
"""
|
||||
Pages 12
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 12:
|
||||
"""
|
||||
12 of 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Custom HTTP Headers)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| userAgent | Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) | field |
|
||||
| extraHttpHeaders | {"X-Header":"foo","X-Scoped-Header-1":"bar;scope=https?:\\/\\/([a-zA-Z0-9-]+\\\\.)*domain\\\\.com\\/.*","X-Scoped-Header-2":"baz;scope=https?:\\/\\/([a-zA-Z0-9-]+\\\\.)*docker\\\\.internal:(\\\\d+)\\/.*"} | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the server request header "User-Agent" should be "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)"
|
||||
Then the server request header "X-Header" should be "foo"
|
||||
Then the server request header "X-Scoped-Header-1" should be ""
|
||||
Then the server request header "X-Scoped-Header-2" should be "baz"
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Cookies)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| cookies | [{"name":"cookie_1","value":"foo","domain":"host.docker.internal:%d"},{"name":"cookie_2","value":"bar","domain":"domain.com"}] | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the server request cookie "cookie_1" should be "foo"
|
||||
Then the server request cookie "cookie_2" should be ""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Wait Delay)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| waitDelay | 2.5s | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Wait For Expression)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| waitForExpression | window.globalVar === 'ready' | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns true.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Emulated Media Type)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'print'.
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'screen'.
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| emulatedMediaType | print | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'print'.
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'screen'.
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| emulatedMediaType | screen | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'screen'.
|
||||
"""
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
Emulated media type is 'print'.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Default Allow / Deny Lists)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the Gotenberg container should NOT log the following entries:
|
||||
# Modern browsers block file URIs from being loaded into iframes when the parent page is served over HTTP/HTTPS.
|
||||
| 'file:///etc/passwd' matches the expression from the denied list |
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Main URL does NOT match allowed list)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_ALLOW_LIST | ^file:(?!//\\/tmp/).* |
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
Then the response status code should be 403
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Forbidden
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Main URL does match denied list)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_ALLOW_LIST | |
|
||||
| CHROMIUM_DENY_LIST | ^http.* |
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
Then the response status code should be 403
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Forbidden
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Request does not match the allowed list)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_ALLOW_LIST | ^.* |
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the Gotenberg container should NOT log the following entries:
|
||||
# Modern browsers block file URIs from being loaded into iframes when the parent page is served over HTTP/HTTPS.
|
||||
| 'file:///etc/passwd' does not match the expression from the allowed list |
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (JavaScript Enabled)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
JavaScript is enabled.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (JavaScript Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_DISABLE_JAVASCRIPT | true |
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should NOT have the following content at page 1:
|
||||
"""
|
||||
JavaScript is enabled.
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Fail On Resource HTTP Status Codes)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| failOnResourceHttpStatusCodes | [499,599] | field |
|
||||
Then the response status code should be 409
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
Invalid HTTP status code from resources:
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
/favicon.ico - 404: Not Found
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Fail On Resource Loading Failed)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| failOnResourceLoadingFailed | true | field |
|
||||
Then the response status code should be 409
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
Chromium failed to load resources
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
resource Stylesheet: net::ERR_CONNECTION_REFUSED
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Fail On Console Exceptions)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/feature-rich-html-remote/index.html | field |
|
||||
| failOnConsoleExceptions | true | field |
|
||||
Then the response status code should be 409
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
Chromium console exceptions
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
exception "Uncaught" (56:12): Error: Exception 1
|
||||
"""
|
||||
Then the response body should contain string:
|
||||
"""
|
||||
exception "Uncaught" (60:12): Error: Exception 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Bad Request)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| singlePage | foo | field |
|
||||
| paperWidth | foo | field |
|
||||
| paperHeight | foo | field |
|
||||
| marginTop | foo | field |
|
||||
| marginBottom | foo | field |
|
||||
| marginLeft | foo | field |
|
||||
| marginRight | foo | field |
|
||||
| preferCssPageSize | foo | field |
|
||||
| generateDocumentOutline | foo | field |
|
||||
| printBackground | foo | field |
|
||||
| omitBackground | foo | field |
|
||||
| landscape | foo | field |
|
||||
| scale | foo | field |
|
||||
| waitDelay | foo | field |
|
||||
| emulatedMediaType | foo | field |
|
||||
| failOnHttpStatusCodes | foo | field |
|
||||
| failOnResourceHttpStatusCodes | foo | field |
|
||||
| failOnResourceLoadingFailed | foo | field |
|
||||
| failOnConsoleExceptions | foo | field |
|
||||
| skipNetworkIdleEvent | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'skipNetworkIdleEvent' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'failOnHttpStatusCodes' is invalid (got 'foo', resulting to unmarshal failOnHttpStatusCodes: invalid character 'o' in literal false (expecting 'a')); form field 'failOnResourceHttpStatusCodes' is invalid (got 'foo', resulting to unmarshal failOnResourceHttpStatusCodes: invalid character 'o' in literal false (expecting 'a')); form field 'failOnResourceLoadingFailed' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'failOnConsoleExceptions' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'waitDelay' is invalid (got 'foo', resulting to time: invalid duration "foo"); form field 'emulatedMediaType' is invalid (got 'foo', resulting to wrong value, expected either 'screen', 'print' or empty); form field 'omitBackground' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'landscape' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'printBackground' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'scale' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'singlePage' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'paperWidth' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'paperHeight' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginTop' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginBottom' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginLeft' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'marginRight' is invalid (got 'foo', resulting to strconv.ParseFloat: parsing "foo": invalid syntax); form field 'preferCssPageSize' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'generateDocumentOutline' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'url' is required
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| omitBackground | true | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
omitBackground requires printBackground set to true
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| paperWidth | 0 | field |
|
||||
| paperHeight | 0 | field |
|
||||
| marginTop | 1000000 | field |
|
||||
| marginBottom | 1000000 | field |
|
||||
| marginLeft | 1000000 | field |
|
||||
| marginRight | 1000000 | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Chromium does not handle the provided settings; please check for aberrant form values
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| nativePageRanges | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Chromium does not handle the page ranges 'foo' (nativePageRanges)
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| waitForExpression | undefined | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
The expression 'undefined' (waitForExpression) returned an exception or undefined
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| cookies | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'cookies' is invalid (got 'foo', resulting to unmarshal cookies: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| cookies | [{"name":"yummy_cookie","value":"choco"}] | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'cookies' is invalid (got '[{"name":"yummy_cookie","value":"choco"}]', resulting to cookie 0 must have its name, value and domain set)
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| extraHttpHeaders | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'extraHttpHeaders' is invalid (got 'foo', resulting to unmarshal extraHttpHeaders: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| extraHttpHeaders | {"foo":"bar;scope;;"} | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'extraHttpHeaders' is invalid (got '{"foo":"bar;scope;;"}', resulting to invalid scope '' for header 'foo')
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| extraHttpHeaders | {"foo":"bar;scope=*."} | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'extraHttpHeaders' is invalid (got '{"foo":"bar;scope=*."}', resulting to invalid scope regex pattern for header 'foo': error parsing regexp: missing argument to repetition operator in `*.`)
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| splitMode | foo | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitMode' is invalid (got 'foo', resulting to wrong value, expected either 'intervals' or 'pages')
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitSpan' is invalid (got 'foo', resulting to strconv.Atoi: parsing "foo": invalid syntax)
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| pdfa | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| pdfua | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'pdfua' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax)
|
||||
"""
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| metadata | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'metadata' is invalid (got 'foo', resulting to unmarshal metadata: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Split Intervals)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/pages-3-html/index.html | field |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
Then the "*_0.pdf" PDF should have 2 page(s)
|
||||
Then the "*_1.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "*_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "*_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Split Pages)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/pages-3-html/index.html | field |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
Then the "*_0.pdf" PDF should have 1 page(s)
|
||||
Then the "*_1.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "*_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Split Pages & Unify)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/pages-3-html/index.html | field |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
| splitUnify | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Split Many PDFs - Lot of Pages)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/pages-12-html/index.html | field |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 1 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 12 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
| *_2.pdf |
|
||||
| *_3.pdf |
|
||||
| *_4.pdf |
|
||||
| *_5.pdf |
|
||||
| *_6.pdf |
|
||||
| *_7.pdf |
|
||||
| *_8.pdf |
|
||||
| *_9.pdf |
|
||||
| *_10.pdf |
|
||||
| *_11.pdf |
|
||||
Then the "*_0.pdf" PDF should have 1 page(s)
|
||||
Then the "*_11.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "*_11.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Split & PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/pages-3-html/index.html | field |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
Then the "*_0.pdf" PDF should have 2 page(s)
|
||||
Then the "*_1.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "*_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "*_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Metadata)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| flatten | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be flatten
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (PDF/A-1b & PDF/UA-1 & Metadata & Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| flatten | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 7 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
Then the response PDF(s) should be flatten
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Routes Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| CHROMIUM_DISABLE_ROUTES | true |
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| Gotenberg-Trace | forms_chromium_convert_url | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then the response header "Gotenberg-Trace" should be "forms_chromium_convert_url"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"forms_chromium_convert_url" |
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Webhook)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a webhook server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
|
||||
| Gotenberg-Webhook-Error-Url | http://host.docker.internal:%d/webhook/error | header |
|
||||
Then the response status code should be 204
|
||||
When I wait for the asynchronous request to the webhook
|
||||
Then the webhook request header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the webhook request
|
||||
Then there should be the following file(s) in the webhook request:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/chromium/convert/url (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: POST /foo/forms/chromium/convert/url (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/foo/forms/chromium/convert/url" endpoint with the following form data and header(s):
|
||||
| url | http://host.docker.internal:%d/html/testdata/page-1-html/index.html | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
147
test/integration/features/debug.feature
Normal file
147
test/integration/features/debug.feature
Normal file
@@ -0,0 +1,147 @@
|
||||
Feature: /debug
|
||||
|
||||
Scenario: GET /debug (Disabled)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/debug" endpoint
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: GET /debug (Enabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
When I make a "GET" request to Gotenberg at the "/debug" endpoint
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"version": "{version}",
|
||||
"architecture": "ignore",
|
||||
"modules": [
|
||||
"api",
|
||||
"chromium",
|
||||
"exiftool",
|
||||
"libreoffice",
|
||||
"libreoffice-api",
|
||||
"libreoffice-pdfengine",
|
||||
"logging",
|
||||
"pdfcpu",
|
||||
"pdfengines",
|
||||
"pdftk",
|
||||
"prometheus",
|
||||
"qpdf",
|
||||
"webhook"
|
||||
],
|
||||
"modules_additional_data": {
|
||||
"chromium": {
|
||||
"version": "ignore"
|
||||
},
|
||||
"exiftool": {
|
||||
"version": "ignore"
|
||||
},
|
||||
"libreoffice-api": {
|
||||
"version": "ignore"
|
||||
},
|
||||
"pdfcpu": {
|
||||
"version": "ignore"
|
||||
},
|
||||
"pdftk": {
|
||||
"version": "ignore"
|
||||
},
|
||||
"qpdf": {
|
||||
"version": "ignore"
|
||||
}
|
||||
},
|
||||
"flags": {
|
||||
"api-bind-ip": "",
|
||||
"api-body-limit": "",
|
||||
"api-disable-download-from": "false",
|
||||
"api-disable-health-check-logging": "false",
|
||||
"api-download-from-allow-list": "",
|
||||
"api-download-from-deny-list": "",
|
||||
"api-download-from-max-retry": "4",
|
||||
"api-enable-basic-auth": "false",
|
||||
"api-enable-debug-route": "true",
|
||||
"api-port": "3000",
|
||||
"api-port-from-env": "",
|
||||
"api-root-path": "/",
|
||||
"api-start-timeout": "30s",
|
||||
"api-timeout": "30s",
|
||||
"api-tls-cert-file": "",
|
||||
"api-tls-key-file": "",
|
||||
"api-trace-header": "Gotenberg-Trace",
|
||||
"chromium-allow-file-access-from-files": "false",
|
||||
"chromium-allow-insecure-localhost": "false",
|
||||
"chromium-allow-list": "",
|
||||
"chromium-auto-start": "false",
|
||||
"chromium-clear-cache": "false",
|
||||
"chromium-clear-cookies": "false",
|
||||
"chromium-deny-list": "^file:(?!//\\/tmp/).*",
|
||||
"chromium-disable-javascript": "false",
|
||||
"chromium-disable-routes": "false",
|
||||
"chromium-disable-web-security": "false",
|
||||
"chromium-host-resolver-rules": "",
|
||||
"chromium-ignore-certificate-errors": "false",
|
||||
"chromium-incognito": "false",
|
||||
"chromium-max-queue-size": "0",
|
||||
"chromium-proxy-server": "",
|
||||
"chromium-restart-after": "10",
|
||||
"chromium-start-timeout": "20s",
|
||||
"gotenberg-graceful-shutdown-duration": "30s",
|
||||
"libreoffice-auto-start": "false",
|
||||
"libreoffice-disable-routes": "false",
|
||||
"libreoffice-max-queue-size": "0",
|
||||
"libreoffice-restart-after": "10",
|
||||
"libreoffice-start-timeout": "20s",
|
||||
"log-fields-prefix": "",
|
||||
"log-format": "auto",
|
||||
"log-level": "info",
|
||||
"pdfengines-convert-engines": "[libreoffice-pdfengine]",
|
||||
"pdfengines-disable-routes": "false",
|
||||
"pdfengines-engines": "[]",
|
||||
"pdfengines-flatten-engines": "[qpdf]",
|
||||
"pdfengines-merge-engines": "[qpdf,pdfcpu,pdftk]",
|
||||
"pdfengines-read-metadata-engines": "[exiftool]",
|
||||
"pdfengines-split-engines": "[pdfcpu,qpdf,pdftk]",
|
||||
"pdfengines-write-metadata-engines": "[exiftool]",
|
||||
"prometheus-collect-interval": "1s",
|
||||
"prometheus-disable-collect": "false",
|
||||
"prometheus-disable-route-logging": "false",
|
||||
"prometheus-namespace": "gotenberg",
|
||||
"webhook-allow-list": "",
|
||||
"webhook-client-timeout": "30s",
|
||||
"webhook-deny-list": "",
|
||||
"webhook-disable": "false",
|
||||
"webhook-error-allow-list": "",
|
||||
"webhook-error-deny-list": "",
|
||||
"webhook-max-retry": "4",
|
||||
"webhook-retry-max-wait": "30s",
|
||||
"webhook-retry-min-wait": "1s"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: GET /debug (Gotenberg Trace)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
When I make a "GET" request to Gotenberg at the "/debug" endpoint with the following header(s):
|
||||
| Gotenberg-Trace | debug |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Gotenberg-Trace" should be "debug"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"debug" |
|
||||
|
||||
Scenario: GET /debug (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "GET" request to Gotenberg at the "/debug" endpoint
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: GET /foo/debug (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "GET" request to Gotenberg at the "/foo/debug" endpoint
|
||||
Then the response status code should be 200
|
||||
107
test/integration/features/health.feature
Normal file
107
test/integration/features/health.feature
Normal file
@@ -0,0 +1,107 @@
|
||||
# TODO:
|
||||
# 1. Check if down for each module.
|
||||
# 2. Restarting modules do not make health check fail.
|
||||
|
||||
Feature: /health
|
||||
|
||||
Scenario: GET /health
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/health" endpoint
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json; charset=utf-8"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"status": "up",
|
||||
"details": {
|
||||
"chromium": {
|
||||
"status": "up",
|
||||
"timestamp": "ignore"
|
||||
},
|
||||
"libreoffice": {
|
||||
"status": "up",
|
||||
"timestamp": "ignore"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "path":"/health" |
|
||||
|
||||
Scenario: GET /health (No Logging)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_DISABLE_HEALTH_CHECK_LOGGING | true |
|
||||
When I make a "GET" request to Gotenberg at the "/health" endpoint
|
||||
Then the response status code should be 200
|
||||
Then the Gotenberg container should NOT log the following entries:
|
||||
| "path":"/health" |
|
||||
|
||||
Scenario: GET /health (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/health" endpoint with the following header(s):
|
||||
| Gotenberg-Trace | get_health |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Gotenberg-Trace" should be "get_health"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"get_health" |
|
||||
|
||||
Scenario: GET /health (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "GET" request to Gotenberg at the "/health" endpoint
|
||||
Then the response status code should be 200
|
||||
|
||||
Scenario: GET /foo/health (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "GET" request to Gotenberg at the "/foo/health" endpoint
|
||||
Then the response status code should be 200
|
||||
|
||||
Scenario: HEAD /health
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "HEAD" request to Gotenberg at the "/health" endpoint
|
||||
Then the response status code should be 200
|
||||
Then the response body should match string:
|
||||
"""
|
||||
|
||||
"""
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "path":"/health" |
|
||||
|
||||
Scenario: HEAD /health (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "HEAD" request to Gotenberg at the "/health" endpoint with the following header(s):
|
||||
| Gotenberg-Trace | head_health |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Gotenberg-Trace" should be "head_health"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"head_health" |
|
||||
|
||||
Scenario: HEAD /health (No Logging)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_DISABLE_HEALTH_CHECK_LOGGING | true |
|
||||
When I make a "HEAD" request to Gotenberg at the "/health" endpoint
|
||||
Then the response status code should be 200
|
||||
Then the Gotenberg container should NOT log the following entries:
|
||||
| "path":"/health" |
|
||||
|
||||
Scenario: HEAD /health (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "HEAD" request to Gotenberg at the "/health" endpoint
|
||||
Then the response status code should be 200
|
||||
|
||||
Scenario: HEAD /foo/health (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "HEAD" request to Gotenberg at the "/foo/health" endpoint
|
||||
Then the response status code should be 200
|
||||
|
||||
|
||||
# TODO:
|
||||
# 1. Check if down for each module.
|
||||
# 2. Restarting modules do not make health check fail.
|
||||
614
test/integration/features/libreoffice_convert.feature
Normal file
614
test/integration/features/libreoffice_convert.feature
Normal file
@@ -0,0 +1,614 @@
|
||||
Feature: /forms/libreoffice/convert
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Single Document)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Many Documents)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| files | testdata/page_2.docx | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.zip |
|
||||
| page_1.docx.pdf |
|
||||
| page_2.docx.pdf |
|
||||
Then the "page_1.docx.pdf" PDF should have 1 page(s)
|
||||
Then the "page_2.docx.pdf" PDF should have 1 page(s)
|
||||
Then the "page_1.docx.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "page_2.docx.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Protected)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/protected_page_1.docx | file |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
LibreOffice failed to process a document: a password may be required, or, if one has been given, it is invalid. In any case, the exact cause is uncertain.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/protected_page_1.docx | file |
|
||||
| password | foo | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Landscape)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should NOT be set to landscape orientation
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| landscape | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should be set to landscape orientation
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Native Page Ranges - Single Document)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| nativePageRanges | 2-3 | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Native Page Ranges - Many Documents)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| files | testdata/pages_12.docx | file |
|
||||
| nativePageRanges | 2-3 | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.zip |
|
||||
| pages_3.docx.pdf |
|
||||
| pages_12.docx.pdf |
|
||||
Then the "pages_3.docx.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_12.docx.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3.docx.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3.docx.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
Then the "pages_12.docx.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_12.docx.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Bad Request)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| landscape | foo | field |
|
||||
| exportFormFields | foo | field |
|
||||
| allowDuplicateFieldNames | foo | field |
|
||||
| exportBookmarks | foo | field |
|
||||
| exportBookmarksToPdfDestination | foo | field |
|
||||
| exportPlaceholders | foo | field |
|
||||
| exportNotes | foo | field |
|
||||
| exportNotesPages | foo | field |
|
||||
| exportOnlyNotesPages | foo | field |
|
||||
| exportNotesInMargin | foo | field |
|
||||
| convertOooTargetToPdfTarget | foo | field |
|
||||
| exportLinksRelativeFsys | foo | field |
|
||||
| exportHiddenSlides | foo | field |
|
||||
| skipEmptyPages | foo | field |
|
||||
| addOriginalDocumentAsStream | foo | field |
|
||||
| singlePageSheets | foo | field |
|
||||
| losslessImageCompression | foo | field |
|
||||
| quality | -1 | field |
|
||||
| reduceImageResolution | foo | field |
|
||||
| maxImageResolution | 10 | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: no form file found for extensions: [.123 .602 .abw .bib .bmp .cdr .cgm .cmx .csv .cwk .dbf .dif .doc .docm .docx .dot .dotm .dotx .dxf .emf .eps .epub .fodg .fodp .fods .fodt .fopd .gif .htm .html .hwp .jpeg .jpg .key .ltx .lwp .mcw .met .mml .mw .numbers .odd .odg .odm .odp .ods .odt .otg .oth .otp .ots .ott .pages .pbm .pcd .pct .pcx .pdb .pdf .pgm .png .pot .potm .potx .ppm .pps .ppt .pptm .pptx .psd .psw .pub .pwp .pxl .ras .rtf .sda .sdc .sdd .sdp .sdw .sgl .slk .smf .stc .std .sti .stw .svg .svm .swf .sxc .sxd .sxg .sxi .sxm .sxw .tga .tif .tiff .txt .uof .uop .uos .uot .vdx .vor .vsd .vsdm .vsdx .wb2 .wk1 .wks .wmf .wpd .wpg .wps .xbm .xhtml .xls .xlsb .xlsm .xlsx .xlt .xltm .xltx .xlw .xml .xpm .zabw]; form field 'landscape' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'exportFormFields' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'allowDuplicateFieldNames' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'exportBookmarks' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'exportBookmarksToPdfDestination' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'exportPlaceholders' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'exportNotes' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'exportNotesPages' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'exportOnlyNotesPages' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'exportNotesInMargin' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'convertOooTargetToPdfTarget' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'exportLinksRelativeFsys' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'exportHiddenSlides' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'skipEmptyPages' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'addOriginalDocumentAsStream' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'singlePageSheets' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'losslessImageCompression' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'quality' is invalid (got '-1', resulting to value is inferior to 1); form field 'reduceImageResolution' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax); form field 'maxImageResolution' is invalid (got '10', resulting to value is not 75, 150, 300, 600 or 1200)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| nativePageRanges | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
LibreOffice failed to process a document: possible causes include malformed page ranges 'foo' (nativePageRanges), or, if a password has been provided, it may not be required. In any case, the exact cause is uncertain.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| password | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
LibreOffice failed to process a document: possible causes include malformed page ranges '' (nativePageRanges), or, if a password has been provided, it may not be required. In any case, the exact cause is uncertain.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/protected_page_1.docx | file |
|
||||
| password | bar | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
LibreOffice failed to process a document: a password may be required, or, if one has been given, it is invalid. In any case, the exact cause is uncertain.
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| files | testdata/page_2.docx | file |
|
||||
| merge | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'merge' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| splitMode | foo | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitMode' is invalid (got 'foo', resulting to wrong value, expected either 'intervals' or 'pages')
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitSpan' is invalid (got 'foo', resulting to strconv.Atoi: parsing "foo": invalid syntax)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| pdfa | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
A PDF format in '{PdfA:foo PdfUa:false}' is not supported
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| pdfua | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'pdfua' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| metadata | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'metadata' is invalid (got 'foo', resulting to unmarshal metadata: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Merge)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| files | testdata/page_2.docx | file |
|
||||
| merge | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Merge & Split)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| files | testdata/page_2.docx | file |
|
||||
| merge | true | field |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 1 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| *_0.pdf |
|
||||
| *_1.pdf |
|
||||
Then the "*_0.pdf" PDF should have 1 page(s)
|
||||
Then the "*_1.pdf" PDF should have 1 page(s)
|
||||
Then the "*_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "*_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Split Intervals)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3.docx_0.pdf |
|
||||
| pages_3.docx_1.pdf |
|
||||
Then the "pages_3.docx_0.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3.docx_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3.docx_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3.docx_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3.docx_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Split Pages)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3.docx_0.pdf |
|
||||
| pages_3.docx_1.pdf |
|
||||
Then the "pages_3.docx_0.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3.docx_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3.docx_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3.docx_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Split Pages & Unify)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
| splitUnify | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3.docx.pdf |
|
||||
Then the "pages_3.docx.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3.docx.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3.docx.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Split Many PDFs - Lot of Pages)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_12.docx | file |
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 1 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 15 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3.docx_0.pdf |
|
||||
| pages_3.docx_1.pdf |
|
||||
| pages_3.docx_2.pdf |
|
||||
| pages_12.docx_0.pdf |
|
||||
| pages_12.docx_1.pdf |
|
||||
| pages_12.docx_2.pdf |
|
||||
| pages_12.docx_3.pdf |
|
||||
| pages_12.docx_4.pdf |
|
||||
| pages_12.docx_5.pdf |
|
||||
| pages_12.docx_6.pdf |
|
||||
| pages_12.docx_7.pdf |
|
||||
| pages_12.docx_8.pdf |
|
||||
| pages_12.docx_9.pdf |
|
||||
| pages_12.docx_10.pdf |
|
||||
| pages_12.docx_11.pdf |
|
||||
Then the "pages_3.docx_0.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3.docx_2.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_12.docx_0.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_12.docx_11.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3.docx_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3.docx_2.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
Then the "pages_12.docx_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_12.docx_11.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Split & PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.docx | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3.docx_0.pdf |
|
||||
| pages_3.docx_1.pdf |
|
||||
Then the "pages_3.docx_0.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3.docx_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3.docx_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3.docx_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3.docx_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Metadata)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| flatten | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be flatten
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (PDF/A-1b & PDF/UA-1 & Metadata & Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| flatten | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 7 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
Then the response PDF(s) should be flatten
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Routes Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| LIBREOFFICE_DISABLE_ROUTES | true |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| Gotenberg-Trace | forms_libreoffice_convert | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then the response header "Gotenberg-Trace" should be "forms_libreoffice_convert"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"forms_libreoffice_convert" |
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Download From)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| downloadFrom | [{"url":"http://host.docker.internal:%d/static/testdata/page_1.docx","extraHttpHeaders":{"X-Foo":"bar"}}] | field |
|
||||
Then the response status code should be 200
|
||||
Then the file request header "X-Foo" should be "bar"
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Webhook)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a webhook server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
|
||||
| Gotenberg-Webhook-Error-Url | http://host.docker.internal:%d/webhook/error | header |
|
||||
Then the response status code should be 204
|
||||
When I wait for the asynchronous request to the webhook
|
||||
Then the webhook request header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the webhook request
|
||||
Then there should be the following file(s) in the webhook request:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 1 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/libreoffice/convert (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: POST /foo/forms/libreoffice/convert (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "POST" request to Gotenberg at the "/foo/forms/libreoffice/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.docx | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
185
test/integration/features/pdfengines_convert.feature
Normal file
185
test/integration/features/pdfengines_convert.feature
Normal file
@@ -0,0 +1,185 @@
|
||||
# TODO:
|
||||
# 1. PDF/UA-2.
|
||||
|
||||
Feature: /forms/pdfengines/convert
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Single PDF/A-1b)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Single PDF/A-2b)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfa | PDF/A-2b | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be valid "PDF/A-2b" with a tolerance of 1 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Single PDF/A-3b)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfa | PDF/A-3b | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be valid "PDF/A-3b" with a tolerance of 1 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Single PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Single PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Many PDFs)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Bad Request)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: either 'pdfa' or 'pdfua' form fields must be provided
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| pdfa | PDF/A-1b | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: no form file found for extensions: [.pdf]
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfa | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfua | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'pdfua' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax)
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| Gotenberg-Trace | forms_pdfengines_convert | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then the response header "Gotenberg-Trace" should be "forms_pdfengines_convert"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"forms_pdfengines_convert" |
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Output Filename - Single PDF)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Output Filename - Many PDFs)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.zip |
|
||||
| page_1.pdf |
|
||||
| page_2.pdf |
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Download From)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| downloadFrom | [{"url":"http://host.docker.internal:%d/static/testdata/page_1.pdf","extraHttpHeaders":{"X-Foo":"bar"}}] | field |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
Then the file request header "X-Foo" should be "bar"
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Webhook)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a webhook server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
|
||||
| Gotenberg-Webhook-Error-Url | http://host.docker.internal:%d/webhook/error | header |
|
||||
Then the response status code should be 204
|
||||
When I wait for the asynchronous request to the webhook
|
||||
Then the webhook request header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the webhook request
|
||||
Then the webhook request PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/pdfengines/convert (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: POST /foo/forms/pdfengines/convert (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "POST" request to Gotenberg at the "/foo/forms/pdfengines/convert" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
112
test/integration/features/pdfengines_flatten.feature
Normal file
112
test/integration/features/pdfengines_flatten.feature
Normal file
@@ -0,0 +1,112 @@
|
||||
Feature: /forms/pdfengines/flatten
|
||||
|
||||
Scenario: POST /forms/pdfengines/flatten (Single PDF)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then the response PDF(s) should be flatten
|
||||
|
||||
Scenario: POST /forms/pdfengines/flatten (Many PDFs)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then the response PDF(s) should be flatten
|
||||
|
||||
Scenario: POST /forms/pdfengines/flatten (Bad Request)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: no form file found for extensions: [.pdf]
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/flatten (Routes Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_DISABLE_ROUTES | true |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: POST /forms/pdfengines/flatten (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| Gotenberg-Trace | forms_pdfengines_flatten | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then the response header "Gotenberg-Trace" should be "forms_pdfengines_flatten"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"forms_pdfengines_flatten" |
|
||||
|
||||
Scenario: POST /forms/pdfengines/flatten (Output Filename - Single PDF)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
|
||||
Scenario: POST /forms/pdfengines/flatten (Output Filename - Many PDFs)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.zip |
|
||||
| page_1.pdf |
|
||||
| page_2.pdf |
|
||||
|
||||
Scenario: POST /forms/pdfengines/flatten (Download From)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| downloadFrom | [{"url":"http://host.docker.internal:%d/static/testdata/page_1.pdf","extraHttpHeaders":{"X-Foo":"bar"}}] | field |
|
||||
Then the file request header "X-Foo" should be "bar"
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
|
||||
Scenario: POST /forms/pdfengines/flatten (Webhook)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a webhook server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
|
||||
| Gotenberg-Webhook-Error-Url | http://host.docker.internal:%d/webhook/error | header |
|
||||
Then the response status code should be 204
|
||||
When I wait for the asynchronous request to the webhook
|
||||
Then the webhook request header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the webhook request
|
||||
Then the response PDF(s) should be flatten
|
||||
|
||||
Scenario: POST /forms/pdfengines/flatten (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: POST /foo/forms/pdfengines/flatten (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "POST" request to Gotenberg at the "/foo/forms/pdfengines/flatten" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
324
test/integration/features/pdfengines_merge.feature
Normal file
324
test/integration/features/pdfengines_merge.feature
Normal file
@@ -0,0 +1,324 @@
|
||||
Feature: /forms/pdfengines/merge
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (default - QPDF)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (pdfcpu)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_MERGE_ENGINES | pdfcpu |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (PDFtk)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_MERGE_ENGINES | pdftk |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (Bad Request)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: no form file found for extensions: [.pdf]
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| pdfa | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| pdfua | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'pdfua' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| metadata | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'metadata' is invalid (got 'foo', resulting to unmarshal metadata: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (Metadata)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| flatten | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the response PDF(s) should be flatten
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (PDF/A-1b & PDF/UA-1 & Metadata & Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| flatten | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 7 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
Then the response PDF(s) should be flatten
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (Routes Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_DISABLE_ROUTES | true |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| Gotenberg-Trace | forms_pdfengines_merge | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then the response header "Gotenberg-Trace" should be "forms_pdfengines_merge"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"forms_pdfengines_merge" |
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (Download From)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| downloadFrom | [{"url":"http://host.docker.internal:%d/static/testdata/page_1.pdf"},{"url":"http://host.docker.internal:%d/static/testdata/page_2.pdf"}] | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (Webhook)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a webhook server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
|
||||
| Gotenberg-Webhook-Error-Url | http://host.docker.internal:%d/webhook/error | header |
|
||||
Then the response status code should be 204
|
||||
When I wait for the asynchronous request to the webhook
|
||||
Then the webhook request header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the webhook request
|
||||
Then there should be the following file(s) in the webhook request:
|
||||
| foo.pdf |
|
||||
Then the "foo.pdf" PDF should have 2 page(s)
|
||||
Then the "foo.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "foo.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/merge (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: POST /foo/forms/pdfengines/merge (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "POST" request to Gotenberg at the "/foo/forms/pdfengines/merge" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
268
test/integration/features/pdfengines_metadata.feature
Normal file
268
test/integration/features/pdfengines_metadata.feature
Normal file
@@ -0,0 +1,268 @@
|
||||
Feature: /forms/pdfengines/{write|read}
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/{write|read} (Single PDF)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/{write|read} (Many PDFs)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files. | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/page_1.pdf | file |
|
||||
| files | teststore/page_2.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"page_1.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
},
|
||||
"page_2.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/write (Bad Request)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'metadata' is required; no form file found for extensions: [.pdf]
|
||||
"""
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| metadata | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'metadata' is invalid (got 'foo', resulting to unmarshal metadata: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/read (Bad Request)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: no form file found for extensions: [.pdf]
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/write (Routes Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_DISABLE_ROUTES | true |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/read (Routes Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_DISABLE_ROUTES | true |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/write (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Trace | forms_pdfengines_metadata_write | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then the response header "Gotenberg-Trace" should be "forms_pdfengines_metadata_write"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"forms_pdfengines_metadata_write" |
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/read (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| Gotenberg-Trace | forms_pdfengines_metadata_read | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response header "Gotenberg-Trace" should be "forms_pdfengines_metadata_read"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"forms_pdfengines_metadata_read" |
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/write (Output Filename - Single PDF)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/write (Output Filename - Many PDFs)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| files | testdata/page_2.pdf | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.zip |
|
||||
| page_1.pdf |
|
||||
| page_2.pdf |
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/write (Download From)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| downloadFrom | [{"url":"http://host.docker.internal:%d/static/testdata/page_1.pdf","extraHttpHeaders":{"X-Foo":"bar"}}] | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the file request header "X-Foo" should be "bar"
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/read (Download From)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| downloadFrom | [{"url":"http://host.docker.internal:%d/static/testdata/page_1.pdf","extraHttpHeaders":{"X-Foo":"bar"}}] | field |
|
||||
Then the file request header "X-Foo" should be "bar"
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/write (Webhook)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a webhook server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
|
||||
| Gotenberg-Webhook-Error-Url | http://host.docker.internal:%d/webhook/error | header |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 204
|
||||
When I wait for the asynchronous request to the webhook
|
||||
Then the webhook request header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the webhook request
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"foo.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/write (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: POST /forms/pdfengines/metadata/read (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: POST /foo/forms/pdfengines/metadata/{write|read} (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "POST" request to Gotenberg at the "/foo/forms/pdfengines/metadata/write" endpoint with the following form data and header(s):
|
||||
| files | testdata/page_1.pdf | file |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
When I make a "POST" request to Gotenberg at the "/foo/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/foo.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
551
test/integration/features/pdfengines_split.feature
Normal file
551
test/integration/features/pdfengines_split.feature
Normal file
@@ -0,0 +1,551 @@
|
||||
Feature: /forms/pdfengines/split
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Intervals - Default - pdfcpu)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
Then the "pages_3_0.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Pages - Default - pdfcpu)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
Then the "pages_3_0.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Pages & Unify - Default - pdfcpu)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
| splitUnify | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3.pdf |
|
||||
Then the "pages_3.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Pages & Unify - QPDF)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_SPLIT_ENGINES | qpdf |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2-z | field |
|
||||
| splitUnify | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3.pdf |
|
||||
Then the "pages_3.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Pages & Unify - PDFtk)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_SPLIT_ENGINES | pdftk |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2-end | field |
|
||||
| splitUnify | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be 1 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3.pdf |
|
||||
Then the "pages_3.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Many PDFs - Lot of Pages)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_12.pdf | file |
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 1 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 15 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
| pages_3_2.pdf |
|
||||
| pages_12_0.pdf |
|
||||
| pages_12_1.pdf |
|
||||
| pages_12_2.pdf |
|
||||
| pages_12_3.pdf |
|
||||
| pages_12_4.pdf |
|
||||
| pages_12_5.pdf |
|
||||
| pages_12_6.pdf |
|
||||
| pages_12_7.pdf |
|
||||
| pages_12_8.pdf |
|
||||
| pages_12_9.pdf |
|
||||
| pages_12_10.pdf |
|
||||
| pages_12_11.pdf |
|
||||
Then the "pages_3_0.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_2.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_12_0.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_12_11.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3_2.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
Then the "pages_12_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_12_11.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 12
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Bad Request)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitMode' is required; form field 'splitSpan' is required; no form file found for extensions: [.pdf]
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | foo | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitMode' is invalid (got 'foo', resulting to wrong value, expected either 'intervals' or 'pages')
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'splitSpan' is invalid (got 'foo', resulting to strconv.Atoi: parsing "foo": invalid syntax)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| pdfa | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| pdfua | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'pdfua' is invalid (got 'foo', resulting to strconv.ParseBool: parsing "foo": invalid syntax)
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| metadata | foo | field |
|
||||
Then the response status code should be 400
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Invalid form data: form field 'metadata' is invalid (got 'foo', resulting to unmarshal metadata: invalid character 'o' in literal false (expecting 'a'))
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (PDF/A-1b & PDF/UA-1)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
Then the "pages_3_0.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 1 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Metadata)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
Then the "pages_3_0.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/pages_3_0.pdf | file |
|
||||
| files | teststore/pages_3_1.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"pages_3_0.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
},
|
||||
"pages_3_1.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| flatten | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
Then the "pages_3_0.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
Then the response PDF(s) should be flatten
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (PDF/A-1b & PDF/UA-1 & Metadata & Flatten)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| pdfa | PDF/A-1b | field |
|
||||
| pdfua | true | field |
|
||||
| metadata | {"Author":"Julien Neuhart","Copyright":"Julien Neuhart","CreateDate":"2006-09-18T16:27:50-04:00","Creator":"Gotenberg","Keywords":["first","second"],"Marked":true,"ModDate":"2006-09-18T16:27:50-04:00","PDFVersion":1.7,"Producer":"Gotenberg","Subject":"Sample","Title":"Sample","Trapped":"Unknown"} | field |
|
||||
| flatten | true | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the response
|
||||
Then there should be the following file(s) in the response:
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
Then the "pages_3_0.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
Then the response PDF(s) should be valid "PDF/A-1b" with a tolerance of 7 failed rule(s)
|
||||
Then the response PDF(s) should be valid "PDF/UA-1" with a tolerance of 2 failed rule(s)
|
||||
Then the response PDF(s) should be flatten
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/metadata/read" endpoint with the following form data and header(s):
|
||||
| files | teststore/pages_3_0.pdf | file |
|
||||
| files | teststore/pages_3_1.pdf | file |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/json"
|
||||
Then the response body should match JSON:
|
||||
"""
|
||||
{
|
||||
"pages_3_0.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
},
|
||||
"pages_3_1.pdf": {
|
||||
"Author": "Julien Neuhart",
|
||||
"Copyright": "Julien Neuhart",
|
||||
"CreateDate": "2006:09:18 16:27:50-04:00",
|
||||
"Creator": "Gotenberg",
|
||||
"Keywords": ["first", "second"],
|
||||
"Marked": true,
|
||||
"ModDate": "2006:09:18 16:27:50-04:00",
|
||||
"PDFVersion": 1.7,
|
||||
"Producer": "Gotenberg",
|
||||
"Subject": "Sample",
|
||||
"Title": "Sample",
|
||||
"Trapped": "Unknown"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Routes Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PDFENGINES_DISABLE_ROUTES | true |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| Gotenberg-Trace | forms_pdfengines_split | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then the response header "Gotenberg-Trace" should be "forms_pdfengines_split"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"forms_pdfengines_split" |
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Output Filename - Single PDF)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | pages | field |
|
||||
| splitSpan | 2- | field |
|
||||
| splitUnify | true | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/pdf"
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.pdf |
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Output Filename - Many PDFs)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| Gotenberg-Output-Filename | foo | header |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
Then there should be the following file(s) in the response:
|
||||
| foo.zip |
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Download From)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a static server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| downloadFrom | [{"url":"http://host.docker.internal:%d/static/testdata/pages_3.pdf","extraHttpHeaders":{"X-Foo":"bar"}}] | field |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 200
|
||||
Then the file request header "X-Foo" should be "bar"
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Webhook)
|
||||
Given I have a default Gotenberg container
|
||||
Given I have a webhook server
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
| Gotenberg-Webhook-Url | http://host.docker.internal:%d/webhook | header |
|
||||
| Gotenberg-Webhook-Error-Url | http://host.docker.internal:%d/webhook/error | header |
|
||||
Then the response status code should be 204
|
||||
When I wait for the asynchronous request to the webhook
|
||||
Then the webhook request header "Content-Type" should be "application/zip"
|
||||
Then there should be 2 PDF(s) in the webhook request
|
||||
Then there should be the following file(s) in the webhook request:
|
||||
| pages_3_0.pdf |
|
||||
| pages_3_1.pdf |
|
||||
Then the "pages_3_0.pdf" PDF should have 2 page(s)
|
||||
Then the "pages_3_1.pdf" PDF should have 1 page(s)
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 1
|
||||
"""
|
||||
Then the "pages_3_0.pdf" PDF should have the following content at page 2:
|
||||
"""
|
||||
Page 2
|
||||
"""
|
||||
Then the "pages_3_1.pdf" PDF should have the following content at page 1:
|
||||
"""
|
||||
Page 3
|
||||
"""
|
||||
|
||||
Scenario: POST /forms/pdfengines/split (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: POST /foo/forms/pdfengines/split (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "POST" request to Gotenberg at the "/foo/forms/pdfengines/split" endpoint with the following form data and header(s):
|
||||
| files | testdata/pages_3.pdf | file |
|
||||
| splitMode | intervals | field |
|
||||
| splitSpan | 2 | field |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "application/zip"
|
||||
90
test/integration/features/prometheus_metrics.feature
Normal file
90
test/integration/features/prometheus_metrics.feature
Normal file
@@ -0,0 +1,90 @@
|
||||
# TODO:
|
||||
# 1. Count restarts.
|
||||
# 2. Count queue size.
|
||||
|
||||
Feature: /prometheus/metrics
|
||||
|
||||
Scenario: GET /prometheus/metrics (Enabled)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/prometheus/metrics" endpoint
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "text/plain; version=0.0.4; charset=utf-8; escaping=underscores"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
# HELP gotenberg_chromium_requests_queue_size Current number of Chromium conversion requests waiting to be treated.
|
||||
# TYPE gotenberg_chromium_requests_queue_size gauge
|
||||
gotenberg_chromium_requests_queue_size 0
|
||||
# HELP gotenberg_chromium_restarts_count Current number of Chromium restarts.
|
||||
# TYPE gotenberg_chromium_restarts_count gauge
|
||||
gotenberg_chromium_restarts_count 0
|
||||
# HELP gotenberg_libreoffice_requests_queue_size Current number of LibreOffice conversion requests waiting to be treated.
|
||||
# TYPE gotenberg_libreoffice_requests_queue_size gauge
|
||||
gotenberg_libreoffice_requests_queue_size 0
|
||||
# HELP gotenberg_libreoffice_restarts_count Current number of LibreOffice restarts.
|
||||
# TYPE gotenberg_libreoffice_restarts_count gauge
|
||||
gotenberg_libreoffice_restarts_count 0
|
||||
|
||||
"""
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "path":"/prometheus/metrics" |
|
||||
|
||||
Scenario: GET /prometheus/metrics (Custom Namespace)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PROMETHEUS_NAMESPACE | foo |
|
||||
When I make a "GET" request to Gotenberg at the "/prometheus/metrics" endpoint
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "text/plain; version=0.0.4; charset=utf-8; escaping=underscores"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
# HELP foo_chromium_requests_queue_size Current number of Chromium conversion requests waiting to be treated.
|
||||
# TYPE foo_chromium_requests_queue_size gauge
|
||||
foo_chromium_requests_queue_size 0
|
||||
# HELP foo_chromium_restarts_count Current number of Chromium restarts.
|
||||
# TYPE foo_chromium_restarts_count gauge
|
||||
foo_chromium_restarts_count 0
|
||||
# HELP foo_libreoffice_requests_queue_size Current number of LibreOffice conversion requests waiting to be treated.
|
||||
# TYPE foo_libreoffice_requests_queue_size gauge
|
||||
foo_libreoffice_requests_queue_size 0
|
||||
# HELP foo_libreoffice_restarts_count Current number of LibreOffice restarts.
|
||||
# TYPE foo_libreoffice_restarts_count gauge
|
||||
foo_libreoffice_restarts_count 0
|
||||
|
||||
"""
|
||||
|
||||
Scenario: GET /prometheus/metrics (Disabled)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PROMETHEUS_DISABLE_COLLECT | true |
|
||||
When I make a "GET" request to Gotenberg at the "/prometheus/metrics" endpoint
|
||||
Then the response status code should be 404
|
||||
|
||||
Scenario: GET /prometheus/metrics (No Logging)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| PROMETHEUS_DISABLE_ROUTE_LOGGING | true |
|
||||
When I make a "GET" request to Gotenberg at the "/prometheus/metrics" endpoint
|
||||
Then the response status code should be 200
|
||||
Then the Gotenberg container should NOT log the following entries:
|
||||
| "path":"/prometheus/metrics" |
|
||||
|
||||
Scenario: GET /prometheus/metrics (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/prometheus/metrics" endpoint with the following header(s):
|
||||
| Gotenberg-Trace | prometheus_metrics |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Gotenberg-Trace" should be "prometheus_metrics"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"prometheus_metrics" |
|
||||
|
||||
Scenario: GET /prometheus/metrics (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "GET" request to Gotenberg at the "/prometheus/metrics" endpoint
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: GET /foo/prometheus/metrics (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "GET" request to Gotenberg at the "/foo/prometheus/metrics" endpoint
|
||||
Then the response status code should be 200
|
||||
62
test/integration/features/root.feature
Normal file
62
test/integration/features/root.feature
Normal file
@@ -0,0 +1,62 @@
|
||||
Feature: /
|
||||
|
||||
Scenario: GET /
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/" endpoint
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "text/html; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
Hey, Gotenberg has no UI, it's an API. Head to the <a href="https://gotenberg.dev">documentation</a> to learn how to interact with it 🚀
|
||||
"""
|
||||
|
||||
Scenario: GET / (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/" endpoint with the following header(s):
|
||||
| Gotenberg-Trace | root |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Gotenberg-Trace" should be "root"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"root" |
|
||||
|
||||
Scenario: GET / (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "GET" request to Gotenberg at the "/" endpoint
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: GET /foo/ (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "GET" request to Gotenberg at the "/foo/" endpoint
|
||||
Then the response status code should be 200
|
||||
|
||||
Scenario: GET /favicon.ico
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/favicon.ico" endpoint
|
||||
Then the response status code should be 204
|
||||
|
||||
Scenario: GET /favicon.ico (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/favicon.ico" endpoint with the following header(s):
|
||||
| Gotenberg-Trace | favicon |
|
||||
Then the response status code should be 204
|
||||
Then the response header "Gotenberg-Trace" should be "favicon"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"favicon" |
|
||||
|
||||
Scenario: GET /favicon.ico (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "GET" request to Gotenberg at the "/favicon.ico" endpoint
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: GET /foo/favicon.ico (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "GET" request to Gotenberg at the "/foo/favicon.ico" endpoint
|
||||
Then the response status code should be 204
|
||||
35
test/integration/features/version.feature
Normal file
35
test/integration/features/version.feature
Normal file
@@ -0,0 +1,35 @@
|
||||
Feature: /version
|
||||
|
||||
Scenario: GET /version
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/version" endpoint
|
||||
Then the response status code should be 200
|
||||
Then the response header "Content-Type" should be "text/plain; charset=UTF-8"
|
||||
Then the response body should match string:
|
||||
"""
|
||||
{version}
|
||||
"""
|
||||
|
||||
Scenario: GET /version (Gotenberg Trace)
|
||||
Given I have a default Gotenberg container
|
||||
When I make a "GET" request to Gotenberg at the "/version" endpoint with the following header(s):
|
||||
| Gotenberg-Trace | version |
|
||||
Then the response status code should be 200
|
||||
Then the response header "Gotenberg-Trace" should be "version"
|
||||
Then the Gotenberg container should log the following entries:
|
||||
| "trace":"version" |
|
||||
|
||||
Scenario: GET /version (Basic Auth)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_BASIC_AUTH | true |
|
||||
| GOTENBERG_API_BASIC_AUTH_USERNAME | foo |
|
||||
| GOTENBERG_API_BASIC_AUTH_PASSWORD | bar |
|
||||
When I make a "GET" request to Gotenberg at the "/version" endpoint
|
||||
Then the response status code should be 401
|
||||
|
||||
Scenario: GET /foo/version (Root Path)
|
||||
Given I have a Gotenberg container with the following environment variable(s):
|
||||
| API_ENABLE_DEBUG_ROUTE | true |
|
||||
| API_ROOT_PATH | /foo/ |
|
||||
When I make a "GET" request to Gotenberg at the "/foo/version" endpoint
|
||||
Then the response status code should be 200
|
||||
50
test/integration/main_test.go
Normal file
50
test/integration/main_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
//go:build integration
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/cucumber/godog/colors"
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"github.com/gotenberg/gotenberg/v8/test/integration/scenario"
|
||||
)
|
||||
|
||||
var opts = godog.Options{
|
||||
Format: "pretty",
|
||||
Paths: []string{"features"},
|
||||
Output: colors.Colored(os.Stdout),
|
||||
Concurrency: runtime.NumCPU(),
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
repository := flag.String("gotenberg-docker-repository", "", "")
|
||||
version := flag.String("gotenberg-version", "", "")
|
||||
platform := flag.String("gotenberg-container-platform", "", "")
|
||||
flag.Parse()
|
||||
|
||||
if *platform == "" {
|
||||
switch runtime.GOARCH {
|
||||
case "arm64":
|
||||
*platform = "linux/arm64"
|
||||
default:
|
||||
*platform = "linux/amd64"
|
||||
}
|
||||
}
|
||||
|
||||
scenario.GotenbergDockerRepository = *repository
|
||||
scenario.GotenbergVersion = *version
|
||||
scenario.GotenbergContainerPlatform = *platform
|
||||
|
||||
code := godog.TestSuite{
|
||||
Name: "integration",
|
||||
ScenarioInitializer: scenario.InitializeScenario,
|
||||
Options: &opts,
|
||||
}.Run()
|
||||
|
||||
os.Exit(code)
|
||||
}
|
||||
57
test/integration/scenario/compare.go
Normal file
57
test/integration/scenario/compare.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package scenario
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func compareJson(expected, actual interface{}) error {
|
||||
// Handle maps (JSON objects).
|
||||
expectedMap, ok := expected.(map[string]interface{})
|
||||
if ok {
|
||||
actualMap, ok := actual.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("expected an object, but actual is: %T", actual)
|
||||
}
|
||||
// For each key in expected, compare if the expected value is not
|
||||
// "ignore".
|
||||
for key, expVal := range expectedMap {
|
||||
if str, isStr := expVal.(string); isStr && str == "ignore" {
|
||||
continue // Skip.
|
||||
}
|
||||
actVal, exists := actualMap[key]
|
||||
if !exists {
|
||||
return fmt.Errorf("missing expected key %q", key)
|
||||
}
|
||||
if err := compareJson(expVal, actVal); err != nil {
|
||||
return fmt.Errorf("key %q: %w", key, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle slices (JSON arrays).
|
||||
expectedSlice, ok := expected.([]interface{})
|
||||
if ok {
|
||||
actualSlice, ok := actual.([]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("expected an array, but actual is: %T", actual)
|
||||
}
|
||||
if len(expectedSlice) != len(actualSlice) {
|
||||
return fmt.Errorf("expected array length to be: %d, but actual is: %d", len(expectedSlice), len(actualSlice))
|
||||
}
|
||||
for i := range expectedSlice {
|
||||
if err := compareJson(expectedSlice[i], actualSlice[i]); err != nil {
|
||||
return fmt.Errorf("at index %d: %w", i, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// For other types, compare directly.
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
return fmt.Errorf("expected %v (%T) but got %v (%T)", expected, expected, actual, actual)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
136
test/integration/scenario/containers.go
Normal file
136
test/integration/scenario/containers.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package scenario
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/network"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
var (
|
||||
GotenbergDockerRepository string
|
||||
GotenbergVersion string
|
||||
GotenbergContainerPlatform string
|
||||
)
|
||||
|
||||
type noopLogger struct{}
|
||||
|
||||
func (n *noopLogger) Printf(format string, v ...interface{}) {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
func startGotenbergContainer(ctx context.Context, env map[string]string) (*testcontainers.DockerNetwork, testcontainers.Container, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
n, err := network.New(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("create Gotenberg container network: %w", err)
|
||||
}
|
||||
|
||||
heathPath := "/health"
|
||||
if env["API_ROOT_PATH"] != "" {
|
||||
heathPath = fmt.Sprintf("%shealth", env["API_ROOT_PATH"])
|
||||
}
|
||||
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: fmt.Sprintf("gotenberg/%s:%s", GotenbergDockerRepository, GotenbergVersion),
|
||||
ImagePlatform: GotenbergContainerPlatform,
|
||||
ExposedPorts: []string{"3000/tcp"},
|
||||
HostConfigModifier: func(hostConfig *container.HostConfig) {
|
||||
hostConfig.ExtraHosts = []string{"host.docker.internal:host-gateway"}
|
||||
},
|
||||
Networks: []string{n.Name},
|
||||
WaitingFor: wait.ForHTTP(heathPath),
|
||||
Env: env,
|
||||
}
|
||||
|
||||
c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
Logger: &noopLogger{},
|
||||
})
|
||||
if err != nil {
|
||||
err = fmt.Errorf("start new Gotenberg container: %w", err)
|
||||
}
|
||||
|
||||
return n, c, err
|
||||
}
|
||||
|
||||
func execCommandInIntegrationToolsContainer(ctx context.Context, cmd []string, path string) (string, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: "gotenberg/integration-tools:latest",
|
||||
Files: []testcontainers.ContainerFile{
|
||||
{
|
||||
HostFilePath: path,
|
||||
ContainerFilePath: filepath.Base(path),
|
||||
FileMode: 0o700,
|
||||
},
|
||||
},
|
||||
Cmd: []string{"tail", "-f", "/dev/null"}, // Keeps container running indefinitely.
|
||||
}
|
||||
|
||||
c, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
Logger: &noopLogger{},
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("start new Integration Tools container: %w", err)
|
||||
}
|
||||
defer func(c testcontainers.Container, ctx context.Context) {
|
||||
err := c.Terminate(ctx)
|
||||
if err != nil {
|
||||
fmt.Printf("terminate container: %v\n", err)
|
||||
}
|
||||
}(c, ctx)
|
||||
|
||||
_, output, err := c.Exec(ctx, cmd)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("exec %q: %w", cmd, err)
|
||||
}
|
||||
|
||||
b, err := io.ReadAll(output)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("read output: %w", err)
|
||||
}
|
||||
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
func containerHttpEndpoint(ctx context.Context, container testcontainers.Container, port nat.Port) (string, error) {
|
||||
ip, err := container.Host(ctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("get container IP: %w", err)
|
||||
}
|
||||
mapped, err := container.MappedPort(ctx, port)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("get container port: %w", err)
|
||||
}
|
||||
return fmt.Sprintf("http://%s:%s", ip, mapped.Port()), nil
|
||||
}
|
||||
|
||||
func containerLogEntries(ctx context.Context, container testcontainers.Container) (string, error) {
|
||||
logReader, err := container.Logs(ctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("get container log entries: %w", err)
|
||||
}
|
||||
defer logReader.Close()
|
||||
|
||||
logsBytes, err := io.ReadAll(logReader)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("read container log entries: %w", err)
|
||||
}
|
||||
|
||||
return string(logsBytes), nil
|
||||
}
|
||||
2
test/integration/scenario/doc.go
Normal file
2
test/integration/scenario/doc.go
Normal file
@@ -0,0 +1,2 @@
|
||||
// Package scenario gathers all steps used in the features.
|
||||
package scenario
|
||||
83
test/integration/scenario/http.go
Normal file
83
test/integration/scenario/http.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package scenario
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func doRequest(method, url string, headers map[string]string, body io.Reader) (*http.Response, error) {
|
||||
req, err := http.NewRequest(method, url, body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create a request: %w", err)
|
||||
}
|
||||
|
||||
for header, value := range headers {
|
||||
req.Header.Set(header, value)
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("send a request: %w", err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func doFormDataRequest(method, url string, fields map[string]string, files map[string][]string, headers map[string]string) (*http.Response, error) {
|
||||
var b bytes.Buffer
|
||||
writer := multipart.NewWriter(&b)
|
||||
|
||||
for name, value := range fields {
|
||||
err := writer.WriteField(name, value)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("write field %q: %w", name, err)
|
||||
}
|
||||
}
|
||||
|
||||
for name, paths := range files {
|
||||
for _, path := range paths {
|
||||
part, err := writer.CreateFormFile(name, filepath.Base(path))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create form file %q: %w", filepath.Base(path), err)
|
||||
}
|
||||
|
||||
reader, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open file %q: %w", path, err)
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
_, err = io.Copy(part, reader)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("copy file %q: %w", path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := writer.Close()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("close writer: %w", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, url, &b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create a request: %w", err)
|
||||
}
|
||||
|
||||
for header, value := range headers {
|
||||
req.Header.Set(header, value)
|
||||
}
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("send a request: %w", err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
911
test/integration/scenario/scenario.go
Normal file
911
test/integration/scenario/scenario.go
Normal file
@@ -0,0 +1,911 @@
|
||||
package scenario
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/google/uuid"
|
||||
"github.com/mholt/archives"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
)
|
||||
|
||||
type scenario struct {
|
||||
resp *httptest.ResponseRecorder
|
||||
workdir string
|
||||
gotenbergContainer testcontainers.Container
|
||||
gotenbergContainerNetwork *testcontainers.DockerNetwork
|
||||
server *server
|
||||
hostPort int
|
||||
}
|
||||
|
||||
func (s *scenario) reset(ctx context.Context) error {
|
||||
s.resp = httptest.NewRecorder()
|
||||
|
||||
err := os.RemoveAll(s.workdir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("remove workdir %q: %w", s.workdir, err)
|
||||
}
|
||||
s.workdir = ""
|
||||
|
||||
if s.server == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = s.server.stop(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("stop server: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) iHaveADefaultGotenbergContainer(ctx context.Context) error {
|
||||
n, c, err := startGotenbergContainer(ctx, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create Gotenberg container: %s", err)
|
||||
}
|
||||
s.gotenbergContainerNetwork = n
|
||||
s.gotenbergContainer = c
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) iHaveAGotenbergContainerWithTheFollowingEnvironmentVariables(ctx context.Context, envTable *godog.Table) error {
|
||||
env := make(map[string]string)
|
||||
for _, row := range envTable.Rows {
|
||||
env[row.Cells[0].Value] = row.Cells[1].Value
|
||||
}
|
||||
n, c, err := startGotenbergContainer(ctx, env)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create Gotenberg container: %s", err)
|
||||
}
|
||||
s.gotenbergContainerNetwork = n
|
||||
s.gotenbergContainer = c
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) iHaveAServer(ctx context.Context) error {
|
||||
srv, err := newServer(ctx, s.workdir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create server: %s", err)
|
||||
}
|
||||
s.server = srv
|
||||
port, err := s.server.start(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("start server: %s", err)
|
||||
}
|
||||
s.hostPort = port
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) iMakeARequestToGotenberg(ctx context.Context, method, endpoint string) error {
|
||||
return s.iMakeARequestToGotenbergWithTheFollowingHeaders(ctx, method, endpoint, nil)
|
||||
}
|
||||
|
||||
func (s *scenario) iMakeARequestToGotenbergWithTheFollowingHeaders(ctx context.Context, method, endpoint string, headersTable *godog.Table) error {
|
||||
if s.gotenbergContainer == nil {
|
||||
return errors.New("no Gotenberg container")
|
||||
}
|
||||
|
||||
base, err := containerHttpEndpoint(ctx, s.gotenbergContainer, "3000")
|
||||
if err != nil {
|
||||
return fmt.Errorf("get container HTTP endpoint: %w", err)
|
||||
}
|
||||
|
||||
headers := make(map[string]string)
|
||||
if headersTable != nil {
|
||||
for _, row := range headersTable.Rows {
|
||||
headers[row.Cells[0].Value] = row.Cells[1].Value
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := doRequest(method, fmt.Sprintf("%s%s", base, endpoint), headers, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("do request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read response body: %w", err)
|
||||
}
|
||||
|
||||
s.resp = httptest.NewRecorder()
|
||||
s.resp.Code = resp.StatusCode
|
||||
for key, values := range resp.Header {
|
||||
for _, v := range values {
|
||||
s.resp.Header().Add(key, v)
|
||||
}
|
||||
}
|
||||
_, err = s.resp.Body.Write(body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write response body: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) iMakeARequestToGotenbergWithTheFollowingFormDataAndHeaders(ctx context.Context, method, endpoint string, dataTable *godog.Table) error {
|
||||
if s.gotenbergContainer == nil {
|
||||
return errors.New("no Gotenberg container")
|
||||
}
|
||||
|
||||
fields := make(map[string]string)
|
||||
files := make(map[string][]string)
|
||||
headers := make(map[string]string)
|
||||
|
||||
for _, row := range dataTable.Rows {
|
||||
name := row.Cells[0].Value
|
||||
value := row.Cells[1].Value
|
||||
kind := row.Cells[2].Value
|
||||
|
||||
switch kind {
|
||||
case "field":
|
||||
if name == "downloadFrom" || name == "url" || name == "cookies" {
|
||||
fields[name] = strings.ReplaceAll(value, "%d", fmt.Sprintf("%d", s.hostPort))
|
||||
continue
|
||||
}
|
||||
fields[name] = value
|
||||
case "file":
|
||||
if strings.Contains(value, "teststore") {
|
||||
dirPath := fmt.Sprintf("%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace"))
|
||||
_, err := os.Stat(dirPath)
|
||||
if os.IsNotExist(err) {
|
||||
return fmt.Errorf("directory %q does not exist", dirPath)
|
||||
}
|
||||
value = strings.ReplaceAll(value, "teststore", dirPath)
|
||||
} else {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return fmt.Errorf("get current directory: %w", err)
|
||||
}
|
||||
value = fmt.Sprintf("%s/%s", wd, value)
|
||||
}
|
||||
files[name] = append(files[name], value)
|
||||
case "header":
|
||||
if name == "Gotenberg-Webhook-Url" || name == "Gotenberg-Webhook-Error-Url" {
|
||||
headers[name] = fmt.Sprintf(value, s.hostPort)
|
||||
continue
|
||||
}
|
||||
headers[name] = value
|
||||
default:
|
||||
return fmt.Errorf("unexpected %q %q", kind, value)
|
||||
}
|
||||
}
|
||||
|
||||
base, err := containerHttpEndpoint(ctx, s.gotenbergContainer, "3000")
|
||||
if err != nil {
|
||||
return fmt.Errorf("get container HTTP endpoint: %w", err)
|
||||
}
|
||||
|
||||
resp, err := doFormDataRequest(method, fmt.Sprintf("%s%s", base, endpoint), fields, files, headers)
|
||||
if err != nil {
|
||||
return fmt.Errorf("do request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read response body: %w", err)
|
||||
}
|
||||
|
||||
s.resp = httptest.NewRecorder()
|
||||
s.resp.Code = resp.StatusCode
|
||||
for key, values := range resp.Header {
|
||||
for _, v := range values {
|
||||
s.resp.Header().Add(key, v)
|
||||
}
|
||||
}
|
||||
_, err = s.resp.Body.Write(body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write response body: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil
|
||||
}
|
||||
|
||||
cd := resp.Header.Get("Content-Disposition")
|
||||
if cd == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, params, err := mime.ParseMediaType(cd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parse Content-Disposition header: %w", err)
|
||||
}
|
||||
|
||||
filename, ok := params["filename"]
|
||||
if !ok {
|
||||
return errors.New("no filename in Content-Disposition header")
|
||||
}
|
||||
|
||||
dirPath := fmt.Sprintf("%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace"))
|
||||
err = os.MkdirAll(dirPath, 0o755)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create working directory: %w", err)
|
||||
}
|
||||
|
||||
fpath := fmt.Sprintf("%s/%s", dirPath, filename)
|
||||
file, err := os.Create(fpath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create file %q: %w", fpath, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.Write(body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write file %q: %w", fpath, err)
|
||||
}
|
||||
|
||||
if resp.Header.Get("Content-Type") == "application/zip" {
|
||||
var format archives.Zip
|
||||
err = format.Extract(ctx, file, func(ctx context.Context, f archives.FileInfo) error {
|
||||
source, err := f.Open()
|
||||
if err != nil {
|
||||
return fmt.Errorf("open file %q: %w", f.Name(), err)
|
||||
}
|
||||
defer source.Close()
|
||||
|
||||
targetPath := fmt.Sprintf("%s/%s", dirPath, f.Name())
|
||||
target, err := os.Create(targetPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create file %q: %w", targetPath, err)
|
||||
}
|
||||
defer target.Close()
|
||||
|
||||
_, err = io.Copy(target, source)
|
||||
if err != nil {
|
||||
return fmt.Errorf("copy file %q: %w", targetPath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) iWaitForTheAsynchronousRequestToWebhook(ctx context.Context) error {
|
||||
if s.server == nil {
|
||||
return errors.New("server not initialized")
|
||||
}
|
||||
if s.server.req != nil {
|
||||
return nil
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case err := <-s.server.errChan:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (s *scenario) theGotenbergContainerShouldLogTheFollowingEntries(ctx context.Context, should string, entriesTable *godog.Table) error {
|
||||
if s.gotenbergContainer == nil {
|
||||
return errors.New("no Gotenberg container")
|
||||
}
|
||||
|
||||
expected := make([]string, len(entriesTable.Rows))
|
||||
for i, row := range entriesTable.Rows {
|
||||
expected[i] = row.Cells[0].Value
|
||||
}
|
||||
|
||||
invert := should == "should NOT"
|
||||
check := func() error {
|
||||
logs, err := containerLogEntries(ctx, s.gotenbergContainer)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get log entries: %w", err)
|
||||
}
|
||||
|
||||
for _, entry := range expected {
|
||||
if !invert && !strings.Contains(logs, entry) {
|
||||
return fmt.Errorf("expected log entry %q not found in %q", expected, logs)
|
||||
}
|
||||
|
||||
if invert && strings.Contains(logs, entry) {
|
||||
return fmt.Errorf("log entry %q NOT expected", expected)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
for i := 0; i < 3; i++ {
|
||||
err = check()
|
||||
if err != nil && !invert {
|
||||
// We have to retry as not all logs may have been produced.
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *scenario) theResponseStatusCodeShouldBe(expected int) error {
|
||||
if expected != s.resp.Code {
|
||||
return fmt.Errorf("expected response status code to be: %d, but actual is: %d %q", expected, s.resp.Code, s.resp.Body.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) theHeaderValueShouldBe(kind, name string, expected string) error {
|
||||
var actual string
|
||||
if kind == "response" {
|
||||
actual = s.resp.Header().Get(name)
|
||||
} else if s.server == nil {
|
||||
return errors.New("server not initialized")
|
||||
} else if s.server.req == nil {
|
||||
return errors.New("no webhook request found")
|
||||
} else {
|
||||
actual = s.server.req.Header.Get(name)
|
||||
}
|
||||
|
||||
if expected != actual {
|
||||
return fmt.Errorf("expected %s header %q to be: %q, but actual is: %q", kind, name, expected, actual)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) theCookieValueShouldBe(kind, name, expected string) error {
|
||||
var cookies []*http.Cookie
|
||||
if kind == "response" {
|
||||
cookies = s.resp.Result().Cookies()
|
||||
} else if s.server == nil {
|
||||
return errors.New("server not initialized")
|
||||
} else if s.server.req == nil {
|
||||
return errors.New("no webhook request found")
|
||||
} else {
|
||||
cookies = s.server.req.Cookies()
|
||||
}
|
||||
|
||||
var actual *http.Cookie
|
||||
for _, cookie := range cookies {
|
||||
if cookie.Name == name {
|
||||
actual = cookie
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if actual == nil {
|
||||
if expected != "" {
|
||||
return fmt.Errorf("expected %s cookie %q not found", kind, name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if expected != actual.Value {
|
||||
return fmt.Errorf("expected %s cookie %q to be: %q, but actual is: %q", kind, name, expected, actual.Value)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) theBodyShouldMatchString(kind string, expectedDoc *godog.DocString) error {
|
||||
var actual string
|
||||
if kind == "response" {
|
||||
actual = s.resp.Body.String()
|
||||
} else if s.server == nil {
|
||||
return errors.New("server not initialized")
|
||||
} else if s.server.req == nil {
|
||||
return errors.New("no webhook request found")
|
||||
} else {
|
||||
body, err := io.ReadAll(s.server.req.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read request body: %w", err)
|
||||
}
|
||||
actual = string(body)
|
||||
}
|
||||
|
||||
expected := strings.ReplaceAll(expectedDoc.Content, "{version}", GotenbergVersion)
|
||||
|
||||
if actual != expected {
|
||||
return fmt.Errorf("expected %q body to be: %q, but actual is: %q", kind, expected, actual)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) theBodyShouldContainString(kind string, expectedDoc *godog.DocString) error {
|
||||
var actual string
|
||||
if kind == "response" {
|
||||
actual = s.resp.Body.String()
|
||||
} else if s.server == nil {
|
||||
return errors.New("server not initialized")
|
||||
} else if s.server.req == nil {
|
||||
return errors.New("no webhook request found")
|
||||
} else {
|
||||
body, err := io.ReadAll(s.server.req.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read request body: %w", err)
|
||||
}
|
||||
actual = string(body)
|
||||
}
|
||||
|
||||
expected := strings.ReplaceAll(expectedDoc.Content, "{version}", GotenbergVersion)
|
||||
|
||||
if !strings.Contains(actual, expected) {
|
||||
return fmt.Errorf("expected %q body to contain: %q, but actual is: %q", kind, expected, actual)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) theBodyShouldMatchJSON(kind string, expectedDoc *godog.DocString) error {
|
||||
var body []byte
|
||||
if kind == "response" {
|
||||
body = s.resp.Body.Bytes()
|
||||
} else if s.server == nil {
|
||||
return errors.New("server not initialized")
|
||||
} else if s.server.req == nil {
|
||||
return errors.New("no webhook request found")
|
||||
} else {
|
||||
b, err := io.ReadAll(s.server.req.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read request body: %w", err)
|
||||
}
|
||||
body = b
|
||||
}
|
||||
|
||||
var expected, actual interface{}
|
||||
|
||||
content := strings.ReplaceAll(expectedDoc.Content, "{version}", GotenbergVersion)
|
||||
err := json.Unmarshal([]byte(content), &expected)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshal expected JSON: %w", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(body, &actual)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshal actual JSON: %w", err)
|
||||
}
|
||||
|
||||
err = compareJson(expected, actual)
|
||||
if err != nil {
|
||||
return fmt.Errorf("expected matching JSON: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) thereShouldBePdfs(expected int, kind string) error {
|
||||
dirPath := fmt.Sprintf("%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace"))
|
||||
|
||||
_, err := os.Stat(dirPath)
|
||||
if os.IsNotExist(err) {
|
||||
return fmt.Errorf("directory %q does not exist", dirPath)
|
||||
}
|
||||
|
||||
var paths []string
|
||||
err = filepath.Walk(dirPath, func(path string, info os.FileInfo, pathErr error) error {
|
||||
if pathErr != nil {
|
||||
return pathErr
|
||||
}
|
||||
if strings.EqualFold(filepath.Ext(info.Name()), ".pdf") {
|
||||
paths = append(paths, path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("walk %q: %w", s.workdir, err)
|
||||
}
|
||||
|
||||
if len(paths) != expected {
|
||||
return fmt.Errorf("expected %d PDF(s), but actual is %d", expected, len(paths))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) thereShouldBeTheFollowingFiles(kind string, filesTable *godog.Table) error {
|
||||
dirPath := fmt.Sprintf("%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace"))
|
||||
|
||||
_, err := os.Stat(dirPath)
|
||||
if os.IsNotExist(err) {
|
||||
return fmt.Errorf("directory %q does not exist", dirPath)
|
||||
}
|
||||
|
||||
var filenames []string
|
||||
err = filepath.Walk(dirPath, func(path string, info os.FileInfo, pathErr error) error {
|
||||
if pathErr != nil {
|
||||
return pathErr
|
||||
}
|
||||
if !info.IsDir() {
|
||||
filenames = append(filenames, info.Name())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("walk %q: %w", s.workdir, err)
|
||||
}
|
||||
|
||||
for _, row := range filesTable.Rows {
|
||||
found := false
|
||||
expected := row.Cells[0].Value
|
||||
for _, filename := range filenames {
|
||||
if strings.HasPrefix(expected, "*_") && strings.Contains(filename, strings.ReplaceAll(expected, "*_", "")) {
|
||||
found = true
|
||||
}
|
||||
if strings.EqualFold(expected, filename) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return fmt.Errorf("expected file %q not found among %q", expected, filenames)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) thePdfsShouldBeValidWithAToleranceOf(ctx context.Context, kind, validate string, tolerance int) error {
|
||||
dirPath := fmt.Sprintf("%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace"))
|
||||
|
||||
_, err := os.Stat(dirPath)
|
||||
if os.IsNotExist(err) {
|
||||
return fmt.Errorf("directory %q does not exist", dirPath)
|
||||
}
|
||||
|
||||
var paths []string
|
||||
err = filepath.Walk(dirPath, func(path string, info os.FileInfo, pathErr error) error {
|
||||
if pathErr != nil {
|
||||
return pathErr
|
||||
}
|
||||
if strings.EqualFold(filepath.Ext(info.Name()), ".pdf") {
|
||||
paths = append(paths, path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("walk %q: %w", s.workdir, err)
|
||||
}
|
||||
|
||||
var flavor string
|
||||
switch validate {
|
||||
case "PDF/A-1b":
|
||||
flavor = "1b"
|
||||
case "PDF/A-2b":
|
||||
flavor = "2b"
|
||||
case "PDF/A-3b":
|
||||
flavor = "3b"
|
||||
case "PDF/UA-1":
|
||||
flavor = "ua1"
|
||||
case "PDF/UA-2":
|
||||
flavor = "ua2"
|
||||
default:
|
||||
return fmt.Errorf("unknown %q", validate)
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
cmd := []string{
|
||||
"verapdf",
|
||||
"-f",
|
||||
flavor,
|
||||
filepath.Base(path),
|
||||
}
|
||||
|
||||
output, err := execCommandInIntegrationToolsContainer(ctx, cmd, path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("exec %q: %w", cmd, err)
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`failedRules="(\d+)"`)
|
||||
matches := re.FindStringSubmatch(output)
|
||||
|
||||
if len(matches) < 2 {
|
||||
return errors.New("expected failed rules")
|
||||
}
|
||||
|
||||
failedRules, err := strconv.Atoi(matches[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("convert failed rules value %q to integer: %w", matches[1], err)
|
||||
}
|
||||
|
||||
if tolerance < failedRules {
|
||||
return fmt.Errorf("expected failed rules to be inferior or equal to: %d, but actual is %d", tolerance, failedRules)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) thePdfShouldHavePages(ctx context.Context, name string, pages int) error {
|
||||
var path string
|
||||
if !strings.HasPrefix(name, "*_") {
|
||||
path = fmt.Sprintf("%s/%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace"), name)
|
||||
|
||||
_, err := os.Stat(path)
|
||||
if os.IsNotExist(err) {
|
||||
return fmt.Errorf("PDF %q does not exist", path)
|
||||
}
|
||||
} else {
|
||||
substr := strings.ReplaceAll(name, "*_", "")
|
||||
err := filepath.Walk(fmt.Sprintf("%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace")), func(currentPath string, info os.FileInfo, pathErr error) error {
|
||||
if pathErr != nil {
|
||||
return pathErr
|
||||
}
|
||||
if strings.Contains(info.Name(), substr) {
|
||||
path = currentPath
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("walk %q: %w", s.workdir, err)
|
||||
}
|
||||
}
|
||||
|
||||
cmd := []string{
|
||||
"pdfinfo",
|
||||
filepath.Base(path),
|
||||
}
|
||||
|
||||
output, err := execCommandInIntegrationToolsContainer(ctx, cmd, path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("exec %q: %w", cmd, err)
|
||||
}
|
||||
|
||||
output = strings.ReplaceAll(output, " ", "")
|
||||
re := regexp.MustCompile(`Pages:(\d+)`)
|
||||
matches := re.FindStringSubmatch(output)
|
||||
|
||||
if len(matches) < 2 {
|
||||
return errors.New("expected pages")
|
||||
}
|
||||
|
||||
actual, err := strconv.Atoi(matches[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("convert pages value %q to integer: %w", matches[1], err)
|
||||
}
|
||||
|
||||
if actual != pages {
|
||||
return fmt.Errorf("expected %d pages, but actual is %d", pages, actual)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) thePdfShouldBeSetToLandscapeOrientation(ctx context.Context, name string, kind string) error {
|
||||
var path string
|
||||
if !strings.HasPrefix(name, "*_") {
|
||||
path = fmt.Sprintf("%s/%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace"), name)
|
||||
|
||||
_, err := os.Stat(path)
|
||||
if os.IsNotExist(err) {
|
||||
return fmt.Errorf("PDF %q does not exist", path)
|
||||
}
|
||||
} else {
|
||||
substr := strings.ReplaceAll(name, "*_", "")
|
||||
err := filepath.Walk(fmt.Sprintf("%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace")), func(currentPath string, info os.FileInfo, pathErr error) error {
|
||||
if pathErr != nil {
|
||||
return pathErr
|
||||
}
|
||||
if strings.Contains(info.Name(), substr) {
|
||||
path = currentPath
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("walk %q: %w", s.workdir, err)
|
||||
}
|
||||
}
|
||||
|
||||
cmd := []string{
|
||||
"pdfinfo",
|
||||
filepath.Base(path),
|
||||
}
|
||||
|
||||
output, err := execCommandInIntegrationToolsContainer(ctx, cmd, path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("exec %q: %w", cmd, err)
|
||||
}
|
||||
|
||||
output = strings.ReplaceAll(output, " ", "")
|
||||
re := regexp.MustCompile(`Pagesize:(\d+)x(\d+).*`)
|
||||
matches := re.FindStringSubmatch(output)
|
||||
|
||||
if len(matches) < 3 {
|
||||
return errors.New("expected page size")
|
||||
}
|
||||
|
||||
invert := kind == "should NOT"
|
||||
|
||||
width, err := strconv.Atoi(matches[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("convert width value %q to integer: %w", matches[1], err)
|
||||
}
|
||||
|
||||
height, err := strconv.Atoi(matches[2])
|
||||
if err != nil {
|
||||
return fmt.Errorf("convert height value %q to integer: %w", matches[2], err)
|
||||
}
|
||||
|
||||
if invert && height < width {
|
||||
return fmt.Errorf("expected height %d to be greater than width %d", height, width)
|
||||
}
|
||||
|
||||
if !invert && width < height {
|
||||
return fmt.Errorf("expected width %d to be greater than height %d", width, height)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) thePdfShouldHaveTheFollowingContentAtPage(ctx context.Context, name, kind string, page int, expected *godog.DocString) error {
|
||||
var path string
|
||||
if !strings.HasPrefix(name, "*_") {
|
||||
path = fmt.Sprintf("%s/%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace"), name)
|
||||
|
||||
_, err := os.Stat(path)
|
||||
if os.IsNotExist(err) {
|
||||
return fmt.Errorf("PDF %q does not exist", path)
|
||||
}
|
||||
} else {
|
||||
substr := strings.ReplaceAll(name, "*_", "")
|
||||
err := filepath.Walk(fmt.Sprintf("%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace")), func(currentPath string, info os.FileInfo, pathErr error) error {
|
||||
if pathErr != nil {
|
||||
return pathErr
|
||||
}
|
||||
if strings.Contains(info.Name(), substr) {
|
||||
path = currentPath
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("walk %q: %w", s.workdir, err)
|
||||
}
|
||||
}
|
||||
|
||||
cmd := []string{
|
||||
"pdftotext",
|
||||
"-f",
|
||||
fmt.Sprintf("%d", page),
|
||||
"-l",
|
||||
fmt.Sprintf("%d", page),
|
||||
filepath.Base(path),
|
||||
"-",
|
||||
}
|
||||
|
||||
output, err := execCommandInIntegrationToolsContainer(ctx, cmd, path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("exec %q: %w", cmd, err)
|
||||
}
|
||||
|
||||
invert := kind == "should NOT"
|
||||
|
||||
if !invert && !strings.Contains(output, expected.Content) {
|
||||
return fmt.Errorf("expected %q not found in %q", expected.Content, output)
|
||||
}
|
||||
|
||||
if invert && strings.Contains(output, expected.Content) {
|
||||
return fmt.Errorf("%q found in %q", expected.Content, output)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) thePdfsShouldBeFlatten(ctx context.Context, kind, should string) error {
|
||||
dirPath := fmt.Sprintf("%s/%s", s.workdir, s.resp.Header().Get("Gotenberg-Trace"))
|
||||
|
||||
_, err := os.Stat(dirPath)
|
||||
if os.IsNotExist(err) {
|
||||
return fmt.Errorf("directory %q does not exist", dirPath)
|
||||
}
|
||||
|
||||
var paths []string
|
||||
err = filepath.Walk(dirPath, func(path string, info os.FileInfo, pathErr error) error {
|
||||
if pathErr != nil {
|
||||
return pathErr
|
||||
}
|
||||
if strings.EqualFold(filepath.Ext(info.Name()), ".pdf") {
|
||||
paths = append(paths, path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("walk %q: %w", s.workdir, err)
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
cmd := []string{
|
||||
"verapdf",
|
||||
"-off",
|
||||
"--extract",
|
||||
"annotations",
|
||||
filepath.Base(path),
|
||||
}
|
||||
|
||||
output, err := execCommandInIntegrationToolsContainer(ctx, cmd, path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("exec %q: %w", cmd, err)
|
||||
}
|
||||
|
||||
invert := should == "should NOT"
|
||||
if invert && strings.Contains(output, "<featuresReport></featuresReport>") {
|
||||
return fmt.Errorf("PDF %q is flatten", path)
|
||||
}
|
||||
|
||||
if !invert && !strings.Contains(output, "<featuresReport></featuresReport>") {
|
||||
return fmt.Errorf("PDF %q is not flatten", path)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
s := &scenario{}
|
||||
ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return ctx, fmt.Errorf("get current directory: %w", err)
|
||||
}
|
||||
s.workdir = fmt.Sprintf("%s/teststore/%s", wd, uuid.NewString())
|
||||
err = os.MkdirAll(s.workdir, 0o755)
|
||||
if err != nil {
|
||||
return ctx, fmt.Errorf("create working directory: %w", err)
|
||||
}
|
||||
return ctx, nil
|
||||
})
|
||||
ctx.Given(`^I have a default Gotenberg container$`, s.iHaveADefaultGotenbergContainer)
|
||||
ctx.Given(`^I have a Gotenberg container with the following environment variable\(s\):$`, s.iHaveAGotenbergContainerWithTheFollowingEnvironmentVariables)
|
||||
ctx.Given(`^I have a (webhook|static) server$`, s.iHaveAServer)
|
||||
ctx.When(`^I make a "(GET|HEAD)" request to Gotenberg at the "([^"]*)" endpoint$`, s.iMakeARequestToGotenberg)
|
||||
ctx.When(`^I make a "(GET|HEAD)" request to Gotenberg at the "([^"]*)" endpoint with the following header\(s\):$`, s.iMakeARequestToGotenbergWithTheFollowingHeaders)
|
||||
ctx.When(`^I make a "(POST)" request to Gotenberg at the "([^"]*)" endpoint with the following form data and header\(s\):$`, s.iMakeARequestToGotenbergWithTheFollowingFormDataAndHeaders)
|
||||
ctx.When(`^I wait for the asynchronous request to the webhook$`, s.iWaitForTheAsynchronousRequestToWebhook)
|
||||
ctx.Then(`^the Gotenberg container (should|should NOT) log the following entries:$`, s.theGotenbergContainerShouldLogTheFollowingEntries)
|
||||
ctx.Then(`^the response status code should be (\d+)$`, s.theResponseStatusCodeShouldBe)
|
||||
ctx.Then(`^the (response|webhook request|file request|server request) header "([^"]*)" should be "([^"]*)"$`, s.theHeaderValueShouldBe)
|
||||
ctx.Then(`^the (response|webhook request|file request|server request) cookie "([^"]*)" should be "([^"]*)"$`, s.theCookieValueShouldBe)
|
||||
ctx.Then(`^the (response|webhook request) body should match string:$`, s.theBodyShouldMatchString)
|
||||
ctx.Then(`^the (response|webhook request) body should contain string:$`, s.theBodyShouldContainString)
|
||||
ctx.Then(`^the (response|webhook request) body should match JSON:$`, s.theBodyShouldMatchJSON)
|
||||
ctx.Then(`^there should be (\d+) PDF\(s\) in the (response|webhook request)$`, s.thereShouldBePdfs)
|
||||
ctx.Then(`^there should be the following file\(s\) in the (response|webhook request):$`, s.thereShouldBeTheFollowingFiles)
|
||||
ctx.Then(`^the (response|webhook request) PDF\(s\) should be valid "([^"]*)" with a tolerance of (\d+) failed rule\(s\)$`, s.thePdfsShouldBeValidWithAToleranceOf)
|
||||
ctx.Then(`^the (response|webhook request) PDF\(s\) (should|should NOT) be flatten$`, s.thePdfsShouldBeFlatten)
|
||||
ctx.Then(`^the "([^"]*)" PDF should have (\d+) page\(s\)$`, s.thePdfShouldHavePages)
|
||||
ctx.Then(`^the "([^"]*)" PDF (should|should NOT) be set to landscape orientation$`, s.thePdfShouldBeSetToLandscapeOrientation)
|
||||
ctx.Then(`^the "([^"]*)" PDF (should|should NOT) have the following content at page (\d+):$`, s.thePdfShouldHaveTheFollowingContentAtPage)
|
||||
ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) {
|
||||
if s.gotenbergContainer != nil {
|
||||
errTerminate := s.gotenbergContainer.Terminate(ctx, testcontainers.StopTimeout(0))
|
||||
if errTerminate != nil {
|
||||
return ctx, fmt.Errorf("terminate Gotenberg container: %w", errTerminate)
|
||||
}
|
||||
}
|
||||
if s.gotenbergContainerNetwork != nil {
|
||||
errRemove := s.gotenbergContainerNetwork.Remove(ctx)
|
||||
if errRemove != nil {
|
||||
return ctx, fmt.Errorf("remove Gotenberg container network: %w", errRemove)
|
||||
}
|
||||
}
|
||||
return ctx, nil
|
||||
})
|
||||
ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) {
|
||||
errReset := s.reset(ctx)
|
||||
if errReset != nil {
|
||||
return ctx, fmt.Errorf("reset scenario: %w", errReset)
|
||||
}
|
||||
return ctx, nil
|
||||
})
|
||||
}
|
||||
176
test/integration/scenario/server.go
Normal file
176
test/integration/scenario/server.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package scenario
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/mholt/archives"
|
||||
)
|
||||
|
||||
type server struct {
|
||||
srv *echo.Echo
|
||||
req *http.Request
|
||||
errChan chan error
|
||||
}
|
||||
|
||||
func newServer(ctx context.Context, workdir string) (*server, error) {
|
||||
srv := echo.New()
|
||||
srv.HideBanner = true
|
||||
srv.HidePort = true
|
||||
s := &server{
|
||||
srv: srv,
|
||||
errChan: make(chan error, 1),
|
||||
}
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get current directory: %w", err)
|
||||
}
|
||||
|
||||
webhookErr := func(err error) error {
|
||||
s.errChan <- err
|
||||
return err
|
||||
}
|
||||
|
||||
webhookHandler := func(c echo.Context) error {
|
||||
s.req = c.Request()
|
||||
|
||||
body, err := io.ReadAll(s.req.Body)
|
||||
if err != nil {
|
||||
return webhookErr(fmt.Errorf("read request body: %w", err))
|
||||
}
|
||||
|
||||
cd := s.req.Header.Get("Content-Disposition")
|
||||
if cd == "" {
|
||||
return webhookErr(fmt.Errorf("no Content-Disposition header"))
|
||||
}
|
||||
|
||||
_, params, err := mime.ParseMediaType(cd)
|
||||
if err != nil {
|
||||
return webhookErr(fmt.Errorf("parse Content-Disposition header: %w", err))
|
||||
}
|
||||
|
||||
filename, ok := params["filename"]
|
||||
if !ok {
|
||||
return webhookErr(errors.New("no filename in Content-Disposition header"))
|
||||
}
|
||||
|
||||
dirPath := fmt.Sprintf("%s/%s", workdir, s.req.Header.Get("Gotenberg-Trace"))
|
||||
err = os.MkdirAll(dirPath, 0o755)
|
||||
if err != nil {
|
||||
return webhookErr(fmt.Errorf("create working directory: %w", err))
|
||||
}
|
||||
|
||||
fpath := fmt.Sprintf("%s/%s", dirPath, filename)
|
||||
file, err := os.Create(fpath)
|
||||
if err != nil {
|
||||
return webhookErr(fmt.Errorf("create file %q: %w", fpath, err))
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.Write(body)
|
||||
if err != nil {
|
||||
return webhookErr(fmt.Errorf("write file %q: %w", fpath, err))
|
||||
}
|
||||
|
||||
if s.req.Header.Get("Content-Type") == "application/zip" {
|
||||
var format archives.Zip
|
||||
err = format.Extract(ctx, file, func(ctx context.Context, f archives.FileInfo) error {
|
||||
source, err := f.Open()
|
||||
if err != nil {
|
||||
return fmt.Errorf("open file %q: %w", f.Name(), err)
|
||||
}
|
||||
defer source.Close()
|
||||
|
||||
targetPath := fmt.Sprintf("%s/%s", dirPath, f.Name())
|
||||
target, err := os.Create(targetPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create file %q: %w", targetPath, err)
|
||||
}
|
||||
defer target.Close()
|
||||
|
||||
_, err = io.Copy(target, source)
|
||||
if err != nil {
|
||||
return fmt.Errorf("copy file %q: %w", targetPath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return webhookErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
return webhookErr(c.String(http.StatusOK, http.StatusText(http.StatusOK)))
|
||||
}
|
||||
webhookErrorHandler := func(c echo.Context) error {
|
||||
s.req = c.Request()
|
||||
return webhookErr(c.String(http.StatusOK, http.StatusText(http.StatusOK)))
|
||||
}
|
||||
|
||||
srv.POST("/webhook", webhookHandler)
|
||||
srv.PATCH("/webhook", webhookHandler)
|
||||
srv.PUT("/webhook", webhookHandler)
|
||||
srv.POST("/webhook/error", webhookErrorHandler)
|
||||
srv.PATCH("/webhook/error", webhookErrorHandler)
|
||||
srv.PUT("/webhook/error", webhookErrorHandler)
|
||||
srv.GET("/static/:path", func(c echo.Context) error {
|
||||
s.req = c.Request()
|
||||
path := c.Param("path")
|
||||
if strings.Contains(path, "teststore") {
|
||||
return c.Attachment(fmt.Sprintf("%s/%s/%s", workdir, s.req.Header.Get("Gotenberg-Trace"), filepath.Base(path)), filepath.Base(path))
|
||||
}
|
||||
return c.Attachment(fmt.Sprintf("%s/%s", wd, path), filepath.Base(path))
|
||||
})
|
||||
srv.GET("/html/:path", func(c echo.Context) error {
|
||||
s.req = c.Request()
|
||||
path := fmt.Sprintf("%s/%s", wd, c.Param("path"))
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return c.String(http.StatusInternalServerError, fmt.Sprintf("open file %q: %s", path, err))
|
||||
}
|
||||
defer f.Close()
|
||||
b, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
return c.String(http.StatusInternalServerError, fmt.Sprintf("read file %q: %s", path, err))
|
||||
}
|
||||
return c.HTML(http.StatusOK, string(b))
|
||||
})
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *server) start(ctx context.Context) (int, error) {
|
||||
// #nosec
|
||||
ln, err := net.Listen("tcp", "0.0.0.0:0")
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("create listener: %w", err)
|
||||
}
|
||||
|
||||
port := ln.Addr().(*net.TCPAddr).Port
|
||||
|
||||
go func() {
|
||||
s.srv.Listener = ln
|
||||
err = s.srv.Start("")
|
||||
if err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
godog.Log(ctx, err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
return port, nil
|
||||
}
|
||||
|
||||
func (s *server) stop(ctx context.Context) error {
|
||||
close(s.errChan)
|
||||
return s.srv.Shutdown(ctx)
|
||||
}
|
||||
64
test/integration/testdata/feature-rich-html-remote/index.html
vendored
Normal file
64
test/integration/testdata/feature-rich-html-remote/index.html
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- net::ERR_CONNECTION_REFUSED -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="http://localhost:100/style.css"
|
||||
/>
|
||||
<title>Feature Rich HTML</title>
|
||||
<style>
|
||||
@media print {
|
||||
#screen {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media screen {
|
||||
#print {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p id="wait" style="display: none">
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns
|
||||
true.
|
||||
</p>
|
||||
<p id="print">Emulated media type is 'print'.</p>
|
||||
<p id="screen">Emulated media type is 'screen'.</p>
|
||||
<p id="javascript" style="display: none">JavaScript is enabled.</p>
|
||||
<iframe src="file:///etc/passwd"></iframe>
|
||||
|
||||
<script type="application/javascript">
|
||||
var globalVar = "notReady";
|
||||
|
||||
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
|
||||
delay(2000).then(() => {
|
||||
document.getElementById("wait").style.display = "contents";
|
||||
window.globalVar = "ready";
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
document.getElementById("javascript").style.display = "contents";
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
console.log("a simple message");
|
||||
console.debug("a debug message");
|
||||
console.warn("a warning message");
|
||||
console.error("an error message");
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
throw new Error("Exception 1");
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
throw new Error("Exception 2");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
69
test/integration/testdata/feature-rich-html/index.html
vendored
Normal file
69
test/integration/testdata/feature-rich-html/index.html
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- net::ERR_FILE_NOT_FOUND -->
|
||||
<link rel="stylesheet" type="text/css" href="doesnotexist.css" />
|
||||
<!-- net::ERR_CONNECTION_REFUSED -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="http://localhost:100/style.css"
|
||||
/>
|
||||
<!-- 400 Bad Request -->
|
||||
<link rel="stylesheet" type="text/css" href="https://httpstat.us/400" />
|
||||
<title>Feature Rich HTML</title>
|
||||
<style>
|
||||
@media print {
|
||||
#screen {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media screen {
|
||||
#print {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p id="wait" style="display: none">
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns
|
||||
true.
|
||||
</p>
|
||||
<p id="print">Emulated media type is 'print'.</p>
|
||||
<p id="screen">Emulated media type is 'screen'.</p>
|
||||
<p id="javascript" style="display: none">JavaScript is enabled.</p>
|
||||
<iframe src="/etc/passwd"></iframe>
|
||||
<iframe src="\\localhost/etc/passwd"></iframe>
|
||||
|
||||
<script type="application/javascript">
|
||||
var globalVar = "notReady";
|
||||
|
||||
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
|
||||
delay(2000).then(() => {
|
||||
document.getElementById("wait").style.display = "contents";
|
||||
window.globalVar = "ready";
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
document.getElementById("javascript").style.display = "contents";
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
console.log("a simple message");
|
||||
console.debug("a debug message");
|
||||
console.warn("a warning message");
|
||||
console.error("an error message");
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
throw new Error("Exception 1");
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
throw new Error("Exception 2");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
70
test/integration/testdata/feature-rich-markdown/index.html
vendored
Normal file
70
test/integration/testdata/feature-rich-markdown/index.html
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<!-- net::ERR_FILE_NOT_FOUND -->
|
||||
<link rel="stylesheet" type="text/css" href="doesnotexist.css" />
|
||||
<!-- net::ERR_CONNECTION_REFUSED -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="http://localhost:100/style.css"
|
||||
/>
|
||||
<!-- 400 Bad Request -->
|
||||
<link rel="stylesheet" type="text/css" href="https://httpstat.us/400" />
|
||||
<title>Feature Rich HTML</title>
|
||||
<style>
|
||||
@media print {
|
||||
#screen {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media screen {
|
||||
#print {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{ toHTML "table.md" }}
|
||||
<p id="wait" style="display: none">
|
||||
Wait delay > 2 seconds or expression window globalVar === 'ready' returns
|
||||
true.
|
||||
</p>
|
||||
<p id="print">Emulated media type is 'print'.</p>
|
||||
<p id="screen">Emulated media type is 'screen'.</p>
|
||||
<p id="javascript" style="display: none">JavaScript is enabled.</p>
|
||||
<iframe src="/etc/passwd"></iframe>
|
||||
<iframe src="\\localhost/etc/passwd"></iframe>
|
||||
|
||||
<script type="application/javascript">
|
||||
var globalVar = "notReady";
|
||||
|
||||
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
|
||||
delay(2000).then(() => {
|
||||
document.getElementById("wait").style.display = "contents";
|
||||
window.globalVar = "ready";
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
document.getElementById("javascript").style.display = "contents";
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
console.log("a simple message");
|
||||
console.debug("a debug message");
|
||||
console.warn("a warning message");
|
||||
console.error("an error message");
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
throw new Error("Exception 1");
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
throw new Error("Exception 2");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
7
test/integration/testdata/feature-rich-markdown/table.md
vendored
Normal file
7
test/integration/testdata/feature-rich-markdown/table.md
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
## This paragraph displays a table from a markdown file
|
||||
|
||||
| Tables | Are | Cool |
|
||||
| -------- | :-----------: | ----: |
|
||||
| col 1 is | left-aligned | $1600 |
|
||||
| col 2 is | centered | $12 |
|
||||
| col 3 is | right-aligned | $1 |
|
||||
13
test/integration/testdata/header-footer-html/footer.html
vendored
Normal file
13
test/integration/testdata/header-footer-html/footer.html
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-size: 12px;
|
||||
margin: auto 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p><span class="pageNumber"></span> of <span class="totalPages"></span></p>
|
||||
</body>
|
||||
</html>
|
||||
13
test/integration/testdata/header-footer-html/header.html
vendored
Normal file
13
test/integration/testdata/header-footer-html/header.html
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-size: 12px;
|
||||
margin: auto 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<span class="title"></span>
|
||||
</body>
|
||||
</html>
|
||||
9
test/integration/testdata/page-1-html/index.html
vendored
Normal file
9
test/integration/testdata/page-1-html/index.html
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Page 1</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Page 1</h1>
|
||||
</body>
|
||||
</html>
|
||||
9
test/integration/testdata/page-1-markdown/index.html
vendored
Normal file
9
test/integration/testdata/page-1-markdown/index.html
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Page 1</title>
|
||||
</head>
|
||||
<body>
|
||||
{{ toHTML "page_1.md" }}
|
||||
</body>
|
||||
</html>
|
||||
1
test/integration/testdata/page-1-markdown/page_1.md
vendored
Normal file
1
test/integration/testdata/page-1-markdown/page_1.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 1
|
||||
BIN
test/integration/testdata/page_1.docx
vendored
Normal file
BIN
test/integration/testdata/page_1.docx
vendored
Normal file
Binary file not shown.
BIN
test/integration/testdata/page_1.pdf
vendored
Normal file
BIN
test/integration/testdata/page_1.pdf
vendored
Normal file
Binary file not shown.
BIN
test/integration/testdata/page_2.docx
vendored
Normal file
BIN
test/integration/testdata/page_2.docx
vendored
Normal file
Binary file not shown.
BIN
test/integration/testdata/page_2.pdf
vendored
Normal file
BIN
test/integration/testdata/page_2.pdf
vendored
Normal file
Binary file not shown.
25
test/integration/testdata/pages-12-html/index.html
vendored
Normal file
25
test/integration/testdata/pages-12-html/index.html
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Pages 12</title>
|
||||
<style>
|
||||
.page-break-after {
|
||||
page-break-after: always;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="page-break-after">Page 1</h1>
|
||||
<h1 class="page-break-after">Page 2</h1>
|
||||
<h1 class="page-break-after">Page 3</h1>
|
||||
<h1 class="page-break-after">Page 4</h1>
|
||||
<h1 class="page-break-after">Page 5</h1>
|
||||
<h1 class="page-break-after">Page 6</h1>
|
||||
<h1 class="page-break-after">Page 7</h1>
|
||||
<h1 class="page-break-after">Page 8</h1>
|
||||
<h1 class="page-break-after">Page 9</h1>
|
||||
<h1 class="page-break-after">Page 10</h1>
|
||||
<h1 class="page-break-after">Page 11</h1>
|
||||
<h1 class="page-break-after">Page 12</h1>
|
||||
</body>
|
||||
</html>
|
||||
25
test/integration/testdata/pages-12-markdown/index.html
vendored
Normal file
25
test/integration/testdata/pages-12-markdown/index.html
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Pages 12</title>
|
||||
<style>
|
||||
.page-break-after {
|
||||
page-break-after: always;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-break-after">{{ toHTML "page_1.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_2.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_3.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_4.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_5.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_6.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_7.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_8.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_9.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_10.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_11.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_12.md" }}</div>
|
||||
</body>
|
||||
</html>
|
||||
1
test/integration/testdata/pages-12-markdown/page_1.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_1.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 1
|
||||
1
test/integration/testdata/pages-12-markdown/page_10.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_10.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 10
|
||||
1
test/integration/testdata/pages-12-markdown/page_11.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_11.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 11
|
||||
1
test/integration/testdata/pages-12-markdown/page_12.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_12.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 12
|
||||
1
test/integration/testdata/pages-12-markdown/page_2.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_2.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 2
|
||||
1
test/integration/testdata/pages-12-markdown/page_3.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_3.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 3
|
||||
1
test/integration/testdata/pages-12-markdown/page_4.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_4.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 4
|
||||
1
test/integration/testdata/pages-12-markdown/page_5.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_5.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 5
|
||||
1
test/integration/testdata/pages-12-markdown/page_6.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_6.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 6
|
||||
1
test/integration/testdata/pages-12-markdown/page_7.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_7.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 7
|
||||
1
test/integration/testdata/pages-12-markdown/page_8.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_8.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 8
|
||||
1
test/integration/testdata/pages-12-markdown/page_9.md
vendored
Normal file
1
test/integration/testdata/pages-12-markdown/page_9.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 9
|
||||
16
test/integration/testdata/pages-3-html/index.html
vendored
Normal file
16
test/integration/testdata/pages-3-html/index.html
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Pages 3</title>
|
||||
<style>
|
||||
.page-break-after {
|
||||
page-break-after: always;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="page-break-after">Page 1</h1>
|
||||
<h1 class="page-break-after">Page 2</h1>
|
||||
<h1 class="page-break-after">Page 3</h1>
|
||||
</body>
|
||||
</html>
|
||||
16
test/integration/testdata/pages-3-markdown/index.html
vendored
Normal file
16
test/integration/testdata/pages-3-markdown/index.html
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Pages 3</title>
|
||||
<style>
|
||||
.page-break-after {
|
||||
page-break-after: always;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-break-after">{{ toHTML "page_1.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_2.md" }}</div>
|
||||
<div class="page-break-after">{{ toHTML "page_3.md" }}</div>
|
||||
</body>
|
||||
</html>
|
||||
1
test/integration/testdata/pages-3-markdown/page_1.md
vendored
Normal file
1
test/integration/testdata/pages-3-markdown/page_1.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 1
|
||||
1
test/integration/testdata/pages-3-markdown/page_2.md
vendored
Normal file
1
test/integration/testdata/pages-3-markdown/page_2.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 2
|
||||
1
test/integration/testdata/pages-3-markdown/page_3.md
vendored
Normal file
1
test/integration/testdata/pages-3-markdown/page_3.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Page 3
|
||||
BIN
test/integration/testdata/pages_12.docx
vendored
Normal file
BIN
test/integration/testdata/pages_12.docx
vendored
Normal file
Binary file not shown.
BIN
test/integration/testdata/pages_12.pdf
vendored
Normal file
BIN
test/integration/testdata/pages_12.pdf
vendored
Normal file
Binary file not shown.
BIN
test/integration/testdata/pages_3.docx
vendored
Normal file
BIN
test/integration/testdata/pages_3.docx
vendored
Normal file
Binary file not shown.
BIN
test/integration/testdata/pages_3.pdf
vendored
Normal file
BIN
test/integration/testdata/pages_3.pdf
vendored
Normal file
Binary file not shown.
14
test/integration/testdata/pem/README.md
vendored
Normal file
14
test/integration/testdata/pem/README.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
To generate a valid certificate and private key use the following command:
|
||||
|
||||
```bash
|
||||
# In OpenSSL ≥ 1.1.1
|
||||
openssl req -x509 -newkey rsa:4096 -sha256 -days 9999 -nodes \
|
||||
-keyout key.pem -out cert.pem -subj "/CN=localhost" \
|
||||
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1"
|
||||
```
|
||||
|
||||
To check a certificate use the following command:
|
||||
|
||||
```bash
|
||||
openssl x509 -in cert.pem -text
|
||||
```
|
||||
30
test/integration/testdata/pem/cert.pem
vendored
Normal file
30
test/integration/testdata/pem/cert.pem
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFOjCCAyKgAwIBAgIUZaht2QoZwWDK8wEuwm+wmip9sqwwDQYJKoZIhvcNAQEL
|
||||
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTI0MDUyNjA1MDExNFoYDzIwNTEx
|
||||
MDExMDUwMTE0WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEB
|
||||
AQUAA4ICDwAwggIKAoICAQCm3TNckD55ae6pxXS03iV2P3X/edZT4vRa8D15elsi
|
||||
CSRf6mdU2TVAQyg22GEcMXgsbba7sotJVg7559LkWAgb3Dj9rbPputdS29ebncat
|
||||
x1nzo1QHMCS/v7nWoPe9fQVlDEf3ebM198f+5vhccSYFxFa+YvsUmSw9yMF8z1nA
|
||||
6POZTpm6ErByAY9EGvC8EcNOQd9xLOfBZc0e+mY/rMRxmL+0N+sSRE/ACU+2zxHN
|
||||
KcCiFX5WQdLDYW1ZjX5xAVatCPNlxSQpj97/ktGsnqwGnJWSTeMUOPv7L0LrQasf
|
||||
k1VXBvfTW2/ZqhI9WA8qfdC5XOuzVwfU14gv+6vv9AGZnUFmOjeo9XG4xWBxlIKj
|
||||
AQAzeNwAGFltPkp5a3yPczxMjKY4xLsMGcDfpaNtv1B24+7fV77Nyty/gLLT9pUa
|
||||
FtXLuRfIPSaUK3kFhAuYzGUL/sO9O9jJkNlxxygxQ+VyIgmdw0zWrUi3q+Lfmdya
|
||||
FFjHdM7LnLrLCjSv3dEoMINngR3+IejsY+98Ehd25O3oW+ZnGIQX0VwykV8sOQWq
|
||||
rpnnZ+2iHMtF6Vsj40z/Y9y7yVE18AIJFC+Yr/dD/nQyg6SE70wdNcOx0Ay1xHbP
|
||||
WuV3fqKOfhONR7NEBSO2UbHi6GZAiYMMwwul+4yKAQ4+lHOEXG4JQcKvtZasxq9v
|
||||
GwIDAQABo4GBMH8wHQYDVR0OBBYEFPPMaH3C0rAkD/E0gtBZwM0x8N9MMB8GA1Ud
|
||||
IwQYMBaAFPPMaH3C0rAkD/E0gtBZwM0x8N9MMA8GA1UdEwEB/wQFMAMBAf8wLAYD
|
||||
VR0RBCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqG
|
||||
SIb3DQEBCwUAA4ICAQB0DXz59JfQgfJvRJfraa+Cv/3nG4NNmHYtNGhrid5sagH3
|
||||
LM8jkbA+JKRAn34SmsqUZb1f2XFI64TwrScgMfAvfi+5ibRqBjM/YL06bTlG61Ua
|
||||
t2IQchV2kcX4zQnaMCIYG0dUj6JoXIspiFULMHyGDs7G9BKVcZxlaLrEvPXBqQjd
|
||||
nwF80KHS/rCConmICU9uWHPgHxS1VmhQiwYGbrakETilau1ppRS0bpH2k/stVyjc
|
||||
plttIr1DUD6xaRV4mZ0NZVlIXl2nDf78iQvreJeMrGl6AcNHzV+/rGHpY/gOrziP
|
||||
PQkB1VtSiHtBe/VMKXcVB69SEzsoGEknqs4GPXuVYm47POo3/U5HmGU+FadSATNP
|
||||
qtorRECUMbVn0IfDzJX2jBLUjZlhPI9gqO9DhiAT8FWHRV2yPsZKuiBBg5/hUvyb
|
||||
Qsswtmi/YV5e6AnXEuvylwE3wYzlqDzxwlZM08bWFyZYnSf38d3hAjVwUHAugiaX
|
||||
4sgE6GPAiONW5FkTZ4Z2oXYiN213QDIIcQeFAl04qSEFkGBV8x2hM0uXgFH1S++j
|
||||
JePdKBbV/CjxegyyYsmnln+eO1kC8pCalB6k6pEtYMqNYOnmimC8UKrJATrH9EVq
|
||||
eAehGBiIe514Oz06Ws2Vm4PTiY2x0KVbqphwkuz85ohSF9UXOHUcMryusr1zlg==
|
||||
-----END CERTIFICATE-----
|
||||
52
test/integration/testdata/pem/key.pem
vendored
Normal file
52
test/integration/testdata/pem/key.pem
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQCm3TNckD55ae6p
|
||||
xXS03iV2P3X/edZT4vRa8D15elsiCSRf6mdU2TVAQyg22GEcMXgsbba7sotJVg75
|
||||
59LkWAgb3Dj9rbPputdS29ebncatx1nzo1QHMCS/v7nWoPe9fQVlDEf3ebM198f+
|
||||
5vhccSYFxFa+YvsUmSw9yMF8z1nA6POZTpm6ErByAY9EGvC8EcNOQd9xLOfBZc0e
|
||||
+mY/rMRxmL+0N+sSRE/ACU+2zxHNKcCiFX5WQdLDYW1ZjX5xAVatCPNlxSQpj97/
|
||||
ktGsnqwGnJWSTeMUOPv7L0LrQasfk1VXBvfTW2/ZqhI9WA8qfdC5XOuzVwfU14gv
|
||||
+6vv9AGZnUFmOjeo9XG4xWBxlIKjAQAzeNwAGFltPkp5a3yPczxMjKY4xLsMGcDf
|
||||
paNtv1B24+7fV77Nyty/gLLT9pUaFtXLuRfIPSaUK3kFhAuYzGUL/sO9O9jJkNlx
|
||||
xygxQ+VyIgmdw0zWrUi3q+LfmdyaFFjHdM7LnLrLCjSv3dEoMINngR3+IejsY+98
|
||||
Ehd25O3oW+ZnGIQX0VwykV8sOQWqrpnnZ+2iHMtF6Vsj40z/Y9y7yVE18AIJFC+Y
|
||||
r/dD/nQyg6SE70wdNcOx0Ay1xHbPWuV3fqKOfhONR7NEBSO2UbHi6GZAiYMMwwul
|
||||
+4yKAQ4+lHOEXG4JQcKvtZasxq9vGwIDAQABAoICAA3s7URkT/0XTMZOUZcRPanI
|
||||
p12oGq2Vhd8GUvBjDbKhdgUAgu8fJsUzgD+o1Ic4eaxQ26x+Z1wPb+CF6vZeLQ8Q
|
||||
1JDB1lSYiy/BuRSmQ4EX30yTQjKiCe8Ws7j9u1nM/Tju9XKUbX2rgr1QeURTDQvz
|
||||
fr8UyO9xzly5oawmLHoKTDTBzS0s3Md8Pys9NFSoXCxDwxSm3WXTy8fcuHvH51Je
|
||||
SmFik/OfpSgu9BVwN9lvX+wm7wwzzMBmzmwS1Y0zbLsJbDFUv9fYHJF8/JKeC1fh
|
||||
6Xme67yG+kB+3o7TmXxhHKt5TBAPfsjOMLIojzDJ9IlY/91PqLpSjRhetdKorRlf
|
||||
gvTUGLPY8lHXwz6UBpdHmMhNHTBBvgHcOVAMD46Y81SdqMhH6TAYSh7XQVuA06Ql
|
||||
MTWzGqzKriaQDWmJ6Nx8eZCRDZGXDq4rKiJFvRFUrGYYr818qU8yC+qv5uLrOF1w
|
||||
YZV0WnZ7DtcaFliBrJVUfeTmrSJBa3yoIKbeaTDuh3TMHqgAbTx0lBdGoI6noRxx
|
||||
v7fCGho/aSOJ2rtFOjRoLQ5K8onZ226arJEyfkTh16wztQgh9DC430OkL4cQkfA0
|
||||
BxN8tGh4P0lqwcBnCOyzi4NV1NkwaaVv+pt757Cz+Cy6e2DQOtDkrFEh4p56NqDr
|
||||
KcJz88LYbbChoFKlb/kBAoIBAQDhcuI0KWTErojWu/dB2Okth8OFaTdvAPEvo+qO
|
||||
ItJgxyYL8JIdWUzS9vKro6vMctwIXvNa3K2AAwdZ1kHvaxDZaikQbnjnSjOqRlZa
|
||||
4rVnI6SSKrYj6xmKcsxxTi9YP8b2msjdLuGhPfO8Dw4EQgOt6xg0rq4msnv6bYki
|
||||
G7vsk/InnKLm8SEhR1XsmtVrpC7KbXniLQEehgs1Kp0nMLptSsOTnA1kGoZDVlXc
|
||||
u+kBBai6MM0MMDpsJgM1IFkUousQl3ItBcTXD2ZCMcg5psQJbdEhu7oXiGkHdKlL
|
||||
1UEIdSGNlzHiVM62uNxhNfwh7I6SPesDksJbE0Yd//jz/7FRAoIBAQC9ee+pDsSs
|
||||
yqunQjMWImTpD5h9fSRTzWT8h0dXsJyYi7s9Dj4mQIuoarscMI6L7njeTqHE8ptc
|
||||
b9DzIEWL+233nTOS59grCTD84Kyrn+Hw6EebgKYmtpZnvMw5cccoZ3qUsxVGurhA
|
||||
lzVaKpHtPKWT1fduNmnqt6RkZ7aRBLZre/i9UntZ7VSZYRKMOBvJLpLdqmiSPkvM
|
||||
w8ra+cedHwDegqLkoX0sxdI1yNYO1GSkJ+w1I1m1rzuCd9X5QXvyQhPezVB9wUwr
|
||||
anNGb6/YgvthzvMQAXYqv4pmb769przieMJ6geQL3O8QEtvpDAV4SvrwnA+H/wfs
|
||||
BvwI4MTHNJ6rAoIBADEfnzpOaq6QeTCQ9GdcpDJPisLfEj0Vr3f593nRDJYZzqh7
|
||||
WtsaQisVs/rCRwTdYiRQzCXYP9XM0yU4ElXgtmMpRplV+PIssOVBPj+/dldq5MkU
|
||||
lWtuJrqMGQ/3QUmxW+EQCQRo2rEPlrQ7c4pp9/NFbpjMFxZHfcwrYd4UvPXnprQK
|
||||
5VP85oMh0A8mDarOs4NYJ16o/71u57JF/sgzTevShpr7Pc+6F9dEUKEwMK0QVpt7
|
||||
VrJ5L8Gw5rIEwmREu4N5/F7jCujxag6yWjZ1p/GGBDOdfAb0qi39tYXYibsWCqGX
|
||||
eD8gy4n07dAguzeJG+expiu5JrBBmt2ekNhZtoECggEAQ90VoraAaOcaPgju5UGi
|
||||
ZPtKAcA9r6pEPlJxkg3WuKhrgr3EMs0xeDvqEnmtxJ7AOdduB21hieUesMXhQvbl
|
||||
9ycd3sMdYKSlIB2Ums/kC/YWF7MnT3xcOIGdoAGJdIZDmFjgCPo9nhzKZiYTKCZt
|
||||
o5qiSZ5Bp2jo/3FKKXzHnY3ElIKjXZ0sjNcA3qoGAbOltLEhTSf03D1QPcfy3+rH
|
||||
0+p0T3ErtUqRNORfDuaxuT33Uzz7F6DQrrUfNWxn6WgTV9yvtKr0DiTNbu/3ypN3
|
||||
WBvYYOY1HbCG8JObfK/ovTDFbz1woXMbSOWIUFsW5nPslxs+UNZeTwJdaQygTj0h
|
||||
iwKCAQBuXOPtjWGZINgfjo/n67Q8FuzUXxDK/IuXzuDXhi+B3/O3/PcVEDHFByhI
|
||||
KHOh2mTD25vgFWh+8dNg1R+m5uIeQ5zbZ5U0205XzmrZgBXXCAHKNruTwqZfQ6er
|
||||
np+8wHhcCbBuy0Z0ponzBGlrDYmbxO9anXGxoe/rE3+pWbzMneZ+cHgNjXCtfZCY
|
||||
XGfLeJWW3+B8y5Lff39ADawmjm8VWVEdd8DP5o2zulbXhgMMnAsSVsR/XgwBqpbf
|
||||
82k1bqvN2v08ID5nmTRdzD+D51Hjw80Uoqhm5DJL4IwaoK/YstCu2TCbmLGiyqSk
|
||||
lrSOZMPTLX1tN/cWa+Ii+/WALnkI
|
||||
-----END PRIVATE KEY-----
|
||||
BIN
test/integration/testdata/protected_page_1.docx
vendored
Normal file
BIN
test/integration/testdata/protected_page_1.docx
vendored
Normal file
Binary file not shown.
0
test/integration/teststore/.gitkeep
Normal file
0
test/integration/teststore/.gitkeep
Normal file
Reference in New Issue
Block a user