From 0febb60a3f1f718a96c58f3ff1455e2731aaadd3 Mon Sep 17 00:00:00 2001 From: Julien Neuhart Date: Fri, 21 Mar 2025 11:18:20 +0100 Subject: [PATCH] test: add integration tests --- .../action.yml | 38 +- .../build.sh} | 18 +- .github/actions/build-test-push/push.sh | 70 + .github/actions/build-test-push/test.sh | 79 + .github/actions/merge/merge.sh | 1 - .github/workflows/continuous-delivery.yml | 20 +- .github/workflows/continuous-integration.yml | 166 +- .node-version | 1 + .prettierrc | 3 +- Makefile | 61 +- README.md | 2 - go.mod | 58 +- go.sum | 168 +- pkg/gotenberg/cmd_test.go | 306 -- pkg/gotenberg/context_test.go | 17 - pkg/gotenberg/fs_test.go | 146 - pkg/gotenberg/gc_test.go | 3 +- pkg/gotenberg/logging_test.go | 23 - pkg/gotenberg/mocks_test.go | 264 -- pkg/modules/api/api_test.go | 1033 ------- pkg/modules/api/context_test.go | 837 ------ pkg/modules/api/formdata_test.go | 24 +- pkg/modules/api/middlewares_test.go | 584 ---- pkg/modules/api/mocks_test.go | 193 -- .../modules/api/testdata/sample.txt | 0 pkg/modules/chromium/browser_test.go | 2484 ----------------- pkg/modules/chromium/chromium_test.go | 637 ----- pkg/modules/chromium/debug_test.go | 24 - pkg/modules/chromium/mocks_test.go | 50 - pkg/modules/chromium/routes_test.go | 1927 ------------- pkg/modules/exiftool/exiftool_test.go | 415 --- pkg/modules/libreoffice/api/api_test.go | 522 ---- .../libreoffice/api/libreoffice_test.go | 699 ----- pkg/modules/libreoffice/api/mocks_test.go | 94 - pkg/modules/libreoffice/libreoffice_test.go | 196 -- .../libreoffice/pdfengine/pdfengine_test.go | 210 -- pkg/modules/libreoffice/routes.go | 10 - pkg/modules/libreoffice/routes_test.go | 817 ------ pkg/modules/pdfcpu/pdfcpu_test.go | 329 --- pkg/modules/pdfengines/pdfengines_test.go | 417 --- pkg/modules/pdfengines/routes_test.go | 1813 ------------ pkg/modules/pdftk/pdftk_test.go | 313 --- pkg/modules/prometheus/prometheus_test.go | 360 --- pkg/modules/qpdf/qpdf_test.go | 425 --- pkg/modules/webhook/middleware_test.go | 582 ---- pkg/modules/webhook/webhook_test.go | 65 - test/Dockerfile | 50 - test/docker-entrypoint.sh | 59 - test/golint.sh | 5 - test/gotest.sh | 10 - test/gotodos.sh | 8 - test/integration/doc.go | 2 + .../features/chromium_convert_html.feature | 852 ++++++ .../chromium_convert_markdown.feature | 977 +++++++ .../features/chromium_convert_url.feature | 929 ++++++ test/integration/features/debug.feature | 147 + test/integration/features/health.feature | 107 + .../features/libreoffice_convert.feature | 614 ++++ .../features/pdfengines_convert.feature | 185 ++ .../features/pdfengines_flatten.feature | 112 + .../features/pdfengines_merge.feature | 324 +++ .../features/pdfengines_metadata.feature | 268 ++ .../features/pdfengines_split.feature | 551 ++++ .../features/prometheus_metrics.feature | 90 + test/integration/features/root.feature | 62 + test/integration/features/version.feature | 35 + test/integration/main_test.go | 50 + test/integration/scenario/compare.go | 57 + test/integration/scenario/containers.go | 136 + test/integration/scenario/doc.go | 2 + test/integration/scenario/http.go | 83 + test/integration/scenario/scenario.go | 911 ++++++ test/integration/scenario/server.go | 176 ++ .../feature-rich-html-remote/index.html | 64 + .../testdata/feature-rich-html/index.html | 69 + .../testdata/feature-rich-markdown/index.html | 70 + .../testdata/feature-rich-markdown/table.md | 7 + .../testdata/header-footer-html/footer.html | 13 + .../testdata/header-footer-html/header.html | 13 + .../testdata/page-1-html/index.html | 9 + .../testdata/page-1-markdown/index.html | 9 + .../testdata/page-1-markdown/page_1.md | 1 + test/integration/testdata/page_1.docx | Bin 0 -> 6408 bytes test/integration/testdata/page_1.pdf | Bin 0 -> 4560 bytes test/integration/testdata/page_2.docx | Bin 0 -> 6408 bytes test/integration/testdata/page_2.pdf | Bin 0 -> 4900 bytes .../testdata/pages-12-html/index.html | 25 + .../testdata/pages-12-markdown/index.html | 25 + .../testdata/pages-12-markdown/page_1.md | 1 + .../testdata/pages-12-markdown/page_10.md | 1 + .../testdata/pages-12-markdown/page_11.md | 1 + .../testdata/pages-12-markdown/page_12.md | 1 + .../testdata/pages-12-markdown/page_2.md | 1 + .../testdata/pages-12-markdown/page_3.md | 1 + .../testdata/pages-12-markdown/page_4.md | 1 + .../testdata/pages-12-markdown/page_5.md | 1 + .../testdata/pages-12-markdown/page_6.md | 1 + .../testdata/pages-12-markdown/page_7.md | 1 + .../testdata/pages-12-markdown/page_8.md | 1 + .../testdata/pages-12-markdown/page_9.md | 1 + .../testdata/pages-3-html/index.html | 16 + .../testdata/pages-3-markdown/index.html | 16 + .../testdata/pages-3-markdown/page_1.md | 1 + .../testdata/pages-3-markdown/page_2.md | 1 + .../testdata/pages-3-markdown/page_3.md | 1 + test/integration/testdata/pages_12.docx | Bin 0 -> 6539 bytes test/integration/testdata/pages_12.pdf | Bin 0 -> 89683 bytes test/integration/testdata/pages_3.docx | Bin 0 -> 6454 bytes test/integration/testdata/pages_3.pdf | Bin 0 -> 22548 bytes .../testdata/pem}/README.md | 0 .../api => integration/testdata/pem}/cert.pem | 0 .../api => integration/testdata/pem}/key.pem | 0 .../testdata/protected_page_1.docx | Bin 0 -> 12288 bytes test/integration/teststore/.gitkeep | 0 test/testdata/api/sample1.txt | 1 - test/testdata/api/sample2.pdf | Bin 208299 -> 0 bytes test/testdata/chromium/html/font.woff | Bin 12644 -> 0 bytes test/testdata/chromium/html/footer.html | 15 - test/testdata/chromium/html/header.html | 13 - test/testdata/chromium/html/img.gif | Bin 29685 -> 0 bytes test/testdata/chromium/html/index.html | 105 - test/testdata/chromium/html/style.css | 29 - .../testdata/chromium/markdown/defaultfont.md | 3 - test/testdata/chromium/markdown/font.woff | Bin 12644 -> 0 bytes test/testdata/chromium/markdown/footer.html | 15 - test/testdata/chromium/markdown/googlefont.md | 3 - test/testdata/chromium/markdown/header.html | 13 - test/testdata/chromium/markdown/img.gif | Bin 29685 -> 0 bytes test/testdata/chromium/markdown/index.html | 49 - test/testdata/chromium/markdown/localfont.md | 3 - test/testdata/chromium/markdown/style.css | 28 - test/testdata/chromium/markdown/table.md | 7 - test/testdata/libreoffice/document.docx | Bin 91571 -> 0 bytes test/testdata/libreoffice/protected.docx | Bin 12288 -> 0 bytes test/testdata/pdfengines/sample1.pdf | Bin 208299 -> 0 bytes test/testdata/pdfengines/sample2.pdf | Bin 208299 -> 0 bytes test/testdata/pdfengines/sample3.pdf | Bin 224175 -> 0 bytes test/testdata/pdfengines/sample4.pdf | Bin 8025 -> 0 bytes test/testdata/pdfengines/sample5.pdf | Bin 224175 -> 0 bytes 139 files changed, 7561 insertions(+), 16381 deletions(-) rename .github/actions/{build-push => build-test-push}/action.yml (56%) rename .github/actions/{build-push/build-push.sh => build-test-push/build.sh} (91%) create mode 100755 .github/actions/build-test-push/push.sh create mode 100755 .github/actions/build-test-push/test.sh create mode 100644 .node-version delete mode 100644 pkg/gotenberg/cmd_test.go delete mode 100644 pkg/gotenberg/fs_test.go delete mode 100644 pkg/gotenberg/logging_test.go delete mode 100644 pkg/gotenberg/mocks_test.go delete mode 100644 pkg/modules/api/api_test.go delete mode 100644 pkg/modules/api/context_test.go delete mode 100644 pkg/modules/api/middlewares_test.go delete mode 100644 pkg/modules/api/mocks_test.go rename test/testdata/libreoffice/document.txt => pkg/modules/api/testdata/sample.txt (100%) delete mode 100644 pkg/modules/chromium/browser_test.go delete mode 100644 pkg/modules/chromium/chromium_test.go delete mode 100644 pkg/modules/chromium/debug_test.go delete mode 100644 pkg/modules/chromium/mocks_test.go delete mode 100644 pkg/modules/chromium/routes_test.go delete mode 100644 pkg/modules/exiftool/exiftool_test.go delete mode 100644 pkg/modules/libreoffice/api/api_test.go delete mode 100644 pkg/modules/libreoffice/api/libreoffice_test.go delete mode 100644 pkg/modules/libreoffice/api/mocks_test.go delete mode 100644 pkg/modules/libreoffice/libreoffice_test.go delete mode 100644 pkg/modules/libreoffice/pdfengine/pdfengine_test.go delete mode 100644 pkg/modules/libreoffice/routes_test.go delete mode 100644 pkg/modules/pdfcpu/pdfcpu_test.go delete mode 100644 pkg/modules/pdfengines/pdfengines_test.go delete mode 100644 pkg/modules/pdfengines/routes_test.go delete mode 100644 pkg/modules/pdftk/pdftk_test.go delete mode 100644 pkg/modules/prometheus/prometheus_test.go delete mode 100644 pkg/modules/qpdf/qpdf_test.go delete mode 100644 pkg/modules/webhook/middleware_test.go delete mode 100644 pkg/modules/webhook/webhook_test.go delete mode 100644 test/Dockerfile delete mode 100755 test/docker-entrypoint.sh delete mode 100755 test/golint.sh delete mode 100755 test/gotest.sh delete mode 100755 test/gotodos.sh create mode 100644 test/integration/doc.go create mode 100644 test/integration/features/chromium_convert_html.feature create mode 100644 test/integration/features/chromium_convert_markdown.feature create mode 100644 test/integration/features/chromium_convert_url.feature create mode 100644 test/integration/features/debug.feature create mode 100644 test/integration/features/health.feature create mode 100644 test/integration/features/libreoffice_convert.feature create mode 100644 test/integration/features/pdfengines_convert.feature create mode 100644 test/integration/features/pdfengines_flatten.feature create mode 100644 test/integration/features/pdfengines_merge.feature create mode 100644 test/integration/features/pdfengines_metadata.feature create mode 100644 test/integration/features/pdfengines_split.feature create mode 100644 test/integration/features/prometheus_metrics.feature create mode 100644 test/integration/features/root.feature create mode 100644 test/integration/features/version.feature create mode 100644 test/integration/main_test.go create mode 100644 test/integration/scenario/compare.go create mode 100644 test/integration/scenario/containers.go create mode 100644 test/integration/scenario/doc.go create mode 100644 test/integration/scenario/http.go create mode 100644 test/integration/scenario/scenario.go create mode 100644 test/integration/scenario/server.go create mode 100644 test/integration/testdata/feature-rich-html-remote/index.html create mode 100644 test/integration/testdata/feature-rich-html/index.html create mode 100644 test/integration/testdata/feature-rich-markdown/index.html create mode 100644 test/integration/testdata/feature-rich-markdown/table.md create mode 100644 test/integration/testdata/header-footer-html/footer.html create mode 100644 test/integration/testdata/header-footer-html/header.html create mode 100644 test/integration/testdata/page-1-html/index.html create mode 100644 test/integration/testdata/page-1-markdown/index.html create mode 100644 test/integration/testdata/page-1-markdown/page_1.md create mode 100644 test/integration/testdata/page_1.docx create mode 100644 test/integration/testdata/page_1.pdf create mode 100644 test/integration/testdata/page_2.docx create mode 100644 test/integration/testdata/page_2.pdf create mode 100644 test/integration/testdata/pages-12-html/index.html create mode 100644 test/integration/testdata/pages-12-markdown/index.html create mode 100644 test/integration/testdata/pages-12-markdown/page_1.md create mode 100644 test/integration/testdata/pages-12-markdown/page_10.md create mode 100644 test/integration/testdata/pages-12-markdown/page_11.md create mode 100644 test/integration/testdata/pages-12-markdown/page_12.md create mode 100644 test/integration/testdata/pages-12-markdown/page_2.md create mode 100644 test/integration/testdata/pages-12-markdown/page_3.md create mode 100644 test/integration/testdata/pages-12-markdown/page_4.md create mode 100644 test/integration/testdata/pages-12-markdown/page_5.md create mode 100644 test/integration/testdata/pages-12-markdown/page_6.md create mode 100644 test/integration/testdata/pages-12-markdown/page_7.md create mode 100644 test/integration/testdata/pages-12-markdown/page_8.md create mode 100644 test/integration/testdata/pages-12-markdown/page_9.md create mode 100644 test/integration/testdata/pages-3-html/index.html create mode 100644 test/integration/testdata/pages-3-markdown/index.html create mode 100644 test/integration/testdata/pages-3-markdown/page_1.md create mode 100644 test/integration/testdata/pages-3-markdown/page_2.md create mode 100644 test/integration/testdata/pages-3-markdown/page_3.md create mode 100644 test/integration/testdata/pages_12.docx create mode 100644 test/integration/testdata/pages_12.pdf create mode 100644 test/integration/testdata/pages_3.docx create mode 100644 test/integration/testdata/pages_3.pdf rename test/{testdata/api => integration/testdata/pem}/README.md (100%) rename test/{testdata/api => integration/testdata/pem}/cert.pem (100%) rename test/{testdata/api => integration/testdata/pem}/key.pem (100%) create mode 100644 test/integration/testdata/protected_page_1.docx create mode 100644 test/integration/teststore/.gitkeep delete mode 100644 test/testdata/api/sample1.txt delete mode 100644 test/testdata/api/sample2.pdf delete mode 100644 test/testdata/chromium/html/font.woff delete mode 100644 test/testdata/chromium/html/footer.html delete mode 100644 test/testdata/chromium/html/header.html delete mode 100644 test/testdata/chromium/html/img.gif delete mode 100644 test/testdata/chromium/html/index.html delete mode 100644 test/testdata/chromium/html/style.css delete mode 100644 test/testdata/chromium/markdown/defaultfont.md delete mode 100644 test/testdata/chromium/markdown/font.woff delete mode 100644 test/testdata/chromium/markdown/footer.html delete mode 100644 test/testdata/chromium/markdown/googlefont.md delete mode 100644 test/testdata/chromium/markdown/header.html delete mode 100644 test/testdata/chromium/markdown/img.gif delete mode 100644 test/testdata/chromium/markdown/index.html delete mode 100644 test/testdata/chromium/markdown/localfont.md delete mode 100644 test/testdata/chromium/markdown/style.css delete mode 100644 test/testdata/chromium/markdown/table.md delete mode 100644 test/testdata/libreoffice/document.docx delete mode 100644 test/testdata/libreoffice/protected.docx delete mode 100644 test/testdata/pdfengines/sample1.pdf delete mode 100644 test/testdata/pdfengines/sample2.pdf delete mode 100644 test/testdata/pdfengines/sample3.pdf delete mode 100644 test/testdata/pdfengines/sample4.pdf delete mode 100644 test/testdata/pdfengines/sample5.pdf diff --git a/.github/actions/build-push/action.yml b/.github/actions/build-test-push/action.yml similarity index 56% rename from .github/actions/build-push/action.yml rename to .github/actions/build-test-push/action.yml index af94b040..019dc911 100644 --- a/.github/actions/build-push/action.yml +++ b/.github/actions/build-test-push/action.yml @@ -1,5 +1,5 @@ -name: Build and Push -description: Build and push Docker images +name: Build Test Push +description: Build, test and push Docker images for a given platform author: Julien Neuhart inputs: @@ -19,6 +19,9 @@ inputs: version: description: Gotenberg version required: true + skip_integrations_tests: + description: Define whether to skip integration testing + default: false alternate_repository: description: Alternate repository to push the tags to dry_run: @@ -27,10 +30,10 @@ inputs: outputs: tags: description: Comma separated list of tag - value: ${{ steps.build_push.outputs.tags }} + value: ${{ steps.build.outputs.tags }} tags_cloud_run: description: Comma separated list of Cloud Run tags (linux/amd64 only) - value: ${{ steps.build_push.outputs.tags_cloud_run }} + value: ${{ steps.build.outputs.tags_cloud_run }} runs: using: composite @@ -50,18 +53,35 @@ runs: username: ${{ inputs.docker_hub_username }} password: ${{ inputs.docker_hub_password }} - - name: Build and push ${{ inputs.platform }} - id: build_push + - name: Build ${{ inputs.platform }} + id: build shell: bash run: | - .github/actions/build-push/build-push.sh \ + .github/actions/build-test-push/build.sh \ --version "${{ inputs.version }}" \ --platform "${{ inputs.platform }}" \ --alternate-repository "${{ inputs.alternate_repository }}" \ --dry-run "${{ inputs.dry_run }}" + - name: Run integration tests + if: ${{ inputs.skip_integrations_tests != 'true' }} + shell: bash + run: | + .github/actions/build-test-push/test.sh \ + --version "${{ inputs.version }}" \ + --platform "${{ inputs.platform }}" \ + --alternate-repository "${{ inputs.alternate_repository }}" \ + --dry-run "${{ inputs.dry_run }}" + + - name: Push + shell: bash + run: | + .github/actions/build-test-push/push.sh \ + --tags "${{ steps.build.outputs.tags }}" \ + --dry-run "${{ inputs.dry_run }}" + - name: Outputs shell: bash run: | - echo "tags=${{ steps.build_push.outputs.tags }}" - echo "tags_cloud_run=${{ steps.build_push.outputs.tags_cloud_run }}" + echo "tags=${{ steps.build.outputs.tags }}" + echo "tags_cloud_run=${{ steps.build.outputs.tags_cloud_run }}" diff --git a/.github/actions/build-push/build-push.sh b/.github/actions/build-test-push/build.sh similarity index 91% rename from .github/actions/build-push/build-push.sh rename to .github/actions/build-test-push/build.sh index c83bb028..410d3abd 100755 --- a/.github/actions/build-push/build-push.sh +++ b/.github/actions/build-test-push/build.sh @@ -92,7 +92,7 @@ fi tags_flags=() tags_cloud_run_flags=() -echo "Will push the following tags:" +echo "Will use the following tags:" for tag in "${tags[@]}"; do tags_flags+=("-t" "$tag") echo "- $tag" @@ -103,7 +103,7 @@ for tag in "${tags_cloud_run[@]}"; do done echo -# Build and push images. +# Build images. run_cmd() { local cmd="$1" @@ -126,6 +126,8 @@ join() { echo "$*" } +no_arch_tag="$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version" + cmd="docker buildx build \ --build-arg GOLANG_VERSION=$GOLANG_VERSION \ --build-arg GOTENBERG_VERSION=$version \ @@ -134,9 +136,10 @@ cmd="docker buildx build \ --build-arg NOTO_COLOR_EMOJI_VERSION=$NOTO_COLOR_EMOJI_VERSION \ --build-arg PDFTK_VERSION=$PDFTK_VERSION \ --build-arg PDFCPU_VERSION=$PDFCPU_VERSION \ - --push \ --platform $platform \ + --load \ ${tags_flags[*]} \ + -t $no_arch_tag \ -f $DOCKERFILE $DOCKER_BUILD_CONTEXT " run_cmd "$cmd" @@ -149,19 +152,10 @@ if [ "$platform" != "linux/amd64" ]; then exit 0 fi -source_tag_cloud_run="$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version-${arch[1]}" -cmd="docker pull $source_tag_cloud_run" -run_cmd "$cmd" - -target_tag_cloud_run="$DOCKER_REGISTRY/$DOCKER_REPOSITORY:$version" -cmd="docker image tag $source_tag_cloud_run $target_tag_cloud_run" -run_cmd "$cmd" - cmd="docker build \ --build-arg DOCKER_REGISTRY=$DOCKER_REGISTRY \ --build-arg DOCKER_REPOSITORY=$DOCKER_REPOSITORY \ --build-arg GOTENBERG_VERSION=$version \ - --push \ ${tags_cloud_run_flags[*]} \ -f $DOCKERFILE_CLOUDRUN $DOCKER_BUILD_CONTEXT " diff --git a/.github/actions/build-test-push/push.sh b/.github/actions/build-test-push/push.sh new file mode 100755 index 00000000..599346f1 --- /dev/null +++ b/.github/actions/build-test-push/push.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# Exit early. +# See: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#The-Set-Builtin. +set -e + +# Source dot env file. +source .env + +# Arguments. +tags="" +dry_run="" + +while [[ $# -gt 0 ]]; do + case $1 in + --tags) + tags="$2" + shift 2 + ;; + --dry-run) + dry_run=$2 + shift 2 + ;; + *) + echo "Unknown option $1" + exit 1 + ;; + esac +done + +echo "Push tag(s) ๐Ÿ“ฆ" +echo + +echo "Tag(s) to push:" +IFS=',' read -ra tags_to_push <<< "$tags" +for tag in "${tags_to_push[@]}"; do + echo "- $tag" +done + +if [ "$dry_run" = "true" ]; then + echo "๐Ÿšง Dry run" +fi +echo + +# Push tags. +run_cmd() { + local cmd="$1" + + if [ "$dry_run" = "true" ]; then + echo "๐Ÿšง Dry run - would run the following command:" + echo "$cmd" + echo + else + echo "โš™๏ธ Running command:" + echo "$cmd" + eval "$cmd" + echo + fi +} + +for tag in "${tags_to_push[@]}"; do + cmd="docker push $tag" + run_cmd "$cmd" + + echo "โžก๏ธ $tag pushed" + echo +done + +echo "โœ… Done!" +exit 0 diff --git a/.github/actions/build-test-push/test.sh b/.github/actions/build-test-push/test.sh new file mode 100755 index 00000000..ee5eb197 --- /dev/null +++ b/.github/actions/build-test-push/test.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +# Exit early. +# See: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#The-Set-Builtin. +set -e + +# Source dot env file. +source .env + +# Arguments. +version="" +platform="" +alternate_repository="" +dry_run="" + +while [[ $# -gt 0 ]]; do + case $1 in + --version) + version="${2//v/}" + shift 2 + ;; + --platform) + platform="$2" + shift 2 + ;; + --alternate-repository) + alternate_repository="$2" + shift 2 + ;; + --dry-run) + dry_run="$2" + shift 2 + ;; + *) + echo "Unknown option $1" + exit 1 + ;; + esac +done + +echo "Integration testing ๐Ÿงช" +echo + +echo "Gotenberg version: $version" +echo "Target platform: $platform" + +repository=$DOCKER_REPOSITORY + +if [ -n "$alternate_repository" ]; then + echo "โš ๏ธ Using $alternate_repository for DOCKER_REPOSITORY" + repository=$alternate_repository +fi + +if [ "$dry_run" = "true" ]; then + echo "๐Ÿšง Dry run" +fi +echo + +# Test image. +run_cmd() { + local cmd="$1" + + if [ "$dry_run" = "true" ]; then + echo "๐Ÿšง Dry run - would run the following command:" + echo "$cmd" + echo + else + echo "โš™๏ธ Running command:" + echo "$cmd" + eval "$cmd" + echo + fi +} + +cmd="make test-integration DOCKER_REPOSITORY=$repository GOTENBERG_VERSION=$version PLATFORM=$platform" +run_cmd "$cmd" + +echo "โœ… Done!" +exit 0 diff --git a/.github/actions/merge/merge.sh b/.github/actions/merge/merge.sh index 951bba22..ef4c0afe 100755 --- a/.github/actions/merge/merge.sh +++ b/.github/actions/merge/merge.sh @@ -49,7 +49,6 @@ fi if [ "$dry_run" = "true" ]; then echo "๐Ÿšง Dry run" fi - echo # Build merge map. diff --git a/.github/workflows/continuous-delivery.yml b/.github/workflows/continuous-delivery.yml index ab40aa6e..1ada08b3 100644 --- a/.github/workflows/continuous-delivery.yml +++ b/.github/workflows/continuous-delivery.yml @@ -20,12 +20,13 @@ jobs: - name: Build and push id: build_push - uses: ./.github/actions/build-push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} - version: ${{ github.event.release.tag_name }} + version: pr-${{ github.event.pull_request.number }} platform: linux/amd64 + skip_integrations_tests: true release_386: name: Release linux/386 @@ -39,12 +40,13 @@ jobs: - name: Build and push id: build_push - uses: ./.github/actions/build-push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} - version: ${{ github.event.release.tag_name }} + version: pr-${{ github.event.pull_request.number }} platform: linux/386 + skip_integrations_tests: true release_arm64: name: Release linux/arm64 @@ -58,12 +60,13 @@ jobs: - name: Build and push id: build_push - uses: ./.github/actions/build-push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} - version: ${{ github.event.release.tag_name }} + version: pr-${{ github.event.pull_request.number }} platform: linux/arm64 + skip_integrations_tests: true release_arm_v7: name: Release linux/arm/v7 @@ -77,12 +80,13 @@ jobs: - name: Build and push id: build_push - uses: ./.github/actions/build-push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} - version: ${{ github.event.release.tag_name }} + version: pr-${{ github.event.pull_request.number }} platform: linux/arm/v7 + skip_integrations_tests: true merge_clean_release_tags: needs: diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 75980b6b..ab8dc1c5 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -17,66 +17,74 @@ permissions: jobs: lint: - name: Lint + name: Lint Golang codebase runs-on: ubuntu-latest steps: + - name: Checkout source code + uses: actions/checkout@v4 + - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.23" - cache: false - - - name: Checkout source code - uses: actions/checkout@v4 + go-version-file: go.mod - name: Run linters uses: golangci/golangci-lint-action@v6 with: version: v1.64.2 - tests: - needs: - - lint - name: Tests + lint-prettier: + name: Lint non-Golang codebase runs-on: ubuntu-latest steps: - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Checkout source code uses: actions/checkout@v4 - - name: Build testing environment - run: make build build-tests + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: .node-version + + - name: Install Dependencies + run: npm i + + - name: Run linters + run: make lint-prettier + + test-unit: + needs: + - lint + - lint-prettier + name: Run unit tests + runs-on: ubuntu-latest + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod - name: Run tests - run: make tests-once - - - name: Upload to Codecov - uses: codecov/codecov-action@v5 - with: - token: ${{ secrets.CODECOV_TOKEN }} - verbose: true + run: make test-unit snapshot_amd64: if: github.event_name == 'pull_request' needs: - - tests + - test-unit name: Snapshot linux/amd64 runs-on: ubuntu-latest outputs: - tags: ${{ steps.build_push.outputs.tags }} - tags_cloud_run: ${{ steps.build_push.outputs.tags_cloud_run }} + tags: ${{ steps.build_test_push.outputs.tags }} + tags_cloud_run: ${{ steps.build_test_push.outputs.tags_cloud_run }} steps: - name: Checkout source code uses: actions/checkout@v4 - - name: Build and push - id: build_push - uses: ./.github/actions/build-push + - name: Build, test and push + id: build_test_push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -87,19 +95,19 @@ jobs: snapshot_386: if: github.event_name == 'pull_request' needs: - - tests + - test-unit name: Snapshot linux/386 runs-on: ubuntu-latest outputs: - tags: ${{ steps.build_push.outputs.tags }} - tags_cloud_run: ${{ steps.build_push.outputs.tags_cloud_run }} + tags: ${{ steps.build_test_push.outputs.tags }} + tags_cloud_run: ${{ steps.build_test_push.outputs.tags_cloud_run }} steps: - name: Checkout source code uses: actions/checkout@v4 - - name: Build and push - id: build_push - uses: ./.github/actions/build-push + - name: Build, test and push + id: build_test_push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -110,19 +118,19 @@ jobs: snapshot_arm64: if: github.event_name == 'pull_request' needs: - - tests + - test-unit name: Snapshot linux/arm64 runs-on: ubuntu-24.04-arm outputs: - tags: ${{ steps.build_push.outputs.tags }} - tags_cloud_run: ${{ steps.build_push.outputs.tags_cloud_run }} + tags: ${{ steps.build_test_push.outputs.tags }} + tags_cloud_run: ${{ steps.build_test_push.outputs.tags_cloud_run }} steps: - name: Checkout source code uses: actions/checkout@v4 - - name: Build and push - id: build_push - uses: ./.github/actions/build-push + - name: Build, test and push + id: build_test_push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -133,19 +141,19 @@ jobs: snapshot_arm_v7: if: github.event_name == 'pull_request' needs: - - tests + - test-unit name: Snapshot linux/arm/v7 runs-on: ubuntu-24.04-arm outputs: - tags: ${{ steps.build_push.outputs.tags }} - tags_cloud_run: ${{ steps.build_push.outputs.tags_cloud_run }} + tags: ${{ steps.build_test_push.outputs.tags }} + tags_cloud_run: ${{ steps.build_test_push.outputs.tags_cloud_run }} steps: - name: Checkout source code uses: actions/checkout@v4 - - name: Build and push - id: build_push - uses: ./.github/actions/build-push + - name: Build, test and push + id: build_test_push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} @@ -182,90 +190,94 @@ jobs: edge_amd64: if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: - - tests + - test-unit name: Edge linux/amd64 runs-on: ubuntu-latest outputs: - tags: ${{ steps.build_push.outputs.tags }} - tags_cloud_run: ${{ steps.build_push.outputs.tags_cloud_run }} + tags: ${{ steps.build_test_push.outputs.tags }} + tags_cloud_run: ${{ steps.build_test_push.outputs.tags_cloud_run }} steps: - name: Checkout source code uses: actions/checkout@v4 - - name: Build and push - id: build_push - uses: ./.github/actions/build-push + - name: Build, test and push + id: build_test_push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} - version: edge + version: pr-${{ github.event.pull_request.number }} platform: linux/amd64 + alternate_repository: snapshot edge_386: if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: - - tests + - test-unit name: Edge linux/386 runs-on: ubuntu-latest outputs: - tags: ${{ steps.build_push.outputs.tags }} - tags_cloud_run: ${{ steps.build_push.outputs.tags_cloud_run }} + tags: ${{ steps.build_test_push.outputs.tags }} + tags_cloud_run: ${{ steps.build_test_push.outputs.tags_cloud_run }} steps: - name: Checkout source code uses: actions/checkout@v4 - - name: Build and push - id: build_push - uses: ./.github/actions/build-push + - name: Build, test and push + id: build_test_push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} - version: edge + version: pr-${{ github.event.pull_request.number }} platform: linux/386 + alternate_repository: snapshot edge_arm64: if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: - - tests + - test-unit name: Edge linux/arm64 runs-on: ubuntu-24.04-arm outputs: - tags: ${{ steps.build_push.outputs.tags }} - tags_cloud_run: ${{ steps.build_push.outputs.tags_cloud_run }} + tags: ${{ steps.build_test_push.outputs.tags }} + tags_cloud_run: ${{ steps.build_test_push.outputs.tags_cloud_run }} steps: - name: Checkout source code uses: actions/checkout@v4 - - name: Build and push - id: build_push - uses: ./.github/actions/build-push + - name: Build, test and push + id: build_test_push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} - version: edge + version: pr-${{ github.event.pull_request.number }} platform: linux/arm64 + alternate_repository: snapshot edge_arm_v7: if: github.event_name == 'push' && github.ref == 'refs/heads/main' needs: - - tests + - test-unit name: Edge linux/arm/v7 runs-on: ubuntu-24.04-arm outputs: - tags: ${{ steps.build_push.outputs.tags }} - tags_cloud_run: ${{ steps.build_push.outputs.tags_cloud_run }} + tags: ${{ steps.build_test_push.outputs.tags }} + tags_cloud_run: ${{ steps.build_test_push.outputs.tags_cloud_run }} steps: - name: Checkout source code uses: actions/checkout@v4 - - name: Build and push - id: build_push - uses: ./.github/actions/build-push + - name: Build, test and push + id: build_test_push + uses: ./.github/actions/build-test-push with: docker_hub_username: ${{ secrets.DOCKERHUB_USERNAME }} docker_hub_password: ${{ secrets.DOCKERHUB_TOKEN }} - version: edge + version: pr-${{ github.event.pull_request.number }} platform: linux/arm/v7 + alternate_repository: snapshot merge_clean_edge_tags: needs: diff --git a/.node-version b/.node-version new file mode 100644 index 00000000..ca8f932a --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +23.9.0 diff --git a/.prettierrc b/.prettierrc index 6d1814a3..18106bad 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,3 +1,4 @@ { - "plugins": ["prettier-plugin-gherkin", "prettier-plugin-sh"] + "plugins": ["prettier-plugin-gherkin", "prettier-plugin-sh"], + "escapeBackslashes": true } diff --git a/Makefile b/Makefile index c3b3576f..e997b419 100644 --- a/Makefile +++ b/Makefile @@ -2,10 +2,7 @@ include .env .PHONY: help help: ## Show the help - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - -.PHONY: it -it: build build-tests ## Initialize the development environment + @grep -hE '^[A-Za-z0-9_ \-]*?:.*##.*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' .PHONY: build build: ## Build the Gotenberg's Docker image @@ -158,52 +155,42 @@ run: ## Start a Gotenberg container --webhook-client-timeout=$(WEBHOOK_CLIENT_TIMEOUT) \ --webhook-disable=$(WEBHOOK_DISABLE) -.PHONY: build-tests -build-tests: ## Build the tests' Docker image - docker build \ - --build-arg GOLANG_VERSION=$(GOLANG_VERSION) \ - --build-arg DOCKER_REGISTRY=$(DOCKER_REGISTRY) \ - --build-arg DOCKER_REPOSITORY=$(DOCKER_REPOSITORY) \ - --build-arg GOTENBERG_VERSION=$(GOTENBERG_VERSION) \ - --build-arg GOLANGCI_LINT_VERSION=$(GOLANGCI_LINT_VERSION) \ - -t $(DOCKER_REGISTRY)/$(DOCKER_REPOSITORY):$(GOTENBERG_VERSION)-tests \ - -f test/Dockerfile . +.PHONY: test-unit +test-unit: ## Run unit tests + go test -race ./... -.PHONY: tests -tests: ## Start the testing environment - docker run --rm -it \ - -v $(PWD):/tests \ - $(DOCKER_REGISTRY)/$(DOCKER_REPOSITORY):$(GOTENBERG_VERSION)-tests \ - bash +PLATFORM= -.PHONY: tests-once -tests-once: ## Run the tests once (prefer the "tests" command while developing) - docker run --rm \ - -v $(PWD):/tests \ - $(DOCKER_REGISTRY)/$(DOCKER_REPOSITORY):$(GOTENBERG_VERSION)-tests \ - gotest - -.PHONY: tests-integration -tests-integration: ## Run integration tests - go test -tags=integration -v github.com/gotenberg/gotenberg/v8/test/integration +.PHONY: test-integration +test-integration: ## Run integration tests + go test -tags=integration -v github.com/gotenberg/gotenberg/v8/test/integration -args \ + --gotenberg-docker-repository=$(DOCKER_REPOSITORY) \ + --gotenberg-version=$(GOTENBERG_VERSION) \ + --gotenberg-container-platform=$(PLATFORM) .PHONY: lint -lint: ## Lint codebase. - #golangci-lint run +lint: ## Lint Golang codebase + golangci-lint run + +.PHONY: lint-prettier +lint-prettier: ## Lint non-Golang codebase npx prettier --check . +.PHONY: lint-todo +lint-todo: ## Find TODOs in Golang codebase + golangci-lint run --no-config --disable-all --enable godox + # go install mvdan.cc/gofumpt@latest # go install github.com/daixiang0/gci@latest .PHONY: fmt -fmt: ## Format codebase and "optimize" the dependencies +fmt: ## Format Golang codebase and "optimize" the dependencies gofumpt -l -w . gci write -s standard -s default -s "prefix(github.com/gotenberg/gotenberg/v8)" --skip-generated --skip-vendor --custom-order . - npx prettier --write . go mod tidy -.PHONY: todo -todo: ## Find TODOs in codebase. - golangci-lint run --no-config --disable-all --enable godox +.PHONY: prettify +prettify: ## Format non-Golang codebase + npx prettier --write . # go install golang.org/x/tools/cmd/godoc@latest .PHONY: godoc diff --git a/README.md b/README.md index 2ae1eb06..8c70fda2 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,8 @@

Total downloads (gotenberg/gotenberg) Total downloads (thecodingmachine/gotenberg) -
Continuous Integration Go Reference - Code coverage

gotenberg%2Fgotenberg | Trendshift diff --git a/go.mod b/go.mod index 687ccd1e..e9157c5e 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ require ( github.com/alexliesenfeld/health v0.8.0 github.com/andybalholm/brotli v1.1.1 // indirect github.com/barasher/go-exiftool v1.10.0 - github.com/chromedp/cdproto v0.0.0-20250311215558-29dfcc2791de - github.com/chromedp/chromedp v0.13.1 + github.com/chromedp/cdproto v0.0.0-20250319231242-a755498943c8 + github.com/chromedp/chromedp v0.13.3 github.com/google/uuid v1.6.0 github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 @@ -33,47 +33,97 @@ require ( ) require ( + github.com/cucumber/godog v0.15.0 github.com/dlclark/regexp2 v1.11.5 + github.com/docker/docker v28.0.2+incompatible + github.com/docker/go-connections v0.5.0 github.com/mholt/archives v0.1.0 github.com/shirou/gopsutil/v4 v4.25.2 + github.com/testcontainers/testcontainers-go v0.35.0 ) require ( + dario.cat/mergo v1.0.1 // indirect + github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect + github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/STARRY-S/zip v0.2.2 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bodgit/plumbing v1.3.0 // indirect github.com/bodgit/sevenzip v1.6.0 // indirect github.com/bodgit/windows v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chromedp/sysutil v1.1.0 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect + github.com/cpuguy83/dockercfg v0.3.2 // indirect + github.com/cucumber/gherkin/go/v26 v26.2.0 // indirect + github.com/cucumber/messages/go/v21 v21.0.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect github.com/ebitengine/purego v0.8.2 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect github.com/gobwas/ws v1.4.0 // indirect + github.com/gofrs/uuid v4.4.0+incompatible // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-memdb v1.3.5 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/lufia/plan9stats v0.0.0-20250303091104-876f3ea5145d // indirect + github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect + github.com/magiconair/properties v1.8.9 // indirect github.com/mattn/go-colorable v0.1.14 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/sys/sequential v0.6.0 // indirect + github.com/moby/sys/user v0.3.0 // indirect + github.com/moby/sys/userns v0.1.0 // indirect + github.com/moby/term v0.5.2 // indirect + github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nwaples/rardecode/v2 v2.1.1 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.63.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect + github.com/prometheus/procfs v0.16.0 // indirect + github.com/shirou/gopsutil/v3 v3.24.5 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/sorairolake/lzip-go v0.3.5 // indirect + github.com/stretchr/testify v1.10.0 // indirect github.com/therootcompany/xz v1.0.1 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect github.com/tklauser/numcpus v0.10.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect golang.org/x/time v0.11.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 237ed873..3b96234c 100644 --- a/go.sum +++ b/go.sum @@ -14,9 +14,17 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/STARRY-S/zip v0.2.2 h1:8QeCbIi1Z9U5MgoDARJR1ClbBo9RD46SmVy+dl0woCk= github.com/STARRY-S/zip v0.2.2/go.mod h1:lqJ9JdeRipyOQJrYSOtpNAiaesFO6zVDsE8GIGFaoSk= github.com/alexliesenfeld/health v0.8.0 h1:lCV0i+ZJPTbqP7LfKG7p3qZBl5VhelwUFCIVWl77fgk= @@ -35,24 +43,50 @@ github.com/bodgit/sevenzip v1.6.0 h1:a4R0Wu6/P1o1pP/3VV++aEOcyeBxeO/xE2Y9NSTrr6A github.com/bodgit/sevenzip v1.6.0/go.mod h1:zOBh9nJUof7tcrlqJFv1koWRrhz3LbDbUNngkuZxLMc= github.com/bodgit/windows v1.0.1 h1:tF7K6KOluPYygXa3Z2594zxlkbKPAOvqr97etrGNIz4= github.com/bodgit/windows v1.0.1/go.mod h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chromedp/cdproto v0.0.0-20250311215558-29dfcc2791de h1:tOKSCbB420VENW1Wz10EnSXr4jLnWoq25vnBW4ScmF0= -github.com/chromedp/cdproto v0.0.0-20250311215558-29dfcc2791de/go.mod h1:NItd7aLkcfOA/dcMXvl8p1u+lQqioRMq/SqDp71Pb/k= -github.com/chromedp/chromedp v0.13.1 h1:FDh9CfaAt0w70gl69Hb69M/xgZrWuppH9AW22aGa+iU= -github.com/chromedp/chromedp v0.13.1/go.mod h1:O3nO4Lno7iLoVX+7GdqQkehhKG7DtLf/zFRyJo0AhXY= +github.com/chromedp/cdproto v0.0.0-20250319231242-a755498943c8 h1:AqW2bDQf67Zbq6Tpop/+yJSIknxhiQecO2B8jNYTAPs= +github.com/chromedp/cdproto v0.0.0-20250319231242-a755498943c8/go.mod h1:NItd7aLkcfOA/dcMXvl8p1u+lQqioRMq/SqDp71Pb/k= +github.com/chromedp/chromedp v0.13.3 h1:c6nTn97XQBykzcXiGYL5LLebw3h3CEyrCihm4HquYh0= +github.com/chromedp/chromedp v0.13.3/go.mod h1:khsDP9OP20GrowpJfZ7N05iGCwcAYxk7qf9AZBzR3Qw= github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM= github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= +github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= +github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= +github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= +github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= +github.com/cucumber/godog v0.15.0 h1:51AL8lBXF3f0cyA5CV4TnJFCTHpgiy+1x1Hb3TtZUmo= +github.com/cucumber/godog v0.15.0/go.mod h1:FX3rzIDybWABU4kuIXLZ/qtqEe1Ac5RdXmqvACJOces= +github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI= +github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s= +github.com/cucumber/messages/go/v22 v22.0.0/go.mod h1:aZipXTKc0JnjCsXrJnuZpWhtay93k7Rn3Dee7iyPJjs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/docker/docker v28.0.2+incompatible h1:9BILleFwug5FSSqWBgVevgL3ewDJfWWWyZVqlDMttE8= +github.com/docker/docker v28.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 h1:2tV76y6Q9BB+NEBasnqvs7e49aEBFI8ejC89PSnWH+4= github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= @@ -62,10 +96,17 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY= github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= @@ -75,6 +116,12 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -107,6 +154,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -114,17 +163,31 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= +github.com/hashicorp/go-memdb v1.3.5 h1:b3taDMxCBCBVgyRrS1AZVHO14ubMYZB++QpNhBg+Nyo= +github.com/hashicorp/go-memdb v1.3.5/go.mod h1:8IVKKBkVe+fxFgdFOYxzQQNjz+sWCyHCdIC/+5+Vy1Y= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= @@ -133,8 +196,13 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= @@ -143,8 +211,10 @@ github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0 github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= -github.com/lufia/plan9stats v0.0.0-20250303091104-876f3ea5145d h1:fjMbDVUGsMQiVZnSQsmouYJvMdwsGiDipOZoN66v844= -github.com/lufia/plan9stats v0.0.0-20250303091104-876f3ea5145d/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= +github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc= +github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= +github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= +github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -153,14 +223,34 @@ github.com/mholt/archives v0.1.0 h1:FacgJyrjiuyomTuNA92X5GyRBRZjE43Y/lrzKIlF35Q= github.com/mholt/archives v0.1.0/go.mod h1:j/Ire/jm42GN7h90F5kzj6hf6ZFzEH66de+hmjEKu+I= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= +github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= +github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= +github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= +github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= +github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nwaples/rardecode/v2 v2.1.1 h1:OJaYalXdliBUXPmC8CZGQ7oZDxzX1/5mQmgn0/GASew= github.com/nwaples/rardecode/v2 v2.1.1/go.mod h1:7uz379lSxPe6j9nvzxUZ+n7mnJNgjsRNb6IbvGVHRmw= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= @@ -172,29 +262,46 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM= +github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= +github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= +github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= github.com/shirou/gopsutil/v4 v4.25.2 h1:NMscG3l2CqtWFS86kj3vP7soOczqrQYIEhO/pMvvQkk= github.com/shirou/gopsutil/v4 v4.25.2/go.mod h1:34gBYJzyqCDT11b6bMHP0XCvWeU3J61XRT7a2EmCRTA= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sorairolake/lzip-go v0.3.5 h1:ms5Xri9o1JBIWvOFAorYtUNik6HI3HgBTkISiqu0Cwg= github.com/sorairolake/lzip-go v0.3.5/go.mod h1:N0KYq5iWrMXI0ZEXKXaS9hCyOjZUQdBDEIbXfoUwbdk= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/testcontainers/testcontainers-go v0.35.0 h1:uADsZpTKFAtp8SLK+hMwSaa+X+JiERHtd4sQAFmXeMo= +github.com/testcontainers/testcontainers-go v0.35.0/go.mod h1:oEVBj5zrfJTrgjwONs1SsRbnBtH9OKl+IGl3UMcr2B4= github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw= github.com/therootcompany/xz v1.0.1/go.mod h1:3K3UH1yCKgBneZYhuQUvJ9HPD19UEXEI0BWbMn8qNMY= github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4= @@ -210,6 +317,8 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= @@ -217,6 +326,26 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -229,6 +358,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= @@ -257,6 +387,7 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -271,6 +402,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -287,6 +420,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= @@ -303,10 +437,13 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -355,10 +492,13 @@ golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -385,6 +525,10 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY= +google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -392,15 +536,21 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/gotenberg/cmd_test.go b/pkg/gotenberg/cmd_test.go deleted file mode 100644 index 1687387c..00000000 --- a/pkg/gotenberg/cmd_test.go +++ /dev/null @@ -1,306 +0,0 @@ -package gotenberg - -import ( - "context" - "testing" - "time" - - "go.uber.org/zap" -) - -func TestCommand(t *testing.T) { - cmd := Command(zap.NewNop(), "foo") - if !cmd.process.SysProcAttr.Setpgid { - t.Error("expected cmd.process.SysProcAttr.Setpgid to be true") - } -} - -func TestCommandContext(t *testing.T) { - tests := []struct { - scenario string - ctx context.Context - expectCommandContextError bool - }{ - { - scenario: "nominal behavior", - ctx: context.Background(), - expectCommandContextError: false, - }, - { - scenario: "nil context", - ctx: nil, - expectCommandContextError: true, - }, - } - - for _, tc := range tests { - t.Run(tc.scenario, func(t *testing.T) { - cmd, err := CommandContext(tc.ctx, zap.NewNop(), "foo") - - if err == nil && !cmd.process.SysProcAttr.Setpgid { - t.Fatal("expected cmd.process.SysProcAttr.Setpgid to be true") - } - - if !tc.expectCommandContextError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectCommandContextError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestCmd_Start(t *testing.T) { - tests := []struct { - scenario string - cmd *Cmd - expectStartError bool - }{ - { - scenario: "nominal behavior", - cmd: Command(zap.NewNop(), "echo", "Hello", "World"), - expectStartError: false, - }, - { - scenario: "start error", - cmd: Command(zap.NewNop(), "foo"), - expectStartError: true, - }, - } - - for _, tc := range tests { - t.Run(tc.scenario, func(t *testing.T) { - err := tc.cmd.Start() - - if !tc.expectStartError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectStartError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestCmd_Wait(t *testing.T) { - tests := []struct { - scenario string - cmd *Cmd - expectWaitError bool - }{ - { - scenario: "nominal behavior", - cmd: func() *Cmd { - cmd := Command(zap.NewNop(), "echo", "Hello", "World") - err := cmd.Start() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - return cmd - }(), - expectWaitError: false, - }, - { - scenario: "wait error", - cmd: Command(zap.NewNop(), "echo", "Hello", "World"), - expectWaitError: true, - }, - } - - for _, tc := range tests { - t.Run(tc.scenario, func(t *testing.T) { - err := tc.cmd.Wait() - - if !tc.expectWaitError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectWaitError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestCmd_Exec(t *testing.T) { - tests := []struct { - scenario string - cmd *Cmd - timeout time.Duration - expectExecError bool - }{ - { - scenario: "nominal behavior", - cmd: func() *Cmd { - cmd, err := CommandContext(context.Background(), zap.NewNop(), "echo", "Hello", "World") - if err != nil { - t.Fatalf("expected no error from CommandContext(), but got: %v", err) - } - return cmd - }(), - expectExecError: false, - }, - { - scenario: "nil context", - cmd: Command(zap.NewNop(), "echo", "Hello", "World"), - expectExecError: true, - }, - { - scenario: "start error", - cmd: func() *Cmd { - cmd, err := CommandContext(context.Background(), zap.NewNop(), "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - return cmd - }(), - expectExecError: true, - }, - { - scenario: "context done", - cmd: Command(zap.NewNop(), "sleep", "2"), - timeout: time.Duration(1) * time.Second, - expectExecError: true, - }, - } - - for _, tc := range tests { - t.Run(tc.scenario, func(t *testing.T) { - if tc.timeout > 0 { - ctx, cancel := context.WithTimeout(context.TODO(), tc.timeout) - defer cancel() - - tc.cmd.ctx = ctx - } - - _, err := tc.cmd.Exec() - - if !tc.expectExecError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectExecError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestCmd_pipeOutput(t *testing.T) { - tests := []struct { - scenario string - cmd *Cmd - run bool - expectPipeOutputError bool - }{ - { - scenario: "nominal behavior", - cmd: Command(zap.NewExample(), "echo", "Hello", "World"), - run: true, - expectPipeOutputError: false, - }, - { - scenario: "no debug, no pipe", - cmd: Command(zap.NewNop(), "echo", "Hello", "World"), - run: false, - expectPipeOutputError: false, - }, - { - scenario: "stdout already piped", - cmd: func() *Cmd { - cmd := Command(zap.NewExample(), "echo", "Hello", "World") - _, err := cmd.process.StdoutPipe() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - return cmd - }(), - run: false, - expectPipeOutputError: true, - }, - { - scenario: "stderr already piped", - cmd: func() *Cmd { - cmd := Command(zap.NewExample(), "echo", "Hello", "World") - _, err := cmd.process.StderrPipe() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - return cmd - }(), - run: false, - expectPipeOutputError: true, - }, - } - - for _, tc := range tests { - t.Run(tc.scenario, func(t *testing.T) { - err := tc.cmd.pipeOutput() - - if tc.run { - errStart := tc.cmd.process.Start() - if errStart != nil { - t.Fatalf("expected no error but got: %v", err) - } - } - - if !tc.expectPipeOutputError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectPipeOutputError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestCmd_Kill(t *testing.T) { - tests := []struct { - scenario string - cmd *Cmd - }{ - { - scenario: "nominal behavior", - cmd: func() *Cmd { - cmd := Command(zap.NewNop(), "sleep", "60") - err := cmd.process.Start() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - return cmd - }(), - }, - { - scenario: "no process", - cmd: &Cmd{logger: zap.NewNop()}, - }, - { - scenario: "process already killed", - cmd: func() *Cmd { - cmd := Command(zap.NewNop(), "sleep", "60") - err := cmd.process.Start() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - err = cmd.Kill() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - return cmd - }(), - }, - } - - for _, tc := range tests { - t.Run(tc.scenario, func(t *testing.T) { - err := tc.cmd.Kill() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }) - } -} diff --git a/pkg/gotenberg/context_test.go b/pkg/gotenberg/context_test.go index 9b48cfd2..f8bc4d6f 100644 --- a/pkg/gotenberg/context_test.go +++ b/pkg/gotenberg/context_test.go @@ -5,23 +5,6 @@ import ( "testing" ) -func TestNewContext(t *testing.T) { - if NewContext(ParsedFlags{}, nil) == nil { - t.Error("expected a non-nil value") - } -} - -func TestContext_ParsedFlags(t *testing.T) { - ctx := NewContext(ParsedFlags{}, nil) - - actual := ctx.ParsedFlags() - expect := ParsedFlags{} - - if actual != expect { - t.Errorf("expected %v but got %v", expect, actual) - } -} - func TestContext_Module(t *testing.T) { for _, tc := range []struct { scenario string diff --git a/pkg/gotenberg/fs_test.go b/pkg/gotenberg/fs_test.go deleted file mode 100644 index ee57d1b9..00000000 --- a/pkg/gotenberg/fs_test.go +++ /dev/null @@ -1,146 +0,0 @@ -package gotenberg - -import ( - "errors" - "fmt" - "io" - "os" - "path/filepath" - "strings" - "testing" - - "github.com/google/uuid" -) - -func TestOsMkdirAll_MkdirAll(t *testing.T) { - dirPath, err := NewFileSystem(new(OsMkdirAll)).MkdirAll() - if err != nil { - t.Fatalf("create working directory: %v", err) - } - - err = os.RemoveAll(dirPath) - if err != nil { - t.Fatalf("remove working directory: %v", err) - } -} - -func TestOsPathRename_Rename(t *testing.T) { - dirPath, err := NewFileSystem(new(OsMkdirAll)).MkdirAll() - if err != nil { - t.Fatalf("create working directory: %v", err) - } - - path := "/tests/test/testdata/api/sample1.txt" - copyPath := filepath.Join(dirPath, fmt.Sprintf("%s.txt", uuid.NewString())) - - in, err := os.Open(path) - if err != nil { - t.Fatalf("open file: %v", err) - } - - defer func() { - err := in.Close() - if err != nil { - t.Fatalf("close file: %v", err) - } - }() - - out, err := os.Create(copyPath) - if err != nil { - t.Fatalf("create new file: %v", err) - } - - defer func() { - err := out.Close() - if err != nil { - t.Fatalf("close new file: %v", err) - } - }() - - _, err = io.Copy(out, in) - if err != nil { - t.Fatalf("copy file to new file: %v", err) - } - - rename := new(OsPathRename) - newPath := filepath.Join(dirPath, fmt.Sprintf("%s.txt", uuid.NewString())) - - err = rename.Rename(copyPath, newPath) - if err != nil { - t.Errorf("expected no error but got: %v", err) - } - - err = os.RemoveAll(dirPath) - if err != nil { - t.Fatalf("remove working directory: %v", err) - } -} - -func TestFileSystem_WorkingDir(t *testing.T) { - fs := NewFileSystem(new(MkdirAllMock)) - dirName := fs.WorkingDir() - - if dirName == "" { - t.Error("expected directory name but got empty string") - } -} - -func TestFileSystem_WorkingDirPath(t *testing.T) { - fs := NewFileSystem(new(MkdirAllMock)) - expectedPath := fmt.Sprintf("%s/%s", os.TempDir(), fs.WorkingDir()) - - if fs.WorkingDirPath() != expectedPath { - t.Errorf("expected path '%s' but got '%s'", expectedPath, fs.WorkingDirPath()) - } -} - -func TestFileSystem_NewDirPath(t *testing.T) { - fs := NewFileSystem(new(MkdirAllMock)) - newDir := fs.NewDirPath() - expectedPrefix := fs.WorkingDirPath() - - if !strings.HasPrefix(newDir, expectedPrefix) { - t.Errorf("expected new directory to start with '%s' but got '%s'", expectedPrefix, newDir) - } -} - -func TestFileSystem_MkdirAll(t *testing.T) { - for _, tc := range []struct { - scenario string - mkdirAll MkdirAll - expectError bool - }{ - { - scenario: "error", - mkdirAll: &MkdirAllMock{ - MkdirAllMock: func(path string, perm os.FileMode) error { - return errors.New("foo") - }, - }, - expectError: true, - }, - { - scenario: "success", - mkdirAll: &MkdirAllMock{ - MkdirAllMock: func(path string, perm os.FileMode) error { - return nil - }, - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - fs := NewFileSystem(tc.mkdirAll) - - _, err := fs.MkdirAll() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} diff --git a/pkg/gotenberg/gc_test.go b/pkg/gotenberg/gc_test.go index c8a4c09e..2124b0dd 100644 --- a/pkg/gotenberg/gc_test.go +++ b/pkg/gotenberg/gc_test.go @@ -3,6 +3,7 @@ package gotenberg import ( "fmt" "os" + "path" "testing" "time" @@ -51,7 +52,7 @@ func TestGarbageCollect(t *testing.T) { return path }(), - includeSubstr: []string{"foo", fmt.Sprintf("%s/a_directory/a_bar_file", os.TempDir())}, + includeSubstr: []string{"foo", path.Join(os.TempDir(), "/a_directory/a_bar_file")}, expectError: false, expectExists: []string{"a_baz_file"}, expectNotExists: []string{"a_foo_file", "a_bar_file"}, diff --git a/pkg/gotenberg/logging_test.go b/pkg/gotenberg/logging_test.go deleted file mode 100644 index cc8f203d..00000000 --- a/pkg/gotenberg/logging_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package gotenberg - -import ( - "testing" - - "go.uber.org/zap" -) - -func TestLeveledLogger_Error(t *testing.T) { - NewLeveledLogger(zap.NewNop()).Error("foo") -} - -func TestLeveledLogger_Warn(t *testing.T) { - NewLeveledLogger(zap.NewNop()).Warn("foo") -} - -func TestLeveledLogger_Info(t *testing.T) { - NewLeveledLogger(zap.NewNop()).Info("foo") -} - -func TestLeveledLogger_Debug(t *testing.T) { - NewLeveledLogger(zap.NewNop()).Debug("foo") -} diff --git a/pkg/gotenberg/mocks_test.go b/pkg/gotenberg/mocks_test.go deleted file mode 100644 index d813499a..00000000 --- a/pkg/gotenberg/mocks_test.go +++ /dev/null @@ -1,264 +0,0 @@ -package gotenberg - -import ( - "context" - "os" - "testing" - - "go.uber.org/zap" -) - -func TestModuleMock(t *testing.T) { - mock := &ModuleMock{ - DescriptorMock: func() ModuleDescriptor { - return ModuleDescriptor{ID: "foo", New: func() Module { - return nil - }} - }, - } - - if mock.Descriptor().ID != "foo" { - t.Errorf("expected ID '%s' from ModuleMock.Descriptor, but got '%s'", "foo", mock.Descriptor().ID) - } -} - -func TestProvisionerMock(t *testing.T) { - mock := &ProvisionerMock{ - ProvisionMock: func(*Context) error { - return nil - }, - } - - err := mock.Provision(&Context{}) - if err != nil { - t.Errorf("expected no error from ProvisionerMock.Provision, but got: %v", err) - } -} - -func TestValidatorMock(t *testing.T) { - mock := &ValidatorMock{ - ValidateMock: func() error { - return nil - }, - } - - err := mock.Validate() - if err != nil { - t.Errorf("expected no error from ValidatorMock.Validate, but got: %v", err) - } -} - -func TestDebuggableMock(t *testing.T) { - mock := &DebuggableMock{ - DebugMock: func() map[string]interface{} { - return map[string]interface{}{ - "foo": "bar", - } - }, - } - - d := mock.Debug() - if d == nil { - t.Errorf("expected debug data, but got nil") - } -} - -func TestPDFEngineMock(t *testing.T) { - mock := &PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - SplitMock: func(ctx context.Context, logger *zap.Logger, mode SplitMode, inputPath, outputDirPath string) ([]string, error) { - return nil, nil - }, - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return nil - }, - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats PdfFormats, inputPath, outputPath string) error { - return nil - }, - ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) { - return nil, nil - }, - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return nil - }, - } - - err := mock.Merge(context.Background(), zap.NewNop(), nil, "") - if err != nil { - t.Errorf("expected no error from PdfEngineMock.Merge, but got: %v", err) - } - - _, err = mock.Split(context.Background(), zap.NewNop(), SplitMode{}, "", "") - if err != nil { - t.Errorf("expected no error from PdfEngineMock.Split, but got: %v", err) - } - - err = mock.Flatten(context.Background(), zap.NewNop(), "") - if err != nil { - t.Errorf("expected no error from PdfEngineMock.Convert, but got: %v", err) - } - - err = mock.Convert(context.Background(), zap.NewNop(), PdfFormats{}, "", "") - if err != nil { - t.Errorf("expected no error from PdfEngineMock.Convert, but got: %v", err) - } - - _, err = mock.ReadMetadata(context.Background(), zap.NewNop(), "") - if err != nil { - t.Errorf("expected no error from PdfEngineMock.ReadMetadata, but got: %v", err) - } - - err = mock.WriteMetadata(context.Background(), zap.NewNop(), map[string]interface{}{}, "") - if err != nil { - t.Errorf("expected no error from PdfEngineMock.WriteMetadata but got: %v", err) - } -} - -func TestPDFEngineProviderMock(t *testing.T) { - mock := &PdfEngineProviderMock{ - PdfEngineMock: func() (PdfEngine, error) { - return new(PdfEngineMock), nil - }, - } - - _, err := mock.PdfEngine() - if err != nil { - t.Errorf("expected no error from PdfEngineProviderMock.PdfEngine, but got: %v", err) - } -} - -func TestProcessMock(t *testing.T) { - mock := &ProcessMock{ - StartMock: func(logger *zap.Logger) error { - return nil - }, - StopMock: func(logger *zap.Logger) error { - return nil - }, - HealthyMock: func(logger *zap.Logger) bool { - return true - }, - } - - err := mock.Start(zap.NewNop()) - if err != nil { - t.Errorf("expected no error from ProcessMock.Start, but got: %v", err) - } - - err = mock.Stop(zap.NewNop()) - if err != nil { - t.Errorf("expected no error from ProcessMock.Stop, but got: %v", err) - } - - healthy := mock.Healthy(zap.NewNop()) - if !healthy { - t.Error("expected true from ProcessMock.Healthy, but got false") - } -} - -func TestProcessSupervisorMock(t *testing.T) { - mock := &ProcessSupervisorMock{ - LaunchMock: func() error { - return nil - }, - ShutdownMock: func() error { - return nil - }, - HealthyMock: func() bool { - return true - }, - RunMock: func(ctx context.Context, logger *zap.Logger, task func() error) error { - return nil - }, - ReqQueueSizeMock: func() int64 { - return 0 - }, - RestartsCountMock: func() int64 { - return 0 - }, - } - - err := mock.Launch() - if err != nil { - t.Errorf("expected no error from ProcessSupervisorMock.Launch, but got: %v", err) - } - - err = mock.Shutdown() - if err != nil { - t.Errorf("expected no error from ProcessSupervisorMock.Shutdown, but got: %v", err) - } - - healthy := mock.Healthy() - if !healthy { - t.Error("expected true from ProcessSupervisorMock.Healthy, but got false") - } - - err = mock.Run(context.TODO(), zap.NewNop(), nil) - if err != nil { - t.Errorf("expected no error from ProcessSupervisorMock.Run, but got: %v", err) - } - - size := mock.ReqQueueSize() - if size != 0 { - t.Errorf("expected 0 from ProcessSupervisorMock.ReqQueueSize, but got: %d", size) - } - - restarts := mock.RestartsCount() - if restarts != 0 { - t.Errorf("expected 0 from ProcessSupervisorMock.RestartsCount, but got: %d", restarts) - } -} - -func TestLoggerProviderMock(t *testing.T) { - mock := &LoggerProviderMock{ - LoggerMock: func(mod Module) (*zap.Logger, error) { - return nil, nil - }, - } - - _, err := mock.Logger(new(ModuleMock)) - if err != nil { - t.Errorf("expected no error from LoggerProviderMock.Logger, but got: %v", err) - } -} - -func TestMetricsProviderMock(t *testing.T) { - mock := &MetricsProviderMock{ - MetricsMock: func() ([]Metric, error) { - return nil, nil - }, - } - - _, err := mock.Metrics() - if err != nil { - t.Errorf("expected no error from MetricsProviderMock.Metrics, but got: %v", err) - } -} - -func TestMkdirAllMock(t *testing.T) { - mock := &MkdirAllMock{ - MkdirAllMock: func(dir string, perm os.FileMode) error { - return nil - }, - } - - err := mock.MkdirAll("/foo", 0o755) - if err != nil { - t.Errorf("expected no error from MkdirAllMock.MkdirAll, but got: %v", err) - } -} - -func TestPathRenameMock(t *testing.T) { - mock := &PathRenameMock{ - RenameMock: func(oldpath, newpath string) error { - return nil - }, - } - - err := mock.Rename("", "") - if err != nil { - t.Errorf("expected no error from PathRenameMock.Rename, but got: %v", err) - } -} diff --git a/pkg/modules/api/api_test.go b/pkg/modules/api/api_test.go deleted file mode 100644 index 465adce3..00000000 --- a/pkg/modules/api/api_test.go +++ /dev/null @@ -1,1033 +0,0 @@ -package api - -import ( - "bytes" - "context" - "errors" - "mime/multipart" - "net/http" - "net/http/httptest" - "os" - "reflect" - "testing" - "time" - - "github.com/alexliesenfeld/health" - "github.com/labstack/echo/v4" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestApi_Descriptor(t *testing.T) { - descriptor := new(Api).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(Api)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestApi_Provision(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *gotenberg.Context - setEnv func() - expectPort int - expectMiddlewares []Middleware - expectError bool - }{ - { - scenario: "port from env: non-existing environment variable", - ctx: func() *gotenberg.Context { - fs := new(Api).Descriptor().FlagSet - err := fs.Parse([]string{"--api-port-from-env=FOO"}) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: fs, - }, - nil, - ) - }(), - expectError: true, - }, - { - scenario: "port from env: invalid environment variable value", - ctx: func() *gotenberg.Context { - fs := new(Api).Descriptor().FlagSet - err := fs.Parse([]string{"--api-port-from-env=PORT"}) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: fs, - }, - nil, - ) - }(), - setEnv: func() { - err := os.Setenv("PORT", "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }, - expectError: true, - }, - { - scenario: "basic auth: non-existing GOTENBERG_API_BASIC_AUTH_USERNAME environment variable", - ctx: func() *gotenberg.Context { - fs := new(Api).Descriptor().FlagSet - err := fs.Parse([]string{"--api-enable-basic-auth=true"}) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: fs, - }, - nil, - ) - }(), - expectError: true, - }, - { - scenario: "basic auth: non-existing GOTENBERG_API_BASIC_AUTH_PASSWORD environment variable", - ctx: func() *gotenberg.Context { - fs := new(Api).Descriptor().FlagSet - err := fs.Parse([]string{"--api-enable-basic-auth=true"}) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: fs, - }, - nil, - ) - }(), - setEnv: func() { - err := os.Setenv("GOTENBERG_API_BASIC_AUTH_USERNAME", "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }, - expectError: true, - }, - { - scenario: "no valid routers", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.ValidatorMock - RouterMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }} - } - mod.ValidateMock = func() error { - return errors.New("foo") - } - mod.RoutesMock = func() ([]Route, error) { - return nil, nil - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "cannot retrieve routes from router", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - RouterMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }} - } - mod.RoutesMock = func() ([]Route, error) { - return nil, errors.New("foo") - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "no valid middleware providers", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.ValidatorMock - MiddlewareProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }} - } - mod.ValidateMock = func() error { - return errors.New("foo") - } - mod.MiddlewaresMock = func() ([]Middleware, error) { - return nil, nil - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "cannot retrieve middlewares from middleware provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - MiddlewareProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }} - } - mod.MiddlewaresMock = func() ([]Middleware, error) { - return nil, errors.New("foo") - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "no valid health checkers", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.ValidatorMock - HealthCheckerMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }} - } - mod.ValidateMock = func() error { - return errors.New("foo") - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "cannot retrieve health checks from health checker", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - HealthCheckerMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }} - } - mod.ChecksMock = func() ([]health.CheckerOption, error) { - return nil, errors.New("foo") - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "no logger provider", - ctx: func() *gotenberg.Context { - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{}, - ) - }(), - expectError: true, - }, - { - scenario: "no logger from logger provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.LoggerProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }} - } - mod.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) { - return nil, errors.New("foo") - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "success", - ctx: func() *gotenberg.Context { - mod1 := &struct { - gotenberg.ModuleMock - RouterMock - }{} - mod1.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod1 }} - } - mod1.RoutesMock = func() ([]Route, error) { - return []Route{{}}, nil - } - - mod2 := &struct { - gotenberg.ModuleMock - MiddlewareProviderMock - }{} - mod2.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod2 }} - } - mod2.MiddlewaresMock = func() ([]Middleware, error) { - return []Middleware{ - { - Priority: VeryLowPriority, - }, - { - Priority: LowPriority, - }, - { - Priority: MediumPriority, - }, - { - Priority: HighPriority, - }, - { - Priority: VeryHighPriority, - }, - }, nil - } - - mod3 := &struct { - gotenberg.ModuleMock - HealthCheckerMock - }{} - mod3.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "baz", New: func() gotenberg.Module { return mod3 }} - } - mod3.ChecksMock = func() ([]health.CheckerOption, error) { - return []health.CheckerOption{health.WithDisabledAutostart()}, nil - } - mod3.ReadyMock = func() error { - return nil - } - - mod4 := &struct { - gotenberg.ModuleMock - gotenberg.LoggerProviderMock - }{} - mod4.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "qux", New: func() gotenberg.Module { return mod4 }} - } - mod4.LoggerMock = func(_ gotenberg.Module) (*zap.Logger, error) { - return zap.NewNop(), nil - } - - fs := new(Api).Descriptor().FlagSet - err := fs.Parse([]string{"--api-port-from-env=PORT", "--api-enable-basic-auth=true"}) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: fs, - }, - []gotenberg.ModuleDescriptor{ - mod1.Descriptor(), - mod2.Descriptor(), - mod3.Descriptor(), - mod4.Descriptor(), - }, - ) - }(), - setEnv: func() { - err := os.Setenv("PORT", "1337") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - err = os.Setenv("GOTENBERG_API_BASIC_AUTH_USERNAME", "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - err = os.Setenv("GOTENBERG_API_BASIC_AUTH_PASSWORD", "bar") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }, - expectPort: 1337, - expectMiddlewares: []Middleware{ - { - Priority: VeryHighPriority, - }, - { - Priority: HighPriority, - }, - { - Priority: MediumPriority, - }, - { - Priority: LowPriority, - }, - { - Priority: VeryLowPriority, - }, - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - if tc.setEnv != nil { - tc.setEnv() - } - - mod := new(Api) - err := mod.Provision(tc.ctx) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectPort != 0 && mod.port != tc.expectPort { - t.Errorf("expected port %d but got %d", tc.expectPort, mod.port) - } - - if !reflect.DeepEqual(mod.externalMiddlewares, tc.expectMiddlewares) { - t.Errorf("expected %+v, but got: %+v", tc.expectMiddlewares, mod.externalMiddlewares) - } - }) - } -} - -func TestApi_Validate(t *testing.T) { - for _, tc := range []struct { - scenario string - port int - bindIp string - tlsCertFile string - tlsKeyFile string - rootPath string - traceHeader string - routes []Route - middlewares []Middleware - expectError bool - }{ - { - scenario: "invalid port (< 1)", - port: 0, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "foo", - routes: nil, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid port (> 65535)", - port: 65536, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "foo", - routes: nil, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid IP", - port: 10, - bindIp: "foo", - rootPath: "/foo/", - traceHeader: "foo", - routes: nil, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid TLS files: only cert file provided", - port: 10, - bindIp: "127.0.0.1", - tlsCertFile: "cert.pem", - rootPath: "/foo/", - traceHeader: "foo", - routes: nil, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid TLS files: only key file provided", - port: 10, - bindIp: "127.0.0.1", - tlsKeyFile: "key.pem", - rootPath: "/foo/", - traceHeader: "foo", - routes: nil, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid root path: missing / prefix", - port: 10, - bindIp: "127.0.0.1", - rootPath: "foo/", - traceHeader: "foo", - routes: nil, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid root path: missing / suffix", - port: 10, - bindIp: "127.0.0.1", - rootPath: "/foo", - traceHeader: "foo", - routes: nil, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid trace header", - port: 10, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "", - routes: nil, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid route: empty path", - port: 10, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "foo", - routes: []Route{ - { - Path: "", - }, - }, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid route: missing / prefix in path", - port: 10, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "foo", - routes: []Route{ - { - Path: "foo", - }, - }, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid multipart route: no /forms prefix in path", - port: 10, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "foo", - routes: []Route{ - { - Path: "/foo", - IsMultipart: true, - }, - }, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid route: no method", - port: 10, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "foo", - routes: []Route{ - { - Path: "/foo", - Method: "", - }, - }, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid route: nil handler", - port: 10, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "foo", - routes: []Route{ - { - Method: http.MethodPost, - Path: "/foo", - Handler: nil, - }, - }, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid route: path already existing", - port: 10, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "foo", - routes: []Route{ - { - Method: http.MethodPost, - Path: "/foo", - Handler: func(_ echo.Context) error { return nil }, - }, - { - Method: http.MethodPost, - Path: "/foo", - Handler: func(_ echo.Context) error { return nil }, - }, - }, - middlewares: nil, - expectError: true, - }, - { - scenario: "invalid middleware: nil handler", - port: 10, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "foo", - routes: nil, - middlewares: []Middleware{ - { - Priority: HighPriority, - Handler: nil, - }, - }, - expectError: true, - }, - { - scenario: "success", - port: 10, - bindIp: "127.0.0.1", - rootPath: "/foo/", - traceHeader: "foo", - routes: []Route{ - { - Method: http.MethodGet, - Path: "/foo", - Handler: func(_ echo.Context) error { return nil }, - }, - { - Method: http.MethodGet, - Path: "/forms/foo", - Handler: func(_ echo.Context) error { return nil }, - IsMultipart: true, - }, - }, - middlewares: []Middleware{ - { - Priority: HighPriority, - Handler: func() echo.MiddlewareFunc { - return func(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - return next(c) - } - } - }(), - }, - }, - }, - { - scenario: "success with TLS", - port: 10, - tlsCertFile: "cert.pem", - tlsKeyFile: "key.pem", - rootPath: "/foo/", - traceHeader: "foo", - routes: []Route{ - { - Method: http.MethodGet, - Path: "/foo", - Handler: func(_ echo.Context) error { return nil }, - }, - { - Method: http.MethodGet, - Path: "/forms/foo", - Handler: func(_ echo.Context) error { return nil }, - IsMultipart: true, - }, - }, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := Api{ - port: tc.port, - bindIp: tc.bindIp, - tlsCertFile: tc.tlsCertFile, - tlsKeyFile: tc.tlsKeyFile, - rootPath: tc.rootPath, - traceHeader: tc.traceHeader, - routes: tc.routes, - externalMiddlewares: tc.middlewares, - } - - err := mod.Validate() - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestApi_Start(t *testing.T) { - for _, tc := range []struct { - scenario string - readyFn []func() error - tlsCertFile string - tlsKeyFile string - expectError bool - }{ - { - scenario: "at least one module not ready", - readyFn: []func() error{ - func() error { return nil }, - func() error { return errors.New("not ready") }, - }, - expectError: true, - }, - { - scenario: "success", - readyFn: []func() error{ - func() error { return nil }, - func() error { return nil }, - }, - expectError: false, - }, - { - scenario: "success with TLS", - readyFn: []func() error{ - func() error { return nil }, - func() error { return nil }, - }, - tlsCertFile: "/tests/test/testdata/api/cert.pem", - tlsKeyFile: "/tests/test/testdata/api/key.pem", - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Api) - mod.port = 3000 - mod.tlsCertFile = tc.tlsCertFile - mod.tlsKeyFile = tc.tlsKeyFile - mod.startTimeout = time.Duration(30) * time.Second - mod.rootPath = "/" - mod.basicAuthUsername = "foo" - mod.basicAuthPassword = "bar" - mod.disableHealthCheckLogging = true - mod.enableDebugRoute = true - mod.routes = []Route{ - { - Method: http.MethodPost, - Path: "/forms/foo", - IsMultipart: true, - DisableLogging: true, - Handler: func(c echo.Context) error { - ctx := c.Get("context").(*Context) - ctx.outputPaths = []string{ - "/tests/test/testdata/api/sample1.txt", - } - - return nil - }, - }, - { - Method: http.MethodPost, - Path: "/forms/bar", - IsMultipart: true, - Handler: func(_ echo.Context) error { return errors.New("foo") }, - }, - } - mod.externalMiddlewares = []Middleware{ - { - Stack: PreRouterStack, - Handler: func() echo.MiddlewareFunc { - return func(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - return next(c) - } - } - }(), - }, - { - Stack: MultipartStack, - Handler: func() echo.MiddlewareFunc { - return func(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - return next(c) - } - } - }(), - }, - { - Stack: DefaultStack, - Handler: func() echo.MiddlewareFunc { - return func(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - return next(c) - } - } - }(), - }, - { - Handler: func() echo.MiddlewareFunc { - return func(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - return next(c) - } - } - }(), - }, - } - mod.readyFn = tc.readyFn - mod.fs = gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - mod.logger = zap.NewNop() - - err := mod.Start() - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectError { - return - } - - // root request. - recorder := httptest.NewRecorder() - rootRequest := httptest.NewRequest(http.MethodGet, "/", nil) - rootRequest.SetBasicAuth(mod.basicAuthUsername, mod.basicAuthPassword) - mod.srv.ServeHTTP(recorder, rootRequest) - if recorder.Code != http.StatusOK { - t.Errorf("expected %d status code but got %d", http.StatusOK, recorder.Code) - } - - // favicon request. - recorder = httptest.NewRecorder() - faviconRequest := httptest.NewRequest(http.MethodGet, "/favicon.ico", nil) - faviconRequest.SetBasicAuth(mod.basicAuthUsername, mod.basicAuthPassword) - mod.srv.ServeHTTP(recorder, faviconRequest) - if recorder.Code != http.StatusNoContent { - t.Errorf("expected %d status code but got %d", http.StatusNoContent, recorder.Code) - } - - // health requests. - recorder = httptest.NewRecorder() - healthGetRequest := httptest.NewRequest(http.MethodGet, "/health", nil) - mod.srv.ServeHTTP(recorder, healthGetRequest) - if recorder.Code != http.StatusOK { - t.Errorf("expected %d status code but got %d", http.StatusOK, recorder.Code) - } - - recorder = httptest.NewRecorder() - healthHeadRequest := httptest.NewRequest(http.MethodHead, "/health", nil) - mod.srv.ServeHTTP(recorder, healthHeadRequest) - if recorder.Code != http.StatusOK { - t.Errorf("expected %d status code but got %d", http.StatusOK, recorder.Code) - } - - // version request. - recorder = httptest.NewRecorder() - versionRequest := httptest.NewRequest(http.MethodGet, "/version", nil) - versionRequest.SetBasicAuth(mod.basicAuthUsername, mod.basicAuthPassword) - mod.srv.ServeHTTP(recorder, versionRequest) - if recorder.Code != http.StatusOK { - t.Errorf("expected %d status code but got %d", http.StatusOK, recorder.Code) - } - - // debug request. - recorder = httptest.NewRecorder() - debugRequest := httptest.NewRequest(http.MethodGet, "/debug", nil) - debugRequest.SetBasicAuth(mod.basicAuthUsername, mod.basicAuthPassword) - mod.srv.ServeHTTP(recorder, debugRequest) - if recorder.Code != http.StatusOK { - t.Errorf("expected %d status code but got %d", http.StatusOK, recorder.Code) - } - - // "multipart/form-data" request. - multipartRequest := func(url string) *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - - err := writer.WriteField("foo", "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - part, err := writer.CreateFormFile("foo.txt", "foo.txt") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - _, err = part.Write([]byte("foo")) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - req := httptest.NewRequest(http.MethodPost, url, body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - req.SetBasicAuth(mod.basicAuthUsername, mod.basicAuthPassword) - - return req - } - - recorder = httptest.NewRecorder() - mod.srv.ServeHTTP(recorder, multipartRequest("/forms/foo")) - - if recorder.Code != http.StatusOK { - t.Errorf("expected %d status code but got %d", http.StatusOK, recorder.Code) - } - - recorder = httptest.NewRecorder() - mod.srv.ServeHTTP(recorder, multipartRequest("/forms/bar")) - - if recorder.Code != http.StatusInternalServerError { - t.Errorf("expected %d status code but got %d", http.StatusInternalServerError, recorder.Code) - } - - err = mod.srv.Shutdown(context.TODO()) - if err != nil { - t.Errorf("expected no error but got: %v", err) - } - }) - } -} - -func TestApi_StartupMessage(t *testing.T) { - for _, tc := range []struct { - scenario string - port int - bindIp string - expectMessage string - }{ - { - scenario: "no custom IP", - port: 3000, - bindIp: "", - expectMessage: "server started on [::]:3000", - }, - { - scenario: "custom IP", - port: 3000, - bindIp: "127.0.0.1", - expectMessage: "server started on 127.0.0.1:3000", - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := Api{ - port: tc.port, - bindIp: tc.bindIp, - } - - actual := mod.StartupMessage() - if actual != tc.expectMessage { - t.Errorf("expected '%s' but got '%s'", tc.expectMessage, actual) - } - }) - } -} - -func TestApi_Stop(t *testing.T) { - mod := &Api{ - port: 3000, - routes: []Route{ - { - Method: http.MethodGet, - Path: "/foo", - Handler: func(_ echo.Context) error { return nil }, - }, - }, - logger: zap.NewNop(), - } - - err := mod.Start() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = mod.Stop(context.TODO()) - if err != nil { - t.Errorf("expected no error but got: %v", err) - } -} diff --git a/pkg/modules/api/context_test.go b/pkg/modules/api/context_test.go deleted file mode 100644 index b69bc0a5..00000000 --- a/pkg/modules/api/context_test.go +++ /dev/null @@ -1,837 +0,0 @@ -package api - -import ( - "bytes" - "context" - "errors" - "mime/multipart" - "net/http" - "net/http/httptest" - "os" - "reflect" - "strings" - "testing" - "time" - - "github.com/dlclark/regexp2" - "github.com/labstack/echo/v4" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestNewContext(t *testing.T) { - defaultAllowList, err := regexp2.Compile("", 0) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - defaultDenyList, err := regexp2.Compile("", 0) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - defaultDownloadFromCfg := downloadFromConfig{ - allowList: defaultAllowList, - denyList: defaultDenyList, - maxRetry: 1, - disable: false, - } - - for _, tc := range []struct { - scenario string - request *http.Request - bodyLimit int64 - downloadFromCfg downloadFromConfig - downloadFromSrv *echo.Echo - expectContext *Context - expectError bool - expectHttpError bool - expectHttpStatus int - }{ - { - scenario: "http.ErrNotMultipart", - request: httptest.NewRequest(http.MethodPost, "/", nil), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusUnsupportedMediaType, - }, - { - scenario: "http.ErrMissingBoundary", - request: func() *http.Request { - req := httptest.NewRequest(http.MethodPost, "/", nil) - req.Header.Set(echo.HeaderContentType, echo.MIMEMultipartForm) - return req - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusUnsupportedMediaType, - }, - { - scenario: "malformed body", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("foo", "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", nil) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "request entity too large: form values", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("key", "value") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - bodyLimit: 1, - downloadFromCfg: defaultDownloadFromCfg, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusRequestEntityTooLarge, - }, - { - scenario: "request entity too large: downloadFrom", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("downloadFrom", `[{"url":"http://localhost:80/"}]`) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - bodyLimit: 45, // form values = 44 bytes. - downloadFromSrv: func() *echo.Echo { - srv := echo.New() - srv.HideBanner = true - srv.GET("/", func(c echo.Context) error { - c.Response().Header().Set(echo.HeaderContentDisposition, `attachment; filename="bar.txt"`) - c.Response().Header().Set(echo.HeaderContentType, "text/plain") - return c.String(http.StatusOK, http.StatusText(http.StatusOK)) - }) - return srv - }(), - downloadFromCfg: defaultDownloadFromCfg, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusRequestEntityTooLarge, - }, - { - scenario: "request entity too large: form files", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - part, err := writer.CreateFormFile("foo.txt", "foo.txt") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - _, err = part.Write([]byte("foo")) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - bodyLimit: 1, - downloadFromCfg: defaultDownloadFromCfg, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusRequestEntityTooLarge, - }, - { - scenario: "invalid downloadFrom form field: cannot unmarshal", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("downloadFrom", "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - downloadFromCfg: defaultDownloadFromCfg, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "invalid downloadFrom form field: no URL", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("downloadFrom", `[{}]`) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - downloadFromCfg: defaultDownloadFromCfg, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "invalid downloadFrom form field: filtered URL", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("downloadFrom", `[{"url":"https://foo.bar"}]`) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - downloadFromCfg: func() downloadFromConfig { - denyList, err := regexp2.Compile("https://foo.bar", 0) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - return downloadFromConfig{allowList: defaultAllowList, denyList: denyList, maxRetry: 1, disable: false} - }(), - expectError: true, - }, - { - scenario: "invalid downloadFrom form field: unreachable URL", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("downloadFrom", `[{"url":"http://localhost:80/"}]`) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - downloadFromCfg: defaultDownloadFromCfg, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "invalid downloadFrom form field: invalid status code", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("downloadFrom", `[{"url":"http://localhost:80/"}]`) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - downloadFromSrv: func() *echo.Echo { - srv := echo.New() - srv.HideBanner = true - srv.GET("/", func(c echo.Context) error { - return c.String(http.StatusNotFound, http.StatusText(http.StatusNotFound)) - }) - return srv - }(), - downloadFromCfg: defaultDownloadFromCfg, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "invalid downloadFrom form field: no 'Content-Disposition' header", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("downloadFrom", `[{"url":"http://localhost:80/"}]`) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - downloadFromSrv: func() *echo.Echo { - srv := echo.New() - srv.HideBanner = true - srv.GET("/", func(c echo.Context) error { - return c.String(http.StatusOK, http.StatusText(http.StatusOK)) - }) - return srv - }(), - downloadFromCfg: defaultDownloadFromCfg, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "invalid downloadFrom form field: malformed 'Content-Disposition' header", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("downloadFrom", `[{"url":"http://localhost:80/"}]`) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - downloadFromSrv: func() *echo.Echo { - srv := echo.New() - srv.HideBanner = true - srv.GET("/", func(c echo.Context) error { - c.Response().Header().Set(echo.HeaderContentDisposition, ";;") - return c.String(http.StatusOK, http.StatusText(http.StatusOK)) - }) - return srv - }(), - downloadFromCfg: defaultDownloadFromCfg, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "invalid downloadFrom form field: no filename parameter in 'Content-Disposition' header", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("downloadFrom", `[{"url":"http://localhost:80/"}]`) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - downloadFromSrv: func() *echo.Echo { - srv := echo.New() - srv.HideBanner = true - srv.GET("/", func(c echo.Context) error { - c.Response().Header().Set(echo.HeaderContentDisposition, "inline;") - return c.String(http.StatusOK, http.StatusText(http.StatusOK)) - }) - return srv - }(), - downloadFromCfg: defaultDownloadFromCfg, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "success", - request: func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - err := writer.WriteField("foo", "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - part, err := writer.CreateFormFile("foo.txt", "foo.txt") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - _, err = part.Write([]byte("foo")) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - err = writer.WriteField("downloadFrom", `[{"url":"http://localhost:80/","extraHttpHeaders":{"X-Foo":"Bar"}}]`) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - return req - }(), - downloadFromSrv: func() *echo.Echo { - srv := echo.New() - srv.HideBanner = true - srv.GET("/", func(c echo.Context) error { - if c.Request().Header.Get("User-Agent") != "Gotenberg" { - t.Fatalf("expected 'Gotenberg' from header 'User-Agent', but got '%s'", c.Request().Header.Get("User-Agent")) - } - if c.Request().Header.Get("X-Foo") != "Bar" { - t.Fatalf("expected 'Bar' from header 'X-Foo', but got '%s'", c.Request().Header.Get("X-Foo")) - } - if c.Request().Header.Get("Gotenberg-Trace") != "123" { - t.Fatalf("expected '123' from header 'Gotenberg-Trace', but got '%s'", c.Request().Header.Get("Gotenberg-Trace")) - } - c.Response().Header().Set(echo.HeaderContentDisposition, `attachment; filename="bar.txt"`) - c.Response().Header().Set(echo.HeaderContentType, "text/plain") - return c.String(http.StatusOK, http.StatusText(http.StatusOK)) - }) - return srv - }(), - downloadFromCfg: defaultDownloadFromCfg, - expectContext: &Context{ - values: map[string][]string{ - "foo": {"foo"}, - "downloadFrom": { - `[{"url":"http://localhost:80/","extraHttpHeaders":{"X-Foo":"Bar"}}]`, - }, - }, - files: map[string]string{ - "foo.txt": "foo.txt", - "bar.txt": "bar.txt", // downloadFrom. - }, - }, - expectError: false, - expectHttpError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - if tc.downloadFromSrv != nil { - go func() { - err := tc.downloadFromSrv.Start(":80") - if !errors.Is(err, http.ErrServerClosed) { - t.Error(err) - return - } - }() - defer func() { - err := tc.downloadFromSrv.Shutdown(context.TODO()) - if err != nil { - t.Error(err) - } - }() - } - - handler := func(c echo.Context) error { - ctx, cancel, err := newContext(c, zap.NewNop(), gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), time.Duration(10)*time.Second, tc.bodyLimit, tc.downloadFromCfg, "Gotenberg-Trace", "123") - defer cancel() - // Context already cancelled. - defer cancel() - - if err != nil { - return err - } - - if tc.expectContext != nil { - if !reflect.DeepEqual(tc.expectContext.values, ctx.values) { - t.Fatalf("expected context.values to be %v but got %v", tc.expectContext.values, ctx.values) - } - if len(tc.expectContext.files) != len(ctx.files) { - t.Fatalf("expected context.files to contain %d items but got %d", len(tc.expectContext.files), len(ctx.files)) - } - for key, value := range tc.expectContext.files { - if !strings.HasSuffix(ctx.files[key], value) { - t.Fatalf("expected context.files to contain '%s' but got '%s'", value, ctx.files[key]) - } - } - } - - return nil - } - - recorder := httptest.NewRecorder() - - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - - c := srv.NewContext(tc.request, recorder) - err := handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - }) - } -} - -func TestContext_Request(t *testing.T) { - request := httptest.NewRequest(http.MethodPost, "/", nil) - recorder := httptest.NewRecorder() - c := echo.New().NewContext(request, recorder) - - ctx := &Context{ - echoCtx: c, - } - - if !reflect.DeepEqual(ctx.Request(), c.Request()) { - t.Errorf("expected %v but got %v", ctx.Request(), c.Request()) - } -} - -func TestContext_FormData(t *testing.T) { - ctx := &Context{ - values: map[string][]string{ - "foo": {"foo"}, - }, - files: map[string]string{ - "foo.txt": "/foo.txt", - }, - } - - actual := ctx.FormData() - expect := &FormData{ - values: ctx.values, - files: ctx.files, - } - - if !reflect.DeepEqual(actual, expect) { - t.Errorf("expected %+v but got %+v", expect, actual) - } -} - -func TestContext_CreateSubDirectory(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *Context - expectError bool - }{ - { - scenario: "failure", - ctx: &Context{mkdirAll: &gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error { - return errors.New("cannot rename") - }}}, - expectError: true, - }, - { - scenario: "success", - ctx: &Context{mkdirAll: &gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error { - return nil - }}}, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.logger = zap.NewNop() - _, err := tc.ctx.CreateSubDirectory("foo") - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }) - } -} - -func TestContext_GeneratePath(t *testing.T) { - ctx := &Context{ - dirPath: "/foo", - } - - path := ctx.GeneratePath(".pdf") - if !strings.HasPrefix(path, ctx.dirPath) { - t.Errorf("expected '%s' to start with '%s'", path, ctx.dirPath) - } -} - -func TestContext_Rename(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *Context - expectError bool - }{ - { - scenario: "failure", - ctx: &Context{pathRename: &gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return errors.New("cannot rename") - }}}, - expectError: true, - }, - { - scenario: "success", - ctx: &Context{pathRename: &gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return nil - }}}, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.logger = zap.NewNop() - err := tc.ctx.Rename("", "") - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }) - } -} - -func TestContext_AddOutputPaths(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *Context - path string - expectCount int - expectError bool - }{ - { - scenario: "ErrContextAlreadyClosed", - ctx: &Context{cancelled: true}, - expectCount: 0, - expectError: true, - }, - { - scenario: "ErrOutOfBoundsOutputPath", - ctx: &Context{dirPath: "/foo"}, - path: "/bar/foo.txt", - expectCount: 0, - expectError: true, - }, - { - scenario: "success", - ctx: &Context{dirPath: "/foo"}, - path: "/foo/foo.txt", - expectCount: 1, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - err := tc.ctx.AddOutputPaths(tc.path) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if len(tc.ctx.outputPaths) != tc.expectCount { - t.Errorf("expected %d output paths but got %d", tc.expectCount, len(tc.ctx.outputPaths)) - } - }) - } -} - -func TestContext_Log(t *testing.T) { - expect := zap.NewNop() - ctx := Context{logger: expect} - actual := ctx.Log() - - if !reflect.DeepEqual(actual, expect) { - t.Errorf("expected %v but got %v", expect, actual) - } -} - -func TestContext_BuildOutputFile(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *Context - expectError bool - }{ - { - scenario: "ErrContextAlreadyClosed", - ctx: &Context{cancelled: true}, - expectError: true, - }, - { - scenario: "no output path", - ctx: &Context{}, - expectError: true, - }, - { - scenario: "success: one output path", - ctx: &Context{outputPaths: []string{"foo.txt"}}, - expectError: false, - }, - { - scenario: "cannot archive: invalid output paths", - ctx: &Context{outputPaths: []string{"foo.txt", "foo.pdf"}}, - expectError: true, - }, - { - scenario: "success: many output paths", - ctx: &Context{ - outputPaths: []string{ - "/tests/test/testdata/api/sample1.txt", - "/tests/test/testdata/api/sample1.txt", - }, - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - dirPath, err := fs.MkdirAll() - if err != nil { - t.Fatalf("expected no erro but got: %v", err) - } - - defer func() { - err := os.RemoveAll(fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up but got: %v", err) - } - }() - - tc.ctx.dirPath = dirPath - tc.ctx.Context = context.Background() - tc.ctx.logger = zap.NewNop() - - _, err = tc.ctx.BuildOutputFile() - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }) - } -} - -func TestContext_OutputFilename(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *Context - outputPath string - expectOutputFilename string - }{ - { - scenario: "with Gotenberg-Output-Filename header", - ctx: func() *Context { - c := echo.New().NewContext(httptest.NewRequest(http.MethodGet, "/foo", nil), nil) - c.Request().Header.Set("Gotenberg-Output-Filename", "foo") - return &Context{echoCtx: c} - }(), - outputPath: "/foo/bar.txt", - expectOutputFilename: "foo.txt", - }, - { - scenario: "without custom filename", - ctx: func() *Context { - c := echo.New().NewContext(httptest.NewRequest(http.MethodGet, "/foo", nil), nil) - return &Context{echoCtx: c} - }(), - outputPath: "/foo/foo.txt", - expectOutputFilename: "foo.txt", - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - actual := tc.ctx.OutputFilename(tc.outputPath) - - if actual != tc.expectOutputFilename { - t.Errorf("expected '%s' but got '%s'", tc.expectOutputFilename, actual) - } - }) - } -} diff --git a/pkg/modules/api/formdata_test.go b/pkg/modules/api/formdata_test.go index 5ebd0b2f..e3ce8f41 100644 --- a/pkg/modules/api/formdata_test.go +++ b/pkg/modules/api/formdata_test.go @@ -1425,36 +1425,36 @@ func TestFormData_Content(t *testing.T) { scenario: "file does exist without file extension", form: &FormData{ files: map[string]string{ - "foo": "/tests/test/testdata/api/sample1.txt", + "foo": "testdata/sample.txt", }, }, filename: "foo", defaultValue: "", - expect: "foo", + expect: "This is a text from a text file.", expectError: false, }, { scenario: "file does exist with an uppercase file extension", form: &FormData{ files: map[string]string{ - "foo.TXT": "/tests/test/testdata/api/sample1.txt", + "foo.TXT": "testdata/sample.txt", }, }, filename: "foo.txt", defaultValue: "", - expect: "foo", + expect: "This is a text from a text file.", expectError: false, }, { scenario: "file does exist without a lowercase file extension", form: &FormData{ files: map[string]string{ - "foo.txt": "/tests/test/testdata/api/sample1.txt", + "foo.txt": "testdata/sample.txt", }, }, filename: "foo.txt", defaultValue: "", - expect: "foo", + expect: "This is a text from a text file.", expectError: false, }, } { @@ -1519,33 +1519,33 @@ func TestFormData_MandatoryContent(t *testing.T) { scenario: "mandatory file does exist without file extension", form: &FormData{ files: map[string]string{ - "foo": "/tests/test/testdata/api/sample1.txt", + "foo": "testdata/sample.txt", }, }, filename: "foo", - expect: "foo", + expect: "This is a text from a text file.", expectError: false, }, { scenario: "mandatory file does exist with an uppercase file extension", form: &FormData{ files: map[string]string{ - "foo.TXT": "/tests/test/testdata/api/sample1.txt", + "foo.TXT": "testdata/sample.txt", }, }, filename: "foo.txt", - expect: "foo", + expect: "This is a text from a text file.", expectError: false, }, { scenario: "mandatory file does exist without a lowercase file extension", form: &FormData{ files: map[string]string{ - "foo.txt": "/tests/test/testdata/api/sample1.txt", + "foo.txt": "testdata/sample.txt", }, }, filename: "foo.txt", - expect: "foo", + expect: "This is a text from a text file.", expectError: false, }, } { diff --git a/pkg/modules/api/middlewares_test.go b/pkg/modules/api/middlewares_test.go deleted file mode 100644 index 8bef1268..00000000 --- a/pkg/modules/api/middlewares_test.go +++ /dev/null @@ -1,584 +0,0 @@ -package api - -import ( - "bytes" - "context" - "errors" - "mime/multipart" - "net/http" - "net/http/httptest" - "strings" - "testing" - "time" - - "github.com/labstack/echo/v4" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestParseError(t *testing.T) { - for i, tc := range []struct { - err error - expectStatus int - expectMessage string - }{ - { - err: echo.ErrInternalServerError, - expectStatus: http.StatusInternalServerError, - expectMessage: http.StatusText(http.StatusInternalServerError), - }, - { - err: gotenberg.ErrFiltered, - expectStatus: http.StatusForbidden, - expectMessage: http.StatusText(http.StatusForbidden), - }, - { - err: gotenberg.ErrMaximumQueueSizeExceeded, - expectStatus: http.StatusTooManyRequests, - expectMessage: http.StatusText(http.StatusTooManyRequests), - }, - { - err: gotenberg.ErrPdfSplitModeNotSupported, - expectStatus: http.StatusBadRequest, - expectMessage: "At least one PDF engine cannot process the requested PDF split mode, while others may have failed to split due to different issues", - }, - { - err: gotenberg.ErrPdfFormatNotSupported, - expectStatus: http.StatusBadRequest, - expectMessage: "At least one PDF engine cannot process the requested PDF format, while others may have failed to convert due to different issues", - }, - { - err: gotenberg.ErrPdfEngineMetadataValueNotSupported, - expectStatus: http.StatusBadRequest, - expectMessage: "At least one PDF engine cannot process the requested metadata, while others may have failed to convert due to different issues", - }, - { - err: WrapError( - errors.New("foo"), - NewSentinelHttpError(http.StatusBadRequest, "foo"), - ), - expectStatus: http.StatusBadRequest, - expectMessage: "foo", - }, - } { - actualStatus, actualMessage := ParseError(tc.err) - - if actualStatus != tc.expectStatus { - t.Errorf("test %d: expected HTTP status code %d but got %d", i, tc.expectStatus, actualStatus) - } - - if actualMessage != tc.expectMessage { - t.Errorf("test %d: expected message '%s' but got '%s'", i, tc.expectMessage, actualMessage) - } - } -} - -func TestHttpErrorHandler(t *testing.T) { - for i, tc := range []struct { - err error - expectStatus int - expectMessage string - }{ - { - err: echo.ErrInternalServerError, - expectStatus: http.StatusInternalServerError, - expectMessage: http.StatusText(http.StatusInternalServerError), - }, - { - err: context.DeadlineExceeded, - expectStatus: http.StatusServiceUnavailable, - expectMessage: http.StatusText(http.StatusServiceUnavailable), - }, - { - err: WrapError( - errors.New("foo"), - NewSentinelHttpError(http.StatusBadRequest, "foo"), - ), - expectStatus: http.StatusBadRequest, - expectMessage: "foo", - }, - } { - recorder := httptest.NewRecorder() - request := httptest.NewRequest(http.MethodGet, "/foo", nil) - - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - - c := srv.NewContext(request, recorder) - c.Set("logger", zap.NewNop()) - - handler := httpErrorHandler() - handler(tc.err, c) - - contentType := recorder.Header().Get(echo.HeaderContentType) - if contentType != echo.MIMETextPlainCharsetUTF8 { - t.Errorf("test %d: expected %s '%s' but got '%s'", i, echo.HeaderContentType, echo.MIMETextPlainCharsetUTF8, contentType) - } - - // Note: we cannot test the trace header in the response here, as it is set in the trace middleware. - - if recorder.Code != tc.expectStatus { - t.Errorf("test %d: expected HTTP status code %d but got %d", i, tc.expectStatus, recorder.Code) - } - - if recorder.Body.String() != tc.expectMessage { - t.Errorf("test %d: expected message '%s' but got '%s'", i, tc.expectMessage, recorder.Body.String()) - } - } -} - -func TestLatencyMiddleware(t *testing.T) { - recorder := httptest.NewRecorder() - request := httptest.NewRequest(http.MethodGet, "/foo", nil) - - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - - c := srv.NewContext(request, recorder) - - err := latencyMiddleware()( - func(c echo.Context) error { - return nil - }, - )(c) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - startTime := c.Get("startTime").(time.Time) - now := time.Now() - - if now.Before(startTime) { - t.Errorf("expected start time %s to be < %s", startTime, now) - } -} - -func TestRootPathMiddleware(t *testing.T) { - recorder := httptest.NewRecorder() - request := httptest.NewRequest(http.MethodGet, "/foo", nil) - - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - - c := srv.NewContext(request, recorder) - - err := rootPathMiddleware("foo")( - func(c echo.Context) error { - return nil - }, - )(c) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - rootPath := c.Get("rootPath").(string) - - if rootPath != "foo" { - t.Errorf("expected '%s' but got '%s", "foo", rootPath) - } -} - -func TestTraceMiddleware(t *testing.T) { - for i, tc := range []struct { - trace string - }{ - { - trace: "foo", - }, - { - trace: "", - }, - } { - recorder := httptest.NewRecorder() - request := httptest.NewRequest(http.MethodGet, "/foo", nil) - - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - - c := srv.NewContext(request, recorder) - - if tc.trace != "" { - c.Request().Header.Set("Gotenberg-Trace", tc.trace) - } - - err := traceMiddleware("Gotenberg-Trace")( - func(c echo.Context) error { - return nil - }, - )(c) - if err != nil { - t.Fatalf("test %d: expected no error but got: %v", i, err) - } - - trace := c.Get("trace").(string) - - if trace == "" { - t.Errorf("test %d: expected non empty trace in context", i) - } - - if tc.trace != "" && trace != tc.trace { - t.Errorf("test %d: expected context trace '%s' but got '%s'", i, tc.trace, trace) - } - - if tc.trace == "" && trace == tc.trace { - t.Errorf("test %d: expected context trace different from '%s' but got '%s'", i, tc.trace, trace) - } - - responseTrace := recorder.Header().Get("Gotenberg-Trace") - - if tc.trace != "" && responseTrace != tc.trace { - t.Errorf("test %d: expected header trace '%s' but got '%s'", i, tc.trace, responseTrace) - } - - if tc.trace == "" && responseTrace == tc.trace { - t.Errorf("test %d: expected header trace different from '%s' but got '%s'", i, tc.trace, responseTrace) - } - } -} - -func TestBasicAuthMiddleware(t *testing.T) { - for _, tc := range []struct { - scenario string - request *http.Request - username string - password string - expectError bool - }{ - { - scenario: "invalid basic auth", - request: func() *http.Request { - req := httptest.NewRequest(http.MethodGet, "/", nil) - req.SetBasicAuth("invalid", "invalid") - return req - }(), - username: "foo", - password: "bar", - expectError: true, - }, - { - scenario: "valid basic auth", - request: func() *http.Request { - req := httptest.NewRequest(http.MethodGet, "/", nil) - req.SetBasicAuth("foo", "bar") - return req - }(), - username: "foo", - password: "bar", - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - recorder := httptest.NewRecorder() - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - c := srv.NewContext(tc.request, recorder) - err := basicAuthMiddleware(tc.username, tc.password)(func(c echo.Context) error { - return nil - })(c) - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestLoggerMiddleware(t *testing.T) { - for i, tc := range []struct { - request *http.Request - next echo.HandlerFunc - skipLogging bool - }{ - { - request: httptest.NewRequest(http.MethodGet, "/", nil), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return errors.New("foo") - } - }(), - }, - { - request: httptest.NewRequest(http.MethodGet, "/health", nil), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return nil - } - }(), - skipLogging: true, - }, - { - request: httptest.NewRequest(http.MethodGet, "/health", nil), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return nil - } - }(), - }, - } { - recorder := httptest.NewRecorder() - - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - - c := srv.NewContext(tc.request, recorder) - c.Set("startTime", time.Now()) - c.Set("trace", "foo") - c.Set("rootPath", "/") - - var disableLoggingForPaths []string - if tc.skipLogging { - disableLoggingForPaths = append(disableLoggingForPaths, tc.request.RequestURI) - } - - err := loggerMiddleware(zap.NewNop(), disableLoggingForPaths)(tc.next)(c) - if err != nil { - t.Errorf("test %d: expected no error but got: %v", i, err) - } - } -} - -func TestContextMiddleware(t *testing.T) { - buildMultipartFormDataRequest := func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - - err := writer.WriteField("foo", "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - - return req - } - - for i, tc := range []struct { - request *http.Request - next echo.HandlerFunc - expectErr bool - expectStatus int - expectContentType string - expectFilename string - }{ - { - request: httptest.NewRequest(http.MethodGet, "/", nil), - expectErr: true, - }, - { - request: buildMultipartFormDataRequest(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return ErrAsyncProcess - } - }(), - expectStatus: http.StatusNoContent, - }, - { - request: buildMultipartFormDataRequest(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return ErrNoOutputFile - } - }(), - expectStatus: http.StatusOK, - }, - { - request: buildMultipartFormDataRequest(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return errors.New("foo") - } - }(), - expectErr: true, - }, - { - request: buildMultipartFormDataRequest(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return nil - } - }(), - expectErr: true, - }, - { - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Output-Filename", "foo") - - return req - }(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - ctx := c.Get("context").(*Context) - ctx.outputPaths = []string{ - "/tests/test/testdata/api/sample2.pdf", - } - - return nil - } - }(), - expectStatus: http.StatusOK, - expectContentType: "application/pdf", - expectFilename: "foo.pdf", - }, - { - request: buildMultipartFormDataRequest(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - ctx := c.Get("context").(*Context) - ctx.outputPaths = []string{ - "/tests/test/testdata/api/sample1.txt", - "/tests/test/testdata/api/sample2.pdf", - } - - return nil - } - }(), - expectStatus: http.StatusOK, - expectContentType: "application/zip", - }, - } { - recorder := httptest.NewRecorder() - - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - - c := srv.NewContext(tc.request, recorder) - c.Set("logger", zap.NewNop()) - c.Set("traceHeader", "Gotenberg-Trace") - c.Set("trace", "foo") - c.Set("startTime", time.Now()) - - err := contextMiddleware(gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), time.Duration(10)*time.Second, 0, downloadFromConfig{})(tc.next)(c) - - if tc.expectErr && err == nil { - t.Errorf("test %d: expected error but got: %v", i, err) - } - - if !tc.expectErr && err != nil { - t.Errorf("test %d: expected no error but got: %v", i, err) - } - - if err != nil { - continue - } - - if recorder.Code != tc.expectStatus { - t.Errorf("test %d: expected HTTP status code %d but got %d", i, tc.expectStatus, recorder.Code) - } - - if tc.expectStatus == http.StatusNoContent { - continue - } - - contentType := recorder.Header().Get(echo.HeaderContentType) - if contentType != tc.expectContentType { - t.Errorf("test %d: expected %s '%s' but got '%s'", i, echo.HeaderContentType, tc.expectContentType, contentType) - } - - contentDisposition := recorder.Header().Get(echo.HeaderContentDisposition) - if !strings.Contains(contentDisposition, tc.expectFilename) { - t.Errorf("test %d: expected %s '%s' to contain '%s'", i, echo.HeaderContentDisposition, contentDisposition, tc.expectFilename) - } - } -} - -func TestHardTimeoutMiddleware(t *testing.T) { - for i, tc := range []struct { - next echo.HandlerFunc - timeout time.Duration - expectErr bool - expectHardTimeout bool - }{ - { - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return nil - } - }(), - timeout: time.Duration(100) * time.Millisecond, - }, - { - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - panic("foo") - } - }(), - timeout: time.Duration(100) * time.Millisecond, - expectErr: true, - expectHardTimeout: true, - }, - { - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return errors.New("foo") - } - }(), - timeout: time.Duration(100) * time.Millisecond, - expectErr: true, - }, - { - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - time.Sleep(time.Duration(200) * time.Millisecond) - - return nil - } - }(), - timeout: time.Duration(100) * time.Millisecond, - expectErr: true, - expectHardTimeout: true, - }, - } { - recorder := httptest.NewRecorder() - request := httptest.NewRequest(http.MethodGet, "/foo", nil) - - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - - c := srv.NewContext(request, recorder) - c.Set("logger", zap.NewNop()) - - err := hardTimeoutMiddleware(tc.timeout)(tc.next)(c) - - if tc.expectErr && err == nil { - t.Errorf("test %d: expected error but got: %v", i, err) - } - - if !tc.expectErr && err != nil { - t.Errorf("test %d: expected no error but got: %v", i, err) - } - - var isHardTimeout bool - if err != nil { - isHardTimeout = strings.Contains(err.Error(), "hard timeout") - } - - if tc.expectHardTimeout && !isHardTimeout { - t.Errorf("test %d: expected hard timeout error but got: %v", i, err) - } - - if !tc.expectHardTimeout && isHardTimeout { - t.Errorf("test %d: expected no hard timeout error but got one: %v", i, err) - } - } -} diff --git a/pkg/modules/api/mocks_test.go b/pkg/modules/api/mocks_test.go deleted file mode 100644 index ecc2a19c..00000000 --- a/pkg/modules/api/mocks_test.go +++ /dev/null @@ -1,193 +0,0 @@ -package api - -import ( - "reflect" - "testing" - - "github.com/alexliesenfeld/health" - "github.com/labstack/echo/v4" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestContextMock_SetDirPath(t *testing.T) { - mock := &ContextMock{&Context{}} - mock.SetDirPath("/foo") - - actual := mock.dirPath - expect := "/foo" - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestContextMock_DirPath(t *testing.T) { - mock := &ContextMock{&Context{}} - mock.SetDirPath("/foo") - - actual := mock.DirPath() - expect := "/foo" - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestContextMock_SetValues(t *testing.T) { - mock := &ContextMock{&Context{}} - mock.SetValues(map[string][]string{ - "foo": {"foo"}, - }) - - actual := mock.values - expect := map[string][]string{ - "foo": {"foo"}, - } - - if !reflect.DeepEqual(actual, expect) { - t.Errorf("expected %+v but got: %+v", expect, actual) - } -} - -func TestContextMock_SetFiles(t *testing.T) { - mock := &ContextMock{&Context{}} - mock.SetFiles(map[string]string{ - "foo": "/foo", - }) - - actual := mock.files - expect := map[string]string{ - "foo": "/foo", - } - - if !reflect.DeepEqual(actual, expect) { - t.Errorf("expected %+v but got: %+v", expect, actual) - } -} - -func TestContextMock_SetCancelled(t *testing.T) { - mock := &ContextMock{&Context{}} - mock.SetCancelled(true) - - actual := mock.cancelled - - if !actual { - t.Errorf("expected %t but got %t", true, actual) - } -} - -func TestContextMock_OutputPaths(t *testing.T) { - mock := ContextMock{ - &Context{ - outputPaths: []string{"/foo"}, - }, - } - - actual := mock.OutputPaths() - expect := []string{"/foo"} - - if !reflect.DeepEqual(actual, expect) { - t.Errorf("expected %+v but got: %+v", expect, actual) - } -} - -func TestContextMock_SetLogger(t *testing.T) { - mock := ContextMock{&Context{}} - - expect := zap.NewNop() - mock.SetLogger(expect) - - actual := mock.logger - - if actual != expect { - t.Errorf("expected %v but got %v", expect, actual) - } -} - -func TestContextMock_SetEchoContext(t *testing.T) { - mock := ContextMock{&Context{}} - - expect := echo.New().NewContext(nil, nil) - mock.SetEchoContext(expect) - - actual := mock.echoCtx - - if actual != expect { - t.Errorf("expected %v but got %v", expect, actual) - } -} - -func TestContextMock_SetMkdirAll(t *testing.T) { - mock := ContextMock{&Context{}} - - expect := new(gotenberg.OsMkdirAll) - mock.SetMkdirAll(expect) - - actual := mock.mkdirAll - - if actual != expect { - t.Errorf("expected %v but got %v", expect, actual) - } -} - -func TestContextMock_SetPathRename(t *testing.T) { - mock := ContextMock{&Context{}} - - expect := new(gotenberg.OsPathRename) - mock.SetPathRename(expect) - - actual := mock.pathRename - - if actual != expect { - t.Errorf("expected %v but got %v", expect, actual) - } -} - -func TestRouterMock(t *testing.T) { - mock := &RouterMock{ - RoutesMock: func() ([]Route, error) { - return nil, nil - }, - } - - _, err := mock.Routes() - if err != nil { - t.Errorf("expected no error from RouterMock.Routes, but got: %v", err) - } -} - -func TestMiddlewareProviderMock(t *testing.T) { - mock := &MiddlewareProviderMock{ - MiddlewaresMock: func() ([]Middleware, error) { - return nil, nil - }, - } - - _, err := mock.Middlewares() - if err != nil { - t.Errorf("expected no error from MiddlewareProviderMock.Middlewares, but got: %v", err) - } -} - -func TestHealthCheckerMock(t *testing.T) { - mock := &HealthCheckerMock{ - ChecksMock: func() ([]health.CheckerOption, error) { - return nil, nil - }, - ReadyMock: func() error { - return nil - }, - } - - _, err := mock.Checks() - if err != nil { - t.Errorf("expected no error from HealthCheckerMock.Checks, but got: %v", err) - } - - err = mock.Ready() - if err != nil { - t.Errorf("expected no error from HealthCheckerMock.Ready, but got: %v", err) - } -} diff --git a/test/testdata/libreoffice/document.txt b/pkg/modules/api/testdata/sample.txt similarity index 100% rename from test/testdata/libreoffice/document.txt rename to pkg/modules/api/testdata/sample.txt diff --git a/pkg/modules/chromium/browser_test.go b/pkg/modules/chromium/browser_test.go deleted file mode 100644 index a4636474..00000000 --- a/pkg/modules/chromium/browser_test.go +++ /dev/null @@ -1,2484 +0,0 @@ -package chromium - -import ( - "context" - "errors" - "fmt" - "os" - "strings" - "testing" - "time" - - "github.com/dlclark/regexp2" - "github.com/google/uuid" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" - "go.uber.org/zap/zaptest/observer" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestChromiumBrowser_Start(t *testing.T) { - for _, tc := range []struct { - scenario string - browser browser - expectError bool - cleanup bool - }{ - { - scenario: "successful start", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - }, - ), - expectError: false, - cleanup: true, - }, - { - scenario: "all browser arguments", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - incognito: true, - allowInsecureLocalhost: true, - ignoreCertificateErrors: true, - disableWebSecurity: true, - allowFileAccessFromFiles: true, - hostResolverRules: "MAP forgery.docker.localhost traefik", - proxyServer: "1.2.3.4", - }, - ), - expectError: false, - cleanup: true, - }, - { - scenario: "browser already started", - browser: func() browser { - b := new(chromiumBrowser) - b.isStarted.Store(true) - return b - }(), - expectError: true, - cleanup: false, - }, - { - scenario: "browser start error", - browser: func() browser { - b := newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - }, - ).(*chromiumBrowser) - - ctx, cancel := context.WithCancel(context.Background()) - cancel() - b.initialCtx = ctx - - return b - }(), - expectError: true, - cleanup: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - logger := zap.NewNop() - err := tc.browser.Start(logger) - - if tc.cleanup { - defer func(b browser, logger *zap.Logger) { - err = b.Stop(logger) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }(tc.browser, logger) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestChromiumBrowser_Stop(t *testing.T) { - for _, tc := range []struct { - scenario string - browser browser - setup func(browser browser, logger *zap.Logger) error - expectError bool - }{ - { - scenario: "successful stop", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - }, - ), - setup: func(b browser, logger *zap.Logger) error { - return b.Start(logger) - }, - expectError: false, - }, - { - scenario: "browser already stopped", - browser: func() browser { - b := new(chromiumBrowser) - b.isStarted.Store(false) - return b - }(), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - logger := zap.NewNop() - - if tc.setup != nil { - err := tc.setup(tc.browser, logger) - if err != nil { - t.Fatalf("setup error: %v", err) - } - } - - err := tc.browser.Stop(logger) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestChromiumBrowser_Healthy(t *testing.T) { - for _, tc := range []struct { - scenario string - browser browser - setup func(browser browser, logger *zap.Logger) error - expectHealthy bool - cleanup bool - }{ - { - scenario: "healthy browser", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - }, - ), - setup: func(b browser, logger *zap.Logger) error { - return b.Start(logger) - }, - expectHealthy: true, - cleanup: true, - }, - { - scenario: "browser not started", - browser: func() browser { - b := new(chromiumBrowser) - b.isStarted.Store(false) - return b - }(), - expectHealthy: false, - cleanup: false, - }, - { - scenario: "unhealthy browser", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - }, - ), - setup: func(b browser, logger *zap.Logger) error { - _ = b.Start(logger) - b.(*chromiumBrowser).cancelFunc() - - return nil - }, - expectHealthy: false, - cleanup: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - logger := zap.NewNop() - - if tc.setup != nil { - err := tc.setup(tc.browser, logger) - if err != nil { - t.Fatalf("setup error: %v", err) - } - } - - if tc.cleanup { - defer func(b browser, logger *zap.Logger) { - err := b.Stop(logger) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }(tc.browser, logger) - } - - healthy := tc.browser.Healthy(logger) - - if !tc.expectHealthy && healthy { - t.Fatal("expected unhealthy browser but got an healthy one") - } - - if tc.expectHealthy && !healthy { - t.Fatal("expected a healthy browser but got an unhealthy one") - } - }) - } -} - -func TestChromiumBrowser_pdf(t *testing.T) { - for _, tc := range []struct { - scenario string - browser browser - fs *gotenberg.FileSystem - options PdfOptions - url string - noDeadline bool - start bool - expectError bool - expectedError error - expectedLogEntries []string - }{ - { - scenario: "browser not started", - browser: func() browser { - b := new(chromiumBrowser) - b.isStarted.Store(false) - return b - }(), - fs: gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), - noDeadline: false, - start: false, - expectError: true, - }, - { - scenario: "context has no deadline", - browser: func() browser { - b := new(chromiumBrowser) - b.isStarted.Store(true) - return b - }(), - fs: gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), - noDeadline: true, - start: false, - expectError: true, - }, - { - scenario: "ErrFiltered: main URL does not match the allowed list", - browser: func() browser { - b := new(chromiumBrowser) - b.arguments = browserArguments{ - allowList: regexp2.MustCompile(`^file:(?!//\/tmp/).*`, 0), - denyList: regexp2.MustCompile("", 0), - } - b.isStarted.Store(true) - return b - }(), - fs: gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), - noDeadline: false, - start: false, - expectError: true, - expectedError: gotenberg.ErrFiltered, - }, - { - scenario: "ErrFiltered: main URL does match the denied list", - browser: func() browser { - b := new(chromiumBrowser) - b.arguments = browserArguments{ - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("^file:///tmp.*", 0), - } - b.isStarted.Store(true) - return b - }(), - fs: gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), - noDeadline: false, - start: false, - expectError: true, - expectedError: gotenberg.ErrFiltered, - }, - { - scenario: "a request does not match the allowed list", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("^file:///tmp.*", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "'file:///etc/passwd' does not match the expression from the allowed list", - }, - }, - { - scenario: "a request does match the denied list", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile(`^file:(?!//\/tmp/).*`, 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "'file:///etc/passwd' matches the expression from the denied list", - }, - }, - { - scenario: "do not skip networkIdle event", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Skip networkIdle event

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{SkipNetworkIdleEvent: false}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "event networkIdle fired", - }, - }, - { - scenario: "ErrInvalidHttpStatusCode", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrInvalidHttpStatusCode

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{FailOnHttpStatusCodes: []int64{299}}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrInvalidHttpStatusCode, - }, - { - scenario: "ErrInvalidResourceHttpStatusCode", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/style.css", fs.WorkingDirPath()), []byte("body{font-family: Arial, Helvetica, sans-serif;}"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrInvalidResourceHttpStatusCode

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{FailOnResourceHttpStatusCodes: []int64{200}}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrInvalidResourceHttpStatusCode, - }, - { - scenario: "ErrConsoleExceptions", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{FailOnConsoleExceptions: true}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrConsoleExceptions, - }, - { - scenario: "ErrLoadingFailed", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - url: "http://localhost:100", - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrLoadingFailed, - }, - { - scenario: "ErrResourceLoadingFailed", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrResourceLoadingFailed

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{FailOnResourceLoadingFailed: true}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrResourceLoadingFailed, - }, - { - scenario: "clear cache", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - clearCache: true, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Clear cache

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "clear cache", - }, - }, - { - scenario: "clear cookies", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - clearCookies: true, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Clear cookies

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "clear cookies", - }, - }, - { - scenario: "disable JavaScript", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - disableJavaScript: true, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "disable JavaScript", - "JavaScript disabled, skipping wait delay", - "JavaScript disabled, skipping wait expression", - }, - }, - { - scenario: "set cookies", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Set cookies

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{Cookies: []Cookie{{Name: "foo", Value: "bar", Domain: ".foo.bar"}}}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "set cookie", - }, - }, - { - scenario: "user agent override", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

User-Agent override

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{UserAgent: "foo"}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - fmt.Sprintf("user agent override: foo"), - }, - }, - { - scenario: "extra HTTP headers", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Extra HTTP headers

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{ExtraHttpHeaders: []ExtraHttpHeader{ - { - Name: "X-Foo", - Value: "foo", - }, - { - Name: "X-Bar", - Value: "bar", - Scope: regexp2.MustCompile(`.*index\.html.*`, 0), - }, - { - Name: "X-Baz", - Value: "baz", - Scope: regexp2.MustCompile(`.*another\.html.*`, 0), - }, - }}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "extra HTTP headers:", - "extra HTTP header 'X-Foo' will be set for request URL", - "extra HTTP header 'X-Bar' (scoped) will be set for request URL", - "extra HTTP header 'X-Baz' (scoped) will not be set for request URL", - "setting extra HTTP headers for request URL", - }, - }, - { - scenario: "ErrOmitBackgroundWithoutPrintBackground", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrOmitBackgroundWithoutPrintBackground

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{OmitBackground: true}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrOmitBackgroundWithoutPrintBackground, - }, - { - scenario: "hide default white background", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Hide default white background

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{OmitBackground: true}, - PrintBackground: true, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "hide default white background", - }, - }, - { - scenario: "ErrInvalidEmulatedMediaType", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrInvalidEmulatedMediaType

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{EmulatedMediaType: "foo"}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrInvalidEmulatedMediaType, - }, - { - scenario: "emulate a media type", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Screen media type

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{EmulatedMediaType: "screen"}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "emulate media type 'screen'", - }, - }, - { - scenario: "wait delay: context done", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{WaitDelay: time.Duration(10) * time.Second}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedLogEntries: []string{ - "wait '10s' before print", - }, - }, - { - scenario: "wait delay", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{WaitDelay: time.Duration(1) * time.Millisecond}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "wait '1ms' before print", - }, - }, - { - scenario: "wait for expression: context done", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - html := ` - -` - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(html), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{WaitForExpression: "window.status === 'ready'"}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedLogEntries: []string{ - "wait until 'window.status === 'ready'' is true before print", - }, - }, - { - scenario: "ErrInvalidEvaluationExpression", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrInvalidEvaluationExpression

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{WaitForExpression: "return undefined"}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedLogEntries: []string{ - "wait until 'return undefined' is true before print", - }, - }, - { - scenario: "wait for expression", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - html := ` - -` - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(html), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - Options: Options{WaitForExpression: "window.globalVar === 'ready'"}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "wait until 'window.globalVar === 'ready'' is true before print", - }, - }, - { - scenario: "single page", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Custom header and footer

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - SinglePage: true, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "single page PDF", - }, - }, - { - scenario: "custom header and footer", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Custom header and footer

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - HeaderTemplate: "

Header

", - FooterTemplate: "

Footer

", - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "with custom header and/or footer", - }, - }, - { - scenario: "ErrInvalidPrinterSettings", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrInvalidPrinterSettings

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - PaperWidth: 0, - PaperHeight: 0, - MarginTop: 1000000, - MarginBottom: 1000000, - MarginLeft: 1000000, - MarginRight: 1000000, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrInvalidPrinterSettings, - }, - { - scenario: "ErrPageRangesSyntaxError", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrPageRangesSyntaxError

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: PdfOptions{ - PageRanges: "foo", - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrPageRangesSyntaxError, - }, - { - scenario: "success (default options)", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Default options

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: DefaultPdfOptions(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "cache not cleared", - "cookies not cleared", - "JavaScript not disabled", - "no cookies to set", - "no extra HTTP headers", - "navigate to", - "skipping network idle event", - "default white background not hidden", - "no emulated media type", - "no wait delay", - "no wait expression", - "no custom header nor footer", - }, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - core, recorded := observer.New(zapcore.DebugLevel) - logger := zap.New(core) - - defer func() { - err := os.RemoveAll(tc.fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }() - - if tc.start { - err := tc.browser.Start(logger) - if err != nil { - t.Fatalf("setup error: %v", err) - } - - defer func(b browser, logger *zap.Logger) { - err = b.Stop(logger) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }(tc.browser, logger) - } - - var ( - ctx context.Context - cancel context.CancelFunc - ) - - if tc.noDeadline { - ctx = context.Background() - } else { - ctx, cancel = context.WithTimeout(context.Background(), time.Duration(5)*time.Second) - defer cancel() - } - - url := fmt.Sprintf("file://%s/index.html", tc.fs.WorkingDirPath()) - if tc.url != "" { - url = tc.url - } - - err := tc.browser.pdf( - ctx, - logger, - url, - fmt.Sprintf("%s/%s.pdf", tc.fs.WorkingDirPath(), uuid.NewString()), - tc.options, - ) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectedError != nil && !errors.Is(err, tc.expectedError) { - t.Fatalf("expected error %v but got: %v", tc.expectedError, err) - } - - for _, entry := range tc.expectedLogEntries { - doExist := true - for _, log := range recorded.All() { - doExist = strings.Contains(log.Message, entry) - if doExist { - break - } - } - - if !doExist { - t.Errorf("expected '%s' to exist as log entry", entry) - } - } - }) - } -} - -func TestChromiumBrowser_screenshot(t *testing.T) { - for _, tc := range []struct { - scenario string - browser browser - fs *gotenberg.FileSystem - options ScreenshotOptions - url string - noDeadline bool - start bool - expectError bool - expectedError error - expectedLogEntries []string - }{ - { - scenario: "browser not started", - browser: func() browser { - b := new(chromiumBrowser) - b.isStarted.Store(false) - return b - }(), - fs: gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), - noDeadline: false, - start: false, - expectError: true, - }, - { - scenario: "context has not deadline", - browser: func() browser { - b := new(chromiumBrowser) - b.arguments = browserArguments{ - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - } - b.isStarted.Store(true) - return b - }(), - fs: gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), - noDeadline: true, - start: false, - expectError: true, - }, - { - scenario: "ErrFiltered: main URL does not match the allowed list", - browser: func() browser { - b := new(chromiumBrowser) - b.arguments = browserArguments{ - allowList: regexp2.MustCompile(`^file:(?!//\/tmp/).*`, 0), - denyList: regexp2.MustCompile("", 0), - } - b.isStarted.Store(true) - return b - }(), - fs: gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), - noDeadline: false, - start: false, - expectError: true, - expectedError: gotenberg.ErrFiltered, - }, - { - scenario: "ErrFiltered: main URL does match the denied list", - browser: func() browser { - b := new(chromiumBrowser) - b.arguments = browserArguments{ - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("^file:///tmp.*", 0), - } - b.isStarted.Store(true) - return b - }(), - fs: gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), - noDeadline: false, - start: false, - expectError: true, - expectedError: gotenberg.ErrFiltered, - }, - { - scenario: "a request does not match the allowed list", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("^file:///tmp.*", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "'file:///etc/passwd' does not match the expression from the allowed list", - }, - }, - { - scenario: "a request does match the denied list", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile(`^file:(?!//\/tmp/).*`, 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "'file:///etc/passwd' matches the expression from the denied list", - }, - }, - { - scenario: "do not skip networkIdle event", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Skip networkIdle event

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{SkipNetworkIdleEvent: false}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "event networkIdle fired", - }, - }, - { - scenario: "ErrInvalidHttpStatusCode", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrInvalidHttpStatusCode

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{FailOnHttpStatusCodes: []int64{299}}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrInvalidHttpStatusCode, - }, - { - scenario: "ErrInvalidResourceHttpStatusCode", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/style.css", fs.WorkingDirPath()), []byte("body{font-family: Arial, Helvetica, sans-serif;}"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrInvalidResourceHttpStatusCode

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{FailOnResourceHttpStatusCodes: []int64{299}}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrInvalidResourceHttpStatusCode, - }, - { - scenario: "ErrConsoleExceptions", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{FailOnConsoleExceptions: true}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrConsoleExceptions, - }, - { - scenario: "ErrLoadingFailed", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - url: "http://localhost:100", - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrLoadingFailed, - }, - { - scenario: "ErrResourceLoadingFailed", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrResourceLoadingFailed

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{FailOnResourceLoadingFailed: true}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrResourceLoadingFailed, - }, - { - scenario: "clear cache", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - clearCache: true, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Clear cache

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "clear cache", - }, - }, - { - scenario: "clear cookies", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - clearCookies: true, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Clear cookies

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "clear cookies", - }, - }, - { - scenario: "disable JavaScript", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - disableJavaScript: true, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "disable JavaScript", - "JavaScript disabled, skipping wait delay", - "JavaScript disabled, skipping wait expression", - }, - }, - { - scenario: "set cookies", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Set cookies

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{Cookies: []Cookie{{Name: "fpp", Value: "bar", Domain: ".foo.bar"}}}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "set cookie", - }, - }, - { - scenario: "user agent override", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

User-Agent override

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{UserAgent: "foo"}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - fmt.Sprintf("user agent override: foo"), - }, - }, - { - scenario: "extra HTTP headers", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Extra HTTP headers

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{ExtraHttpHeaders: []ExtraHttpHeader{ - { - Name: "X-Foo", - Value: "foo", - }, - { - Name: "X-Bar", - Value: "bar", - Scope: regexp2.MustCompile(`.*index\.html.*`, 0), - }, - { - Name: "X-Baz", - Value: "baz", - Scope: regexp2.MustCompile(`.*another\.html.*`, 0), - }, - }}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "extra HTTP headers:", - "extra HTTP header 'X-Foo' will be set for request URL", - "extra HTTP header 'X-Bar' (scoped) will be set for request URL", - "extra HTTP header 'X-Baz' (scoped) will not be set for request URL", - "setting extra HTTP headers for request URL", - }, - }, - { - scenario: "ErrOmitBackgroundWithoutPrintBackground", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrOmitBackgroundWithoutPrintBackground

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{OmitBackground: true}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "hide default white background", - }, - }, - { - scenario: "ErrInvalidEmulatedMediaType", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrInvalidEmulatedMediaType

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{EmulatedMediaType: "foo"}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedError: ErrInvalidEmulatedMediaType, - }, - { - scenario: "emulate a media type", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Screen media type

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{EmulatedMediaType: "screen"}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "emulate media type 'screen'", - }, - }, - { - scenario: "wait delay: context done", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{WaitDelay: time.Duration(10) * time.Second}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedLogEntries: []string{ - "wait '10s' before print", - }, - }, - { - scenario: "wait delay", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(""), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{WaitDelay: time.Duration(1) * time.Millisecond}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "wait '1ms' before print", - }, - }, - { - scenario: "wait for expression: context done", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - html := ` - -` - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(html), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{WaitForExpression: "window.status === 'ready'"}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedLogEntries: []string{ - "wait until 'window.status === 'ready'' is true before print", - }, - }, - { - scenario: "ErrInvalidEvaluationExpression", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

ErrInvalidEvaluationExpression

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{WaitForExpression: "return undefined"}, - }, - noDeadline: false, - start: true, - expectError: true, - expectedLogEntries: []string{ - "wait until 'return undefined' is true before print", - }, - }, - { - scenario: "wait for expression", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - html := ` - -` - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte(html), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: ScreenshotOptions{ - Options: Options{WaitForExpression: "window.globalVar === 'ready'"}, - }, - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "wait until 'window.globalVar === 'ready'' is true before print", - }, - }, - { - scenario: "success (default options)", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Default options

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: DefaultScreenshotOptions(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "cache not cleared", - "cookies not cleared", - "JavaScript not disabled", - "no user agent override", - "no extra HTTP headers", - "navigate to", - "default white background not hidden", - "no emulated media type", - "no wait delay", - "no wait expression", - "set device metrics override", - }, - }, - { - scenario: "success (clip)", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Default options

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Clip = true - return options - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "cache not cleared", - "cookies not cleared", - "JavaScript not disabled", - "no cookies to set", - "no user agent override", - "no extra HTTP headers", - "navigate to", - "default white background not hidden", - "no emulated media type", - "no wait delay", - "no wait expression", - "set device metrics override", - }, - }, - { - scenario: "success (jpeg)", - browser: newChromiumBrowser( - browserArguments{ - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - wsUrlReadTimeout: 5 * time.Second, - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", fs.WorkingDirPath()), []byte("

Default options

"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Format = "jpeg" - return options - }(), - noDeadline: false, - start: true, - expectError: false, - expectedLogEntries: []string{ - "cache not cleared", - "cookies not cleared", - "JavaScript not disabled", - "no cookies to set", - "no user agent override", - "no extra HTTP headers", - "navigate to", - "skipping network idle event", - "default white background not hidden", - "no emulated media type", - "no wait delay", - "no wait expression", - "set device metrics override", - }, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - core, recorded := observer.New(zapcore.DebugLevel) - logger := zap.New(core) - - defer func() { - err := os.RemoveAll(tc.fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }() - - if tc.start { - err := tc.browser.Start(logger) - if err != nil { - t.Fatalf("setup error: %v", err) - } - - defer func(b browser, logger *zap.Logger) { - err = b.Stop(logger) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }(tc.browser, logger) - } - - var ( - ctx context.Context - cancel context.CancelFunc - ) - - if tc.noDeadline { - ctx = context.Background() - } else { - ctx, cancel = context.WithTimeout(context.Background(), time.Duration(5)*time.Second) - defer cancel() - } - - url := fmt.Sprintf("file://%s/index.html", tc.fs.WorkingDirPath()) - if tc.url != "" { - url = tc.url - } - - err := tc.browser.screenshot( - ctx, - logger, - url, - fmt.Sprintf("%s/%s.pdf", tc.fs.WorkingDirPath(), uuid.NewString()), - tc.options, - ) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectedError != nil && !errors.Is(err, tc.expectedError) { - t.Fatalf("expected error %v but got: %v", tc.expectedError, err) - } - - for _, entry := range tc.expectedLogEntries { - doExist := true - for _, log := range recorded.All() { - doExist = strings.Contains(log.Message, entry) - if doExist { - break - } - } - - if !doExist { - t.Errorf("expected '%s' to exist as log entry", entry) - } - } - }) - } -} diff --git a/pkg/modules/chromium/chromium_test.go b/pkg/modules/chromium/chromium_test.go deleted file mode 100644 index 720bc943..00000000 --- a/pkg/modules/chromium/chromium_test.go +++ /dev/null @@ -1,637 +0,0 @@ -package chromium - -import ( - "context" - "errors" - "os" - "reflect" - "testing" - "time" - - "github.com/alexliesenfeld/health" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestDefaultOptions(t *testing.T) { - actual := DefaultOptions() - notExpect := Options{} - - if reflect.DeepEqual(actual, notExpect) { - t.Errorf("expected %v and got identical %v", actual, notExpect) - } -} - -func TestDefaultPdfOptions(t *testing.T) { - actual := DefaultPdfOptions() - notExpect := PdfOptions{} - - if reflect.DeepEqual(actual, notExpect) { - t.Errorf("expected %v and got identical %v", actual, notExpect) - } -} - -func TestDefaultScreenshotOptions(t *testing.T) { - actual := DefaultScreenshotOptions() - notExpect := ScreenshotOptions{} - - if reflect.DeepEqual(actual, notExpect) { - t.Errorf("expected %v and got identical %v", actual, notExpect) - } -} - -func TestChromium_Descriptor(t *testing.T) { - descriptor := new(Chromium).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(Chromium)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestChromium_Provision(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *gotenberg.Context - expectError bool - }{ - { - scenario: "no logger provider", - ctx: func() *gotenberg.Context { - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Chromium).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{}, - ) - }(), - expectError: true, - }, - { - scenario: "no logger from logger provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.LoggerProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod }} - } - mod.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) { - return nil, errors.New("foo") - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Chromium).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "no PDF engine provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.LoggerProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod }} - } - mod.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) { - return zap.NewNop(), nil - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Chromium).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "no PDF engine from PDF engine provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.LoggerProviderMock - gotenberg.PdfEngineProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod }} - } - mod.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) { - return zap.NewNop(), nil - } - mod.PdfEngineMock = func() (gotenberg.PdfEngine, error) { - return nil, errors.New("foo") - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Chromium).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "provision success", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.LoggerProviderMock - gotenberg.PdfEngineProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod }} - } - mod.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) { - return zap.NewNop(), nil - } - mod.PdfEngineMock = func() (gotenberg.PdfEngine, error) { - return new(gotenberg.PdfEngineMock), nil - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Chromium).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Chromium) - err := mod.Provision(tc.ctx) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestChromium_Validate(t *testing.T) { - for _, tc := range []struct { - scenario string - binPath string - expectError bool - }{ - { - scenario: "empty bin path", - binPath: "", - expectError: true, - }, - { - scenario: "bin path does not exist", - binPath: "/foo", - expectError: true, - }, - { - scenario: "validate success", - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Chromium) - mod.args = browserArguments{ - binPath: tc.binPath, - } - err := mod.Validate() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestChromium_Start(t *testing.T) { - for _, tc := range []struct { - scenario string - autoStart bool - supervisor *gotenberg.ProcessSupervisorMock - expectError bool - }{ - { - scenario: "no auto-start", - autoStart: false, - expectError: false, - }, - { - scenario: "auto-start success", - autoStart: true, - supervisor: &gotenberg.ProcessSupervisorMock{LaunchMock: func() error { - return nil - }}, - expectError: false, - }, - { - scenario: "auto-start failed", - autoStart: true, - supervisor: &gotenberg.ProcessSupervisorMock{LaunchMock: func() error { - return errors.New("foo") - }}, - expectError: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Chromium) - mod.autoStart = tc.autoStart - mod.supervisor = tc.supervisor - - err := mod.Start() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestChromium_StartupMessage(t *testing.T) { - mod := new(Chromium) - - mod.autoStart = true - autoStartMsg := mod.StartupMessage() - - mod.autoStart = false - noAutoStartMsg := mod.StartupMessage() - - if autoStartMsg == noAutoStartMsg { - t.Errorf("expected differrent startup messages based on auto start, but got '%s'", autoStartMsg) - } -} - -func TestChromium_Stop(t *testing.T) { - for _, tc := range []struct { - scenario string - supervisor *gotenberg.ProcessSupervisorMock - expectError bool - }{ - { - scenario: "stop success", - supervisor: &gotenberg.ProcessSupervisorMock{ShutdownMock: func() error { - return nil - }}, - expectError: false, - }, - { - scenario: "stop failed", - supervisor: &gotenberg.ProcessSupervisorMock{ShutdownMock: func() error { - return errors.New("foo") - }}, - expectError: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Chromium) - mod.logger = zap.NewNop() - mod.supervisor = tc.supervisor - - ctx, cancel := context.WithTimeout(context.Background(), 0*time.Second) - cancel() - - err := mod.Stop(ctx) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestChromium_Debug(t *testing.T) { - for _, tc := range []struct { - scenario string - mod *Chromium - expect map[string]interface{} - doNotExpect map[string]interface{} - }{ - { - scenario: "cannot determine version", - mod: &Chromium{ - args: browserArguments{ - binPath: "foo", - }, - }, - expect: map[string]interface{}{ - "version": `exec: "foo": executable file not found in $PATH`, - }, - }, - { - scenario: "success", - mod: &Chromium{ - args: browserArguments{ - binPath: "echo", - }, - }, - doNotExpect: map[string]interface{}{ - "version": `exec: "echo": executable file not found in $PATH`, - }, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - d := tc.mod.Debug() - - if tc.expect != nil { - if !reflect.DeepEqual(d, tc.expect) { - t.Errorf("expected '%v' but got '%v'", tc.expect, d) - } - } - - if tc.doNotExpect != nil { - if reflect.DeepEqual(d, tc.doNotExpect) { - t.Errorf("did not expect '%v'", d) - } - } - }) - } -} - -func TestChromium_Metrics(t *testing.T) { - mod := new(Chromium) - mod.supervisor = &gotenberg.ProcessSupervisorMock{ - ReqQueueSizeMock: func() int64 { - return 10 - }, - RestartsCountMock: func() int64 { - return 0 - }, - } - - metrics, err := mod.Metrics() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if len(metrics) != 2 { - t.Fatalf("expected %d metrics, but got %d", 2, len(metrics)) - } - - actual := metrics[0].Read() - if actual != float64(10) { - t.Errorf("expected %f for chromium_requests_queue_size, but got %f", float64(10), actual) - } - - actual = metrics[1].Read() - if actual != float64(0) { - t.Errorf("expected %f for chromium_restarts_count, but got %f", float64(0), actual) - } -} - -func TestChromium_Checks(t *testing.T) { - for _, tc := range []struct { - scenario string - supervisor gotenberg.ProcessSupervisor - expectAvailabilityStatus health.AvailabilityStatus - }{ - { - scenario: "healthy module", - supervisor: &gotenberg.ProcessSupervisorMock{HealthyMock: func() bool { - return true - }}, - expectAvailabilityStatus: health.StatusUp, - }, - { - scenario: "unhealthy module", - supervisor: &gotenberg.ProcessSupervisorMock{HealthyMock: func() bool { - return false - }}, - expectAvailabilityStatus: health.StatusDown, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Chromium) - mod.supervisor = tc.supervisor - - checks, err := mod.Checks() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - checker := health.NewChecker(checks...) - result := checker.Check(context.Background()) - - if result.Status != tc.expectAvailabilityStatus { - t.Errorf("expected '%s' as availability status, but got '%s'", tc.expectAvailabilityStatus, result.Status) - } - }) - } -} - -func TestChromium_Ready(t *testing.T) { - for _, tc := range []struct { - scenario string - autoStart bool - startTimeout time.Duration - browser browser - expectError bool - }{ - { - scenario: "no auto-start", - autoStart: false, - startTimeout: time.Duration(30) * time.Second, - browser: &browserMock{ProcessMock: gotenberg.ProcessMock{HealthyMock: func(logger *zap.Logger) bool { - return false - }}}, - expectError: false, - }, - { - scenario: "auto-start: context done", - autoStart: true, - startTimeout: time.Duration(200) * time.Millisecond, - browser: &browserMock{ProcessMock: gotenberg.ProcessMock{HealthyMock: func(logger *zap.Logger) bool { - return false - }}}, - expectError: true, - }, - { - scenario: "auto-start success", - autoStart: true, - startTimeout: time.Duration(30) * time.Second, - browser: &browserMock{ProcessMock: gotenberg.ProcessMock{HealthyMock: func(logger *zap.Logger) bool { - return true - }}}, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Chromium) - mod.autoStart = tc.autoStart - mod.args = browserArguments{wsUrlReadTimeout: tc.startTimeout} - mod.browser = tc.browser - - err := mod.Ready() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestChromium_Chromium(t *testing.T) { - mod := new(Chromium) - - _, err := mod.Chromium() - if err != nil { - t.Errorf("expected no error but got: %v", err) - } -} - -func TestChromium_Routes(t *testing.T) { - for _, tc := range []struct { - scenario string - expectRoutes int - disableRoutes bool - }{ - { - scenario: "routes not disabled", - expectRoutes: 6, - disableRoutes: false, - }, - { - scenario: "routes disabled", - expectRoutes: 0, - disableRoutes: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Chromium) - mod.disableRoutes = tc.disableRoutes - - routes, err := mod.Routes() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectRoutes != len(routes) { - t.Errorf("expected %d routes but got %d", tc.expectRoutes, len(routes)) - } - }) - } -} - -func TestChromium_Pdf(t *testing.T) { - for _, tc := range []struct { - scenario string - supervisor gotenberg.ProcessSupervisor - browser browser - expectError bool - }{ - { - scenario: "PDF task success", - browser: &browserMock{pdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - expectError: false, - }, - { - scenario: "PDF task error", - browser: &browserMock{pdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return errors.New("PDF task error") - }}, - expectError: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Chromium) - mod.supervisor = &gotenberg.ProcessSupervisorMock{RunMock: func(ctx context.Context, logger *zap.Logger, task func() error) error { - return task() - }} - mod.browser = tc.browser - - err := mod.Pdf(context.Background(), zap.NewNop(), "", "", PdfOptions{}) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestChromium_Screenshot(t *testing.T) { - for _, tc := range []struct { - scenario string - supervisor gotenberg.ProcessSupervisor - browser browser - expectError bool - }{ - { - scenario: "Screenshot task success", - browser: &browserMock{screenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return nil - }}, - expectError: false, - }, - { - scenario: "Screenshot task error", - browser: &browserMock{screenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return errors.New("screenshot task error") - }}, - expectError: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Chromium) - mod.supervisor = &gotenberg.ProcessSupervisorMock{RunMock: func(ctx context.Context, logger *zap.Logger, task func() error) error { - return task() - }} - mod.browser = tc.browser - - err := mod.Screenshot(context.Background(), zap.NewNop(), "", "", ScreenshotOptions{}) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} diff --git a/pkg/modules/chromium/debug_test.go b/pkg/modules/chromium/debug_test.go deleted file mode 100644 index 579f84db..00000000 --- a/pkg/modules/chromium/debug_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package chromium - -import ( - "testing" - - "go.uber.org/zap" -) - -func TestDebugLogger_Write(t *testing.T) { - actual, err := (&debugLogger{logger: zap.NewNop()}).Write([]byte("foo")) - expected := len([]byte("foo")) - - if actual != expected { - t.Errorf("expected %d but got %d", expected, actual) - } - - if err != nil { - t.Errorf("expected not error but got: %v", err) - } -} - -func TestDebugLogger_Printf(t *testing.T) { - (&debugLogger{logger: zap.NewNop()}).Printf("%s", "foo") -} diff --git a/pkg/modules/chromium/mocks_test.go b/pkg/modules/chromium/mocks_test.go deleted file mode 100644 index 1f361a8a..00000000 --- a/pkg/modules/chromium/mocks_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package chromium - -import ( - "context" - "testing" - - "go.uber.org/zap" -) - -func TestApiMock(t *testing.T) { - mock := &ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }, - ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return nil - }, - } - - err := mock.Pdf(context.Background(), zap.NewNop(), "", "", PdfOptions{}) - if err != nil { - t.Errorf("expected no error from ApiMock.Pdf, but got: %v", err) - } - - err = mock.Screenshot(context.Background(), zap.NewNop(), "", "", ScreenshotOptions{}) - if err != nil { - t.Errorf("expected no error from ApiMock.Screenshot, but got: %v", err) - } -} - -func TestBrowserMock(t *testing.T) { - mock := &browserMock{ - pdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }, - screenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return nil - }, - } - - err := mock.pdf(context.Background(), zap.NewNop(), "", "", PdfOptions{}) - if err != nil { - t.Errorf("expected no error from browserMock.pdf, but got: %v", err) - } - - err = mock.screenshot(context.Background(), zap.NewNop(), "", "", ScreenshotOptions{}) - if err != nil { - t.Errorf("expected no error from browserMock.screenshot, but got: %v", err) - } -} diff --git a/pkg/modules/chromium/routes_test.go b/pkg/modules/chromium/routes_test.go deleted file mode 100644 index 552e55ca..00000000 --- a/pkg/modules/chromium/routes_test.go +++ /dev/null @@ -1,1927 +0,0 @@ -package chromium - -import ( - "context" - "errors" - "fmt" - "net/http" - "os" - "reflect" - "sort" - "testing" - - "github.com/dlclark/regexp2" - "github.com/google/uuid" - "github.com/labstack/echo/v4" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" - "github.com/gotenberg/gotenberg/v8/pkg/modules/api" -) - -func TestFormDataChromiumOptions(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - expectedOptions Options - compareWithoutDeepEqual bool - expectValidationError bool - }{ - { - scenario: "no custom form fields", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectedOptions: DefaultOptions(), - compareWithoutDeepEqual: false, - expectValidationError: false, - }, - { - scenario: "invalid failOnHttpStatusCodes form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "failOnHttpStatusCodes": { - "foo", - }, - }) - return ctx - }(), - expectedOptions: func() Options { - options := DefaultOptions() - options.FailOnHttpStatusCodes = nil - return options - }(), - compareWithoutDeepEqual: false, - expectValidationError: true, - }, - { - scenario: "valid failOnHttpStatusCodes form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "failOnHttpStatusCodes": { - `[399,499,599]`, - }, - }) - return ctx - }(), - expectedOptions: func() Options { - options := DefaultOptions() - options.FailOnHttpStatusCodes = []int64{399, 499, 599} - return options - }(), - compareWithoutDeepEqual: false, - expectValidationError: false, - }, - { - scenario: "invalid failOnResourceHttpStatusCodes form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "failOnResourceHttpStatusCodes": { - "foo", - }, - }) - return ctx - }(), - expectedOptions: func() Options { - options := DefaultOptions() - options.FailOnResourceHttpStatusCodes = nil - return options - }(), - compareWithoutDeepEqual: false, - expectValidationError: true, - }, - { - scenario: "valid failOnResourceHttpStatusCodes form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "failOnResourceHttpStatusCodes": { - `[399,499,599]`, - }, - }) - return ctx - }(), - expectedOptions: func() Options { - options := DefaultOptions() - options.FailOnResourceHttpStatusCodes = []int64{399, 499, 599} - return options - }(), - compareWithoutDeepEqual: false, - expectValidationError: false, - }, - { - scenario: "invalid cookies form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "cookies": { - "foo", - }, - }) - return ctx - }(), - expectedOptions: DefaultOptions(), - compareWithoutDeepEqual: false, - expectValidationError: true, - }, - { - scenario: "invalid cookies form field (missing required values)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "cookies": { - "[{}]", - }, - }) - return ctx - }(), - expectedOptions: func() Options { - options := DefaultOptions() - // No validation in this method, so it still instantiates - // an empty item. - options.Cookies = []Cookie{{}} - return options - }(), - compareWithoutDeepEqual: false, - expectValidationError: true, - }, - { - scenario: "valid cookies form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "cookies": { - `[{"name":"foo","value":"bar","domain":".foo.bar"}]`, - }, - }) - return ctx - }(), - expectedOptions: func() Options { - options := DefaultOptions() - options.Cookies = []Cookie{{ - Name: "foo", - Value: "bar", - Domain: ".foo.bar", - }} - return options - }(), - compareWithoutDeepEqual: false, - expectValidationError: false, - }, - { - scenario: "invalid extraHttpHeaders form field: cannot unmarshall", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "extraHttpHeaders": { - "foo", - }, - }) - return ctx - }(), - expectedOptions: DefaultOptions(), - compareWithoutDeepEqual: false, - expectValidationError: true, - }, - { - scenario: "invalid extraHttpHeaders form field: invalid scope", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "extraHttpHeaders": { - `{"foo":"bar;scope;;"}`, - }, - }) - return ctx - }(), - expectedOptions: DefaultOptions(), - compareWithoutDeepEqual: false, - expectValidationError: true, - }, - { - scenario: "invalid extraHttpHeaders form field: invalid scope regex pattern", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "extraHttpHeaders": { - `{"foo":"bar;scope=*."}`, - }, - }) - return ctx - }(), - expectedOptions: DefaultOptions(), - compareWithoutDeepEqual: false, - expectValidationError: true, - }, - { - scenario: "valid extraHttpHeaders form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "extraHttpHeaders": { - `{"foo":"bar","baz":"qux;scope=https?:\\/\\/([a-zA-Z0-9-]+\\.)*qux\\.com\\/.*"}`, - }, - }) - return ctx - }(), - expectedOptions: func() Options { - options := DefaultOptions() - options.ExtraHttpHeaders = []ExtraHttpHeader{ - { - Name: "foo", - Value: "bar", - }, - { - Name: "baz", - Value: "qux", - Scope: regexp2.MustCompile(`https?:\/\/([a-zA-Z0-9-]+\.)*qux\.com\/.*`, 0), - }, - } - return options - }(), - compareWithoutDeepEqual: true, - expectValidationError: false, - }, - { - scenario: "invalid emulatedMediaType form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "emulatedMediaType": { - "foo", - }, - }) - return ctx - }(), - expectedOptions: DefaultOptions(), - expectValidationError: true, - }, - { - scenario: "valid emulatedMediaType form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "emulatedMediaType": { - "screen", - }, - }) - return ctx - }(), - expectedOptions: func() Options { - options := DefaultOptions() - options.EmulatedMediaType = "screen" - return options - }(), - expectValidationError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - form, actual := FormDataChromiumOptions(tc.ctx.Context) - - if tc.compareWithoutDeepEqual { - if len(tc.expectedOptions.ExtraHttpHeaders) != len(actual.ExtraHttpHeaders) { - t.Fatalf("expected %d extra HTTP headers, but got %d", len(tc.expectedOptions.ExtraHttpHeaders), len(actual.ExtraHttpHeaders)) - } - - sort.Slice(tc.expectedOptions.ExtraHttpHeaders, func(i, j int) bool { - return tc.expectedOptions.ExtraHttpHeaders[i].Name < tc.expectedOptions.ExtraHttpHeaders[j].Name - }) - sort.Slice(actual.ExtraHttpHeaders, func(i, j int) bool { - return actual.ExtraHttpHeaders[i].Name < actual.ExtraHttpHeaders[j].Name - }) - - for i := range tc.expectedOptions.ExtraHttpHeaders { - if tc.expectedOptions.ExtraHttpHeaders[i].Name != actual.ExtraHttpHeaders[i].Name { - t.Fatalf("expected '%s' extra HTTP header, but got '%s'", tc.expectedOptions.ExtraHttpHeaders[i].Name, tc.expectedOptions.ExtraHttpHeaders[i].Name) - } - - if tc.expectedOptions.ExtraHttpHeaders[i].Value != actual.ExtraHttpHeaders[i].Value { - t.Fatalf("expected '%s' as value for extra HTTP header '%s', but got '%s'", tc.expectedOptions.ExtraHttpHeaders[i].Value, tc.expectedOptions.ExtraHttpHeaders[i].Name, actual.ExtraHttpHeaders[i].Value) - } - - var expectedScope string - if tc.expectedOptions.ExtraHttpHeaders[i].Scope != nil { - expectedScope = tc.expectedOptions.ExtraHttpHeaders[i].Scope.String() - } - var actualScope string - if actual.ExtraHttpHeaders[i].Scope != nil { - actualScope = actual.ExtraHttpHeaders[i].Scope.String() - } - - if expectedScope != actualScope { - t.Fatalf("expected '%s' as scope for extra HTTP header '%s', but got '%s'", expectedScope, tc.expectedOptions.ExtraHttpHeaders[i].Name, actualScope) - } - } - } else { - if !reflect.DeepEqual(actual, tc.expectedOptions) { - t.Fatalf("expected %+v but got: %+v", tc.expectedOptions, actual) - } - } - - err := form.Validate() - - if tc.expectValidationError && err == nil { - t.Fatal("expected validation error but got none", err) - } - - if !tc.expectValidationError && err != nil { - t.Fatalf("expected no validation error but got: %v", err) - } - }) - } -} - -func TestFormDataChromiumPdfOptions(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - expectedOptions PdfOptions - expectValidationError bool - }{ - { - scenario: "no custom form fields", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectedOptions: DefaultPdfOptions(), - expectValidationError: false, - }, - { - scenario: "custom form fields (Options & PdfOptions)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "landscape": { - "true", - }, - "emulatedMediaType": { - "screen", - }, - }) - return ctx - }(), - expectedOptions: func() PdfOptions { - options := DefaultPdfOptions() - options.Landscape = true - options.EmulatedMediaType = "screen" - return options - }(), - expectValidationError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - form, actual := FormDataChromiumPdfOptions(tc.ctx.Context) - - if !reflect.DeepEqual(actual, tc.expectedOptions) { - t.Fatalf("expected %+v but got: %+v", tc.expectedOptions, actual) - } - - err := form.Validate() - - if tc.expectValidationError && err == nil { - t.Fatal("expected validation error but got none", err) - } - - if !tc.expectValidationError && err != nil { - t.Fatalf("expected no validation error but got: %v", err) - } - }) - } -} - -func TestFormDataChromiumScreenshotOptions(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - expectedOptions ScreenshotOptions - expectValidationError bool - }{ - { - scenario: "no custom form fields", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectedOptions: DefaultScreenshotOptions(), - expectValidationError: false, - }, - { - scenario: "invalid format form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "format": { - "gif", - }, - }) - return ctx - }(), - expectedOptions: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Format = "" - return options - }(), - expectValidationError: true, - }, - { - scenario: "valid png format form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "format": { - "png", - }, - }) - return ctx - }(), - expectedOptions: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Format = "png" - return options - }(), - expectValidationError: false, - }, - { - scenario: "valid jpeg format form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "format": { - "jpeg", - }, - }) - return ctx - }(), - expectedOptions: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Format = "jpeg" - return options - }(), - expectValidationError: false, - }, - { - scenario: "valid webp format form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "format": { - "webp", - }, - }) - return ctx - }(), - expectedOptions: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Format = "webp" - return options - }(), - expectValidationError: false, - }, - { - scenario: "invalid quality form field (not an integer)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "quality": { - "foo", - }, - }) - return ctx - }(), - expectedOptions: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Quality = 0 - return options - }(), - expectValidationError: true, - }, - { - scenario: "invalid quality form field (< 0)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "quality": { - "-1", - }, - }) - return ctx - }(), - expectedOptions: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Quality = 0 - return options - }(), - expectValidationError: true, - }, - { - scenario: "invalid quality form field (> 100)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "quality": { - "101", - }, - }) - return ctx - }(), - expectedOptions: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Quality = 0 - return options - }(), - expectValidationError: true, - }, - { - scenario: "valid quality form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "quality": { - "50", - }, - }) - return ctx - }(), - expectedOptions: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Quality = 50 - return options - }(), - expectValidationError: false, - }, - { - scenario: "custom form fields (Options & ScreenshotOptions)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "width": { - "1280", - }, - "height": { - "800", - }, - "clip": { - "true", - }, - "optimizeForSpeed": { - "true", - }, - "emulatedMediaType": { - "screen", - }, - }) - return ctx - }(), - expectedOptions: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.Width = 1280 - options.Height = 800 - options.Clip = true - options.OptimizeForSpeed = true - options.EmulatedMediaType = "screen" - return options - }(), - expectValidationError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - form, actual := FormDataChromiumScreenshotOptions(tc.ctx.Context) - - if !reflect.DeepEqual(actual, tc.expectedOptions) { - t.Fatalf("expected %+v but got: %+v", tc.expectedOptions, actual) - } - - err := form.Validate() - - if tc.expectValidationError && err == nil { - t.Fatal("expected validation error but got none", err) - } - - if !tc.expectValidationError && err != nil { - t.Fatalf("expected no validation error but got: %v", err) - } - }) - } -} - -func TestConvertUrlRoute(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - api Api - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - }{ - { - scenario: "missing mandatory url form field", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "empty url form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "url": { - "", - }, - }) - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "error from Chromium", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "url": { - "foo", - }, - }) - return ctx - }(), - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return errors.New("foo") - }}, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "url": { - "foo", - }, - }) - return ctx - }(), - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := convertUrlRoute(tc.api, nil).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - }) - } -} - -func TestScreenshotUrlRoute(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - api Api - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - }{ - { - scenario: "missing mandatory url form field", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "empty url form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "url": { - "", - }, - }) - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "error from Chromium", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "url": { - "foo", - }, - }) - return ctx - }(), - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return errors.New("foo") - }}, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "url": { - "foo", - }, - }) - return ctx - }(), - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return nil - }}, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := screenshotUrlRoute(tc.api).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - }) - } -} - -func TestConvertHtmlRoute(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - api Api - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - }{ - { - scenario: "missing mandatory index.html form file", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "error from Chromium", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "index.html": "/index.html", - }) - return ctx - }(), - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return errors.New("foo") - }}, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "index.html": "/index.html", - }) - return ctx - }(), - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := convertHtmlRoute(tc.api, nil).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - }) - } -} - -func TestScreenshotHtmlRoute(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - api Api - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - }{ - { - scenario: "missing mandatory index.html form file", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "error from Chromium", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "index.html": "/index.html", - }) - return ctx - }(), - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return errors.New("foo") - }}, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "index.html": "/index.html", - }) - return ctx - }(), - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return nil - }}, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := screenshotHtmlRoute(tc.api).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - }) - } -} - -func TestConvertMarkdownRoute(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - api Api - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - }{ - { - scenario: "missing mandatory index.html form file", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "missing mandatory markdown form files", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "index.html": "/index.html", - }) - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "markdown file requested in index.html not found", - ctx: func() *api.ContextMock { - dirPath := fmt.Sprintf("%s/%s", os.TempDir(), uuid.NewString()) - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetDirPath(dirPath) - ctx.SetFiles(map[string]string{ - "index.html": fmt.Sprintf("%s/index.html", dirPath), - "wrong_name.md": fmt.Sprintf("%s/wrong_name.md", dirPath), - }) - - err := os.MkdirAll(dirPath, 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", dirPath), []byte("
{{ toHTML \"markdown.md\" }}
"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "non-existing markdown file", - ctx: func() *api.ContextMock { - dirPath := fmt.Sprintf("%s/%s", os.TempDir(), uuid.NewString()) - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetDirPath(dirPath) - ctx.SetFiles(map[string]string{ - "index.html": fmt.Sprintf("%s/index.html", dirPath), - "markdown.md": fmt.Sprintf("%s/markdown.md", dirPath), - }) - - err := os.MkdirAll(dirPath, 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", dirPath), []byte("
{{ toHTML \"markdown.md\" }}
"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return ctx - }(), - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "error from Chromium", - ctx: func() *api.ContextMock { - dirPath := fmt.Sprintf("%s/%s", os.TempDir(), uuid.NewString()) - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetDirPath(dirPath) - ctx.SetFiles(map[string]string{ - "index.html": fmt.Sprintf("%s/index.html", dirPath), - "markdown.md": fmt.Sprintf("%s/markdown.md", dirPath), - }) - - err := os.MkdirAll(dirPath, 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", dirPath), []byte("
{{ toHTML \"markdown.md\" }}
"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/markdown.md", dirPath), []byte("# Hello World!"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return ctx - }(), - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return errors.New("foo") - }}, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: func() *api.ContextMock { - dirPath := fmt.Sprintf("%s/%s", os.TempDir(), uuid.NewString()) - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetDirPath(dirPath) - ctx.SetFiles(map[string]string{ - "index.html": fmt.Sprintf("%s/index.html", dirPath), - "markdown.md": fmt.Sprintf("%s/markdown.md", dirPath), - }) - - err := os.MkdirAll(dirPath, 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", dirPath), []byte("
{{ toHTML \"markdown.md\" }}
"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/markdown.md", dirPath), []byte("# Hello World!"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return ctx - }(), - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - if tc.ctx.DirPath() != "" { - defer func() { - err := os.RemoveAll(tc.ctx.DirPath()) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - } - - tc.ctx.SetLogger(zap.NewNop()) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := convertMarkdownRoute(tc.api, nil).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - }) - } -} - -func TestScreenshotMarkdownRoute(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - api Api - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - }{ - { - scenario: "missing mandatory index.html form file", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "missing mandatory markdown form files", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "index.html": "/index.html", - }) - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "markdown file requested in index.html not found", - ctx: func() *api.ContextMock { - dirPath := fmt.Sprintf("%s/%s", os.TempDir(), uuid.NewString()) - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetDirPath(dirPath) - ctx.SetFiles(map[string]string{ - "index.html": fmt.Sprintf("%s/index.html", dirPath), - "wrong_name.md": fmt.Sprintf("%s/wrong_name.md", dirPath), - }) - - err := os.MkdirAll(dirPath, 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", dirPath), []byte("
{{ toHTML \"markdown.md\" }}
"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "non-existing markdown file", - ctx: func() *api.ContextMock { - dirPath := fmt.Sprintf("%s/%s", os.TempDir(), uuid.NewString()) - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetDirPath(dirPath) - ctx.SetFiles(map[string]string{ - "index.html": fmt.Sprintf("%s/index.html", dirPath), - "markdown.md": fmt.Sprintf("%s/markdown.md", dirPath), - }) - - err := os.MkdirAll(dirPath, 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", dirPath), []byte("
{{ toHTML \"markdown.md\" }}
"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return ctx - }(), - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "error from Chromium", - ctx: func() *api.ContextMock { - dirPath := fmt.Sprintf("%s/%s", os.TempDir(), uuid.NewString()) - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetDirPath(dirPath) - ctx.SetFiles(map[string]string{ - "index.html": fmt.Sprintf("%s/index.html", dirPath), - "markdown.md": fmt.Sprintf("%s/markdown.md", dirPath), - }) - - err := os.MkdirAll(dirPath, 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", dirPath), []byte("
{{ toHTML \"markdown.md\" }}
"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/markdown.md", dirPath), []byte("# Hello World!"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return ctx - }(), - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return errors.New("foo") - }}, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: func() *api.ContextMock { - dirPath := fmt.Sprintf("%s/%s", os.TempDir(), uuid.NewString()) - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetDirPath(dirPath) - ctx.SetFiles(map[string]string{ - "index.html": fmt.Sprintf("%s/index.html", dirPath), - "markdown.md": fmt.Sprintf("%s/markdown.md", dirPath), - }) - - err := os.MkdirAll(dirPath, 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/index.html", dirPath), []byte("
{{ toHTML \"markdown.md\" }}
"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/markdown.md", dirPath), []byte("# Hello World!"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return ctx - }(), - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return nil - }}, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - if tc.ctx.DirPath() != "" { - defer func() { - err := os.RemoveAll(tc.ctx.DirPath()) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - } - - tc.ctx.SetLogger(zap.NewNop()) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := screenshotMarkdownRoute(tc.api).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - }) - } -} - -func TestConvertUrl(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - api Api - engine gotenberg.PdfEngine - options PdfOptions - splitMode gotenberg.SplitMode - pdfFormats gotenberg.PdfFormats - metadata map[string]interface{} - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - }{ - { - scenario: "ErrOmitBackgroundWithoutPrintBackground", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return ErrOmitBackgroundWithoutPrintBackground - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrInvalidEvaluationExpression (without waitForExpression form field)", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return ErrInvalidEvaluationExpression - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrInvalidEvaluationExpression (with waitForExpression form field)", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return ErrInvalidEvaluationExpression - }}, - options: func() PdfOptions { - options := DefaultPdfOptions() - options.WaitForExpression = "foo" - - return options - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrInvalidPrinterSettings", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return ErrInvalidPrinterSettings - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrPageRangesSyntaxError", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return ErrPageRangesSyntaxError - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrInvalidHttpStatusCode", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return ErrInvalidHttpStatusCode - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusConflict, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrInvalidResourceHttpStatusCode", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return ErrInvalidResourceHttpStatusCode - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusConflict, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrConsoleExceptions", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return ErrConsoleExceptions - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusConflict, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrLoadingFailed", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return ErrLoadingFailed - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrResourceLoadingFailed", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return ErrResourceLoadingFailed - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusConflict, - expectOutputPathsCount: 0, - }, - { - scenario: "error from Chromium", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return errors.New("foo") - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "PDF engine split error", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - engine: &gotenberg.PdfEngineMock{SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return nil, errors.New("foo") - }}, - options: DefaultPdfOptions(), - splitMode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1"}, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success with split mode", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - engine: &gotenberg.PdfEngineMock{SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return []string{inputPath}, nil - }}, - options: DefaultPdfOptions(), - splitMode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1"}, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - { - scenario: "PDF engine convert error", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - engine: &gotenberg.PdfEngineMock{ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return errors.New("foo") - }}, - options: DefaultPdfOptions(), - pdfFormats: gotenberg.PdfFormats{PdfA: "foo"}, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success with PDF formats", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - engine: &gotenberg.PdfEngineMock{ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }}, - options: DefaultPdfOptions(), - pdfFormats: gotenberg.PdfFormats{PdfA: gotenberg.PdfA1b}, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - { - scenario: "success with split mode and PDF formats", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return []string{inputPath}, nil - }, - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - }, - options: DefaultPdfOptions(), - splitMode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1"}, - pdfFormats: gotenberg.PdfFormats{PdfA: gotenberg.PdfA1b}, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - { - scenario: "PDF engine write metadata error", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - engine: &gotenberg.PdfEngineMock{WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return errors.New("foo") - }}, - options: DefaultPdfOptions(), - metadata: map[string]interface{}{ - "Creator": "foo", - "Producer": "bar", - }, - expectError: true, - expectHttpError: false, - }, - { - scenario: "cannot add output paths", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetCancelled(true) - return ctx - }(), - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - options: DefaultPdfOptions(), - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{PdfMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options PdfOptions) error { - return nil - }}, - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return nil - }, - }, - options: DefaultPdfOptions(), - pdfFormats: gotenberg.PdfFormats{PdfA: gotenberg.PdfA1b}, - metadata: map[string]interface{}{ - "Creator": "foo", - "Producer": "bar", - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - tc.ctx.SetMkdirAll(&gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error { - return nil - }}) - tc.ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return nil - }}) - err := convertUrl(tc.ctx.Context, tc.api, tc.engine, "", tc.options, tc.splitMode, tc.pdfFormats, tc.metadata) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - }) - } -} - -func TestScreenshotUrl(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - api Api - options ScreenshotOptions - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - }{ - { - scenario: "ErrInvalidEvaluationExpression (without waitForExpression form field)", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return ErrInvalidEvaluationExpression - }}, - options: DefaultScreenshotOptions(), - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrInvalidEvaluationExpression (with waitForExpression form field)", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return ErrInvalidEvaluationExpression - }}, - options: func() ScreenshotOptions { - options := DefaultScreenshotOptions() - options.WaitForExpression = "foo" - - return options - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrInvalidHttpStatusCode", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return ErrInvalidHttpStatusCode - }}, - options: DefaultScreenshotOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusConflict, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrInvalidResourceHttpStatusCode", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return ErrInvalidResourceHttpStatusCode - }}, - options: DefaultScreenshotOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusConflict, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrConsoleExceptions", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return ErrConsoleExceptions - }}, - options: DefaultScreenshotOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusConflict, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrLoadingFailed", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return ErrLoadingFailed - }}, - options: DefaultScreenshotOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrResourceLoadingFailed", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return ErrResourceLoadingFailed - }}, - options: DefaultScreenshotOptions(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusConflict, - expectOutputPathsCount: 0, - }, - { - scenario: "error from Chromium", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return errors.New("foo") - }}, - options: DefaultScreenshotOptions(), - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "cannot add output paths", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetCancelled(true) - return ctx - }(), - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return nil - }}, - options: DefaultScreenshotOptions(), - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: &api.ContextMock{Context: new(api.Context)}, - api: &ApiMock{ScreenshotMock: func(ctx context.Context, logger *zap.Logger, url, outputPath string, options ScreenshotOptions) error { - return nil - }}, - options: DefaultScreenshotOptions(), - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - err := screenshotUrl(tc.ctx.Context, tc.api, "", tc.options) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - }) - } -} diff --git a/pkg/modules/exiftool/exiftool_test.go b/pkg/modules/exiftool/exiftool_test.go deleted file mode 100644 index 87576b69..00000000 --- a/pkg/modules/exiftool/exiftool_test.go +++ /dev/null @@ -1,415 +0,0 @@ -package exiftool - -import ( - "context" - "errors" - "fmt" - "io" - "os" - "reflect" - "testing" - - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestExifTool_Descriptor(t *testing.T) { - descriptor := new(ExifTool).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(ExifTool)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestExifTool_Provision(t *testing.T) { - engine := new(ExifTool) - ctx := gotenberg.NewContext(gotenberg.ParsedFlags{}, nil) - - err := engine.Provision(ctx) - if err != nil { - t.Errorf("expected no error but got: %v", err) - } -} - -func TestExifTool_Validate(t *testing.T) { - for _, tc := range []struct { - scenario string - binPath string - expectError bool - }{ - { - scenario: "empty bin path", - binPath: "", - expectError: true, - }, - { - scenario: "bin path does not exist", - binPath: "/foo", - expectError: true, - }, - { - scenario: "validate success", - binPath: os.Getenv("EXIFTOOL_BIN_PATH"), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(ExifTool) - engine.binPath = tc.binPath - err := engine.Validate() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestExifTool_Debug(t *testing.T) { - for _, tc := range []struct { - scenario string - engine *ExifTool - expect map[string]interface{} - doNotExpect map[string]interface{} - }{ - { - scenario: "cannot determine version", - engine: &ExifTool{ - binPath: "foo", - }, - expect: map[string]interface{}{ - "version": `exec: "foo": executable file not found in $PATH`, - }, - }, - { - scenario: "success", - engine: &ExifTool{ - binPath: "echo", - }, - doNotExpect: map[string]interface{}{ - "version": `exec: "echo": executable file not found in $PATH`, - }, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - d := tc.engine.Debug() - - if tc.expect != nil { - if !reflect.DeepEqual(d, tc.expect) { - t.Errorf("expected '%v' but got '%v'", tc.expect, d) - } - } - - if tc.doNotExpect != nil { - if reflect.DeepEqual(d, tc.doNotExpect) { - t.Errorf("did not expect '%v'", d) - } - } - }) - } -} - -func TestExiftool_Merge(t *testing.T) { - engine := new(ExifTool) - err := engine.Merge(context.Background(), zap.NewNop(), nil, "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestExiftool_Split(t *testing.T) { - engine := new(ExifTool) - _, err := engine.Split(context.Background(), zap.NewNop(), gotenberg.SplitMode{}, "", "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestExiftool_Flatten(t *testing.T) { - engine := new(ExifTool) - err := engine.Flatten(context.Background(), zap.NewNop(), "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestExiftool_Convert(t *testing.T) { - engine := new(ExifTool) - err := engine.Convert(context.Background(), zap.NewNop(), gotenberg.PdfFormats{}, "", "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestExiftool_ReadMetadata(t *testing.T) { - for _, tc := range []struct { - scenario string - inputPath string - expectMetadata map[string]interface{} - expectError bool - }{ - { - scenario: "invalid input path", - inputPath: "foo", - expectMetadata: nil, - expectError: true, - }, - { - scenario: "success", - inputPath: "/tests/test/testdata/pdfengines/sample1.pdf", - expectMetadata: map[string]interface{}{ - "FileName": "sample1.pdf", - "FileTypeExtension": "pdf", - "MIMEType": "application/pdf", - "PDFVersion": 1.4, - "PageCount": float64(3), - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(ExifTool) - err := engine.Provision(nil) - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - metadata, err := engine.ReadMetadata(context.Background(), zap.NewNop(), tc.inputPath) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectMetadata != nil && err == nil { - for k, v := range tc.expectMetadata { - if v2, ok := metadata[k]; !ok || v != v2 { - t.Errorf("expected entry %s with value %v to exists", k, v) - } - } - } - }) - } -} - -func TestExiftool_WriteMetadata(t *testing.T) { - for _, tc := range []struct { - scenario string - createCopy bool - inputPath string - metadata map[string]interface{} - expectMetadata map[string]interface{} - expectError bool - expectedError error - }{ - { - scenario: "invalid input path", - createCopy: false, - inputPath: "foo", - expectError: true, - }, - { - scenario: "gotenberg.ErrPdfEngineMetadataValueNotSupported (not string array)", - createCopy: true, - inputPath: "/tests/test/testdata/pdfengines/sample1.pdf", - metadata: map[string]interface{}{ - "Unsupported": []interface{}{ - "foo", - 1, - }, - }, - expectError: true, - expectedError: gotenberg.ErrPdfEngineMetadataValueNotSupported, - }, - { - scenario: "gotenberg.ErrPdfEngineMetadataValueNotSupported (default)", - createCopy: true, - inputPath: "/tests/test/testdata/pdfengines/sample1.pdf", - metadata: map[string]interface{}{ - "Unsupported": map[string]interface{}{}, - }, - expectError: true, - expectedError: gotenberg.ErrPdfEngineMetadataValueNotSupported, - }, - { - scenario: "success (interface array to string array)", - createCopy: true, - inputPath: "/tests/test/testdata/pdfengines/sample1.pdf", - metadata: map[string]interface{}{ - "Keywords": []interface{}{ - "first", - "second", - }, - }, - expectMetadata: map[string]interface{}{ - "Keywords": []interface{}{ - "first", - "second", - }, - }, - expectError: false, - }, - { - scenario: "success", - createCopy: true, - inputPath: "/tests/test/testdata/pdfengines/sample1.pdf", - metadata: map[string]interface{}{ - "Author": "Julien Neuhart", - "Copyright": "Julien Neuhart", - "CreationDate": "2006-09-18T16:27:50-04:00", - "Creator": "Gotenberg", - "Keywords": []string{ - "first", - "second", - }, - "Marked": true, - "ModDate": "2006-09-18T16:27:50-04:00", - "PDFVersion": 1.7, - "Producer": "Gotenberg", - "Subject": "Sample", - "Title": "Sample", - "Trapped": "Unknown", - // Those are not valid PDF metadata. - "int": 1, - "int64": int64(2), - "float32": float32(2.2), - "float64": 3.3, - }, - expectMetadata: map[string]interface{}{ - "Author": "Julien Neuhart", - "Copyright": "Julien Neuhart", - "CreationDate": "2006:09:18 16:27:50-04:00", - "Creator": "Gotenberg", - "Keywords": []interface{}{ - "first", - "second", - }, - "Marked": true, - "ModDate": "2006:09:18 16:27:50-04:00", - "PDFVersion": 1.7, - "Producer": "Gotenberg", - "Subject": "Sample", - "Title": "Sample", - "Trapped": "Unknown", - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(ExifTool) - err := engine.Provision(nil) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var destinationPath string - if tc.createCopy { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - outputDir, err := fs.MkdirAll() - if err != nil { - t.Fatalf("expected error no but got: %v", err) - } - - defer func() { - err = os.RemoveAll(fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up but got: %v", err) - } - }() - - destinationPath = fmt.Sprintf("%s/copy_temp.pdf", outputDir) - source, err := os.Open(tc.inputPath) - if err != nil { - t.Fatalf("open source file: %v", err) - } - - defer func(source *os.File) { - err := source.Close() - if err != nil { - t.Fatalf("close file: %v", err) - } - }(source) - - destination, err := os.Create(destinationPath) - if err != nil { - t.Fatalf("create destination file: %v", err) - } - - defer func(destination *os.File) { - err := destination.Close() - if err != nil { - t.Fatalf("close file: %v", err) - } - }(destination) - - _, err = io.Copy(destination, source) - if err != nil { - t.Fatalf("copy source into destination: %v", err) - } - } else { - destinationPath = tc.inputPath - } - - err = engine.WriteMetadata(context.Background(), zap.NewNop(), tc.metadata, destinationPath) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectedError != nil && !errors.Is(err, tc.expectedError) { - t.Fatalf("expected error %v but got: %v", tc.expectedError, err) - } - - if tc.expectError { - return - } - - metadata, err := engine.ReadMetadata(context.Background(), zap.NewNop(), destinationPath) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectMetadata != nil && err == nil { - for k, v := range tc.expectMetadata { - v2, ok := metadata[k] - if !ok { - t.Errorf("expected entry %s with value %v to exists, but got none", k, v) - continue - } - - switch v2.(type) { - case []interface{}: - for i, entry := range v.([]interface{}) { - if entry != v2.([]interface{})[i] { - t.Errorf("expected entry %s to contain value %v, but got %v", k, entry, v2.([]interface{})[i]) - } - } - default: - if v != v2 { - t.Errorf("expected entry %s with value %v to exists, but got %v", k, v, v2) - } - } - } - } - }) - } -} diff --git a/pkg/modules/libreoffice/api/api_test.go b/pkg/modules/libreoffice/api/api_test.go deleted file mode 100644 index 7df16d9c..00000000 --- a/pkg/modules/libreoffice/api/api_test.go +++ /dev/null @@ -1,522 +0,0 @@ -package api - -import ( - "context" - "errors" - "os" - "reflect" - "testing" - "time" - - "github.com/alexliesenfeld/health" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestDefaultOptions(t *testing.T) { - actual := DefaultOptions() - notExpect := Options{} - - if reflect.DeepEqual(actual, notExpect) { - t.Errorf("expected %v and got identical %v", actual, notExpect) - } -} - -func TestApi_Descriptor(t *testing.T) { - descriptor := new(Api).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(Api)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestApi_Provision(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *gotenberg.Context - expectError bool - }{ - { - scenario: "no logger provider", - ctx: func() *gotenberg.Context { - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{}, - ) - }(), - expectError: true, - }, - { - scenario: "no logger from logger provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.LoggerProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod }} - } - mod.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) { - return nil, errors.New("foo") - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "provision success", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.LoggerProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod }} - } - mod.LoggerMock = func(mod gotenberg.Module) (*zap.Logger, error) { - return zap.NewNop(), nil - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Api).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - a := new(Api) - err := a.Provision(tc.ctx) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestApi_Validate(t *testing.T) { - for _, tc := range []struct { - scenario string - binPath string - unoBinPath string - expectError bool - }{ - { - scenario: "empty LibreOffice bin path", - binPath: "", - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - expectError: true, - }, - { - scenario: "LibreOffice bin path does not exist", - binPath: "/foo", - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - expectError: true, - }, - { - scenario: "empty uno bin path", - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - unoBinPath: "", - expectError: true, - }, - { - scenario: "uno bin path does not exist", - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - unoBinPath: "/foo", - expectError: true, - }, - { - scenario: "validate success", - binPath: os.Getenv("CHROMIUM_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - a := new(Api) - a.args = libreOfficeArguments{ - binPath: tc.binPath, - unoBinPath: tc.unoBinPath, - } - err := a.Validate() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestApi_Start(t *testing.T) { - for _, tc := range []struct { - scenario string - autoStart bool - supervisor *gotenberg.ProcessSupervisorMock - expectError bool - }{ - { - scenario: "no auto-start", - autoStart: false, - expectError: false, - }, - { - scenario: "auto-start success", - autoStart: true, - supervisor: &gotenberg.ProcessSupervisorMock{LaunchMock: func() error { - return nil - }}, - expectError: false, - }, - { - scenario: "auto-start failed", - autoStart: true, - supervisor: &gotenberg.ProcessSupervisorMock{LaunchMock: func() error { - return errors.New("foo") - }}, - expectError: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - a := new(Api) - a.autoStart = tc.autoStart - a.supervisor = tc.supervisor - - err := a.Start() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestApi_StartupMessage(t *testing.T) { - a := new(Api) - - a.autoStart = true - autoStartMsg := a.StartupMessage() - - a.autoStart = false - noAutoStartMsg := a.StartupMessage() - - if autoStartMsg == noAutoStartMsg { - t.Errorf("expected differrent startup messages based on auto start, but got '%s'", autoStartMsg) - } -} - -func TestApi_Stop(t *testing.T) { - for _, tc := range []struct { - scenario string - supervisor *gotenberg.ProcessSupervisorMock - expectError bool - }{ - { - scenario: "stop success", - supervisor: &gotenberg.ProcessSupervisorMock{ShutdownMock: func() error { - return nil - }}, - expectError: false, - }, - { - scenario: "stop failed", - supervisor: &gotenberg.ProcessSupervisorMock{ShutdownMock: func() error { - return errors.New("foo") - }}, - expectError: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - a := new(Api) - a.logger = zap.NewNop() - a.supervisor = tc.supervisor - - ctx, cancel := context.WithTimeout(context.Background(), 0*time.Second) - cancel() - - err := a.Stop(ctx) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestPdfTk_Debug(t *testing.T) { - for _, tc := range []struct { - scenario string - a *Api - expect map[string]interface{} - doNotExpect map[string]interface{} - }{ - { - scenario: "cannot determine version", - a: &Api{ - args: libreOfficeArguments{ - binPath: "foo", - }, - }, - expect: map[string]interface{}{ - "version": `exec: "foo": executable file not found in $PATH`, - }, - }, - { - scenario: "success", - a: &Api{ - args: libreOfficeArguments{ - binPath: "echo", - }, - }, - doNotExpect: map[string]interface{}{ - "version": `exec: "echo": executable file not found in $PATH`, - }, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - d := tc.a.Debug() - - if tc.expect != nil { - if !reflect.DeepEqual(d, tc.expect) { - t.Errorf("expected '%v' but got '%v'", tc.expect, d) - } - } - - if tc.doNotExpect != nil { - if reflect.DeepEqual(d, tc.doNotExpect) { - t.Errorf("did not expect '%v'", d) - } - } - }) - } -} - -func TestApi_Metrics(t *testing.T) { - a := new(Api) - a.supervisor = &gotenberg.ProcessSupervisorMock{ - ReqQueueSizeMock: func() int64 { - return 10 - }, - RestartsCountMock: func() int64 { - return 0 - }, - } - - metrics, err := a.Metrics() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if len(metrics) != 2 { - t.Fatalf("expected %d metrics, but got %d", 2, len(metrics)) - } - - actual := metrics[0].Read() - if actual != float64(10) { - t.Errorf("expected %f for libreoffice_requests_queue_size, but got %f", float64(10), actual) - } - - actual = metrics[1].Read() - if actual != float64(0) { - t.Errorf("expected %f for libreoffice_restarts_count, but got %f", float64(0), actual) - } -} - -func TestApi_Checks(t *testing.T) { - for _, tc := range []struct { - scenario string - supervisor gotenberg.ProcessSupervisor - expectAvailabilityStatus health.AvailabilityStatus - }{ - { - scenario: "healthy module", - supervisor: &gotenberg.ProcessSupervisorMock{HealthyMock: func() bool { - return true - }}, - expectAvailabilityStatus: health.StatusUp, - }, - { - scenario: "unhealthy module", - supervisor: &gotenberg.ProcessSupervisorMock{HealthyMock: func() bool { - return false - }}, - expectAvailabilityStatus: health.StatusDown, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - a := new(Api) - a.supervisor = tc.supervisor - - checks, err := a.Checks() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - checker := health.NewChecker(checks...) - result := checker.Check(context.Background()) - - if result.Status != tc.expectAvailabilityStatus { - t.Errorf("expected '%s' as availability status, but got '%s'", tc.expectAvailabilityStatus, result.Status) - } - }) - } -} - -func TestChromium_Ready(t *testing.T) { - for _, tc := range []struct { - scenario string - autoStart bool - startTimeout time.Duration - libreOffice libreOffice - expectError bool - }{ - { - scenario: "no auto-start", - autoStart: false, - startTimeout: time.Duration(30) * time.Second, - libreOffice: &libreOfficeMock{ProcessMock: gotenberg.ProcessMock{HealthyMock: func(logger *zap.Logger) bool { - return false - }}}, - expectError: false, - }, - { - scenario: "auto-start: context done", - autoStart: true, - startTimeout: time.Duration(200) * time.Millisecond, - libreOffice: &libreOfficeMock{ProcessMock: gotenberg.ProcessMock{HealthyMock: func(logger *zap.Logger) bool { - return false - }}}, - expectError: true, - }, - { - scenario: "auto-start success", - autoStart: true, - startTimeout: time.Duration(30) * time.Second, - libreOffice: &libreOfficeMock{ProcessMock: gotenberg.ProcessMock{HealthyMock: func(logger *zap.Logger) bool { - return true - }}}, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - a := new(Api) - a.autoStart = tc.autoStart - a.args = libreOfficeArguments{startTimeout: tc.startTimeout} - a.libreOffice = tc.libreOffice - - err := a.Ready() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestApi_LibreOffice(t *testing.T) { - a := new(Api) - - _, err := a.LibreOffice() - if err != nil { - t.Errorf("expected no error but got: %v", err) - } -} - -func TestApi_Pdf(t *testing.T) { - for _, tc := range []struct { - scenario string - supervisor gotenberg.ProcessSupervisor - libreOffice libreOffice - expectError bool - }{ - { - scenario: "PDF task success", - libreOffice: &libreOfficeMock{pdfMock: func(ctx context.Context, logger *zap.Logger, input, outputPath string, options Options) error { - return nil - }}, - expectError: false, - }, - { - scenario: "PDF task error", - libreOffice: &libreOfficeMock{pdfMock: func(ctx context.Context, logger *zap.Logger, input, outputPath string, options Options) error { - return errors.New("PDF task error") - }}, - expectError: true, - }, - { - scenario: "ErrCoreDumped", - libreOffice: &libreOfficeMock{pdfMock: func(ctx context.Context, logger *zap.Logger, input, outputPath string, options Options) error { - return ErrCoreDumped - }}, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - a := new(Api) - a.supervisor = &gotenberg.ProcessSupervisorMock{RunMock: func(ctx context.Context, logger *zap.Logger, task func() error) error { - return task() - }} - a.libreOffice = tc.libreOffice - - err := a.Pdf(context.Background(), zap.NewNop(), "", "", Options{}) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestApi_Extensions(t *testing.T) { - a := new(Api) - extensions := a.Extensions() - - actual := len(extensions) - expect := 130 - - if actual != expect { - t.Errorf("expected %d extensions, but got %d", expect, actual) - } -} diff --git a/pkg/modules/libreoffice/api/libreoffice_test.go b/pkg/modules/libreoffice/api/libreoffice_test.go deleted file mode 100644 index 348d6c18..00000000 --- a/pkg/modules/libreoffice/api/libreoffice_test.go +++ /dev/null @@ -1,699 +0,0 @@ -package api - -import ( - "context" - "errors" - "fmt" - "io" - "os" - "testing" - "time" - - "github.com/google/uuid" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestLibreOfficeProcess_Start(t *testing.T) { - for _, tc := range []struct { - scenario string - libreOffice libreOffice - expectError bool - cleanup bool - }{ - { - scenario: "successful start", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - expectError: false, - cleanup: true, - }, - { - scenario: "LibreOffice already started", - libreOffice: func() libreOffice { - p := new(libreOfficeProcess) - p.isStarted.Store(true) - return p - }(), - expectError: true, - cleanup: false, - }, - { - scenario: "non-exit code 81 on first start", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: "foo", - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - expectError: true, - cleanup: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - logger := zap.NewNop() - err := tc.libreOffice.Start(logger) - - if tc.cleanup { - defer func(p libreOffice, logger *zap.Logger) { - err = p.Stop(logger) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }(tc.libreOffice, logger) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestLibreOfficeProcess_Stop(t *testing.T) { - for _, tc := range []struct { - scenario string - libreOffice libreOffice - setup func(libreOffice libreOffice, logger *zap.Logger) error - expectError bool - }{ - { - scenario: "successful stop", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - setup: func(p libreOffice, logger *zap.Logger) error { - return p.Start(logger) - }, - expectError: false, - }, - { - scenario: "LibreOffice already stopped", - libreOffice: func() libreOffice { - p := new(libreOfficeProcess) - p.isStarted.Store(false) - return p - }(), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - logger := zap.NewNop() - - if tc.setup != nil { - err := tc.setup(tc.libreOffice, logger) - if err != nil { - t.Fatalf("setup error: %v", err) - } - } - - err := tc.libreOffice.Stop(logger) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestLibreOfficeProcess_Healthy(t *testing.T) { - for _, tc := range []struct { - scenario string - libreOffice libreOffice - setup func(libreOffice libreOffice, logger *zap.Logger) error - expectHealthy bool - cleanup bool - }{ - { - scenario: "healthy LibreOffice", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - setup: func(p libreOffice, logger *zap.Logger) error { - return p.Start(logger) - }, - expectHealthy: true, - cleanup: true, - }, - { - scenario: "LibreOffice not started", - libreOffice: func() libreOffice { - p := new(libreOfficeProcess) - p.isStarted.Store(false) - return p - }(), - expectHealthy: false, - cleanup: false, - }, - { - scenario: "unhealthy LibreOffice", - libreOffice: func() libreOffice { - p := new(libreOfficeProcess) - p.isStarted.Store(true) - p.socketPort = 12345 - return p - }(), - expectHealthy: false, - cleanup: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - logger := zap.NewNop() - - if tc.setup != nil { - err := tc.setup(tc.libreOffice, logger) - if err != nil { - t.Fatalf("setup error: %v", err) - } - } - - if tc.cleanup { - defer func(p libreOffice, logger *zap.Logger) { - err := p.Stop(logger) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }(tc.libreOffice, logger) - } - - healthy := tc.libreOffice.Healthy(logger) - - if !tc.expectHealthy && healthy { - t.Fatal("expected unhealthy LibreOffice but got an healthy one") - } - - if tc.expectHealthy && !healthy { - t.Fatal("expected a healthy LibreOffice but got an unhealthy one") - } - }) - } -} - -func TestLibreOfficeProcess_pdf(t *testing.T) { - for _, tc := range []struct { - scenario string - libreOffice libreOffice - fs *gotenberg.FileSystem - options Options - cancelledCtx bool - start bool - expectError bool - expectedError error - }{ - { - scenario: "LibreOffice not started", - libreOffice: func() libreOffice { - p := new(libreOfficeProcess) - p.isStarted.Store(false) - return p - }(), - fs: gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), - cancelledCtx: false, - start: false, - expectError: true, - }, - { - scenario: "ErrInvalidPdfFormats", - libreOffice: func() libreOffice { - p := new(libreOfficeProcess) - p.socketPort = 12345 - p.isStarted.Store(true) - return p - }(), - fs: gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)), - options: Options{PdfFormats: gotenberg.PdfFormats{PdfA: "foo"}}, - cancelledCtx: false, - start: false, - expectError: true, - expectedError: ErrInvalidPdfFormats, - }, - { - scenario: "ErrUnoException", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - options: Options{PageRanges: "foo"}, - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/document.txt", fs.WorkingDirPath()), []byte("Context done"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - cancelledCtx: false, - start: true, - expectError: true, - expectedError: ErrUnoException, - }, - { - scenario: "ErrRuntimeException", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - options: Options{Password: "foo"}, - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - in, err := os.Open("/tests/test/testdata/libreoffice/protected.docx") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - defer func() { - err := in.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - - out, err := os.Create(fmt.Sprintf("%s/protected.docx", fs.WorkingDirPath())) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - defer func() { - err := out.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - - _, err = io.Copy(out, in) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - cancelledCtx: false, - start: true, - expectError: true, - expectedError: ErrRuntimeException, - }, - { - scenario: "context done", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/document.txt", fs.WorkingDirPath()), []byte("Context done"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - cancelledCtx: true, - start: true, - expectError: true, - }, - { - scenario: "success (default options)", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/document.txt", fs.WorkingDirPath()), []byte("Success"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - cancelledCtx: false, - start: true, - expectError: false, - }, - { - scenario: "success (not default options)", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/document.txt", fs.WorkingDirPath()), []byte("Success"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: Options{ - Password: "", // Ok, the only exception in this list. - Landscape: true, - PageRanges: "1", - ExportFormFields: false, - AllowDuplicateFieldNames: true, - ExportBookmarks: false, - ExportBookmarksToPdfDestination: true, - ExportPlaceholders: true, - ExportNotes: true, - ExportNotesPages: true, - ExportOnlyNotesPages: true, - ExportNotesInMargin: true, - ConvertOooTargetToPdfTarget: true, - ExportLinksRelativeFsys: true, - ExportHiddenSlides: true, - SkipEmptyPages: true, - AddOriginalDocumentAsStream: true, - SinglePageSheets: true, - LosslessImageCompression: true, - Quality: 100, - ReduceImageResolution: true, - MaxImageResolution: 600, - }, - cancelledCtx: false, - start: true, - expectError: false, - }, - { - scenario: "success (PDF/A-1b)", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/document.txt", fs.WorkingDirPath()), []byte("Landscape"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: Options{PdfFormats: gotenberg.PdfFormats{PdfA: gotenberg.PdfA1b}}, - cancelledCtx: false, - start: true, - expectError: false, - }, - { - scenario: "success (PDF/A-2b)", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/document.txt", fs.WorkingDirPath()), []byte("Landscape"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: Options{PdfFormats: gotenberg.PdfFormats{PdfA: gotenberg.PdfA2b}}, - cancelledCtx: false, - start: true, - expectError: false, - }, - { - scenario: "success (PDF/A-3b)", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/document.txt", fs.WorkingDirPath()), []byte("Landscape"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: Options{PdfFormats: gotenberg.PdfFormats{PdfA: gotenberg.PdfA3b}}, - cancelledCtx: false, - start: true, - expectError: false, - }, - { - scenario: "success (PDF/UA)", - libreOffice: newLibreOfficeProcess( - libreOfficeArguments{ - binPath: os.Getenv("LIBREOFFICE_BIN_PATH"), - unoBinPath: os.Getenv("UNOCONVERTER_BIN_PATH"), - startTimeout: 5 * time.Second, - }, - ), - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/document.txt", fs.WorkingDirPath()), []byte("Landscape"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - options: Options{PdfFormats: gotenberg.PdfFormats{PdfUa: true}}, - cancelledCtx: false, - start: true, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - // Force the debug level. - logger := zap.NewExample() - - defer func() { - err := os.RemoveAll(tc.fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }() - - if tc.start { - err := tc.libreOffice.Start(logger) - if err != nil { - t.Fatalf("setup error: %v", err) - } - - defer func(p libreOffice, logger *zap.Logger) { - err = p.Stop(logger) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }(tc.libreOffice, logger) - } - - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(5)*time.Second) - defer cancel() - - if tc.cancelledCtx { - cancel() - } - - err := tc.libreOffice.pdf( - ctx, - logger, - fmt.Sprintf("%s/document.txt", tc.fs.WorkingDirPath()), - fmt.Sprintf("%s/%s.pdf", tc.fs.WorkingDirPath(), uuid.NewString()), - tc.options, - ) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectedError != nil && !errors.Is(err, tc.expectedError) { - t.Fatalf("expected error %v but got: %v", tc.expectedError, err) - } - }) - } -} - -func TestNonBasicLatinCharactersGuard(t *testing.T) { - for _, tc := range []struct { - scenario string - fs *gotenberg.FileSystem - filename string - expectSameInputPath bool - expectError bool - }{ - { - scenario: "basic latin characters", - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/document.txt", fs.WorkingDirPath()), []byte("Basic latin characters"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - filename: "document.txt", - expectSameInputPath: true, - expectError: false, - }, - { - scenario: "non-basic latin characters", - fs: func() *gotenberg.FileSystem { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - - err := os.MkdirAll(fs.WorkingDirPath(), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - err = os.WriteFile(fmt.Sprintf("%s/รฉรจรŸร รนรค.txt", fs.WorkingDirPath()), []byte("Non-basic latin characters"), 0o755) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return fs - }(), - filename: "รฉรจรŸร รนรค.txt", - expectSameInputPath: false, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - defer func() { - err := os.RemoveAll(tc.fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up, but got: %v", err) - } - }() - - inputPath := fmt.Sprintf("%s/%s", tc.fs.WorkingDirPath(), tc.filename) - newInputPath, err := nonBasicLatinCharactersGuard( - zap.NewNop(), - inputPath, - ) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectSameInputPath && newInputPath != inputPath { - t.Fatalf("expected same input path, but got '%s'", newInputPath) - } - - if !tc.expectSameInputPath && newInputPath == inputPath { - t.Fatalf("expected different input path, but got same '%s'", newInputPath) - } - }) - } -} diff --git a/pkg/modules/libreoffice/api/mocks_test.go b/pkg/modules/libreoffice/api/mocks_test.go deleted file mode 100644 index f2a03530..00000000 --- a/pkg/modules/libreoffice/api/mocks_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package api - -import ( - "context" - "testing" - - "go.uber.org/zap" -) - -func TestApiMock(t *testing.T) { - mock := &ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, input, outputPath string, options Options) error { - return nil - }, - ExtensionsMock: func() []string { - return nil - }, - } - - err := mock.Pdf(context.Background(), zap.NewNop(), "", "", Options{}) - if err != nil { - t.Errorf("expected no error from ApiMock.Pdf, but got: %v", err) - } - - ext := mock.Extensions() - if ext != nil { - t.Errorf("expected nil result from ApiMock.Extensions, but got: %v", ext) - } -} - -func TestProviderMock(t *testing.T) { - mock := &ProviderMock{ - LibreOfficeMock: func() (Uno, error) { - return nil, nil - }, - } - - _, err := mock.LibreOffice() - if err != nil { - t.Errorf("expected no error from ProviderMock.LibreOffice, but got: %v", err) - } -} - -func TestLibreOfficeMock(t *testing.T) { - for _, tc := range []struct { - scenario string - mock *libreOfficeMock - expectError bool - }{ - { - scenario: "success", - mock: &libreOfficeMock{ - pdfMock: func(ctx context.Context, logger *zap.Logger, input, outputPath string, options Options) error { - return nil - }, - }, - expectError: false, - }, - { - scenario: "ErrCoreDumped (first call)", - mock: &libreOfficeMock{ - pdfMock: func(ctx context.Context, logger *zap.Logger, input, outputPath string, options Options) error { - return ErrCoreDumped - }, - }, - expectError: true, - }, - { - scenario: "ErrCoreDumped (second call)", - mock: func() *libreOfficeMock { - m := &libreOfficeMock{ - pdfMock: func(ctx context.Context, logger *zap.Logger, input, outputPath string, options Options) error { - return ErrCoreDumped - }, - } - m.pdf(context.Background(), zap.NewNop(), "", "", Options{}) - return m - }(), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - err := tc.mock.pdf(context.Background(), zap.NewNop(), "", "", Options{}) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error from libreOfficeMock.pdf but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error from libreOfficeMock.pdf but got none") - } - }) - } -} diff --git a/pkg/modules/libreoffice/libreoffice_test.go b/pkg/modules/libreoffice/libreoffice_test.go deleted file mode 100644 index 4d756a07..00000000 --- a/pkg/modules/libreoffice/libreoffice_test.go +++ /dev/null @@ -1,196 +0,0 @@ -package libreoffice - -import ( - "errors" - "reflect" - "testing" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" - libreofficeapi "github.com/gotenberg/gotenberg/v8/pkg/modules/libreoffice/api" -) - -func TestLibreOffice_Descriptor(t *testing.T) { - descriptor := new(LibreOffice).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(LibreOffice)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestLibreOffice_Provision(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *gotenberg.Context - expectError bool - }{ - { - scenario: "no LibreOffice API provider", - ctx: func() *gotenberg.Context { - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(LibreOffice).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{}, - ) - }(), - expectError: true, - }, - { - scenario: "no LibreOffice API from LibreOffice API provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - libreofficeapi.ProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod }} - } - mod.LibreOfficeMock = func() (libreofficeapi.Uno, error) { - return nil, errors.New("foo") - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(LibreOffice).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "no PDF engine provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - libreofficeapi.ProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod }} - } - mod.LibreOfficeMock = func() (libreofficeapi.Uno, error) { - return new(libreofficeapi.ApiMock), nil - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(LibreOffice).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "no PDF engine from PDF engine provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - libreofficeapi.ProviderMock - gotenberg.PdfEngineProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod }} - } - mod.LibreOfficeMock = func() (libreofficeapi.Uno, error) { - return new(libreofficeapi.ApiMock), nil - } - mod.PdfEngineMock = func() (gotenberg.PdfEngine, error) { - return nil, errors.New("foo") - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(LibreOffice).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "provision success", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - libreofficeapi.ProviderMock - gotenberg.PdfEngineProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return mod }} - } - mod.LibreOfficeMock = func() (libreofficeapi.Uno, error) { - return new(libreofficeapi.ApiMock), nil - } - mod.PdfEngineMock = func() (gotenberg.PdfEngine, error) { - return new(gotenberg.PdfEngineMock), nil - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(LibreOffice).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(LibreOffice) - err := mod.Provision(tc.ctx) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestLibreOffice_Routes(t *testing.T) { - for _, tc := range []struct { - scenario string - expectRoutes int - disableRoutes bool - }{ - { - scenario: "routes not disabled", - expectRoutes: 1, - disableRoutes: false, - }, - { - scenario: "routes disabled", - expectRoutes: 0, - disableRoutes: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(LibreOffice) - mod.disableRoutes = tc.disableRoutes - - routes, err := mod.Routes() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectRoutes != len(routes) { - t.Errorf("expected %d routes but got %d", tc.expectRoutes, len(routes)) - } - }) - } -} diff --git a/pkg/modules/libreoffice/pdfengine/pdfengine_test.go b/pkg/modules/libreoffice/pdfengine/pdfengine_test.go deleted file mode 100644 index d7034c2e..00000000 --- a/pkg/modules/libreoffice/pdfengine/pdfengine_test.go +++ /dev/null @@ -1,210 +0,0 @@ -package pdfengine - -import ( - "context" - "errors" - "reflect" - "testing" - - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" - "github.com/gotenberg/gotenberg/v8/pkg/modules/libreoffice/api" -) - -func TestLibreOfficePdfEngine_Descriptor(t *testing.T) { - descriptor := new(LibreOfficePdfEngine).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(LibreOfficePdfEngine)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestLibreOfficePdfEngine_Provider(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *gotenberg.Context - expectError bool - }{ - { - scenario: "no LibreOffice API provider", - ctx: gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(LibreOfficePdfEngine).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{}, - ), - expectError: true, - }, - { - scenario: "no API from LibreOffice API provider", - ctx: func() *gotenberg.Context { - provider := &struct { - gotenberg.ModuleMock - api.ProviderMock - }{} - provider.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { - return provider - }} - } - provider.LibreOfficeMock = func() (api.Uno, error) { - return nil, errors.New("foo") - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(LibreOfficePdfEngine).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - provider.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "provision success", - ctx: func() *gotenberg.Context { - provider := &struct { - gotenberg.ModuleMock - api.ProviderMock - }{} - provider.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { - return provider - }} - } - provider.LibreOfficeMock = func() (api.Uno, error) { - return new(api.ApiMock), nil - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(LibreOfficePdfEngine).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - provider.Descriptor(), - }, - ) - }(), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(LibreOfficePdfEngine) - err := engine.Provision(tc.ctx) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestLibreOfficePdfEngine_Merge(t *testing.T) { - engine := new(LibreOfficePdfEngine) - err := engine.Merge(context.Background(), zap.NewNop(), nil, "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestLibreOfficePdfEngine_Split(t *testing.T) { - engine := new(LibreOfficePdfEngine) - _, err := engine.Split(context.Background(), zap.NewNop(), gotenberg.SplitMode{}, "", "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestLibreOfficePdfEngine_Flatten(t *testing.T) { - engine := new(LibreOfficePdfEngine) - err := engine.Flatten(context.Background(), zap.NewNop(), "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestLibreOfficePdfEngine_Convert(t *testing.T) { - for _, tc := range []struct { - scenario string - api api.Uno - expectError bool - expectedError error - }{ - { - scenario: "convert success", - api: &api.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options api.Options) error { - return nil - }, - }, - expectError: false, - }, - { - scenario: "ErrInvalidPdfFormats", - api: &api.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options api.Options) error { - return api.ErrInvalidPdfFormats - }, - }, - expectError: true, - expectedError: gotenberg.ErrPdfFormatNotSupported, - }, - { - scenario: "convert fail", - api: &api.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options api.Options) error { - return errors.New("foo") - }, - }, - expectError: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := &LibreOfficePdfEngine{unoApi: tc.api} - err := engine.Convert(context.Background(), zap.NewNop(), gotenberg.PdfFormats{}, "", "") - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectedError != nil && !errors.Is(err, tc.expectedError) { - t.Fatalf("expected error %v but got: %v", tc.expectedError, err) - } - }) - } -} - -func TestLibreOfficePdfEngine_ReadMetadata(t *testing.T) { - engine := new(LibreOfficePdfEngine) - _, err := engine.ReadMetadata(context.Background(), zap.NewNop(), "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestLibreOfficePdfEngine_WriteMetadata(t *testing.T) { - engine := new(LibreOfficePdfEngine) - err := engine.WriteMetadata(context.Background(), zap.NewNop(), nil, "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} diff --git a/pkg/modules/libreoffice/routes.go b/pkg/modules/libreoffice/routes.go index 47a2846f..113b5d79 100644 --- a/pkg/modules/libreoffice/routes.go +++ b/pkg/modules/libreoffice/routes.go @@ -1,7 +1,6 @@ package libreoffice import ( - "encoding/json" "errors" "fmt" "net/http" @@ -129,15 +128,6 @@ func convertRoute(libreOffice libreofficeapi.Uno, engine gotenberg.PdfEngine) ap }). Bool("nativePdfFormats", &nativePdfFormats, true). Bool("merge", &merge, false). - Custom("metadata", func(value string) error { - if len(value) > 0 { - err := json.Unmarshal([]byte(value), &metadata) - if err != nil { - return fmt.Errorf("unmarshal metadata: %w", err) - } - } - return nil - }). Bool("flatten", &flatten, false). Validate() if err != nil { diff --git a/pkg/modules/libreoffice/routes_test.go b/pkg/modules/libreoffice/routes_test.go deleted file mode 100644 index c033591d..00000000 --- a/pkg/modules/libreoffice/routes_test.go +++ /dev/null @@ -1,817 +0,0 @@ -package libreoffice - -import ( - "context" - "errors" - "fmt" - "net/http" - "os" - "path/filepath" - "slices" - "testing" - - "github.com/labstack/echo/v4" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" - "github.com/gotenberg/gotenberg/v8/pkg/modules/api" - libreofficeapi "github.com/gotenberg/gotenberg/v8/pkg/modules/libreoffice/api" -) - -func TestConvertRoute(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - libreOffice libreofficeapi.Uno - engine gotenberg.PdfEngine - expectOptions libreofficeapi.Options - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - expectOutputPaths []string - }{ - { - scenario: "missing at least one mandatory file", - ctx: &api.ContextMock{Context: new(api.Context)}, - libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string { - return []string{".docx"} - }}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid quality form field (not an integer)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "quality": { - "foo", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string { - return []string{".docx"} - }}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid quality form field (< 1)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "quality": { - "0", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string { - return []string{".docx"} - }}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid quality form field (> 100)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "quality": { - "101", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string { - return []string{".docx"} - }}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid maxImageResolution form field (not an integer)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "maxImageResolution": { - "foo", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string { - return []string{".docx"} - }}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid maxImageResolution form field (not in range)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "maxImageResolution": { - "1", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string { - return []string{".docx"} - }}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid metadata form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "metadata": { - "foo", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ExtensionsMock: func() []string { - return []string{".docx"} - }}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrPdfFormatNotSupported (nativePdfFormats)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return libreofficeapi.ErrInvalidPdfFormats - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrUnoException", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "nativePageRanges": { - "foo", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return libreofficeapi.ErrUnoException - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrRuntimeException", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "password": { - "invalid", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return libreofficeapi.ErrRuntimeException - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "error from LibreOffice", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return errors.New("foo") - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "PDF engine merge error", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - "document2.docx": "/document2.docx", - }) - ctx.SetValues(map[string][]string{ - "merge": { - "true", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "PDF engine split error", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "splitMode": { - gotenberg.SplitModeIntervals, - }, - "splitSpan": { - "1", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return nil, errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "PDF engine convert error", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "pdfa": { - gotenberg.PdfA1b, - }, - "nativePdfFormats": { - "false", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "PDF engine write metadata error", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "metadata": { - "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - engine: &gotenberg.PdfEngineMock{ - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "PDF engine flatten error", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "flatten": { - "true", - }, - }) - ctx.SetCancelled(true) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - engine: &gotenberg.PdfEngineMock{ - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "cannot add output paths", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetCancelled(true) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success (single file)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - "document2.docx": "/document2.docx", - }) - ctx.SetValues(map[string][]string{ - "quality": { - "100", - }, - "maxImageResolution": { - "1200", - }, - "merge": { - "true", - }, - "pdfa": { - gotenberg.PdfA1b, - }, - "pdfua": { - "true", - }, - "nativePdfFormats": { - "false", - }, - "metadata": { - "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", - }, - "flatten": { - "true", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return nil - }, - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - { - scenario: "success (many files)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - "document2.docx": "/document2.docx", - "document2.doc": "/document2.doc", - }) - ctx.SetValues(map[string][]string{ - "pdfa": { - gotenberg.PdfA1b, - }, - "pdfua": { - "true", - }, - "nativePdfFormats": { - "false", - }, - "metadata": { - "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", - }, - "flatten": { - "true", - }, - }) - ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return nil - }}) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx", ".doc"} - }, - }, - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return nil - }, - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 3, - expectOutputPaths: []string{"/document.docx.pdf", "/document2.docx.pdf", "/document2.doc.pdf"}, - }, - { - scenario: "success with native PDF/A & PDF/UA", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "pdfa": { - gotenberg.PdfA1b, - }, - "pdfua": { - "true", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - { - scenario: "success with split (many files)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - "document2.docx": "/document2.docx", - }) - ctx.SetValues(map[string][]string{ - "splitMode": { - gotenberg.SplitModeIntervals, - }, - "splitSpan": { - "1", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - inputPathNoExt := inputPath[:len(inputPath)-len(filepath.Ext(inputPath))] - filenameNoExt := filepath.Base(inputPathNoExt) - return []string{ - fmt.Sprintf( - "%s/%s_%d.pdf", - outputDirPath, filenameNoExt, 0, - ), - fmt.Sprintf( - "%s/%s_%d.pdf", - outputDirPath, filenameNoExt, 1, - ), - }, nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 4, - expectOutputPaths: []string{"/document_docx/document.docx_0.pdf", "/document_docx/document.docx_1.pdf", "/document2_docx/document2.docx_0.pdf", "/document2_docx/document2.docx_1.pdf"}, - }, - { - scenario: "success with merge and split", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - "document2.docx": "/document2.docx", - }) - ctx.SetValues(map[string][]string{ - "merge": { - "true", - }, - "splitMode": { - gotenberg.SplitModeIntervals, - }, - "splitSpan": { - "1", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - inputPathNoExt := inputPath[:len(inputPath)-len(filepath.Ext(inputPath))] - filenameNoExt := filepath.Base(inputPathNoExt) - return []string{ - fmt.Sprintf( - "%s/%s_%d.pdf", - outputDirPath, filenameNoExt, 0, - ), - fmt.Sprintf( - "%s/%s_%d.pdf", - outputDirPath, filenameNoExt, 1, - ), - }, nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 2, - }, - { - scenario: "success with split and native PDF/A & PDF/UA (many files)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - "document2.docx": "/document2.docx", - }) - ctx.SetValues(map[string][]string{ - "splitMode": { - gotenberg.SplitModeIntervals, - }, - "splitSpan": { - "1", - }, - "pdfa": { - gotenberg.PdfA1b, - }, - "pdfua": { - "true", - }, - }) - return ctx - }(), - libreOffice: &libreofficeapi.ApiMock{ - PdfMock: func(ctx context.Context, logger *zap.Logger, inputPath, outputPath string, options libreofficeapi.Options) error { - return nil - }, - ExtensionsMock: func() []string { - return []string{".docx"} - }, - }, - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - inputPathNoExt := inputPath[:len(inputPath)-len(filepath.Ext(inputPath))] - filenameNoExt := filepath.Base(inputPathNoExt) - return []string{ - fmt.Sprintf( - "%s/%s_%d.pdf", - outputDirPath, filenameNoExt, 0, - ), - fmt.Sprintf( - "%s/%s_%d.pdf", - outputDirPath, filenameNoExt, 1, - ), - }, nil - }, - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 4, - expectOutputPaths: []string{"/document_docx/document.docx_0.pdf", "/document_docx/document.docx_1.pdf", "/document2_docx/document2.docx_0.pdf", "/document2_docx/document2.docx_1.pdf"}, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - tc.ctx.SetMkdirAll(&gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error { - return nil - }}) - tc.ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return nil - }}) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := convertRoute(tc.libreOffice, tc.engine).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - - for _, path := range tc.expectOutputPaths { - if !slices.Contains(tc.ctx.OutputPaths(), path) { - t.Errorf("expected '%s' in output paths %v", path, tc.ctx.OutputPaths()) - } - } - }) - } -} diff --git a/pkg/modules/pdfcpu/pdfcpu_test.go b/pkg/modules/pdfcpu/pdfcpu_test.go deleted file mode 100644 index b1253cfd..00000000 --- a/pkg/modules/pdfcpu/pdfcpu_test.go +++ /dev/null @@ -1,329 +0,0 @@ -package pdfcpu - -import ( - "context" - "errors" - "os" - "reflect" - "testing" - - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestPdfCpu_Descriptor(t *testing.T) { - descriptor := new(PdfCpu).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(PdfCpu)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestPdfCpu_Provision(t *testing.T) { - engine := new(PdfCpu) - ctx := gotenberg.NewContext(gotenberg.ParsedFlags{}, nil) - - err := engine.Provision(ctx) - if err != nil { - t.Errorf("expected no error but got: %v", err) - } -} - -func TestPdfCpu_Validate(t *testing.T) { - for _, tc := range []struct { - scenario string - binPath string - expectError bool - }{ - { - scenario: "empty bin path", - binPath: "", - expectError: true, - }, - { - scenario: "bin path does not exist", - binPath: "/foo", - expectError: true, - }, - { - scenario: "validate success", - binPath: os.Getenv("PDFTK_BIN_PATH"), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(PdfCpu) - engine.binPath = tc.binPath - err := engine.Validate() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestPdfCpu_Debug(t *testing.T) { - for _, tc := range []struct { - scenario string - engine *PdfCpu - expect map[string]interface{} - doNotExpect map[string]interface{} - }{ - { - scenario: "cannot determine version (command error)", - engine: &PdfCpu{ - binPath: "foo", - }, - expect: map[string]interface{}{ - "version": `exec: "foo": executable file not found in $PATH`, - }, - }, - { - scenario: "cannot determine version (no pdfcpu)", - engine: &PdfCpu{ - binPath: "echo", - }, - expect: map[string]interface{}{ - "version": "Unable to determine pdfcpu version", - }, - }, - { - scenario: "success", - engine: &PdfCpu{ - binPath: "pdfcpu", - }, - doNotExpect: map[string]interface{}{ - "version": "Unable to determine pdfcpu version", - }, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - d := tc.engine.Debug() - - if tc.expect != nil { - if !reflect.DeepEqual(d, tc.expect) { - t.Errorf("expected '%v' but got '%v'", tc.expect, d) - } - } - - if tc.doNotExpect != nil { - if reflect.DeepEqual(d, tc.doNotExpect) { - t.Errorf("did not expect '%v'", d) - } - } - }) - } -} - -func TestPdfCpu_Merge(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx context.Context - inputPaths []string - expectError bool - }{ - { - scenario: "invalid context", - ctx: nil, - expectError: true, - }, - { - scenario: "invalid input path", - ctx: context.TODO(), - inputPaths: []string{ - "foo", - }, - expectError: true, - }, - { - scenario: "single file success", - ctx: context.TODO(), - inputPaths: []string{ - "/tests/test/testdata/pdfengines/sample1.pdf", - }, - expectError: false, - }, - { - scenario: "many files success", - ctx: context.TODO(), - inputPaths: []string{ - "/tests/test/testdata/pdfengines/sample1.pdf", - "/tests/test/testdata/pdfengines/sample2.pdf", - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(PdfCpu) - err := engine.Provision(nil) - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - outputDir, err := fs.MkdirAll() - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - defer func() { - err = os.RemoveAll(fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up but got: %v", err) - } - }() - - err = engine.Merge(tc.ctx, zap.NewNop(), tc.inputPaths, outputDir+"/foo.pdf") - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestPdfCpu_Split(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx context.Context - mode gotenberg.SplitMode - inputPath string - expectError bool - expectedError error - expectOutputPathsCount int - }{ - { - scenario: "ErrPdfSplitModeNotSupported", - expectError: true, - expectedError: gotenberg.ErrPdfSplitModeNotSupported, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid context", - ctx: nil, - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1"}, - expectError: true, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid input path", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1"}, - inputPath: "", - expectError: true, - expectOutputPathsCount: 0, - }, - { - scenario: "success (intervals)", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1"}, - inputPath: "/tests/test/testdata/pdfengines/sample4.pdf", - expectError: false, - expectOutputPathsCount: 20, - }, - { - scenario: "success (pages)", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1"}, - inputPath: "/tests/test/testdata/pdfengines/sample4.pdf", - expectError: false, - expectOutputPathsCount: 1, - }, - { - scenario: "success (pages & unify)", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1-2", Unify: true}, - inputPath: "/tests/test/testdata/pdfengines/sample4.pdf", - expectError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(PdfCpu) - err := engine.Provision(nil) - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - outputDir, err := fs.MkdirAll() - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - defer func() { - err = os.RemoveAll(fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up but got: %v", err) - } - }() - - outputPaths, err := engine.Split(tc.ctx, zap.NewNop(), tc.mode, tc.inputPath, outputDir) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectedError != nil && !errors.Is(err, tc.expectedError) { - t.Fatalf("expected error %v but got: %v", tc.expectedError, err) - } - - if tc.expectOutputPathsCount != len(outputPaths) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(outputPaths)) - } - }) - } -} - -func TestPdfCpu_Flatten(t *testing.T) { - mod := new(PdfCpu) - err := mod.Flatten(context.TODO(), zap.NewNop(), "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestPdfCpu_Convert(t *testing.T) { - mod := new(PdfCpu) - err := mod.Convert(context.TODO(), zap.NewNop(), gotenberg.PdfFormats{}, "", "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestLibreOfficePdfEngine_ReadMetadata(t *testing.T) { - engine := new(PdfCpu) - _, err := engine.ReadMetadata(context.Background(), zap.NewNop(), "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestLibreOfficePdfEngine_WriteMetadata(t *testing.T) { - engine := new(PdfCpu) - err := engine.WriteMetadata(context.Background(), zap.NewNop(), nil, "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} diff --git a/pkg/modules/pdfengines/pdfengines_test.go b/pkg/modules/pdfengines/pdfengines_test.go deleted file mode 100644 index b0beed3e..00000000 --- a/pkg/modules/pdfengines/pdfengines_test.go +++ /dev/null @@ -1,417 +0,0 @@ -package pdfengines - -import ( - "errors" - "fmt" - "reflect" - "strings" - "testing" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestPdfEngines_Descriptor(t *testing.T) { - descriptor := new(PdfEngines).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(PdfEngines)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestPdfEngines_Provision(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *gotenberg.Context - expectedMergePdfEngines []string - expectedSplitPdfEngines []string - expectedFlattenPdfEngines []string - expectedConvertPdfEngines []string - expectedReadMetadataPdfEngines []string - expectedWriteMetadataPdfEngines []string - expectError bool - }{ - { - scenario: "no selection from user", - ctx: func() *gotenberg.Context { - provider := &struct { - gotenberg.ModuleMock - }{} - provider.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { - return provider - }} - } - - engine := &struct { - gotenberg.ModuleMock - gotenberg.ValidatorMock - gotenberg.PdfEngineMock - }{} - engine.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return engine }} - } - engine.ValidateMock = func() error { - return nil - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(PdfEngines).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - provider.Descriptor(), - engine.Descriptor(), - }, - ) - }(), - expectedMergePdfEngines: []string{"qpdf", "pdfcpu", "pdftk"}, - expectedSplitPdfEngines: []string{"pdfcpu", "qpdf", "pdftk"}, - expectedFlattenPdfEngines: []string{"qpdf"}, - expectedConvertPdfEngines: []string{"libreoffice-pdfengine"}, - expectedReadMetadataPdfEngines: []string{"exiftool"}, - expectedWriteMetadataPdfEngines: []string{"exiftool"}, - expectError: false, - }, - { - scenario: "selection from user", - ctx: func() *gotenberg.Context { - provider := &struct { - gotenberg.ModuleMock - }{} - provider.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { - return provider - }} - } - engine1 := &struct { - gotenberg.ModuleMock - gotenberg.ValidatorMock - gotenberg.PdfEngineMock - }{} - engine1.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "a", New: func() gotenberg.Module { return engine1 }} - } - engine1.ValidateMock = func() error { - return nil - } - - engine2 := &struct { - gotenberg.ModuleMock - gotenberg.ValidatorMock - gotenberg.PdfEngineMock - }{} - engine2.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "b", New: func() gotenberg.Module { return engine2 }} - } - engine2.ValidateMock = func() error { - return nil - } - - fs := new(PdfEngines).Descriptor().FlagSet - err := fs.Parse([]string{"--pdfengines-merge-engines=b", "--pdfengines-split-engines=a", "--pdfengines-flatten-engines=c", "--pdfengines-convert-engines=b", "--pdfengines-read-metadata-engines=a", "--pdfengines-write-metadata-engines=a"}) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: fs, - }, - []gotenberg.ModuleDescriptor{ - provider.Descriptor(), - engine1.Descriptor(), - engine2.Descriptor(), - }, - ) - }(), - - expectedMergePdfEngines: []string{"b"}, - expectedSplitPdfEngines: []string{"a"}, - expectedFlattenPdfEngines: []string{"c"}, - expectedConvertPdfEngines: []string{"b"}, - expectedReadMetadataPdfEngines: []string{"a"}, - expectedWriteMetadataPdfEngines: []string{"a"}, - expectError: false, - }, - { - scenario: "no valid PDF engine", - ctx: func() *gotenberg.Context { - provider := &struct { - gotenberg.ModuleMock - }{} - provider.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { - return provider - }} - } - engine := &struct { - gotenberg.ModuleMock - gotenberg.ValidatorMock - gotenberg.PdfEngineMock - }{} - engine.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return engine }} - } - engine.ValidateMock = func() error { - return errors.New("foo") - } - - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(PdfEngines).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - provider.Descriptor(), - engine.Descriptor(), - }, - ) - }(), - expectError: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(PdfEngines) - err := mod.Provision(tc.ctx) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if len(tc.expectedMergePdfEngines) != len(mod.mergeNames) { - t.Fatalf("expected %d merge names but got %d", len(tc.expectedMergePdfEngines), len(mod.mergeNames)) - } - - if len(tc.expectedFlattenPdfEngines) != len(mod.flattenNames) { - t.Fatalf("expected %d flatten names but got %d", len(tc.expectedFlattenPdfEngines), len(mod.flattenNames)) - } - - if len(tc.expectedConvertPdfEngines) != len(mod.convertNames) { - t.Fatalf("expected %d convert names but got %d", len(tc.expectedConvertPdfEngines), len(mod.convertNames)) - } - - if len(tc.expectedReadMetadataPdfEngines) != len(mod.readMetadataNames) { - t.Fatalf("expected %d read metadata names but got %d", len(tc.expectedReadMetadataPdfEngines), len(mod.readMetadataNames)) - } - - if len(tc.expectedWriteMetadataPdfEngines) != len(mod.writeMetadataNames) { - t.Fatalf("expected %d write metadata names but got %d", len(tc.expectedWriteMetadataPdfEngines), len(mod.writeMetadataNames)) - } - - for index, name := range mod.mergeNames { - if name != tc.expectedMergePdfEngines[index] { - t.Fatalf("expected merge name at index %d to be %s, but got: %s", index, name, tc.expectedMergePdfEngines[index]) - } - } - - for index, name := range mod.splitNames { - if name != tc.expectedSplitPdfEngines[index] { - t.Fatalf("expected split name at index %d to be %s, but got: %s", index, name, tc.expectedSplitPdfEngines[index]) - } - } - - for index, name := range mod.convertNames { - if name != tc.expectedConvertPdfEngines[index] { - t.Fatalf("expected convert name at index %d to be %s, but got: %s", index, name, tc.expectedConvertPdfEngines[index]) - } - } - - for index, name := range mod.readMetadataNames { - if name != tc.expectedReadMetadataPdfEngines[index] { - t.Fatalf("expected read metadata name at index %d to be %s, but got: %s", index, name, tc.expectedReadMetadataPdfEngines[index]) - } - } - - for index, name := range mod.writeMetadataNames { - if name != tc.expectedWriteMetadataPdfEngines[index] { - t.Fatalf("expected write metadat name at index %d to be %s, but got: %s", index, name, tc.expectedWriteMetadataPdfEngines[index]) - } - } - }) - } -} - -func TestPdfEngines_Validate(t *testing.T) { - for _, tc := range []struct { - scenario string - names []string - engines []gotenberg.PdfEngine - expectError bool - }{ - { - scenario: "existing PDF engine", - names: []string{"foo"}, - engines: func() []gotenberg.PdfEngine { - engine := &struct { - gotenberg.ModuleMock - gotenberg.PdfEngineMock - }{} - engine.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return engine }} - } - - return []gotenberg.PdfEngine{ - engine, - } - }(), - expectError: false, - }, - { - scenario: "non-existing bar PDF engine", - names: []string{"foo", "bar", "baz"}, - engines: func() []gotenberg.PdfEngine { - engine1 := &struct { - gotenberg.ModuleMock - gotenberg.PdfEngineMock - }{} - engine1.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return engine1 }} - } - - engine2 := &struct { - gotenberg.ModuleMock - gotenberg.PdfEngineMock - }{} - engine2.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "baz", New: func() gotenberg.Module { return engine2 }} - } - - return []gotenberg.PdfEngine{ - engine1, - engine2, - } - }(), - expectError: true, - }, - { - scenario: "no PDF engine", - expectError: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := PdfEngines{ - mergeNames: tc.names, - convertNames: tc.names, - readMetadataNames: tc.names, - writeMetadataNames: tc.names, - engines: tc.engines, - } - - err := mod.Validate() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestPdfEngines_SystemMessages(t *testing.T) { - mod := new(PdfEngines) - mod.mergeNames = []string{"foo", "bar"} - mod.splitNames = []string{"foo", "bar"} - mod.convertNames = []string{"foo", "bar"} - mod.readMetadataNames = []string{"foo", "bar"} - mod.writeMetadataNames = []string{"foo", "bar"} - - expectedMessages := 6 - messages := mod.SystemMessages() - if len(messages) != expectedMessages { - t.Errorf("expected %d message(s), but got %d", expectedMessages, len(messages)) - } - - expect := []string{ - fmt.Sprintf("merge engines - %s", strings.Join(mod.mergeNames[:], " ")), - fmt.Sprintf("split engines - %s", strings.Join(mod.splitNames[:], " ")), - fmt.Sprintf("flatten engines - %s", strings.Join(mod.flattenNames[:], " ")), - fmt.Sprintf("convert engines - %s", strings.Join(mod.convertNames[:], " ")), - fmt.Sprintf("read metadata engines - %s", strings.Join(mod.readMetadataNames[:], " ")), - fmt.Sprintf("write metadata engines - %s", strings.Join(mod.writeMetadataNames[:], " ")), - } - - for i, message := range messages { - if message != expect[i] { - t.Errorf("expected message at index %d to be %s, but got %s", i, message, expect[i]) - } - } -} - -func TestPdfEngines_PdfEngine(t *testing.T) { - mod := PdfEngines{ - mergeNames: []string{"foo", "bar"}, - splitNames: []string{"foo", "bar"}, - convertNames: []string{"foo", "bar"}, - readMetadataNames: []string{"foo", "bar"}, - writeMetadataNames: []string{"foo", "bar"}, - engines: func() []gotenberg.PdfEngine { - engine1 := &struct { - gotenberg.ModuleMock - gotenberg.PdfEngineMock - }{} - engine1.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return engine1 }} - } - - engine2 := &struct { - gotenberg.ModuleMock - gotenberg.PdfEngineMock - }{} - engine2.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "bar", New: func() gotenberg.Module { return engine2 }} - } - - return []gotenberg.PdfEngine{ - engine1, - engine2, - } - }(), - } - - _, err := mod.PdfEngine() - if err != nil { - t.Errorf("expected no error but got: %v", err) - } -} - -func TestPdfEngines_Routes(t *testing.T) { - for _, tc := range []struct { - scenario string - expectRoutes int - disableRoutes bool - }{ - { - scenario: "routes not disabled", - expectRoutes: 6, - disableRoutes: false, - }, - { - scenario: "routes disabled", - expectRoutes: 0, - disableRoutes: true, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(PdfEngines) - mod.disableRoutes = tc.disableRoutes - - routes, err := mod.Routes() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectRoutes != len(routes) { - t.Errorf("expected %d routes but got %d", tc.expectRoutes, len(routes)) - } - }) - } -} diff --git a/pkg/modules/pdfengines/routes_test.go b/pkg/modules/pdfengines/routes_test.go deleted file mode 100644 index c50d470e..00000000 --- a/pkg/modules/pdfengines/routes_test.go +++ /dev/null @@ -1,1813 +0,0 @@ -package pdfengines - -import ( - "context" - "errors" - "fmt" - "net/http" - "net/http/httptest" - "os" - "reflect" - "slices" - "strings" - "testing" - - "github.com/google/uuid" - "github.com/labstack/echo/v4" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" - "github.com/gotenberg/gotenberg/v8/pkg/modules/api" -) - -func TestFormDataPdfSplitMode(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - mandatory bool - expectedSplitMode gotenberg.SplitMode - expectValidationError bool - }{ - { - scenario: "no custom form fields", - ctx: &api.ContextMock{Context: new(api.Context)}, - mandatory: false, - expectedSplitMode: gotenberg.SplitMode{}, - expectValidationError: false, - }, - { - scenario: "no custom form fields (mandatory)", - ctx: &api.ContextMock{Context: new(api.Context)}, - mandatory: true, - expectedSplitMode: gotenberg.SplitMode{}, - expectValidationError: true, - }, - { - scenario: "invalid splitMode", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "splitMode": { - "foo", - }, - }) - return ctx - }(), - mandatory: false, - expectedSplitMode: gotenberg.SplitMode{}, - expectValidationError: true, - }, - { - scenario: "invalid splitSpan (intervals)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "splitMode": { - "intervals", - }, - "splitSpan": { - "1-2", - }, - }) - return ctx - }(), - mandatory: false, - expectedSplitMode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals}, - expectValidationError: true, - }, - { - scenario: "splitSpan inferior to 1 (intervals)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "splitMode": { - "intervals", - }, - "splitSpan": { - "-1", - }, - }) - return ctx - }(), - mandatory: false, - expectedSplitMode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals}, - expectValidationError: true, - }, - { - scenario: "invalid splitUnify (intervals)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "splitMode": { - "intervals", - }, - "splitSpan": { - "1", - }, - "splitUnify": { - "true", - }, - }) - return ctx - }(), - mandatory: false, - expectedSplitMode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1", Unify: true}, - expectValidationError: true, - }, - { - scenario: "valid form fields (intervals)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "splitMode": { - "intervals", - }, - "splitSpan": { - "1", - }, - }) - return ctx - }(), - mandatory: false, - expectedSplitMode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1"}, - expectValidationError: false, - }, - { - scenario: "valid form fields (pages)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "splitMode": { - "pages", - }, - "splitSpan": { - "1-2", - }, - "splitUnify": { - "true", - }, - }) - return ctx - }(), - mandatory: false, - expectedSplitMode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1-2", Unify: true}, - expectValidationError: false, - }, - { - scenario: "valid form fields (mandatory)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "splitMode": { - "intervals", - }, - "splitSpan": { - "1", - }, - }) - return ctx - }(), - mandatory: true, - expectedSplitMode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1"}, - expectValidationError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - form := tc.ctx.Context.FormData() - actual := FormDataPdfSplitMode(form, tc.mandatory) - - if !reflect.DeepEqual(actual, tc.expectedSplitMode) { - t.Fatalf("expected %+v but got: %+v", tc.expectedSplitMode, actual) - } - - err := form.Validate() - - if tc.expectValidationError && err == nil { - t.Fatal("expected validation error but got none", err) - } - - if !tc.expectValidationError && err != nil { - t.Fatalf("expected no validation error but got: %v", err) - } - }) - } -} - -func TestFormDataPdfFormats(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - expectedPdfFormats gotenberg.PdfFormats - expectValidationError bool - }{ - { - scenario: "no custom form fields", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectedPdfFormats: gotenberg.PdfFormats{}, - expectValidationError: false, - }, - { - scenario: "pdfa and pdfua form fields", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "pdfa": { - "foo", - }, - "pdfua": { - "true", - }, - }) - return ctx - }(), - expectedPdfFormats: gotenberg.PdfFormats{PdfA: "foo", PdfUa: true}, - expectValidationError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - form := tc.ctx.Context.FormData() - actual := FormDataPdfFormats(form) - - if !reflect.DeepEqual(actual, tc.expectedPdfFormats) { - t.Fatalf("expected %+v but got: %+v", tc.expectedPdfFormats, actual) - } - - err := form.Validate() - - if tc.expectValidationError && err == nil { - t.Fatal("expected validation error but got none", err) - } - - if !tc.expectValidationError && err != nil { - t.Fatalf("expected no validation error but got: %v", err) - } - }) - } -} - -func TestFormDataPdfMetadata(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - mandatory bool - expectedMetadata map[string]interface{} - expectValidationError bool - }{ - { - scenario: "no metadata form field", - ctx: &api.ContextMock{Context: new(api.Context)}, - mandatory: false, - expectedMetadata: nil, - expectValidationError: false, - }, - { - scenario: "no metadata form field (mandatory)", - ctx: &api.ContextMock{Context: new(api.Context)}, - mandatory: true, - expectedMetadata: nil, - expectValidationError: true, - }, - { - scenario: "invalid metadata form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "metadata": { - "foo", - }, - }) - return ctx - }(), - mandatory: false, - expectedMetadata: nil, - expectValidationError: true, - }, - { - scenario: "valid metadata form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetValues(map[string][]string{ - "metadata": { - "{\"foo\":\"bar\"}", - }, - }) - return ctx - }(), - mandatory: false, - expectedMetadata: map[string]interface{}{ - "foo": "bar", - }, - expectValidationError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - form := tc.ctx.Context.FormData() - actual := FormDataPdfMetadata(form, tc.mandatory) - - if !reflect.DeepEqual(actual, tc.expectedMetadata) { - t.Fatalf("expected %+v but got: %+v", tc.expectedMetadata, actual) - } - - err := form.Validate() - - if tc.expectValidationError && err == nil { - t.Fatal("expected validation error but got none", err) - } - - if !tc.expectValidationError && err != nil { - t.Fatalf("expected no validation error but got: %v", err) - } - }) - } -} - -func TestMergeStub(t *testing.T) { - for _, tc := range []struct { - scenario string - engine gotenberg.PdfEngine - inputPaths []string - expectError bool - }{ - { - scenario: "no input path (nil)", - inputPaths: nil, - expectError: true, - }, - { - scenario: "no input path (empty)", - inputPaths: make([]string, 0), - expectError: true, - }, - { - scenario: "only one input path", - inputPaths: []string{"my.pdf"}, - expectError: false, - }, - { - scenario: "merge error", - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return errors.New("foo") - }, - }, - inputPaths: []string{"my.pdf", "my2.pdf"}, - expectError: true, - }, - { - scenario: "merge success", - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - }, - inputPaths: []string{"my.pdf", "my2.pdf"}, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - _, err := MergeStub(new(api.Context), tc.engine, tc.inputPaths) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }) - } -} - -func TestSplitPdfStub(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - engine gotenberg.PdfEngine - mode gotenberg.SplitMode - expectError bool - }{ - { - scenario: "no split mode", - mode: gotenberg.SplitMode{}, - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: false, - }, - { - scenario: "cannot create subdirectory", - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1"}, - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetMkdirAll(&gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error { - return errors.New("cannot create subdirectory") - }}) - return ctx - }(), - expectError: true, - }, - { - scenario: "split error", - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1"}, - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetMkdirAll(&gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error { - return nil - }}) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return nil, errors.New("foo") - }, - }, - expectError: true, - }, - { - scenario: "rename error", - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1"}, - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetMkdirAll(&gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error { - return nil - }}) - ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return errors.New("cannot rename") - }}) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return []string{inputPath}, nil - }, - }, - expectError: true, - }, - { - scenario: "success (intervals)", - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModeIntervals, Span: "1"}, - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetMkdirAll(&gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error { - return nil - }}) - ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return nil - }}) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return []string{inputPath}, nil - }, - }, - expectError: false, - }, - { - scenario: "success (pages)", - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1-2", Unify: true}, - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetMkdirAll(&gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error { - return nil - }}) - ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return nil - }}) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return []string{inputPath}, nil - }, - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - dirPath := fmt.Sprintf("%s/%s", os.TempDir(), uuid.NewString()) - tc.ctx.SetDirPath(dirPath) - tc.ctx.SetLogger(zap.NewNop()) - - _, err := SplitPdfStub(tc.ctx.Context, tc.engine, tc.mode, []string{"my.pdf", "my2.pdf"}) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }) - } -} - -func TestFlattenStub(t *testing.T) { - for _, tc := range []struct { - scenario string - engine gotenberg.PdfEngine - expectError bool - }{ - { - scenario: "flatten error", - engine: &gotenberg.PdfEngineMock{ - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - }, - { - scenario: "flatten success", - engine: &gotenberg.PdfEngineMock{ - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return nil - }, - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - err := FlattenStub(new(api.Context), tc.engine, []string{"my.pdf", "my2.pdf"}) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }) - } -} - -func TestConvertStub(t *testing.T) { - for _, tc := range []struct { - scenario string - engine gotenberg.PdfEngine - pdfFormats gotenberg.PdfFormats - expectError bool - }{ - { - scenario: "no PDF formats", - pdfFormats: gotenberg.PdfFormats{}, - expectError: false, - }, - { - scenario: "convert error", - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return errors.New("foo") - }, - }, - pdfFormats: gotenberg.PdfFormats{ - PdfA: gotenberg.PdfA3b, - PdfUa: true, - }, - expectError: true, - }, - { - scenario: "convert success", - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - }, - pdfFormats: gotenberg.PdfFormats{ - PdfA: gotenberg.PdfA3b, - PdfUa: true, - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - _, err := ConvertStub(new(api.Context), tc.engine, tc.pdfFormats, []string{"my.pdf", "my2.pdf"}) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }) - } -} - -func TestWriteMetadataStub(t *testing.T) { - for _, tc := range []struct { - scenario string - engine gotenberg.PdfEngine - metadata map[string]interface{} - expectError bool - }{ - { - scenario: "no metadata (nil)", - metadata: nil, - expectError: false, - }, - { - scenario: "no metadata (empty)", - metadata: make(map[string]interface{}, 0), - expectError: false, - }, - { - scenario: "write metadata error", - engine: &gotenberg.PdfEngineMock{ - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return errors.New("foo") - }, - }, - metadata: map[string]interface{}{"foo": "bar"}, - expectError: true, - }, - { - scenario: "write metadata success", - engine: &gotenberg.PdfEngineMock{ - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return nil - }, - }, - metadata: map[string]interface{}{"foo": "bar"}, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - err := WriteMetadataStub(new(api.Context), tc.engine, tc.metadata, []string{"my.pdf", "my2.pdf"}) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }) - } -} - -func TestMergeHandler(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - engine gotenberg.PdfEngine - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - }{ - { - scenario: "missing at least one mandatory file", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid metadata form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - "file2.pdf": "/file2.pdf", - }) - ctx.SetValues(map[string][]string{ - "metadata": { - "foo", - }, - }) - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine (merge)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - "file2.pdf": "/file2.pdf", - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine (convert)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - "file2.pdf": "/file2.pdf", - }) - ctx.SetValues(map[string][]string{ - "pdfa": { - gotenberg.PdfA1b, - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine (write metadata)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - "file2.pdf": "/file2.pdf", - }) - ctx.SetValues(map[string][]string{ - "metadata": { - "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine (flatten)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - "file2.pdf": "/file2.pdf", - }) - ctx.SetValues(map[string][]string{ - "flatten": { - "true", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "cannot add output paths", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - "file2.pdf": "/file2.pdf", - }) - ctx.SetCancelled(true) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - "file2.pdf": "/file2.pdf", - }) - ctx.SetValues(map[string][]string{ - "pdfa": { - gotenberg.PdfA1b, - }, - "metadata": { - "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", - }, - "flatten": { - "true", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - MergeMock: func(ctx context.Context, logger *zap.Logger, inputPaths []string, outputPath string) error { - return nil - }, - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return nil - }, - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := mergeRoute(tc.engine).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - }) - } -} - -func TestSplitHandler(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - engine gotenberg.PdfEngine - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - expectOutputPaths []string - }{ - { - scenario: "missing at least one mandatory file", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "no split mode", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine (split)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "splitMode": { - gotenberg.SplitModeIntervals, - }, - "splitSpan": { - "1", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return nil, errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine (convert)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "splitMode": { - gotenberg.SplitModeIntervals, - }, - "splitSpan": { - "1", - }, - "pdfua": { - "true", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return []string{inputPath}, nil - }, - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine (write metadata)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "splitMode": { - gotenberg.SplitModeIntervals, - }, - "splitSpan": { - "1", - }, - "metadata": { - "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return []string{inputPath}, nil - }, - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine (flatten)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "splitMode": { - gotenberg.SplitModeIntervals, - }, - "splitSpan": { - "1", - }, - "flatten": { - "true", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return []string{inputPath}, nil - }, - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "cannot add output paths", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "splitMode": { - gotenberg.SplitModeIntervals, - }, - "splitSpan": { - "1", - }, - }) - ctx.SetCancelled(true) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return []string{inputPath}, nil - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "splitMode": { - gotenberg.SplitModeIntervals, - }, - "splitSpan": { - "1", - }, - "pdfua": { - "true", - }, - "metadata": { - "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", - }, - "flatten": { - "true", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - SplitMock: func(ctx context.Context, logger *zap.Logger, mode gotenberg.SplitMode, inputPath, outputDirPath string) ([]string, error) { - return []string{"file_split_1.pdf", "file_split_2.pdf"}, nil - }, - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return nil - }, - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 2, - expectOutputPaths: []string{"/file/file_0.pdf", "/file/file_1.pdf"}, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - tc.ctx.SetMkdirAll(&gotenberg.MkdirAllMock{MkdirAllMock: func(path string, perm os.FileMode) error { - return nil - }}) - tc.ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return nil - }}) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := splitRoute(tc.engine).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - - for _, path := range tc.expectOutputPaths { - if !slices.Contains(tc.ctx.OutputPaths(), path) { - t.Errorf("expected '%s' in output paths %v", path, tc.ctx.OutputPaths()) - } - } - }) - } -} - -func TestFlattenHandler(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - engine gotenberg.PdfEngine - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - expectOutputPaths []string - }{ - { - scenario: "missing at least one mandatory file", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "cannot add output paths", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetCancelled(true) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return nil - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success with single file", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - { - scenario: "success (many files)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - "file2.pdf": "/file2.pdf", - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - FlattenMock: func(ctx context.Context, logger *zap.Logger, inputPath string) error { - return nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 2, - expectOutputPaths: []string{"/file.pdf", "/file2.pdf"}, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := flattenRoute(tc.engine).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - - for _, path := range tc.expectOutputPaths { - if !slices.Contains(tc.ctx.OutputPaths(), path) { - t.Errorf("expected '%s' in output paths %v", path, tc.ctx.OutputPaths()) - } - } - }) - } -} - -func TestConvertHandler(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - engine gotenberg.PdfEngine - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - expectOutputPaths []string - }{ - { - scenario: "missing at least one mandatory file", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "no PDF formats", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "pdfa": { - gotenberg.PdfA1b, - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "cannot add output paths", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "pdfa": { - gotenberg.PdfA1b, - }, - }) - ctx.SetCancelled(true) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success with PDF/A & PDF/UA form fields (single file)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "pdfa": { - gotenberg.PdfA1b, - }, - "pdfua": { - "true", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - { - scenario: "cannot rename many files", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - "file2.pdf": "/file2.pdf", - }) - ctx.SetValues(map[string][]string{ - "pdfa": { - gotenberg.PdfA1b, - }, - "pdfua": { - "true", - }, - }) - ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return errors.New("cannot rename") - }}) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success with PDF/A & PDF/UA form fields (many files)", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - "file2.pdf": "/file2.pdf", - }) - ctx.SetValues(map[string][]string{ - "pdfa": { - gotenberg.PdfA1b, - }, - "pdfua": { - "true", - }, - }) - ctx.SetPathRename(&gotenberg.PathRenameMock{RenameMock: func(oldpath, newpath string) error { - return nil - }}) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - ConvertMock: func(ctx context.Context, logger *zap.Logger, formats gotenberg.PdfFormats, inputPath, outputPath string) error { - return nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 2, - expectOutputPaths: []string{"/file.pdf", "/file2.pdf"}, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := convertRoute(tc.engine).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - - for _, path := range tc.expectOutputPaths { - if !slices.Contains(tc.ctx.OutputPaths(), path) { - t.Errorf("expected '%s' in output paths %v", path, tc.ctx.OutputPaths()) - } - } - }) - } -} - -func TestReadMetadataHandler(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - engine gotenberg.PdfEngine - expectError bool - expectedError error - expectHttpError bool - expectHttpStatus int - expectedJson string - }{ - { - scenario: "missing at least one mandatory file", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "error from PDF engine", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) { - return nil, errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - }, - { - scenario: "success", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - ReadMetadataMock: func(ctx context.Context, logger *zap.Logger, inputPath string) (map[string]interface{}, error) { - return map[string]interface{}{ - "foo": "bar", - "bar": "foo", - }, nil - }, - }, - expectError: true, - expectedError: api.ErrNoOutputFile, - expectHttpError: false, - expectedJson: `{"file.pdf":{"bar":"foo","foo":"bar"}}`, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - req := httptest.NewRequest(http.MethodPost, "/forms/pdfengines/metadata/read", nil) - rec := httptest.NewRecorder() - c := echo.New().NewContext(req, rec) - c.Set("context", tc.ctx.Context) - - err := readMetadataRoute(tc.engine).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if tc.expectedError != nil && !errors.Is(err, tc.expectedError) { - t.Fatalf("expected error %v but got: %v", tc.expectedError, err) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectedJson != "" && tc.expectedJson != strings.TrimSpace(rec.Body.String()) { - t.Errorf("expected '%s' as HTTP response but got '%s'", tc.expectedJson, strings.TrimSpace(rec.Body.String())) - } - }) - } -} - -func TestWriteMetadataHandler(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *api.ContextMock - engine gotenberg.PdfEngine - expectError bool - expectHttpError bool - expectHttpStatus int - expectOutputPathsCount int - expectOutputPaths []string - }{ - { - scenario: "missing at least one mandatory file", - ctx: &api.ContextMock{Context: new(api.Context)}, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "no metadata form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid metadata form field", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "metadata": { - "foo", - }, - }) - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "no metadata", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "document.docx": "/document.docx", - }) - ctx.SetValues(map[string][]string{ - "metadata": { - "{}", - }, - }) - return ctx - }(), - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - expectOutputPathsCount: 0, - }, - { - scenario: "error from PDF engine", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "metadata": { - "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return errors.New("foo") - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "cannot add output paths", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "metadata": { - "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", - }, - }) - ctx.SetCancelled(true) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return nil - }, - }, - expectError: true, - expectHttpError: false, - expectOutputPathsCount: 0, - }, - { - scenario: "success", - ctx: func() *api.ContextMock { - ctx := &api.ContextMock{Context: new(api.Context)} - ctx.SetFiles(map[string]string{ - "file.pdf": "/file.pdf", - }) - ctx.SetValues(map[string][]string{ - "metadata": { - "{\"Creator\": \"foo\", \"Producer\": \"bar\" }", - }, - }) - return ctx - }(), - engine: &gotenberg.PdfEngineMock{ - WriteMetadataMock: func(ctx context.Context, logger *zap.Logger, metadata map[string]interface{}, inputPath string) error { - return nil - }, - }, - expectError: false, - expectHttpError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - tc.ctx.SetLogger(zap.NewNop()) - c := echo.New().NewContext(nil, nil) - c.Set("context", tc.ctx.Context) - - err := writeMetadataRoute(tc.engine).Handler(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - - if tc.expectOutputPathsCount != len(tc.ctx.OutputPaths()) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(tc.ctx.OutputPaths())) - } - - for _, path := range tc.expectOutputPaths { - if !slices.Contains(tc.ctx.OutputPaths(), path) { - t.Errorf("expected '%s' in output paths %v", path, tc.ctx.OutputPaths()) - } - } - }) - } -} diff --git a/pkg/modules/pdftk/pdftk_test.go b/pkg/modules/pdftk/pdftk_test.go deleted file mode 100644 index 0a49aeda..00000000 --- a/pkg/modules/pdftk/pdftk_test.go +++ /dev/null @@ -1,313 +0,0 @@ -package pdftk - -import ( - "context" - "errors" - "os" - "reflect" - "testing" - - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestPdfTk_Descriptor(t *testing.T) { - descriptor := new(PdfTk).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(PdfTk)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestPdfTk_Provision(t *testing.T) { - engine := new(PdfTk) - ctx := gotenberg.NewContext(gotenberg.ParsedFlags{}, nil) - - err := engine.Provision(ctx) - if err != nil { - t.Errorf("expected no error but got: %v", err) - } -} - -func TestPdfTk_Validate(t *testing.T) { - for _, tc := range []struct { - scenario string - binPath string - expectError bool - }{ - { - scenario: "empty bin path", - binPath: "", - expectError: true, - }, - { - scenario: "bin path does not exist", - binPath: "/foo", - expectError: true, - }, - { - scenario: "validate success", - binPath: os.Getenv("PDFTK_BIN_PATH"), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(PdfTk) - engine.binPath = tc.binPath - err := engine.Validate() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestPdfTk_Debug(t *testing.T) { - for _, tc := range []struct { - scenario string - engine *PdfTk - expect map[string]interface{} - doNotExpect map[string]interface{} - }{ - { - scenario: "cannot determine version", - engine: &PdfTk{ - binPath: "foo", - }, - expect: map[string]interface{}{ - "version": `exec: "foo": executable file not found in $PATH`, - }, - }, - { - scenario: "success", - engine: &PdfTk{ - binPath: "echo", - }, - doNotExpect: map[string]interface{}{ - "version": `exec: "echo": executable file not found in $PATH`, - }, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - d := tc.engine.Debug() - - if tc.expect != nil { - if !reflect.DeepEqual(d, tc.expect) { - t.Errorf("expected '%v' but got '%v'", tc.expect, d) - } - } - - if tc.doNotExpect != nil { - if reflect.DeepEqual(d, tc.doNotExpect) { - t.Errorf("did not expect '%v'", d) - } - } - }) - } -} - -func TestPdfTk_Merge(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx context.Context - inputPaths []string - expectError bool - }{ - { - scenario: "invalid context", - ctx: nil, - expectError: true, - }, - { - scenario: "invalid input path", - ctx: context.TODO(), - inputPaths: []string{ - "foo", - }, - expectError: true, - }, - { - scenario: "single file success", - ctx: context.TODO(), - inputPaths: []string{ - "/tests/test/testdata/pdfengines/sample1.pdf", - }, - expectError: false, - }, - { - scenario: "many files success", - ctx: context.TODO(), - inputPaths: []string{ - "/tests/test/testdata/pdfengines/sample1.pdf", - "/tests/test/testdata/pdfengines/sample2.pdf", - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(PdfTk) - err := engine.Provision(nil) - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - outputDir, err := fs.MkdirAll() - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - defer func() { - err = os.RemoveAll(fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up but got: %v", err) - } - }() - - err = engine.Merge(tc.ctx, zap.NewNop(), tc.inputPaths, outputDir+"/foo.pdf") - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestPdfCpu_Split(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx context.Context - mode gotenberg.SplitMode - inputPath string - expectError bool - expectedError error - expectOutputPathsCount int - expectOutputPaths []string - }{ - { - scenario: "ErrPdfSplitModeNotSupported", - expectError: true, - expectedError: gotenberg.ErrPdfSplitModeNotSupported, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrPdfSplitModeNotSupported (no unify with pages)", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1", Unify: false}, - expectError: true, - expectedError: gotenberg.ErrPdfSplitModeNotSupported, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid context", - ctx: nil, - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1-2", Unify: true}, - expectError: true, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid input path", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1-2", Unify: true}, - inputPath: "", - expectError: true, - expectOutputPathsCount: 0, - }, - { - scenario: "success (pages & unify)", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1-2", Unify: true}, - inputPath: "/tests/test/testdata/pdfengines/sample1.pdf", - expectError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(PdfTk) - err := engine.Provision(nil) - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - outputDir, err := fs.MkdirAll() - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - defer func() { - err = os.RemoveAll(fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up but got: %v", err) - } - }() - - outputPaths, err := engine.Split(tc.ctx, zap.NewNop(), tc.mode, tc.inputPath, outputDir) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectedError != nil && !errors.Is(err, tc.expectedError) { - t.Fatalf("expected error %v but got: %v", tc.expectedError, err) - } - - if tc.expectOutputPathsCount != len(outputPaths) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(outputPaths)) - } - }) - } -} - -func TestPdfTk_Flatten(t *testing.T) { - engine := new(PdfTk) - err := engine.Flatten(context.TODO(), zap.NewNop(), "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestPdfTk_Convert(t *testing.T) { - engine := new(PdfTk) - err := engine.Convert(context.TODO(), zap.NewNop(), gotenberg.PdfFormats{}, "", "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestLibreOfficePdfEngine_ReadMetadata(t *testing.T) { - engine := new(PdfTk) - _, err := engine.ReadMetadata(context.Background(), zap.NewNop(), "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestLibreOfficePdfEngine_WriteMetadata(t *testing.T) { - engine := new(PdfTk) - err := engine.WriteMetadata(context.Background(), zap.NewNop(), nil, "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} diff --git a/pkg/modules/prometheus/prometheus_test.go b/pkg/modules/prometheus/prometheus_test.go deleted file mode 100644 index 02816b0f..00000000 --- a/pkg/modules/prometheus/prometheus_test.go +++ /dev/null @@ -1,360 +0,0 @@ -package prometheus - -import ( - "errors" - "reflect" - "testing" - "time" - - "github.com/prometheus/client_golang/prometheus" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestPrometheus_Descriptor(t *testing.T) { - descriptor := new(Prometheus).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(Prometheus)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestPrometheus_Provision(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx *gotenberg.Context - expectMetrics []gotenberg.Metric - expectError bool - }{ - { - scenario: "disable collect", - ctx: func() *gotenberg.Context { - fs := new(Prometheus).Descriptor().FlagSet - err := fs.Parse([]string{"--prometheus-disable-collect=true"}) - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: fs, - }, - nil, - ) - }(), - expectError: false, - }, - { - scenario: "invalid metrics provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.ValidatorMock - gotenberg.MetricsProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }} - } - mod.ValidateMock = func() error { - return errors.New("foo") - } - mod.MetricsMock = func() ([]gotenberg.Metric, error) { - return nil, nil - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Prometheus).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "invalid metrics from metrics provider", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.ValidatorMock - gotenberg.MetricsProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }} - } - mod.ValidateMock = func() error { - return nil - } - mod.MetricsMock = func() ([]gotenberg.Metric, error) { - return nil, errors.New("foo") - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Prometheus).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectError: true, - }, - { - scenario: "provision success", - ctx: func() *gotenberg.Context { - mod := &struct { - gotenberg.ModuleMock - gotenberg.ValidatorMock - gotenberg.MetricsProviderMock - }{} - mod.DescriptorMock = func() gotenberg.ModuleDescriptor { - return gotenberg.ModuleDescriptor{ID: "foo", New: func() gotenberg.Module { return mod }} - } - mod.ValidateMock = func() error { - return nil - } - mod.MetricsMock = func() ([]gotenberg.Metric, error) { - return []gotenberg.Metric{ - { - Name: "foo", - Description: "Bar.", - }, - }, nil - } - return gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Prometheus).Descriptor().FlagSet, - }, - []gotenberg.ModuleDescriptor{ - mod.Descriptor(), - }, - ) - }(), - expectMetrics: []gotenberg.Metric{ - { - Name: "foo", - Description: "Bar.", - }, - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := new(Prometheus) - err := mod.Provision(tc.ctx) - - if !reflect.DeepEqual(mod.metrics, tc.expectMetrics) { - t.Fatalf("expected metrics %+v, but got: %+v", tc.expectMetrics, mod.metrics) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestPrometheus_Validate(t *testing.T) { - for _, tc := range []struct { - scenario string - namespace string - metrics []gotenberg.Metric - disableCollect bool - expectError bool - }{ - { - scenario: "collect disabled", - namespace: "foo", - disableCollect: true, - expectError: false, - }, - { - scenario: "empty namespace", - namespace: "", - disableCollect: false, - expectError: true, - }, - { - scenario: "empty metric name", - namespace: "foo", - metrics: []gotenberg.Metric{ - { - Name: "", - }, - }, - disableCollect: false, - expectError: true, - }, - { - scenario: "nil read metric method", - namespace: "foo", - metrics: []gotenberg.Metric{ - { - Name: "foo", - Read: nil, - }, - }, - disableCollect: false, - expectError: true, - }, - { - scenario: "already registered metric", - namespace: "foo", - metrics: []gotenberg.Metric{ - { - Name: "foo", - Read: func() float64 { - return 0 - }, - }, - { - Name: "foo", - Read: func() float64 { - return 0 - }, - }, - }, - disableCollect: false, - expectError: true, - }, - { - scenario: "validate success", - namespace: "foo", - metrics: []gotenberg.Metric{ - { - Name: "foo", - Read: func() float64 { - return 0 - }, - }, - { - Name: "bar", - Read: func() float64 { - return 0 - }, - }, - }, - disableCollect: false, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := &Prometheus{ - namespace: tc.namespace, - metrics: tc.metrics, - disableCollect: tc.disableCollect, - } - err := mod.Validate() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestPrometheus_Start(t *testing.T) { - for _, tc := range []struct { - scenario string - metrics []gotenberg.Metric - disableCollect bool - }{ - { - scenario: "collect disabled", - disableCollect: true, - }, - { - scenario: "start success", - metrics: []gotenberg.Metric{ - { - Name: "foo", - Read: func() float64 { - return 0 - }, - }, - }, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := &Prometheus{ - namespace: "foo", - interval: time.Duration(1) * time.Second, - metrics: tc.metrics, - disableCollect: tc.disableCollect, - registry: prometheus.NewRegistry(), - } - - err := mod.Start() - if err != nil { - t.Errorf("expected no error but got: %v", err) - } - }) - } -} - -func TestPrometheus_StartupMessage(t *testing.T) { - mod := new(Prometheus) - - mod.disableCollect = true - disableCollectMsg := mod.StartupMessage() - - mod.disableCollect = false - noDisableCollectMsg := mod.StartupMessage() - - if disableCollectMsg == noDisableCollectMsg { - t.Errorf("expected differrent startup messages if collect is disabled or not, but got '%s'", disableCollectMsg) - } -} - -func TestPrometheus_Stop(t *testing.T) { - err := new(Prometheus).Stop(nil) - if err != nil { - t.Errorf("expected no error but got: %v", err) - } -} - -func TestPrometheus_Routes(t *testing.T) { - for _, tc := range []struct { - scenario string - disableCollect bool - expectRoutes int - }{ - { - scenario: "collect disabled", - disableCollect: true, - expectRoutes: 0, - }, - { - scenario: "routes not disabled", - disableCollect: false, - expectRoutes: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - mod := &Prometheus{ - disableCollect: tc.disableCollect, - registry: prometheus.NewRegistry(), - } - - routes, err := mod.Routes() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectRoutes != len(routes) { - t.Errorf("expected %d routes but got %d", tc.expectRoutes, len(routes)) - } - }) - } -} diff --git a/pkg/modules/qpdf/qpdf_test.go b/pkg/modules/qpdf/qpdf_test.go deleted file mode 100644 index 212a2cc4..00000000 --- a/pkg/modules/qpdf/qpdf_test.go +++ /dev/null @@ -1,425 +0,0 @@ -package qpdf - -import ( - "context" - "errors" - "fmt" - "io" - "os" - "reflect" - "testing" - - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestQPdf_Descriptor(t *testing.T) { - descriptor := new(QPdf).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(QPdf)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestQPdf_Provision(t *testing.T) { - engine := new(QPdf) - ctx := gotenberg.NewContext(gotenberg.ParsedFlags{}, nil) - - err := engine.Provision(ctx) - if err != nil { - t.Errorf("expected no error but got: %v", err) - } -} - -func TestQPdf_Validate(t *testing.T) { - for _, tc := range []struct { - scenario string - binPath string - expectError bool - }{ - { - scenario: "empty bin path", - binPath: "", - expectError: true, - }, - { - scenario: "bin path does not exist", - binPath: "/foo", - expectError: true, - }, - { - scenario: "validate success", - binPath: os.Getenv("QPDF_BIN_PATH"), - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(QPdf) - engine.binPath = tc.binPath - err := engine.Validate() - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestQPdf_Debug(t *testing.T) { - for _, tc := range []struct { - scenario string - engine *QPdf - expect map[string]interface{} - doNotExpect map[string]interface{} - }{ - { - scenario: "cannot determine version", - engine: &QPdf{ - binPath: "foo", - }, - expect: map[string]interface{}{ - "version": `exec: "foo": executable file not found in $PATH`, - }, - }, - { - scenario: "success", - engine: &QPdf{ - binPath: "echo", - }, - doNotExpect: map[string]interface{}{ - "version": `exec: "echo": executable file not found in $PATH`, - }, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - d := tc.engine.Debug() - - if tc.expect != nil { - if !reflect.DeepEqual(d, tc.expect) { - t.Errorf("expected '%v' but got '%v'", tc.expect, d) - } - } - - if tc.doNotExpect != nil { - if reflect.DeepEqual(d, tc.doNotExpect) { - t.Errorf("did not expect '%v'", d) - } - } - }) - } -} - -func TestQPdf_Merge(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx context.Context - inputPaths []string - expectError bool - }{ - { - scenario: "invalid context", - ctx: nil, - expectError: true, - }, - { - scenario: "invalid input path", - ctx: context.TODO(), - inputPaths: []string{ - "foo", - }, - expectError: true, - }, - { - scenario: "single file success", - ctx: context.TODO(), - inputPaths: []string{ - "/tests/test/testdata/pdfengines/sample1.pdf", - }, - expectError: false, - }, - { - scenario: "many files success", - ctx: context.TODO(), - inputPaths: []string{ - "/tests/test/testdata/pdfengines/sample1.pdf", - "/tests/test/testdata/pdfengines/sample2.pdf", - }, - expectError: false, - }, - { - scenario: "success even with warnings", - ctx: context.TODO(), - inputPaths: []string{ - "/tests/test/testdata/pdfengines/sample1.pdf", - "/tests/test/testdata/pdfengines/sample5.pdf", - }, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(QPdf) - err := engine.Provision(nil) - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - outputDir, err := fs.MkdirAll() - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - defer func() { - err = os.RemoveAll(fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up but got: %v", err) - } - }() - - err = engine.Merge(tc.ctx, zap.NewNop(), tc.inputPaths, outputDir+"/foo.pdf") - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestQPdf_Split(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx context.Context - mode gotenberg.SplitMode - inputPath string - expectError bool - expectedError error - expectOutputPathsCount int - expectOutputPaths []string - }{ - { - scenario: "ErrPdfSplitModeNotSupported", - expectError: true, - expectedError: gotenberg.ErrPdfSplitModeNotSupported, - expectOutputPathsCount: 0, - }, - { - scenario: "ErrPdfSplitModeNotSupported (no unify with pages)", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1", Unify: false}, - expectError: true, - expectedError: gotenberg.ErrPdfSplitModeNotSupported, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid context", - ctx: nil, - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1-2", Unify: true}, - expectError: true, - expectOutputPathsCount: 0, - }, - { - scenario: "invalid input path", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1-2", Unify: true}, - inputPath: "", - expectError: true, - expectOutputPathsCount: 0, - }, - { - scenario: "success (pages & unify)", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1-2", Unify: true}, - inputPath: "/tests/test/testdata/pdfengines/sample1.pdf", - expectError: false, - expectOutputPathsCount: 1, - }, - { - scenario: "success even with warnings", - ctx: context.TODO(), - mode: gotenberg.SplitMode{Mode: gotenberg.SplitModePages, Span: "1-2", Unify: true}, - inputPath: "/tests/test/testdata/pdfengines/sample5.pdf", - expectError: false, - expectOutputPathsCount: 1, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(QPdf) - err := engine.Provision(nil) - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - outputDir, err := fs.MkdirAll() - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - defer func() { - err = os.RemoveAll(fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up but got: %v", err) - } - }() - - outputPaths, err := engine.Split(tc.ctx, zap.NewNop(), tc.mode, tc.inputPath, outputDir) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - - if tc.expectedError != nil && !errors.Is(err, tc.expectedError) { - t.Fatalf("expected error %v but got: %v", tc.expectedError, err) - } - - if tc.expectOutputPathsCount != len(outputPaths) { - t.Errorf("expected %d output paths but got %d", tc.expectOutputPathsCount, len(outputPaths)) - } - }) - } -} - -func TestQPdf_Flatten(t *testing.T) { - for _, tc := range []struct { - scenario string - ctx context.Context - inputPath string - createCopy bool - expectError bool - }{ - { - scenario: "invalid context", - ctx: nil, - expectError: true, - }, - { - scenario: "invalid input path", - ctx: context.TODO(), - inputPath: "foo.pdf", - expectError: true, - }, - { - scenario: "success", - ctx: context.TODO(), - inputPath: "/tests/test/testdata/pdfengines/sample3.pdf", - createCopy: true, - expectError: false, - }, - { - scenario: "success even with warnings", - ctx: context.TODO(), - inputPath: "/tests/test/testdata/pdfengines/sample5.pdf", - createCopy: true, - expectError: false, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - engine := new(QPdf) - err := engine.Provision(nil) - if err != nil { - t.Fatalf("expected error but got: %v", err) - } - - var destinationPath string - if tc.createCopy { - fs := gotenberg.NewFileSystem(new(gotenberg.OsMkdirAll)) - outputDir, err := fs.MkdirAll() - if err != nil { - t.Fatalf("expected error no but got: %v", err) - } - - defer func() { - err = os.RemoveAll(fs.WorkingDirPath()) - if err != nil { - t.Fatalf("expected no error while cleaning up but got: %v", err) - } - }() - - destinationPath = fmt.Sprintf("%s/copy_temp.pdf", outputDir) - source, err := os.Open(tc.inputPath) - if err != nil { - t.Fatalf("open source file: %v", err) - } - - defer func(source *os.File) { - err := source.Close() - if err != nil { - t.Fatalf("close file: %v", err) - } - }(source) - - destination, err := os.Create(destinationPath) - if err != nil { - t.Fatalf("create destination file: %v", err) - } - - defer func(destination *os.File) { - err := destination.Close() - if err != nil { - t.Fatalf("close file: %v", err) - } - }(destination) - - _, err = io.Copy(destination, source) - if err != nil { - t.Fatalf("copy source into destination: %v", err) - } - } else { - destinationPath = tc.inputPath - } - - err = engine.Flatten(tc.ctx, zap.NewNop(), destinationPath) - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectError && err == nil { - t.Fatal("expected error but got none") - } - }) - } -} - -func TestQPdf_Convert(t *testing.T) { - engine := new(QPdf) - err := engine.Convert(context.TODO(), zap.NewNop(), gotenberg.PdfFormats{}, "", "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestLibreOfficePdfEngine_ReadMetadata(t *testing.T) { - engine := new(QPdf) - _, err := engine.ReadMetadata(context.Background(), zap.NewNop(), "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} - -func TestLibreOfficePdfEngine_WriteMetadata(t *testing.T) { - engine := new(QPdf) - err := engine.WriteMetadata(context.Background(), zap.NewNop(), nil, "") - - if !errors.Is(err, gotenberg.ErrPdfEngineMethodNotSupported) { - t.Errorf("expected error %v, but got: %v", gotenberg.ErrPdfEngineMethodNotSupported, err) - } -} diff --git a/pkg/modules/webhook/middleware_test.go b/pkg/modules/webhook/middleware_test.go deleted file mode 100644 index 8940f406..00000000 --- a/pkg/modules/webhook/middleware_test.go +++ /dev/null @@ -1,582 +0,0 @@ -package webhook - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "io" - "math/rand" - "mime/multipart" - "net/http" - "net/http/httptest" - "strings" - "testing" - "time" - - "github.com/dlclark/regexp2" - "github.com/labstack/echo/v4" - "go.uber.org/zap" - - "github.com/gotenberg/gotenberg/v8/pkg/modules/api" -) - -func TestWebhookMiddlewareGuards(t *testing.T) { - buildMultipartFormDataRequest := func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - - err := writer.WriteField("foo", "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - - return req - } - - buildWebhookModule := func() *Webhook { - return &Webhook{ - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - errorAllowList: regexp2.MustCompile("", 0), - errorDenyList: regexp2.MustCompile("", 0), - maxRetry: 0, - retryMinWait: 0, - retryMaxWait: 0, - disable: false, - } - } - - for _, tc := range []struct { - scenario string - request *http.Request - mod *Webhook - next echo.HandlerFunc - noDeadline bool - expectError bool - expectHttpError bool - expectHttpStatus int - }{ - { - scenario: "no webhook URL, skip middleware", - request: buildMultipartFormDataRequest(), - mod: buildWebhookModule(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return nil - } - }(), - noDeadline: false, - expectError: false, - expectHttpError: false, - }, - { - scenario: "no webhook error URL", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - return req - }(), - mod: buildWebhookModule(), - noDeadline: false, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "context has no deadline", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - return req - }(), - mod: buildWebhookModule(), - noDeadline: true, - expectError: true, - }, - { - scenario: "webhook URL is not allowed", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - return req - }(), - mod: func() *Webhook { - mod := buildWebhookModule() - mod.allowList = regexp2.MustCompile("bar", 0) - return mod - }(), - noDeadline: false, - expectError: true, - }, - { - scenario: "webhook URL is denied", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - return req - }(), - mod: func() *Webhook { - mod := buildWebhookModule() - mod.denyList = regexp2.MustCompile("foo", 0) - return mod - }(), - noDeadline: false, - expectError: true, - }, - { - scenario: "webhook error URL is not allowed", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - return req - }(), - mod: func() *Webhook { - mod := buildWebhookModule() - mod.errorAllowList = regexp2.MustCompile("foo", 0) - return mod - }(), - noDeadline: false, - expectError: true, - }, - { - scenario: "webhook error URL is denied", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - return req - }(), - mod: func() *Webhook { - mod := buildWebhookModule() - mod.errorDenyList = regexp2.MustCompile("bar", 0) - return mod - }(), - noDeadline: false, - expectError: true, - }, - { - scenario: "invalid webhook method (GET)", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Method", http.MethodGet) - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - return req - }(), - mod: buildWebhookModule(), - noDeadline: false, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "invalid webhook error method (GET)", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - req.Header.Set("Gotenberg-Webhook-Error-Method", http.MethodGet) - return req - }(), - mod: buildWebhookModule(), - noDeadline: false, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "valid webhook method (POST) but invalid webhook error method (GET)", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Method", http.MethodPost) - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - req.Header.Set("Gotenberg-Webhook-Error-Method", http.MethodGet) - return req - }(), - mod: buildWebhookModule(), - noDeadline: false, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "valid webhook method (PATH) but invalid webhook error method (GET)", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Method", http.MethodPatch) - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - req.Header.Set("Gotenberg-Webhook-Error-Method", http.MethodGet) - return req - }(), - mod: buildWebhookModule(), - noDeadline: false, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "valid webhook method (PUT) but invalid webhook error method (GET)", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Method", http.MethodPut) - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - req.Header.Set("Gotenberg-Webhook-Error-Method", http.MethodGet) - return req - }(), - mod: buildWebhookModule(), - noDeadline: false, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - { - scenario: "invalid webhook extra HTTP headers", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Webhook-Url", "foo") - req.Header.Set("Gotenberg-Webhook-Error-Url", "bar") - req.Header.Set("Gotenberg-Webhook-Extra-Http-Headers", "foo") - return req - }(), - mod: buildWebhookModule(), - noDeadline: false, - expectError: true, - expectHttpError: true, - expectHttpStatus: http.StatusBadRequest, - }, - } { - t.Run(tc.scenario, func(t *testing.T) { - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - - c := srv.NewContext(tc.request, httptest.NewRecorder()) - - if tc.noDeadline { - ctx := &api.ContextMock{Context: &api.Context{Context: context.Background()}} - ctx.SetEchoContext(c) - c.Set("context", ctx.Context) - c.Set("cancel", func() context.CancelFunc { - return nil - }()) - } else { - timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Duration(10)*time.Second) - ctx := &api.ContextMock{Context: &api.Context{Context: timeoutCtx}} - ctx.SetEchoContext(c) - c.Set("context", ctx.Context) - c.Set("cancel", cancel) - } - - err := webhookMiddleware(tc.mod).Handler(tc.next)(c) - - if tc.expectError && err == nil { - t.Fatal("expected error but got none", err) - } - - if !tc.expectError && err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - var httpErr api.HttpError - isHttpError := errors.As(err, &httpErr) - - if tc.expectHttpError && !isHttpError { - t.Errorf("expected an HTTP error but got: %v", err) - } - - if !tc.expectHttpError && isHttpError { - t.Errorf("expected no HTTP error but got one: %v", httpErr) - } - - if err != nil && tc.expectHttpError && isHttpError { - status, _ := httpErr.HttpError() - if status != tc.expectHttpStatus { - t.Errorf("expected %d as HTTP status code but got %d", tc.expectHttpStatus, status) - } - } - }) - } -} - -func TestWebhookMiddlewareAsynchronousProcess(t *testing.T) { - buildMultipartFormDataRequest := func() *http.Request { - body := &bytes.Buffer{} - writer := multipart.NewWriter(body) - - defer func() { - err := writer.Close() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - }() - - err := writer.WriteField("foo", "foo") - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - req := httptest.NewRequest(http.MethodPost, "/", body) - req.Header.Set(echo.HeaderContentType, writer.FormDataContentType()) - - return req - } - - buildWebhookModule := func() *Webhook { - return &Webhook{ - allowList: regexp2.MustCompile("", 0), - denyList: regexp2.MustCompile("", 0), - errorAllowList: regexp2.MustCompile("", 0), - errorDenyList: regexp2.MustCompile("", 0), - maxRetry: 0, - retryMinWait: 0, - retryMaxWait: 0, - clientTimeout: time.Duration(30) * time.Second, - disable: false, - } - } - - for _, tc := range []struct { - scenario string - request *http.Request - mod *Webhook - next echo.HandlerFunc - expectWebhookContentType string - expectWebhookMethod string - expectWebhookExtraHttpHeaders map[string]string - expectWebhookFilename string - expectWebhookErrorStatus int - expectWebhookErrorMessage string - returnedError *echo.HTTPError - }{ - { - scenario: "next handler return an error", - request: buildMultipartFormDataRequest(), - mod: buildWebhookModule(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return errors.New("foo") - } - }(), - expectWebhookContentType: echo.MIMEApplicationJSON, - expectWebhookMethod: http.MethodPost, - expectWebhookErrorStatus: http.StatusInternalServerError, - expectWebhookErrorMessage: http.StatusText(http.StatusInternalServerError), - }, - { - scenario: "next handler return an HTTP error", - request: buildMultipartFormDataRequest(), - mod: buildWebhookModule(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - return api.NewSentinelHttpError(http.StatusBadRequest, http.StatusText(http.StatusBadRequest)) - } - }(), - expectWebhookContentType: echo.MIMEApplicationJSON, - expectWebhookMethod: http.MethodPost, - expectWebhookErrorStatus: http.StatusBadRequest, - expectWebhookErrorMessage: http.StatusText(http.StatusBadRequest), - }, - { - scenario: "success", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Output-Filename", "foo") - req.Header.Set("Gotenberg-Webhook-Extra-Http-Headers", `{ "foo": "bar" }`) - return req - }(), - mod: buildWebhookModule(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - ctx := c.Get("context").(*api.Context) - return ctx.AddOutputPaths("/tests/test/testdata/api/sample2.pdf") - } - }(), - expectWebhookContentType: "application/pdf", - expectWebhookMethod: http.MethodPost, - expectWebhookFilename: "foo", - expectWebhookExtraHttpHeaders: map[string]string{"foo": "bar"}, - }, - { - scenario: "success (return an error)", - request: func() *http.Request { - req := buildMultipartFormDataRequest() - req.Header.Set("Gotenberg-Output-Filename", "foo") - return req - }(), - mod: buildWebhookModule(), - next: func() echo.HandlerFunc { - return func(c echo.Context) error { - ctx := c.Get("context").(*api.Context) - return ctx.AddOutputPaths("/tests/test/testdata/api/sample1.pdf") - } - }(), - returnedError: echo.ErrInternalServerError, - expectWebhookContentType: echo.MIMEApplicationJSON, - expectWebhookMethod: http.MethodPost, - expectWebhookErrorStatus: http.StatusInternalServerError, - expectWebhookErrorMessage: http.StatusText(http.StatusInternalServerError), - expectWebhookFilename: "foo", - }, - } { - func() { - srv := echo.New() - srv.HideBanner = true - srv.HidePort = true - - c := srv.NewContext(tc.request, httptest.NewRecorder()) - c.Set("logger", zap.NewNop()) - c.Set("traceHeader", "Gotenberg-Trace") - c.Set("trace", "foo") - c.Set("startTime", time.Now()) - - timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Duration(10)*time.Second) - ctx := &api.ContextMock{Context: &api.Context{Context: timeoutCtx}} - ctx.SetLogger(zap.NewNop()) - ctx.SetEchoContext(c) - - c.Set("context", ctx.Context) - c.Set("cancel", cancel) - - webhook := echo.New() - webhook.HideBanner = true - webhook.HidePort = true - webhookPort := rand.Intn(65535-1025+1) + 1025 - - c.Request().Header.Set("Gotenberg-Webhook-Url", fmt.Sprintf("http://localhost:%d/", webhookPort)) - c.Request().Header.Set("Gotenberg-Webhook-Error-Url", fmt.Sprintf("http://localhost:%d/", webhookPort)) - - errChan := make(chan error, 1) - - webhook.POST( - "/", - func() echo.HandlerFunc { - return func(c echo.Context) error { - contentType := c.Request().Header.Get(echo.HeaderContentType) - if contentType != tc.expectWebhookContentType { - t.Errorf("expected '%s' '%s' but got '%s'", echo.HeaderContentType, tc.expectWebhookContentType, contentType) - } - - trace := c.Request().Header.Get("Gotenberg-Trace") - if trace != "foo" { - t.Errorf("expected '%s' '%s' but got '%s'", "Gotenberg-Trace", "foo", trace) - } - - method := c.Request().Method - if method != tc.expectWebhookMethod { - t.Errorf("expected HTTP method '%s' but got '%s'", tc.expectWebhookMethod, method) - } - - for key, expect := range tc.expectWebhookExtraHttpHeaders { - actual := c.Request().Header.Get(key) - - if actual != expect { - t.Errorf("expected '%s' '%s' but got '%s'", key, expect, actual) - } - } - - if contentType == echo.MIMEApplicationJSON { - body, err := io.ReadAll(c.Request().Body) - if err != nil { - errChan <- err - return nil - } - - result := struct { - Status int `json:"status"` - Message string `json:"message"` - }{} - - err = json.Unmarshal(body, &result) - if err != nil { - errChan <- err - return nil - } - - if result.Status != tc.expectWebhookErrorStatus { - t.Errorf("expected status %d from JSON but got %d", tc.expectWebhookErrorStatus, result.Status) - } - - if result.Message != tc.expectWebhookErrorMessage { - t.Errorf("expected message '%s' from JSON but got '%s'", tc.expectWebhookErrorMessage, result.Message) - } - - errChan <- nil - return nil - } - - contentLength := c.Request().Header.Get(echo.HeaderContentLength) - if contentLength == "" { - t.Errorf("expected non empty '%s'", echo.HeaderContentLength) - } - - contentDisposition := c.Request().Header.Get(echo.HeaderContentDisposition) - if !strings.Contains(contentDisposition, tc.expectWebhookFilename) { - t.Errorf("expected '%s' '%s' to contain '%s'", echo.HeaderContentDisposition, contentDisposition, tc.expectWebhookFilename) - } - - body, err := io.ReadAll(c.Request().Body) - if err != nil { - errChan <- err - return nil - } - - if body == nil || len(body) == 0 { - t.Error("expected non nil body") - } - - errChan <- nil - - if tc.returnedError != nil { - return tc.returnedError - } - - return nil - } - }(), - ) - - go func() { - err := webhook.Start(fmt.Sprintf(":%d", webhookPort)) - if !errors.Is(err, http.ErrServerClosed) { - t.Errorf("expected no error but got: %v", err) - } - }() - - defer func() { - err := webhook.Shutdown(context.TODO()) - if err != nil { - t.Errorf("expected no error but got: %v", err) - } - }() - - err := webhookMiddleware(tc.mod).Handler(tc.next)(c) - if err != nil && !errors.Is(err, api.ErrAsyncProcess) { - t.Errorf("expected no error but got: %v", err) - } - - err = <-errChan - if err != nil { - t.Errorf("expected no error but got: %v", err) - } - }() - } -} diff --git a/pkg/modules/webhook/webhook_test.go b/pkg/modules/webhook/webhook_test.go deleted file mode 100644 index 03928046..00000000 --- a/pkg/modules/webhook/webhook_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package webhook - -import ( - "reflect" - "testing" - - "github.com/gotenberg/gotenberg/v8/pkg/gotenberg" -) - -func TestWebhook_Descriptor(t *testing.T) { - descriptor := new(Webhook).Descriptor() - - actual := reflect.TypeOf(descriptor.New()) - expect := reflect.TypeOf(new(Webhook)) - - if actual != expect { - t.Errorf("expected '%s' but got '%s'", expect, actual) - } -} - -func TestWebhook_Provision(t *testing.T) { - mod := new(Webhook) - ctx := gotenberg.NewContext( - gotenberg.ParsedFlags{ - FlagSet: new(Webhook).Descriptor().FlagSet, - }, - nil, - ) - - err := mod.Provision(ctx) - if err != nil { - t.Errorf("expected no error but got: %v", err) - } -} - -func TestWebhook_Middlewares(t *testing.T) { - for _, tc := range []struct { - scenario string - disable bool - expectMiddlewares int - }{ - { - scenario: "webhook disabled", - disable: true, - expectMiddlewares: 0, - }, - { - scenario: "webhook enabled", - disable: false, - expectMiddlewares: 1, - }, - } { - mod := new(Webhook) - mod.disable = tc.disable - - middlewares, err := mod.Middlewares() - if err != nil { - t.Fatalf("expected no error but got: %v", err) - } - - if tc.expectMiddlewares != len(middlewares) { - t.Errorf("expected %d middlewares but got %d", tc.expectMiddlewares, len(middlewares)) - } - } -} diff --git a/test/Dockerfile b/test/Dockerfile deleted file mode 100644 index a0dad3ff..00000000 --- a/test/Dockerfile +++ /dev/null @@ -1,50 +0,0 @@ -ARG GOLANG_VERSION -ARG DOCKER_REGISTRY -ARG DOCKER_REPOSITORY -ARG GOTENBERG_VERSION -ARG GOLANGCI_LINT_VERSION - -FROM golang:$GOLANG_VERSION-bookworm AS golang - -# We're extending the Gotenberg's Docker image because our code relies on external -# dependencies like Google Chrome, LibreOffice, etc. -FROM $DOCKER_REGISTRY/$DOCKER_REPOSITORY:$GOTENBERG_VERSION - -USER root - -ENV GOPATH=/go -ENV PATH=$GOPATH/bin:/usr/local/go/bin:$PATH -ENV CGO_ENABLED=1 - -COPY --from=golang /usr/local/go /usr/local/go - -RUN apt-get update -qq &&\ - apt-get upgrade -yqq &&\ - apt-get install -y -qq --no-install-recommends \ - sudo \ - # gcc for cgo. - g++ \ - gcc \ - libc6-dev \ - make \ - pkg-config &&\ - rm -rf /var/lib/apt/lists/* &&\ - mkdir -p "$GOPATH/src" "$GOPATH/bin" &&\ - chmod -R 777 "$GOPATH" &&\ - adduser gotenberg sudo &&\ - echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers &&\ - # We cannot use $PATH in the next command (print $PATH instead of the environment variable value). - sed -i 's#/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin#/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/go/bin:/usr/local/go/bin#g' /etc/sudoers &&\ - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin $GOLANGCI_LINT_VERSION &&\ - go install mvdan.cc/gofumpt@latest &&\ - go install github.com/daixiang0/gci@latest - -COPY ./test/docker-entrypoint.sh /usr/bin/docker-entrypoint.sh -COPY ./test/golint.sh /usr/bin/golint -COPY ./test/gotest.sh /usr/bin/gotest -COPY ./test/gotodos.sh /usr/bin/gotodos - -# Pristine working directory. -WORKDIR /tests - -ENTRYPOINT [ "/usr/bin/tini", "--", "docker-entrypoint.sh" ] \ No newline at end of file diff --git a/test/docker-entrypoint.sh b/test/docker-entrypoint.sh deleted file mode 100755 index 4862f516..00000000 --- a/test/docker-entrypoint.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -# This entrypoint allows us to set the UID and GID of the host user so that -# our testing environment does not override files permissions from the host. -# Credits: https://github.com/thecodingmachine/docker-images-php. - -set +e -mkdir -p testing_file_system_rights.foo -chmod 700 testing_file_system_rights.foo -su gotenberg -c "touch testing_file_system_rights.foo/foo > /dev/null 2>&1" -HAS_CONSISTENT_RIGHTS=$? - -if [[ "$HAS_CONSISTENT_RIGHTS" != "0" ]]; then - # If not specified, the DOCKER_USER is the owner of the current working directory (heuristic!). - DOCKER_USER=$(stat -c '%u' "$(pwd)") -else - # macOs or Windows. - # Note: in most cases, we don't care about the rights (they are not respected). - FILE_OWNER=$(stat -c '%u' "testing_file_system_rights.foo/foo") - if [[ "$FILE_OWNER" == "0" ]]; then - # If root, we are likely on a Windows host. - # All files will belong to root, but it does not matter as everybody can write/delete - # those (0777 access rights). - DOCKER_USER=gotenberg - else - # In case of a NFS mount (common on macOS), the created files will belong to the NFS user. - DOCKER_USER=$FILE_OWNER - fi -fi - -rm -rf testing_file_system_rights.foo -set -e -unset HAS_CONSISTENT_RIGHTS - -# Note: DOCKER_USER is either a username (if the user exists in the container), -# otherwise a user ID (a user from the host). - -# DOCKER_USER is an ID. -if [[ "$DOCKER_USER" =~ ^[0-9]+$ ]] ; then - # Let's change the gotenberg user's ID in order to match this free ID. - usermod -u "$DOCKER_USER" -G sudo gotenberg - DOCKER_USER=gotenberg -fi - -DOCKER_USER_ID=$(id -ur $DOCKER_USER) - -# Fix access rights to stdout and stderr. -set +e -chown $DOCKER_USER /proc/self/fd/{1,2} -set -e - -# Install modules. -set -x -go mod download -go mod tidy -set +x - -# Run the command with the correct user. -exec "sudo" "-E" "-H" "-u" "#$DOCKER_USER_ID" "$@" diff --git a/test/golint.sh b/test/golint.sh deleted file mode 100755 index 107c7018..00000000 --- a/test/golint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -set -x - -golangci-lint run \ No newline at end of file diff --git a/test/gotest.sh b/test/gotest.sh deleted file mode 100755 index 99bb6433..00000000 --- a/test/gotest.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -x - -go test -race -covermode=atomic -coverprofile=/tests/coverage.txt ./... -RESULT=$? - -go tool cover -html=coverage.txt -o /tests/coverage.html - -exit $RESULT \ No newline at end of file diff --git a/test/gotodos.sh b/test/gotodos.sh deleted file mode 100755 index c6201369..00000000 --- a/test/gotodos.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -set -x - -golangci-lint run \ - --no-config \ - --disable-all \ - --enable godox \ No newline at end of file diff --git a/test/integration/doc.go b/test/integration/doc.go new file mode 100644 index 00000000..d52de84a --- /dev/null +++ b/test/integration/doc.go @@ -0,0 +1,2 @@ +// Package integration contains everything related to integration testing. +package integration diff --git a/test/integration/features/chromium_convert_html.feature b/test/integration/features/chromium_convert_html.feature new file mode 100644 index 00000000..4f615c74 --- /dev/null +++ b/test/integration/features/chromium_convert_html.feature @@ -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" diff --git a/test/integration/features/chromium_convert_markdown.feature b/test/integration/features/chromium_convert_markdown.feature new file mode 100644 index 00000000..286ea933 --- /dev/null +++ b/test/integration/features/chromium_convert_markdown.feature @@ -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" diff --git a/test/integration/features/chromium_convert_url.feature b/test/integration/features/chromium_convert_url.feature new file mode 100644 index 00000000..b48c2f4a --- /dev/null +++ b/test/integration/features/chromium_convert_url.feature @@ -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" diff --git a/test/integration/features/debug.feature b/test/integration/features/debug.feature new file mode 100644 index 00000000..a68e5fe7 --- /dev/null +++ b/test/integration/features/debug.feature @@ -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 diff --git a/test/integration/features/health.feature b/test/integration/features/health.feature new file mode 100644 index 00000000..887808f8 --- /dev/null +++ b/test/integration/features/health.feature @@ -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. \ No newline at end of file diff --git a/test/integration/features/libreoffice_convert.feature b/test/integration/features/libreoffice_convert.feature new file mode 100644 index 00000000..91a4fcb9 --- /dev/null +++ b/test/integration/features/libreoffice_convert.feature @@ -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" diff --git a/test/integration/features/pdfengines_convert.feature b/test/integration/features/pdfengines_convert.feature new file mode 100644 index 00000000..867dfcf0 --- /dev/null +++ b/test/integration/features/pdfengines_convert.feature @@ -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" diff --git a/test/integration/features/pdfengines_flatten.feature b/test/integration/features/pdfengines_flatten.feature new file mode 100644 index 00000000..521a93ae --- /dev/null +++ b/test/integration/features/pdfengines_flatten.feature @@ -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" diff --git a/test/integration/features/pdfengines_merge.feature b/test/integration/features/pdfengines_merge.feature new file mode 100644 index 00000000..248a81ad --- /dev/null +++ b/test/integration/features/pdfengines_merge.feature @@ -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" diff --git a/test/integration/features/pdfengines_metadata.feature b/test/integration/features/pdfengines_metadata.feature new file mode 100644 index 00000000..1cbb0ee1 --- /dev/null +++ b/test/integration/features/pdfengines_metadata.feature @@ -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" diff --git a/test/integration/features/pdfengines_split.feature b/test/integration/features/pdfengines_split.feature new file mode 100644 index 00000000..d9813bfb --- /dev/null +++ b/test/integration/features/pdfengines_split.feature @@ -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" diff --git a/test/integration/features/prometheus_metrics.feature b/test/integration/features/prometheus_metrics.feature new file mode 100644 index 00000000..e42c3d78 --- /dev/null +++ b/test/integration/features/prometheus_metrics.feature @@ -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 diff --git a/test/integration/features/root.feature b/test/integration/features/root.feature new file mode 100644 index 00000000..9ebf0e17 --- /dev/null +++ b/test/integration/features/root.feature @@ -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 documentation 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 diff --git a/test/integration/features/version.feature b/test/integration/features/version.feature new file mode 100644 index 00000000..b9d9ae93 --- /dev/null +++ b/test/integration/features/version.feature @@ -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 diff --git a/test/integration/main_test.go b/test/integration/main_test.go new file mode 100644 index 00000000..f7743281 --- /dev/null +++ b/test/integration/main_test.go @@ -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) +} diff --git a/test/integration/scenario/compare.go b/test/integration/scenario/compare.go new file mode 100644 index 00000000..5f61337f --- /dev/null +++ b/test/integration/scenario/compare.go @@ -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 +} diff --git a/test/integration/scenario/containers.go b/test/integration/scenario/containers.go new file mode 100644 index 00000000..1d752ca1 --- /dev/null +++ b/test/integration/scenario/containers.go @@ -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 +} diff --git a/test/integration/scenario/doc.go b/test/integration/scenario/doc.go new file mode 100644 index 00000000..a874ef8f --- /dev/null +++ b/test/integration/scenario/doc.go @@ -0,0 +1,2 @@ +// Package scenario gathers all steps used in the features. +package scenario diff --git a/test/integration/scenario/http.go b/test/integration/scenario/http.go new file mode 100644 index 00000000..7d88d02b --- /dev/null +++ b/test/integration/scenario/http.go @@ -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 +} diff --git a/test/integration/scenario/scenario.go b/test/integration/scenario/scenario.go new file mode 100644 index 00000000..b76e739d --- /dev/null +++ b/test/integration/scenario/scenario.go @@ -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, "") { + return fmt.Errorf("PDF %q is flatten", path) + } + + if !invert && !strings.Contains(output, "") { + 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 + }) +} diff --git a/test/integration/scenario/server.go b/test/integration/scenario/server.go new file mode 100644 index 00000000..ddf2f0a1 --- /dev/null +++ b/test/integration/scenario/server.go @@ -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) +} diff --git a/test/integration/testdata/feature-rich-html-remote/index.html b/test/integration/testdata/feature-rich-html-remote/index.html new file mode 100644 index 00000000..edfb3077 --- /dev/null +++ b/test/integration/testdata/feature-rich-html-remote/index.html @@ -0,0 +1,64 @@ + + + + + + + Feature Rich HTML + + + + +

Emulated media type is 'print'.

+

Emulated media type is 'screen'.

+ + + + + + + + + + + + + + diff --git a/test/integration/testdata/feature-rich-html/index.html b/test/integration/testdata/feature-rich-html/index.html new file mode 100644 index 00000000..f679383e --- /dev/null +++ b/test/integration/testdata/feature-rich-html/index.html @@ -0,0 +1,69 @@ + + + + + + + + + + + Feature Rich HTML + + + + +

Emulated media type is 'print'.

+

Emulated media type is 'screen'.

+ + + + + + + + + + + + + + + diff --git a/test/integration/testdata/feature-rich-markdown/index.html b/test/integration/testdata/feature-rich-markdown/index.html new file mode 100644 index 00000000..cc3fec01 --- /dev/null +++ b/test/integration/testdata/feature-rich-markdown/index.html @@ -0,0 +1,70 @@ + + + + + + + + + + + Feature Rich HTML + + + + {{ toHTML "table.md" }} + +

Emulated media type is 'print'.

+

Emulated media type is 'screen'.

+ + + + + + + + + + + + + + + diff --git a/test/integration/testdata/feature-rich-markdown/table.md b/test/integration/testdata/feature-rich-markdown/table.md new file mode 100644 index 00000000..bf2ab2f7 --- /dev/null +++ b/test/integration/testdata/feature-rich-markdown/table.md @@ -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 | diff --git a/test/integration/testdata/header-footer-html/footer.html b/test/integration/testdata/header-footer-html/footer.html new file mode 100644 index 00000000..41185251 --- /dev/null +++ b/test/integration/testdata/header-footer-html/footer.html @@ -0,0 +1,13 @@ + + + + + +

of

+ + diff --git a/test/integration/testdata/header-footer-html/header.html b/test/integration/testdata/header-footer-html/header.html new file mode 100644 index 00000000..f9501f91 --- /dev/null +++ b/test/integration/testdata/header-footer-html/header.html @@ -0,0 +1,13 @@ + + + + + + + + diff --git a/test/integration/testdata/page-1-html/index.html b/test/integration/testdata/page-1-html/index.html new file mode 100644 index 00000000..9fd123da --- /dev/null +++ b/test/integration/testdata/page-1-html/index.html @@ -0,0 +1,9 @@ + + + + Page 1 + + +

Page 1

+ + diff --git a/test/integration/testdata/page-1-markdown/index.html b/test/integration/testdata/page-1-markdown/index.html new file mode 100644 index 00000000..d2b7442b --- /dev/null +++ b/test/integration/testdata/page-1-markdown/index.html @@ -0,0 +1,9 @@ + + + + Page 1 + + + {{ toHTML "page_1.md" }} + + diff --git a/test/integration/testdata/page-1-markdown/page_1.md b/test/integration/testdata/page-1-markdown/page_1.md new file mode 100644 index 00000000..96080014 --- /dev/null +++ b/test/integration/testdata/page-1-markdown/page_1.md @@ -0,0 +1 @@ +# Page 1 diff --git a/test/integration/testdata/page_1.docx b/test/integration/testdata/page_1.docx new file mode 100644 index 0000000000000000000000000000000000000000..1868509c5fe654e5dc4edb66f210459c88aa3f25 GIT binary patch literal 6408 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 + + + Pages 12 + + + +

Page 1

+

Page 2

+

Page 3

+

Page 4

+

Page 5

+

Page 6

+

Page 7

+

Page 8

+

Page 9

+

Page 10

+

Page 11

+

Page 12

+ + diff --git a/test/integration/testdata/pages-12-markdown/index.html b/test/integration/testdata/pages-12-markdown/index.html new file mode 100644 index 00000000..79b9c6d2 --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/index.html @@ -0,0 +1,25 @@ + + + + Pages 12 + + + +
{{ toHTML "page_1.md" }}
+
{{ toHTML "page_2.md" }}
+
{{ toHTML "page_3.md" }}
+
{{ toHTML "page_4.md" }}
+
{{ toHTML "page_5.md" }}
+
{{ toHTML "page_6.md" }}
+
{{ toHTML "page_7.md" }}
+
{{ toHTML "page_8.md" }}
+
{{ toHTML "page_9.md" }}
+
{{ toHTML "page_10.md" }}
+
{{ toHTML "page_11.md" }}
+
{{ toHTML "page_12.md" }}
+ + diff --git a/test/integration/testdata/pages-12-markdown/page_1.md b/test/integration/testdata/pages-12-markdown/page_1.md new file mode 100644 index 00000000..96080014 --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_1.md @@ -0,0 +1 @@ +# Page 1 diff --git a/test/integration/testdata/pages-12-markdown/page_10.md b/test/integration/testdata/pages-12-markdown/page_10.md new file mode 100644 index 00000000..50459fd6 --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_10.md @@ -0,0 +1 @@ +# Page 10 diff --git a/test/integration/testdata/pages-12-markdown/page_11.md b/test/integration/testdata/pages-12-markdown/page_11.md new file mode 100644 index 00000000..fad63c84 --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_11.md @@ -0,0 +1 @@ +# Page 11 diff --git a/test/integration/testdata/pages-12-markdown/page_12.md b/test/integration/testdata/pages-12-markdown/page_12.md new file mode 100644 index 00000000..cfe1ccf8 --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_12.md @@ -0,0 +1 @@ +# Page 12 diff --git a/test/integration/testdata/pages-12-markdown/page_2.md b/test/integration/testdata/pages-12-markdown/page_2.md new file mode 100644 index 00000000..f310be33 --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_2.md @@ -0,0 +1 @@ +# Page 2 diff --git a/test/integration/testdata/pages-12-markdown/page_3.md b/test/integration/testdata/pages-12-markdown/page_3.md new file mode 100644 index 00000000..294d95c1 --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_3.md @@ -0,0 +1 @@ +# Page 3 diff --git a/test/integration/testdata/pages-12-markdown/page_4.md b/test/integration/testdata/pages-12-markdown/page_4.md new file mode 100644 index 00000000..7caf305d --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_4.md @@ -0,0 +1 @@ +# Page 4 diff --git a/test/integration/testdata/pages-12-markdown/page_5.md b/test/integration/testdata/pages-12-markdown/page_5.md new file mode 100644 index 00000000..eb51736e --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_5.md @@ -0,0 +1 @@ +# Page 5 diff --git a/test/integration/testdata/pages-12-markdown/page_6.md b/test/integration/testdata/pages-12-markdown/page_6.md new file mode 100644 index 00000000..74deae7e --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_6.md @@ -0,0 +1 @@ +# Page 6 diff --git a/test/integration/testdata/pages-12-markdown/page_7.md b/test/integration/testdata/pages-12-markdown/page_7.md new file mode 100644 index 00000000..8bc5eeaf --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_7.md @@ -0,0 +1 @@ +# Page 7 diff --git a/test/integration/testdata/pages-12-markdown/page_8.md b/test/integration/testdata/pages-12-markdown/page_8.md new file mode 100644 index 00000000..32ea6ab3 --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_8.md @@ -0,0 +1 @@ +# Page 8 diff --git a/test/integration/testdata/pages-12-markdown/page_9.md b/test/integration/testdata/pages-12-markdown/page_9.md new file mode 100644 index 00000000..6288d6f8 --- /dev/null +++ b/test/integration/testdata/pages-12-markdown/page_9.md @@ -0,0 +1 @@ +# Page 9 diff --git a/test/integration/testdata/pages-3-html/index.html b/test/integration/testdata/pages-3-html/index.html new file mode 100644 index 00000000..ab0e1d83 --- /dev/null +++ b/test/integration/testdata/pages-3-html/index.html @@ -0,0 +1,16 @@ + + + + Pages 3 + + + +

Page 1

+

Page 2

+

Page 3

+ + diff --git a/test/integration/testdata/pages-3-markdown/index.html b/test/integration/testdata/pages-3-markdown/index.html new file mode 100644 index 00000000..46ba2fe4 --- /dev/null +++ b/test/integration/testdata/pages-3-markdown/index.html @@ -0,0 +1,16 @@ + + + + Pages 3 + + + +
{{ toHTML "page_1.md" }}
+
{{ toHTML "page_2.md" }}
+
{{ toHTML "page_3.md" }}
+ + diff --git a/test/integration/testdata/pages-3-markdown/page_1.md b/test/integration/testdata/pages-3-markdown/page_1.md new file mode 100644 index 00000000..96080014 --- /dev/null +++ b/test/integration/testdata/pages-3-markdown/page_1.md @@ -0,0 +1 @@ +# Page 1 diff --git a/test/integration/testdata/pages-3-markdown/page_2.md b/test/integration/testdata/pages-3-markdown/page_2.md new file mode 100644 index 00000000..f310be33 --- /dev/null +++ b/test/integration/testdata/pages-3-markdown/page_2.md @@ -0,0 +1 @@ +# Page 2 diff --git a/test/integration/testdata/pages-3-markdown/page_3.md b/test/integration/testdata/pages-3-markdown/page_3.md new file mode 100644 index 00000000..294d95c1 --- /dev/null +++ b/test/integration/testdata/pages-3-markdown/page_3.md @@ -0,0 +1 @@ +# Page 3 diff --git a/test/integration/testdata/pages_12.docx b/test/integration/testdata/pages_12.docx new file mode 100644 index 0000000000000000000000000000000000000000..6fa6d1272cae78b6174b480d97c95cf462b31f9b GIT binary patch literal 6539 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 EA8~!?A^-pY literal 0 HcmV?d00001 diff --git a/test/integration/testdata/pages_3.docx b/test/integration/testdata/pages_3.docx new file mode 100644 index 0000000000000000000000000000000000000000..792f530be917475ca0e366a963535ec3d38b573d GIT binary patch literal 6454 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 literal 0 HcmV?d00001 diff --git a/test/integration/testdata/pages_3.pdf b/test/integration/testdata/pages_3.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2f5c4c030c8c1b14813e3d70c536f2b2f78da569 GIT binary patch literal 22548 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%0ACYL9{(&E+-Ie8;bPpF2ThpvZugc>7Fl2efp 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 E2DjGkHvj+t literal 0 HcmV?d00001 diff --git a/test/testdata/api/README.md b/test/integration/testdata/pem/README.md similarity index 100% rename from test/testdata/api/README.md rename to test/integration/testdata/pem/README.md diff --git a/test/testdata/api/cert.pem b/test/integration/testdata/pem/cert.pem similarity index 100% rename from test/testdata/api/cert.pem rename to test/integration/testdata/pem/cert.pem diff --git a/test/testdata/api/key.pem b/test/integration/testdata/pem/key.pem similarity index 100% rename from test/testdata/api/key.pem rename to test/integration/testdata/pem/key.pem diff --git a/test/integration/testdata/protected_page_1.docx b/test/integration/testdata/protected_page_1.docx new file mode 100644 index 0000000000000000000000000000000000000000..a7b0deb29acfe174e08f7a9b68fd9c866325f000 GIT binary patch literal 12288 zcmeHtbyVC*)@bAI9^8UMaCdLqCAe#Fg1fuBBm@W=2(E#oakt69B*l z(~!D{$HzxVH9i=@@0`8%Eu-?Z8tG+$f|1TXcw+k;`Urx^ z+wprQ-?^$lCK-5Yaq-L#PW$L6OUDv7Wi>wZmIFr5(fnw$lweX|?!H(sD-@*AoUI=Z zLhE69MeL(+1*dIS!;1?=Arf>{$&@%9hyZvJ(xgKNdc0^7d{L?&Z?eq$r-dk=v&i_G zVDTJ|iJ_lIVIE;kk2ZU}FUyIpS6!6}KRsZlsa^DZXjZu=u}VMOnBuk94BfnErAKhr zc&4TzAnmmpU+U7yfZ}iL-Z&%eF_WXmS&;By$32e`mWixW1k@tY7_uxterfb=qtX{u z98t}^r%vMeC?|eUtKHEGZK+AFq&HeC41&Eeao=sjFt)Y>s`)p7HK4`%zxKFCNaWG$aF6Cl&WR$tC4_G=STb@;7lpo=WyA0f zpVbR~2kXT*cVryOsTkj4`5LxsdBl9J#NOc!TW}q&eS+{Afh$SdOe2Xz#sjc) zzb^D){wyiiCT*9vF;xvCe8$tRU>rN;we$p5RvC41u-Jg;LX&-s??u>Fl3g!XzePmR6F^XqC_yZeD_{`c@zJRd=}K2g`!o~i zJ9eRBzgRpv%Zn;TeDGwGnFZ!`yzXmZHWL*SZ}eg=#ZLdL`KSSDEY4T4Gng3Jr7Pr4 z(n(=~rSM!9Qp`ZzUcd^Q$%#&#*WgA`kBt4oN8FBr%TZ||}K zhv0NbT=j)7xU4WyKIjm8ku@=A4Pm3~`}n!KbW(dvhd`I4Pa4BW^TuiSe9x>3QeS_- z;;Du2tPc5j=9dKiejN0JL3<-)-kk72rc$fK`ahkTvVZPTUxt0APnRI%*VZ19af^|vLL3MW;cW$a*~8JjUM><$ zDSno~?F_%VeYt+GZZIjUz|)9>^*F5@`Zm5%c=JMpx-uN@d$p^zq!2L-TM54qR)n;1 zPDKuU8NwG2cIWbNx-ya3)Ts0pm$mEXnqg#2&XnE0%$o5csGi^YF^Q9T9&Sir%pRuz z{H_yZ#}>Y^!0Sx|#Lo$eji?nuGzHQF={GD7rYJko(RU>qHcSi*s?R{&+#WQ~--UMI zrVhBTQ#nKXU-@S1iX@NB>m+$3VOt&%bFWN^;LyLenY*`0Exh2T&p!)8huW$O2uR@N zEZ1rguF1Elg;Pld^(N?Tpw{3uZi(;^@w@snVGCd~))5gD(hjYo@eq(s$C0j^5%ygL z0q04k@l0RgVJLaEQN`AlqdMxYv1x78oU&W!QoMB9-D5|1aX3}^ErN`E`D{gU~FxdsDYuJ#durrnew$8lslA-@n4HNm4v z8L_1-*VFy^#Qf8g4xP5*%3+?6o~e*rDjH&2r*Tz71vPh@X2DW{#0ytdd9%Zju4}}+ zya-s7@G!zns1KD>c$1nk`^uG4_dx zMI-H-*Us8RK9YX(J0YMx76SV!nWxG(wH@5TY~LOEP>MQkr5%{}u^ z$gnS()=Nr>5Kg|%wpaLtVJ&sh_Tb(#zHc{xA_jsUYHa==1+qAu{CTY~?7$+)X zcw8dBA1p6ZMn~36;%h*zu!hU$9{m0l4QJ{yLaXQ;X(vww`aURq5`!aUOV4^O(S%&n z-8d}bXgh7srOUF{%21%EFVlb$%M@M$U<|QYCis3gyq}Ira=(p1H)k^J`BFUV@IaQ?3yEMf{uQZNp zR9v)@uvTsvCj#6A_YiE@;@7nt_l2+px`l#)s*jz0z9H|jsNC5SdaC8#KMk$DHr{$R zGt%FTh5Srk>5#o_}eCeW@wK|15~yb%<&}(-HG>ibW0Xd8D_XYdvR9IP3}bUP@E8I%#em zNq``Z@_8xcbQ;ZP5zZhg@+)&RHotQ`3G!j|-smEqYCHh0Pp4tvmh3Ca#!rzTPl?sL zsFQj07-kiz@Qkkw-+05yUQN!8e$IpgMUh01!tPYerd_gNg+Gx$sOUb_Jm0!Zi@MK$ zvO^^N)fLZYSS#~uxFXEUl7n9h9 zhMg-j$Afc6V~0gYJtd1-{7b%#@BuP6^q#@n_hvUgyben{MUiv}e0EIx`Y`7Gs_*?q z?*fp6s#`i6R}#Twxm~r7O`LZBocZavn7QD$p!;M+W&yC{5Pc)gI*!(Z`K^kE8T@ch=6g_n*vi=ryh zOUEsmROsvtG2Sa;R-;w*+47?>91Q*Yf0s|Rg zRSrhekF-jYus>Ucl9a3$NW*{SMCz`6IlfE7PF2TrLIFZ%wAQEKq-`bKC_jWc+c#5D z(UDbGQK6Nhw;~F-6H2O4RLb=t)3!}|L&eL#zgJbQWi+QJk(b!IOm58)8Co@PY_bjC zX}&g1z44R+_6v#R%v{&N)6PmvBa^Q$E1DbME`W?gOU2nd`C+V5UIV2c`FD$PYvhl^ zjj=ApEn5p`P~%5^#N?a+YF~z31_iDU+4R#uH0~{y53TeWk>5E z@1I4Jpix*$Tt)b%9zjnjWiJL?X*8bjOX}kcj_fq&Wh;#2l>$KY*vc)b_PztHe@{A%-6~0r!t z?2EwhVIWu+qq5ES6H(WXRRwZAFN-`>+5BT=X`o5W_m|&#IjYmFCaXFFNdgJcJ=sYV z7swWrgYA1J>$FGtXlXQ|J*TJTKfM+&9QNU+=jmPuG!fjbCDC_u?I4_f=&ytNUMrPt z4|LfcA1QrahPw|d+GO(3eKSO+o^4&->Z2hXNM2IWGA%XRWyBPBY-f^^ z%No_BDc5SK;HgvV(;9y{R$}9dMN#Hrk(TL?oBFgAHmVC3LuV z2v;~pdyF4-I&!0}@ppO?N>ybKwhONnV{D<`R>s7Us&lvEbV#mXjmV)K^!u-HnWmai z$e!-`VM5`WsPCy4Hp__{iF4MzSnyauVaTrLR5#ir$0*2z+nS{+>d$wilaQNUKO+5v zZtK<}@m?*T39n7>rp@utLRs-^7^(mIlNTtaxX5@J|OYSCxiFuASez@*0uui=C8R68lCltL2O7E`9`nAOrD zieiSXH*AVxtqb^X(onfcxJc&YRH({_g~^7i8|=_SRxxLDN)xSgvNz0(n9%DPg7g)4 zUfN8!z6*%|sGL@{-)W+AS)ha^Xp>Fgra<< zOM>`H6=K6jqC%IVIo3k=$PuWT;w1WI5cXqG$c>7*imrZCLgelM&%!y33+UNZ8+P7C zE0tO zv=v19T503oa6@O^fR6t$SzyG>>&)Zpn$yE~4<1LF@yi8Ip2Wr;Z^{_$dO3 zbh*Xoxg(zs`B{7%)w#;DX`F^{Lr?Gbp*htO9hjAvtd?G`x+ zx0+uL>P9HXIY*Puq@OuRlW()GB0O5pg>Z}Ng*47NZ8o$BR4>QATNzlY{!ChNVvca~RQB0@bezG+oNbQu{bF1OKN_=DD3BvN4nyccR^if2$-#%0No`T0 zn86zFjbcsWkcVvxA?Je$FHBs~&36jPaHn{(!nbt51SdqSAT_^ZAKi}l*R+M8J`p26^eu`DDb|${nS+wMe6AIHmA=5+IZ_SoQ$s~iM~I}_`~M1Jq0Jl z^5BY&nox(4^!#9eeh_>xg-iSNhqfHrQ2P1Mf}G^2h+7QB&&2#D*Xt-f4V#TA>K1)S zFF6!3teArnx1W}2Rvs)J zr8(>hkhZv0ahGVDU^&~(3z4DGgZF4RWqPpRm*Pr=OnyOcwwOzvY)xg`HVeKZc(x6r zL1Gg+AIDX>pLK8hlF<(kJT5&aS^vEIa9cc-CBlEb>^?%S+^Y%C!e4uBnc?>dDrNVPVoGRbk%_teqmi4Iesu zgxJxpmb@hdw(mV`7zv*a$&&MczSBm^yW)GG1DOe*^5qZZ57s0lxK+eN!0I2{+!=<~ zx3X9jL_BJ3FVCO?pd)klv#_*$(!@JY%&tCQ2b6uBOMS)gN>y@{WZs-Q#%MS?!9Ptg zJ&h``WpF!c!a1PY=B7(4?wzIi0OvZeuPWMgCQ1%%?OZAWR8oeXufEoCVCmaKm64h( zAr|7-I3Q^dP95my)}$`hksxx63d^rm>U-?b_bA+Hd*elgZIv)L8%=Gv2-Hz`wIAhQ z3qb<%)fg{C@-Q>g?}0477t_WMp#^XrmavwS3?Y1J-q=+;&oa_6OY~Z3a3yn zEp!#%hvZw!TvsUR$m}k)*8V3u6e0@WC22FcJ(+6m=f(PP?u~5^fRVs(1JNHzAtKT} z`WW}Pp~_xJ5qMAfD>;wCQ|Ot;0x{nzn~P_%Xv-4|JV^~@OBQ+kW8T9IalN#_dyC3< z1r9zCyC{L1PwQaq7OkqUB$6TBjq4NqIdhsf^ixfb8|F>55B(r3B7gHB&bk@KL%RmE ztQcw#pQN{2x*l0A3eSRReV+$Sm~29RSa$fkrNl6&&TA&|Tx&(4Pu*H&OT0LX486s# zwhumO+Q~*<$5YC8WR@`E@sra-YvsMjj;aMKB&EF~-2jTR=sSUTM z2%lxx04DlbUtObQ_K*1u1UCR)ST+(lynRKz8=o)VG~z!%QfB8+-!{j7!VoJ+*!o5_ zkiC_$4J031YGK9$TB-D+ZS;k+A()rGPOWrwROjD=Wh8w@%3LclITaW(c0$;Oom3=V z&S80^m3zuIu^Mm?86nZeL>V4RrS>#}xkl5V*kIG8oEc35e?z{(1pl5p(7Dxv{vpzb z?#NRpu{^PNV*4QbYW1`KfHNVz@bZ_3pBS z4PCc5wjX2Uk(`=UlsmrqBo`0O?_WUeR+H*ryes_}D_1&kWuEzJI5_9FcUv z%VdwPZp|r1`mGn|Q4rglWqD^AmbwekLli=aDxSMTvk|Dbuwp(5ORS=;B>6i?YHDxL ze~vnRq=ce;>j6S6uJx@BqJ7 zlN@=ob$8i;;z?IroDcTOM1FLlYo38p`WqGr2N#K0Xm$BY6%sXi{4uc5+J#kqqoRX) zb#)mT0WXYqbs6sm_(B=(G4Z+Z>pcJ`!SlNjDrH8@+C3BTyaqV@Yo3KywyCpIUn0KO z-oZf+YZr{qikQnGv>9tR#KUJYd2|>{`v50QSdymzHJWG>!$yJ(Sh{DtD(FpF<*Cdz zUqoAzm@)5cE^ktHzxssSUa!t_eOAnR-9OY`82GaI5&<1L%w<0eesn0!~1gd_M34Hu*of)it1rOn$e>KQ|$=)y|3C zP9pi4EC7}*KG}4Op%(oAdIWEZ)(?Z^1StFpCwGsHdQA?%Md*x(lR2TaknCCf`|uZt zJ~^>?ch`S^N4cCA^E>tYEF3lmiHn2eF5|G9S$UNT-~CAc8m5q&|a7 zgO8ON=X+>Sj)?2g);NkJu5TBNrxW?Urfv^6ItJ$;@d8b0#hkKQ_Xc#B&5LL`2>)dB z8y;E^dy3j7=q8rb46j~uIs%w2lopyx>sMZB94C$Yw&$A7I7sj7rqLI#BxT%y6oJ~e zE+cp9Vbj%NeN7j7dv}#|t_5`o-6GvWh&)Dyer~TmLUYfYc(9#L7qKuB2^3*fTnFC) z(L~9(8|kkSkP_iUf?Ncz>0r%Kb!+{);gfeAW-4$-4rDAQeq6+mduV>OzY_IqbTpR- zF@JA%PkL-o_lNI2F8Pr*gK{bmRrQ0vMk`UCTJg0E@*6%S1{RWg??oocmG92|8GC*? zjg2@q+vDwqtCX-cA$&&pMwHi5mT&3fW7xuNzXXg50BzuhVUwdMUe-?rzMwaKGVs{> zRZOw_TmAa*ev^Wr7d2i+M#p0I1hPCQN3nocJ3xdWa1f3fv9PI7>YQS%*r3LrZYYLb zPHCzJd!5(Y604kO_U78+$l``rPN(~msCRN%SE^|vIl+ajex5D5T|3el9#P(Ta0Ack zkG$#$f-+q^4a%;JgY>+#?9^^L(ePoem^ZB?$OvW#*ADWUE}Pz+8a8JkNkm4Ep9Ehr zpR*)r(dA`pOEPbu9!Rkb+xyfb;e6q`TyAZhd!~9hp4He+Mb6i>L(#KBXO0(0F3W<( z*17NoY7fB;Q{JFg{|w5!pgb#M(~0HXu0KB}9FGP=pRuuYq4iNQM%m-g(oLIqw#zt! zG29lbZ@xl8&u{xj_w9Hu@!a6aO4|zg%LkcUZ zoR>Whc_}m3GDO~rU6#}UM!;g}Nn!m`jUY0%N=fd%VvOU#Fc(iDy>LY6$8+r8e-AvG zDlWp{um?@G0I&M>W}0TO?^tHVjIk)~uK6!thx?{{3&C&_=8BJ!4b}fxzT55dO0~T# zXMZsJk;@N8vf}gazxVi$owCBiqKPu#)X80nh%&+QJDm@WJ*+$Hvpxy}zxqk@aI#!Q zpV7fEKdLg?xP7FD!%ozBs3_I<7&3G?L;83>iC>+`G<#-PI7z+Pvs(=(_7LF0VrGR8 zM^`^vPZx*6FJVsJs1;P_z?`NUAL3?Ji7z*?J!#PEyVqsLUK$zL-8PzpI@frZJf|fc z{QMr7D%Lm1F$c7$tn0vh+D|zmu)4}HIU-Tc*a_8m>WYw{4*$NlC<7;yJ8prRU(h{* z61k0L*7(j*HOy#4F8*>Ao@q3dB-dsa95C;d%*#B@IbT;HZ)Ry(v^QOKmj?dc|J~Dr z16j7&?9UOWMCLJmY?+ul2dboZ;$u8n&IuoGrf9ctM2+_%+Gzi8CxwznwuEij#Qb;T^dfp-jDo26)5KJi` zMXFStl2|fwm%ANZ&~)Ox=&=Pa=5D-Ve%H{2!@_Us8OY)!Q?d}vB(B=XP@Tl{1u@20 z#fYS|*p6(+O7XZasNwhfQ_Q(~;H8z~6^40TF^rR+;P3tax3Ap)O@HqJA#jBfz!qQ* za0NI4+`woBa0jpgB*D}RFl7pEdjYTnx3U7Hz$HkH2EZAdnuBZIe!l;Jya9pWe*%c$ zL6EUFzj6o<3NT88r9yP_2Fr2>OR@l{{*-ACPOZUZ4sah0a0^817vP$I?r;0E_K*64 z2mKCylmBPjW$S8bAXc76(R14gqv4001@!009312*LOp{LvnYpYvw()2op6WC5Ogb@053 zgL8s;K;VyOl+w@0_P5r5pFa5|9}>g= ztbB-{oPV+YqkMU=A0X%3p97L#{)fa2xIZ`KpL+e@p5a`-?Ekp{|D^vRz7qST#UIbf z|IB`fd`QgvtMKpa|D%5YEP?Bn{~_`r@%pa<{Liz~7JQd6{mXkFA`AOJ@IPdo4E$2` zU)^2)$_$YGk`FnfAU^oT_J7PEv1094kAIf`$9v}g$Ozm>^&i*|;kozg-R-~Q|0ml2 z9)JI={r|`l60;%k0203-`vNjI|9JjGeD#m#KN`4<4n_OjA;E&X4iI2)hu{MQcXxLfAh^rmF2Nbx-Q6Wvut0!d0S1>r1KiyE z^1uCS^}|_xs;leN>9xCRS23tc%YFi~^I$UkI62EHM#_r=BX|1TmYhH2$&`M)M`{XbJQzq(pcbLgs=+gn+9VsdDJ z%{~8b2IORBV};3~V`u4UOU)&~kI5l#WoKjSNzKj0`OhX7M;CVuS2K%$Yo)Ec>@2L* zmVB<(ysRIS{lT%258oUNQasRb}OWbGV1|9usQtm8lXrL8PnEdQxhvU0Zhrg zke5$PjM~HVpF^B5eR5AXIWozYf1q8iETHq?#qPeNrc?cjCLm4!bU3&N^ugxCiQmud zLHc#{ywq867^vcOe`=lTDA}~Za5po1d+WJf*9Ctwu*ki&TR3pqFVM z=j}I`3&kUBx!U`6AywHIrDgB3|MjVQze4)Y^FLAZ#b%qiHsk>KvW|($ll#I|Rudq{ zeOrd&H5PnK$Ib|4t^C?np$s=y$56AYyI?e04rYi1ztbs&LsP{9)@5#{I9Usrb4tUj z4a?PO88luDz`DIAnAHz&kI+Q{c-IINTG^+2;iD$0>9P|0WMIN}pjCeoo7*a+lGpRf z#ii&|zn%nt9XHPW=LBjNF^+6VKFiM2L8b}1CNL;q={adUGne5wEH6HLUyF6MHWM{kw=+5yI57h za?0`9S{;z{oZEm>-e)`{@2@~!jOce1mVQKpK>*p%TJ`X}ng^IL1+Z(jk>_&+T9*^v zXV?-{XBsY*UwL~4YFAcW*Ge-@ZIyV3qn*frtYUOu6c2!?CoSMM_g`5Na5&dpR_ub+ zf*v^E*9h&xztOi}nbJ%gnSv=mh`^amBmSJ30$8>Pz-5-J%*vK&FA*}%sDgsR8*u0V zLpbowluV%@V9;d5-iaf_XZWXLHOYO}7@ehlb~@Z=6j6n)li-qT$$QN*ro3BVrIOf+ z{>$j&=uWAX!n<_tgRBWt40+I(0R5*@U89x;OM2W$U$sMksFpRf(1gO!T~2pOf$e7{ zGRn=QPCzxzxf$e%HpWW{!|sKhrizH6)~yfbsOHh<&QhN$hRafy5Xvn3X%Mhd%kLs= z{8{F>b#|CX4MP$nXP4xwR?dP!p|JwX#bL)vtps(z@`SP$D-#9u;DHpXhaAZ@KURPY zi41@Gj5A?iilk}f!jg(Ucg$7L8{v*9h?V9_n$Z4GTwD5=cC;e?B#2N^gGx;lEYZtx z#wu37D=D2^TvN{}?CqRp8<|zKm=Mm3UKow}QaWLO7_t0Eg7g0lJQ3@xGTVT#JRW3I zm)w}8hPV$JjBuSrKDo>i@<|Osrd6!ANFTs9YcjqxXa$e4SZasS|J%Y<6rR2q#*jYA z%i0QQqjh*OHfPW8{F5ril^#qGwKr^jv3}RBdv==^q*#c;3W+~Kovx+Qwqbs?A+MsT zp*!e-1suMCQ}#~ir#w%H6VwCR`*^K$=|86f1L{)h-A_=64@MP$$=YCTw~nJ$6k@vL ze?JSC+41W)zr}3;AG@{nYx>j?NvZFr231K-$)X%dXm4PsI2gLkIGL#?1$>lj#2Z~p zJ*(o^s9Nx_WC&<+MX80dEhILd-$N6nn&dZTgccY_52v!d5Y!P_SbQ zTH_7RJ_5iRCXWGl9IetmW7Vt(NgEJ`rx)Ur$pt)Ix(3iW({i5JzpR;K|%} z_tGXO>)BM(8DSjA3??U}l%)K6nr>eNw6)e`Bu(_ER&+j%8VT+$B#8d6(p~$y4=?Hp zA-W5=F3{%&D?uyT$I-RYILMp#PV$ouy|mfi_E_SOG*U%g(&mYiE=@@VOJA7)NEu9i zi=;m;K$jLEWfYZnw*#UIg(&`1E9HgA#J=CQVd{sK0mM#SR$K_9-UN=LK=5MA^1!au z+m&`hg8)rh&Wv1jS1S}Q3J-m=_#j5y0-+|H60H+ujm^f|9s~@+PydiRiZdi`)P{UCz_hZo0&BsE{{g- zCMGp|pz6y#l3xPHc>rs5H-hS#Ex;D57#oFJedAHsTg69tx1lHSS*p>IYHx{syI6o* zYD~6rLi~((AMc~i zZeROp{~CuT4Rj~Tcxq5c>;_xdUUJ}ZFEzv^WLT;}gka$_>rEJnX$m5hokHcFUMbVX zu~U+;u{{qNmJ5vo@FJ*P%?Um#BVF0im{pM96~wbAmL~1t=0oBK$A@RSl>SvQz^sSV zr~Q^He^r*=y6UDoVN#HN_yU*0V0o%QQRrrXXL|i12>H<4wT@;Oo|;bzLOzxnf$a1~ zf%z}nJf@776JK4_6+T|Pj;8cc+Hnl4jMR_AC?qoI+~5Y4;yqym2-Ba-t6;aC%D()N z65Kb*renmQVjfMP*Mmr}{=J;#b-K{-EJhV~IrTh{pqJZZ!i>(#l|+huhCyr_!C?veu14+%=w40pvnjp>mA%^}-&Q*Lh#` zY21jd53}6JGPVj*{q=2_8FbaN-KDp(_vUiq|AiCM%Md3B_X%7SD|bu&_czxPi2~() zI`n}oAuAo65dAYk^Ohib}cAR|d~Ycx`_-{)+H|@4{v;LBG^PzULx^ zw3FM;$;C!l%<%GP%P2U9Jlj|yMK=J>8W?&m@Nv0$J3$}MS2p~BZ)YkUieS;AiY*bm zQTO+OgBoB%7snOwm!tZYI^;(xC4Xgi7}tW-yL+Zy8VnQG3V}BAvBD}700|=QUS4;Q z+Q$tCYvXnVVY~KQv9!e3W2Z&W)AK{80G}wm zJT>&C4;{n_{pZiZ%Ie}qaZfl}RIM1~ourEwD^KJ*7TazwG)AU9eCA{-4Ijt*84Te@ zRxE=;0;$tXo3f*yeBTRxwhG=9cO56Jswd9ZGEdR3G?%CK;1yrS7}|NMzdJ`xv)MP* z>U#-QWPukAbRCNueRNz`YLQ&?tAsndiOOe!3N77dJ`7fgMC#_;Y}V@G!v|qmNbjJVso4;GAfKmG4y<_nUa+ zkV+HC740H`d*`X9)&oYxEvbr(YIRfhnU< zQ{%nM*aVk5{{aX9A*2f-SjXa=?7t>~Mexwa39kHLM{5vM;Q)qYsuMP}4c`&Vz3k|sU%I8GO(oi8jnXot>vISXGnY5RnEU{3o6L6j_*dZ< zfhTkj-i_%t((ZxWE`6*l*Ks>?F*gVvz^bV2^Y@f2GZAl@Q1Jm1Zw9WwAZJvSU|aNL01!>z~BL}yC*xJ;mpLQ$7h0L4e!qVjfkxG^|cZ52;# z?b1J7owW;;PPjMP@dc}X2*&UWxIZ-v3|$K08oSnRz^ALd+uvodqxL9bzNlXk5Z8j2AcXSu-r$=8TU$m?RtntMo>H9Q znC0S^5wklPobpXrOcbxW-jano{aUz%-46AdeEWh!tF6*W*9o?4P*k_Tu?N&u zhZgxkgz;lihEv3Rec*kYcPNT3j2anN8k@Es<4cy0I^I%wO`v}li}T0w5$PG|QpTEH ztx60w^%L-uS!v{~)QUn5HYbGgZLQsNalEwQgAY&*6)|KtbpZL=SN`MiWv!p~jwy0<2pvKs+@>E#o$q&TaAu<9B?$D zpoX=Qxa@>tAd}0TZ%o=7peuI16hZeh^@|m^&6gOFUu8vNgDEs5K=k4(%t_6cTGVh_ z1|Wags6oAji+AqUzgr~6v?7zWNPZJZ1ueP-`#6iGjOcXvo4b%1S)QuyG!U14r!O1; z>1OV;NIokEy-Fa$XzEk!cL8&7dupakbY{}2dju9xk*~02k zKOUNXqB6g!dOZ5UkbmsS=U_jsbn}7d9Mh?wnF(~Td-6%VyIxjE1&z~ zbLvnJ52;*-s(mU1&n6*NOj}LEj@_tzq`~Xd`AwcDlh#5GBks8c<%98gkmvn{%p~0i z8@&}`mNoyDS3a?=fqcvD;TXKdg9o?h2M7CjkyRMe`>Vw&Ea_ zzvZibi^KTe-nb6K#y4P)xDf^`DOaU34M$ax60MO!P=+x^p8r+b7+Vw5v>}Sbl?h>c zkW!Tq!#r)PLaS%%L|FmKGw^4f$KrfRk?%@F|I@e2K_zOf<4k7l{W`IO*!Xl#Ep93$ z`eX_DV=$!vf~#%n$)mqR?iS=X-kR4;ORM4OzVWQvkc23XLjJ17StDD~^_ri>R9bYw z&{B#3XdlR+7^MSJ4Zy03`|qos1s;Ey$kV0}$W5(`Ct>^>cYI|oX}Z3UgF*ZI$xodP zKN$Tj3689D=Ps-JafM{uew~>|rhL8;PP!XNksEEto9fCQyWK0ab+19P9b@DXdl2t^ zey{wK=T-r2xnTvLR0|DDYx(cC@g?ZJqNtZzqVcKo{X77GdM494NUAzyvB;miki=jz zGfGf4+>m=YC6-2B0xVos`gt$uk4mm|&N0t~?YHMC%6~X91ANA_WF)5~rovb5 zJAI-%0??>mk-p^sr)f)hngt1Z`^z|&Pv$_THyTl$WF(RHSXGJ#UWhk88QEVziRqfC z#I31_h`}CL_HKYvLt!Vz0B?dL-^Pu=*n(qRuR_f5fqJ0y_RSPNc!^1?zto1?%&E9# zQxcBbbMGBJ8-ixGe!zsH{OmM^w-RB+QVOMv)5!Gp$`mngN_KCFQRywok?b)i;_T7? zk~|^1^g*@6oW?dB#=oC@LTs_O^|tGT1ipgv-)Kv`N?xvM^RiV)V3r!w|LCp#vn}*0 zCX~j$WqsalykzA4$Xg#0?2r`qYjX6*x)F>@?`<8Fhh(6J4TweqcpDslN|q40{KsyV z_g2%D6Ka4ND_5-%1Z{xn>)2CqRpm=nxMI-v6;h`7khR)FP-2W%^BN~jSi@S`YmSDA z%gTxKtCfOI0UCc9RT|)qr)0g;>7%Ne<%NGMh|tQ^tvv1*?dO3qiLORRMYa3Yxv-D4G`{gG$>PCB*W_n?D%!a%KCZk;%h6 zLQi?hqR$Zc<7iYjG!E$#m7P)c$;u1J0Rild2MK~r=n)G#@XQmU0O=r_l28~YhJfz* zul8!L4Vy2dPQPe&+j-MEO^|o0WGX!HCaF)n=!a7&fw<%hPHWaRAIyD%sglJ?2Bsg- z|FL+(2yz77D_9v&ZldPpE8#ERD#g^MVtzI@8V4MCR$ZSdT(0H$lDgJ?$6Y}t9Pd&j zcdJ*eyQA+l#Xo-qzO^mKFE9J%HM2`N=P@n|yY7~Y;ts`!SL-ScqaT!}Bzc?mpE2UE zsH+vO2?zen8f=j$Q-oaof&GmX?2}52;f%g=?M{?%EfkUv<;42*Usl#wvtX5a#voy! z@FW`^FsXXh6vhJh+{+ihtXokHUDx8th7m6R@!H^QN~L5dMfCbM$Z7zT@NwB4-rADs z=#lF1`rdry5I(|P@;Co;C*3kptd51{A9`7HcxY5tTgq*m$QryEff3#wRBg=qtp_&s zGia>3QbV4D@C)X(w{@(98znM($jA<^=|tpZwa%$log1Wh}oc+ z=c@;y=5Y4{1Ost<3d(>DI7kk2ril^#`>W{OvS>gNx3yU=j)nq-sgGzvEe9j@WSTG9 zL3*KdB_|;+65Xs}E>#hJ#WvxEQK^vBzX-D!-EwI+L9ii%P1mjW2LHX)y zfg|tQ?=HJpKy6iF8$C|X-iZ8Ty2m980UY;;BuM?hXAyy!cNS2mO1v%Mu_M4-B3#)Y z@2kCv#WE*gQJ)Cm{Xy#w4RWfPs!j{NP4(aw)KlFHW$_=wDB!v}iOsW&7??=PBj?Oe zieJu}@$ISo*iMAd|LwX9R?~>l`;li2lq#}G(Zra7kqi*CR$=g7y4TN;&j>pS?lxv?K@?;_K}=W*h9qa9V0@8)~LldA+}P|ZtBh~jQ{+i`0kzvh5N0U zr3?OZ;OVKIi)e`Z_Nl-&lV|)4oONH1lRy2pM#zQ&0}F>uHg1ev?-lG6`65$l%`b2~ znIhUxJe*4ni!mAgL&6PasBk9ZsKl)l&VOe)^1LRq``-L`=r|h)rIw!OQi#HObX2wm zW%xVLaSggx{kkNi&1G!e3zg>Fv*X#Uj3SzLMWhg_;;u#aAjSP0f??Hemm0;CBR!sJn`@gls6L zcb&DzZfyhU;uK(=!AiEv3fLb@&~Xx9&$CuGFyws}_xU&cyzJ03bQM2+pk$pjLtE(| zY=Qpnu;{CMSTnVOk$i(Lu(3f43bt!ZrbJ2AGc=rD@GR}a-;c!Dx1 zLJA@86%!i5bD|uNNowX5wYYZ@tSSnJHIs6E2dQFu>iZhB+Qsx;>|wc}zEKvgiS8GZMme_OU3RVse+8$` z*Vy-m0jlJ!pKc*?n*9cuBhn(X>)p>O#PM@~9{%v8pwMhzTx&TTlatrP;m2P>KU}JG zt^=3nb+3TU;pgc77{B5x5leaq)aYsR%BIoE2hh2fQHa4BDd_eGoBz#VJpBY}QkVbu zm#nr(W^Ses3=2w;FvV*%pg?VvWIm#qydH6ld)=Bxx+)8@-Pxyu0r-mq;@Y(j&la{l z$$y``uzEe_7m2&~p2JTrK*i@IATRBq0sx>Vfpvt0c$#ydO~w`oHWtzD}7+1G+ltS4va+*1NV#QDTu zMdG=tawbKJN3+Z{KsM6Hg+%@!#2P*E;W|!AL|w8U&q;R6gz0f>Htp46G2Mq&-9NY| z!Rn!oDFQhu2}xWK9n_ZYkIae}=!GL!BtOzw@iS(IgB|PnyDudfC zeHXHf^NFZxt3oW{#cBM3r6ZSOm-*%bu**?bWncRd=RribmPQ!SAE` z+n|u5Sv##pmXip5?lLVs!@M6&lFR=Eh5OZ?>^t^p5ye3Ug=Z$VY@YJL4@?0omeCk% zhdqGco|AUoQ=gWzO?f#)i7N#9+RAd^};>AT?zDX>7&h68Va{-R8K~(gq zw^dp!&)9^6{OEZ^pV+}kOcL5A&`zV+f-=M2>!XqN$p`j$rnH2z6sLEO?p3;3(Esvf z-SqSBqCjG`{NO^%76)qAyhEvbHaUpmhj49J`AL~l%}ILdi$O7uu$8A?SXSz?JJHM# zKJM)#UeE1o!qK+w?@I>fitJ)C=BJRc^#0Yol>8v6E; z4}W9h)}p%IK-HUn-Cm}{d*?6|-sp0Z^2n@^rghJ&$gp)^euA$pj|J8{UJuAoO>`W8 zrL{MH(1#&d$hG}P&Df@b?ZCuu{8fp2k}VzG9e_g>LKCq{ljo$cSy%olrP{S-OCn=v zo`0^W6$5~obC?GUtHjd*{@9^k+eUlbs|Xd`PB8N-o2BQuTG6XcDguLSeB@^_OUJ5k zFqh>S=Jod)$K%A zhD0`FVA+dB^jwy9F*1*nAQyLN<564Wa~vu;X&aA@Lrq6itr$T6zhz-;<{*B|U{1Lj z=b}B$apxK<+^rg6m{z8x!n-wHqyIE-ylloEq2mfM(`VtVC85`WF`)WLh2Noc+x^bB z!2%)$4i2SZ^Gm(joZ{MF&D=}_q)(E)CyE)CT!fV#1JE(!tpIsgT@YIB94o*R3N0B9 z2G@||3@^`@)0zO^9B7T^L-lHJwZe61@eVsYv?3hwgroFNH|Gj-Azq7lr}2vcww()q z;h-y&vAW^OvKs{y=<-#)SRE3Ku`rS!A1Y8-5em^xxZqXoAZ z>X=yG71N{d_e;0N#Tl>|c)yy&^%}2!8xMrs8Zm|w$Fds7KoT0wse4k)<%bfOUZ&9A zS;hVx?wqn(jW|#~DVdQ4WotwJ>t5E6C2^$MK4{IuS;dF$W+0qUd`54KpPay{^X8JG zQN0X>gogAPjDLf5P(Y|478VjKDjEi(kN}tR&Vl_gNk55c7BYDZNm-g78m1nw6>Q|G zD@hWz9ibWhpX7@I+<#^zZmG`_wMyKPY(>5_As-%>PbLqG<)peP&v&L5?p7c{#Nh}2M ztbVbwhmJgDRo3}NxgLnT_jzFoc!GAY=cncUN)i?^;TW>UZ8@rc>ZN8ei$}~D-ilHLWb!PbE6`IV7YHO2f<+ljz!yjYNthks8&iPQ z_ES!5#YOMkD$y^y7b7euzL05dYo)ME&0G>Hg$%uS#&M-BwlU2Z=Hq)67IpRol=7PO z%)5=XLz`m9emzmH3`5lCI!uYJdi8!akw4mpQ5XT9_$Zwzp9duZtAX!QA{+U{^;veH zD)IZCLl)Ls2fTXn`(`c5X3L)~tVUn~%^?*cL#2*kA{j@xJ1H8A;dXv|x&fLl_6C&G zW;-WNF5ARSB}(-gcE9)`Zuk|nX0(cS^R5Zrui#}Yfn z{a`$FIVz4@=Ntb5Nmlww#@hBLc(+kVcJgFf$R!-$10-RVNw&H?OA%LI-i z7N~csX}RuBKV;}nBEdghn~6KZ8$qQ1Jak&>HJR+_cdJ&M8L2>xsaOe0nZ0oR&Lm1| zP7>MZw`@2W`^kuW>l>zCuk|}Tm6Z|}>0E0u9S$}Q#7ce&6Q;^UW8R{sn{sys>;PvSq2HxT{-O&DZLKOb`);+`gz$TL_D?MM3eeC4u?H`f zlwanbx;9|?&Cpl{;?UWSZG6=rWEEEB;J(9$*x=v!$OI&psoLuXP1Z;#s2lAkyT)tv zyWOAWS8L92z$TRGdYZtU`SKzCMt!iV(DgHoSAt;|rBaR!=kDJ@R#jMXY(rpKtOCZJ zvv7`~VFuE16#T$gT1CWk<4>n7ULk^XhNIy?KxHk#A`xqu|Ad^ycY==)|0qo^)Tx1! zcSG3`{3{}bN|N`n$@M~E*LW%B^j3w7c=JhF6{!s(!l%msRi+qjZuD4?y05X)tJWU~;seiPCH zp=3`Hmlz+Q+LVR!S7Bmm(@UZZ$74C5duJ^dJF0sllp6AvE^w(PmAmHglw}cYxZa$| z+@gQ};7G-~t{N0;R1EiEDgV4S2b9y&U4C|4XG5YrJx)f%lN^8Hn{*a%6A20WC5 z7j0xB-NN!h_Os1>NadCSlz;#+6=secB$L6uB(V*B6X+>kD+8yqPJQaQredUn5+4q+ zGVNcu2Yl2>#*KNcv*lYq!zjSF#(SS2w_$H6ruaik7pjnQ3wK|Bf*OtQ5QCp`2NyrL z0=MiRJp&)S6ZY-^jxhx8tUG+In$c{LCTP-rn|d>WKfML%n7#Z`6VN$QU<}WoKGtZI zztGYTSQh;V5xNU}sl@1<5j;jrQRqp~(N+Jg34T}4xD4;6ht#hW)%CxoLp4|~I1Yr% zEGCq|-+lX#J}~X6noI`IzK72!Kl#gxRrut?io8R2^xi1RG7ie|qP^(frF13iHX8S6 zk_iX0x<$X!E;omsu>-!(?l<;LK*(x8xv@Qto>@#i0|%j1s%Dp22lw-lplYMiI_~BL z#T96y`7P!i@FJV*TNZRe>*mfmCpDjKbbOrhm;}n(aF8Wbt)npEK}eTvPZVzd zE4q@J8eFNC4=kHki%9!3`{E4(TVJF`3o%J2Jaw|4g5QNZ)Zo-q|0XtVk(teIjWKJY zqzO+mRj6}f4MIEo@~S+t6%9%!BNdmyZT0F>9)f2lXp0{Yf?ATu)Ui{Y4RI#2t|Que zO>$Ra{UP7+wm-su13wrgwJht$MeJ+8S;s|pm>cCY`z|=SW8#Tx zk@&8({WQntZwO=<{F?k`S?uryCX_BI81_Z#cQ5*fM&ioQI$yaq_T))4KY6BrHUge$ zYHBt9QKqIJ&5G#77d|iBxiv zf1XoC;+P~|0^woAxh}h?84Qv$YFjq5FAEDw^eMT2HIRv6_)T4YMhvnr85W1zL|GKHa6{XpqRw$dhZs`uCBYvb8cUUw^H$}(3+k{e;fn!j{DV`2ZgGuK?Gu+;=5Rm!*0LlW$b{8%u@sakjdV$ z?8@zpWfy@mfhyffJ!(ikJipai3k(y>*dI^N6p*uq~oF=Hzjg(XIp;*&J~)$Vg_*>G<-uvz;J>b-v; z$l!SQYmp({%(W93Cjbl=ZG?XXrz(@CQbDq597j+!sM8otguM_9MlNIXx>(bS`*MHM zr!`L9`O}ArYHtt?KsFgb66Mp5zZ^3@|G|&{X~ZxrLx|ays0F1-5iffuqOBINn>r=$ zRWWqc8LbjS7)`0JaBVVHbL{U*<20upwBU?cZjM186sB691r-jPa8J}e%K8s9_$swiBVZm?u;AR46OXh6y7pJ^za}4N#;cg2|{}#AE*)KmSXnksWQ62TW ztf8Hw`{OC990;o&vl>o$o@l7(y~KYqLC0Xs6ud;Xbmi-5(S+4l;1~hF)#2B2#h=TF z+sBpLYEz}2Wva}hkG&GrP^kvdizDV3i}cslJ&BFRv@);LxRQfU|E;!!=~b?^n_o0v zGl`m~2x10WyE#h7%*}o$I-)jgY*iODc@~kb1j13@(b8`*RBR;*jNJcJ8~ODCMSQA2 z9l{}N^Bbu)4c&hnk&@MFe)=~_!HYLtTrqy!K%uFd;18}OKR~vYNLyZO#6R%qlA4%i zPO4)JtylaCru)MDyrzhEU#=mf=X=T?mv^kwtucA2POB;m*(d=h$RdSNZ9^ua?QUlY z)O;zkwQDwAB9OE`HCv+vv#YBEXtY0E-yx_S^qI%|ZmGi$<8WAe1oM=8y z*$_4_5aq-s@@ZW;DKVD!&it$aS8e!W2zUHUP`|H!{nr|9c>IGNHG2&&!aQ)rmWK2l zuZy(3dYGC!lu?>*Fp1*|bmrLkIf01-&h|^xu4VDolgb920uQf7h42w!9z7|-0-}>> zy9Umu%&g|&3)NMgDLQ*zflF$a(C;knrO`;Dn z`f~xLEIvxeP11?RTa>;6e?SF*QgE*i-jl-nDVi;5H}@{V(53cTp)HF`!Bn$x&zdn< zd{?a*y{Pv1y+;1vPN)E;q#T-pWt*iv+H5wipGABiLS)CYL#pmUPcHsd3e#R z_V3y}!+@&Iw>OYQYwt-TL;}!)-^c6>)Ls-GHJyrIjL&Ks9%(<(m{qGMUZU=a1$&DU z9&IM6lpyM*7kf!Ekh2fTc$BtU>exueF84N=lC*fwu()eLM5CP|<*4dcpcs0NeK2Q< zvwu|X$jeiB=#xQ@%`L(}=`KHrVf3=+y@Ir~o59N~X6aBy^zO}5)mi!MT|(^s?2=tr z#UCHl0nJ0_6kLT*?51;1U3JyP)%ip}aO8PW+8U`h-IX9rwfPx5Zm(xb?xJ56rkC3o z5tmIa**1o-2s@bnU|f4R%4F>8${Z8pePHgHZxM>@2M|0_nS`~>YuI7v&DzaG0g zkt~X02y02m=Bmm*k>(q{Ju2I4a%G|ktRA><;$n7U{GHztiF;G>{B;qZo+3zzjlpX~ zjyG?iP6A0d^h?+C$&X#pgReZ9gY}K?n?ulU8gS;jlO2xqg3&XlApX$gsyb~lMSm(@ zO@ZylZb=L~ud&D90_rOa2b=%0i2ytlCYL68d)|t^uP}Qe=5qNAUGR|n7SFu`_wQpo0Jm_je^nn zLx&TtkH04VnsnGVhMJROCVsQ}U}zYH3M|o>tnqYBi(Lt<*K_zvVMY+tF_V12*f4UA zM;T*v0#}o)v=(wuVg(|;6CD-Y;QJO^+W+(4Y1@mVQ2gfi4hcv5PWQNtTk|1pvhRzP zrKESUjSt~d-93hKqapT?F;s2F#aA9k*k;2(DRoX>x`EdLeq~qHME>kG`(WY8aP9nYQ&WO@new zKg_h(1gEz5si;Wmr#hGw;h`?+){ofQ6C%zf!(qBvW>h7utar2K$-RLjY;~Jj@ew9x zt(gAKrWC66yq-rK=fwFb=$;=;w~Q7Xwq28@E+SB_V z`0<2N2z%&{d;YDgb?s=J-dpd>`|xB%n_x^z(8D73QD<&TL4VQ!HQU46I*HW6PRb8` z$DIAH@~ivcQU)Y>gKOyH7wjmSDQmBT6kD)XFjd$~Y{jgGhbWHuK(u1CrnL9bSEVp5 ziQJL*7CY#l#!^}SEbTCmvChZ0|4=nyBLX0_9m^2a8Iu(-7p#mnPQg)i-IE<<b_bx)v$>Vu@Kf$d-c=c{8|M>128S|kJFOo`oGi#@bHS1{(BdiXhJsrd5Sv-%1CnB~`?3E%!I3eKVm%8H8tYB|K<2#XGkhvl^4`drb6}R#u z;V#xaRN*IaD(wnmKEr%PwXfL{to(b!V8HVTGn76GHAH!FS1RJfb*X`rVCQ3r(-Wx7 z?+0CplhqhMXv;;CRO`~-;7XE2i;!Y6<0q&PonqY)%WCy0cEEmH)D|Yp0ttbX+EoPK zi^;0#HkjI)Yg6K|WidjY|71@c9Cu^5mk>KrmoFCekma-24ou(7+OYk2!{=VHeQ7;F6|H?7Rsgp=5Gsjk;l6cN5`kz@HNtOvBPD~coLd-Ajt z1UAdk8RfmXFP4LPqxeOycRm263@Vh_CC;bbo`A4eX!sb?v=uE^0gU$s$@=H zDjeP5zYUM+!HdA%h(yN%qQU^4co;0v!`xQs|*1Rax7=MM9V`a+RS zZqD==+j2+jZia`V7ifwjaJ*AtaEho1ihgfFFbZq_0h@u`E?=4B5PS?qCxx+0=`ES> zg8N3*A(`c}YQ+8C6nEB-z{i3~`l&DAyPYcKh#L%@DTi*zv6ecR1i*zW5l!F31Rn3G z5+a^kJt^Uv@jslI)^Ht?!;ex!)2k3A1F$_`Obz={hRLNi2+~;kzzeafU?=iRP%$+TE#Hs{fXBn||S;&!YSj zgYw5Bc8Ke!G>;Y6P9HluJdnrw0}+XJkaBS)vSMrP9e(>UX5w$P7>EFM2GbArthEgE zSp(M=HhmtQH^q@z&{P2w8F>XF_pPKD+<2`q)U z+M1jE+A)3*D*8eYdov7X)G*&u$1P>VU9?7wOI50nv`M__P1g5?U211sS6EgK`9G8T zl4g1TGM)aYtQF_aNv^-x&b1Ocew;R9=#9R-IKQ{O4J7*K|IZl1OT)0?6DhYkR366$ z9|P~6;vYa%?#3&62LWn9vV}EmgioyzWp}@Imjg5t*~@2{7&nOuwv9;BI*Nz6%4}L9 zcZCuIq<((F_f-1YBjh2NpZQ$tT?3N4k617g&-`rhQM=c?zegX9l%<3OhCqR`kgiiO z(dH;=FzQ2-X<@+&K|e^cQ`s3e^RS{V;qUO4M)FDCQw&1CbcaA#HaBfeqp%q*-qh;& z(D<5jo9*!+u0E)fU}FuH+vM3+%d&ffv0Gn-OKfzZhxn0&3sm~leUs_ptv;VA-mNPr_k zhiG_jLQVB1Dtlr1f5ju%nTLeB6yUXo+ z?Y@QCzNvq9g|Jto@kRvXp4D~IV1yAJ$GG^rhA|Mp*kNM=b5+r{{*_sP=uFKPFB%H7 zg#31Cf`jcE%hQ~`5y zX_N`q@~(V$WL~Nm59nbX`>P72^ePrMc2d^HZR;`hd!UsJH0GRBcJPEeLx_1HI6;lh zDwmvDr+RB}@h4bjmir3oG6aq+SualJe#koB$g3PV8gboyCXZm%YokX!72M$Rj#V$g z`ZV%BWHcJ|(@ng?XOd8|D>7Zk+A>UqUw@6$^tbTfPhJP6+!QnzE7Qo4932UBY{A{w znKi_OSVS!IDOV|RNFQ#*XkMn_#4Y6X_o&UBTIlEUw%47izRCw4rv*K>;jKsJg^cyl z4`TiLZIHuWKHPsa$R`>lj#)vK0D1b1nQ8wQ&DF2GbY)wkkLjq z%{y(XU8C5c-jL>uds6lbh}xc9<}3F$-GM>48~E7 znYvY`q+zd)#dSUrr;8KTu~biOubRh{8-;pK1)e~BMk^zRiG$Fc5J~%tjQVxUmlA@N zUA|bQu{cck*5V1%k$8Y`FIKm9j9|{D1d^opH?g#uo+8uirAh&oSV8SdZ2Y0YDsy(M z4lz(;b*$Ioa}tE2cuA-GFr`h)-yr1xLzcZs@wv|b3!jwlJM;2AH-dxF{{crpxW5CU zoBSv)idD%ki@%f3$4mof^NiWjVk~2wv$w$X&gfoPa@7_xMaaF>CFLt!xI!t>A4`=} zc3QnmE$J>EYp~95Wimxw`nY>xnPQpWWk6;OrN)824fYOY5mfsOmkKDWu&T<>Y(Y+9 z{fmIqy)_S=bd5|gP&gzy*E2O^mE15S>Ti(xlFf|a)Ss_sT3nRIf3}}u)Or)VSp7{8 zMR8*Zi11f29;302>|CAnF}$X+$}{x%!-I;qGTPk9v09Z!tA7wb&&kz2rdE)okTuDs z-IktOskB+)e8!$Su5I}^f;noQGpW3HX~n1OpVx6Pkb3)Omz^uA{F3cS(0$f^c;=VJ_+5Z zxP^-v!~%)*L9Eb;Ju&R|j{ zCga+QZ!HU>F0EBB=aA(HPQn_OHTMDO9q^;w!6c+&J1Kt7bJ>-|C(}W`NUl))SU$BK zkD7)ZKJpI3)tQa>@191wp8?`2$q{h5Kss1U`{<)P+qtY9_e zqUl54S@mp;!{D%usd_r#Onp(oc{-ka9b6lw(8HUdj!C#n+IEV#L3EFf%P)pfM?v3V zNNp?(FsZ$$0ES|3dsG3k`(43*YsiK4zD73Rl5>~oNZGK8=tQD=4>ElON^4u*v0aX? zw~dJ3n%ln3@X;w>?@a8mdQ94&@N+G19%ylLy#6{Y%*iz#Q?Di4)lsHBxNPG=9>W0X zfvU$xC-Oc_KZ%i}FMbzx5Q_^YJR#MR98)$Z!=3R!46%Ptq7;JVFBF56b_!@8wcC7&iFwZjJph!(4!+EUxu z6V2UNJ?Z|0)wdZy5KR)H>R9E;;DE^UeujspuBJYPC5t7Pm!u=2=jqG0MlN7%3NPcL zguHTw-DMYp87rBVF@gpYNk01O%mqDSV{YU3>AZ+=QCK^f4PdW;8v{6)_Reoj953uC zB$)F%tk=f(`a`B#elZY^W@sjg&Ki`kh`N_1PH~jAg&CfQ?zH5Kip*eWT3CoCw{V6K z-$*@aW#vhhg4n1Djx)6)jpBVlW?6oZsaVLwUMDA6dDd7W)<{5Fq-gb88g3HDJpRiL zgffmSg4-lUzARAP90}DK%SxU)dHeeM++LUapfu zf_2P4&xk!E?B*B)AID^>B%3%Fo<73^q+S{ZdjvjB>tnTB3X)&eRD~2ZK{jKcYFJJo zN3Xl+1fz*jit*}ONqg)Ms=yRIK4EK?a}4S*(m+(W+Fz(=o?q; zq_Ko0`x_aN>x?Y$<-HEBdw-o`R9;&EZ?_dZEauM>Nkdjbg1ir7bdn6kJb2OtY&TIx zJH>4wn?ZPXgLkB95@5edVK&hZtRAqbD8%6X5~buX>f}mo$4YytX-Ri>%Cv%4)8l~& zs9LTr%YE!@fT8sDN4UCtCDz0rwA6i|GyT=Gfku4t4WBKP0EJ}R>W@h8>PbgR-K@X@ z27vt%%fT_J-_BktjdfYzmW~M!L@y>3G4K=s3<|YfCU(tkY=`YVNb=sP7YV^}=&s(5 zot6cg?c#3NK-b27)+!ckU`u06s=XYmnwR^}j0{X@3})qCwI&h`7M5u@T2jE^q5OJy zI4$8_xDt~bHzO50O6dsA&TP(4cm(kQQ#O{CG&>&1#Qw0vmhZEMPlS5)V7DUd#yvEx zGia=!Q^trS#B{V1Jl|BJ#-i{j)8#iNW7Nr$BNI}_w+cU8m8kx+HK6=zXnm}5^xaHh z;&$6Q#Pq#e24UT}eP`A_UnkFexiI(Su zB~3^~@0fN}KNodl4FL-%?u~Tpq7&rn2#2E8&Z%sMJ8Z7)tVO&@8PF3-)pzfx4VM;s zcUP;U%8)V-$Sxgdh;7+&v1IC_V9z=U3%|aIEyb~W0yH+ipObLu&VH)ji$(hd+)W~u z_lYelu~4)u(Z;_cUj!ioF>CcQRx%@8T{it?opn@=Wg(A+BrxXYX3z2Ky~iYp;DGb+ zm1y~0KQa*Khj2Sq zs5U9!Y)ygp#8!|F8udQ#z+{k<2*aW&>)O`fzrc*7yDjT^%oZN^vulkH~BcJKj$=Gs~4X~J=&L}y#> zHUOn=LIe}Tt{zp@iv-fSzqNwH(K;)mKB56tT)dp)a>ir{iP1XVrv0+bIvEYJgIcT~ zO)x)VxUE6ML`;@#tV*7sEeXC|RZoQLKAWvXs?aDsm2xTJ!3-0Z#U4|C*^V$j-qtna z04DKhtu8ynU6fRU>3iOUTsM}4*2?rUPNsEWv{44ZupEr`b2fR9uEfc#1NesNVu%c? z+)z~|u$kZDLb93doNrv=&z)iiW&-0_Lew9D_jT}jUB|y%6Ctq{(AQn_EQL}h6!2H#WADAcLD3 zLM)=O2A9Wpc4V|C<%Rv8&CWG74|H6dSuI^kzp@Ca^|Asz`IR27v69iF&AQE2Nh z5GZ4^0dotp_48X~2)guFx5u=o%Vbf48i=?XaqCRMqf(hP@MoUQcE#rtRbHfPEZ0w; zi^uAcD8U|QhRu6i6FmRMNEh+1AFcbUpQsB<84{dlO+t>r}kd|0x{7qumg>!3cFhbQUG*eW;TWADLWo9*h%%eloYj<U_SQQ{Ki(vd~J5N$vKw;zTKNV8E%maCL07+ZKnxbB9xg>Qr=h7KhELalpi` z(E@iE%#GXdp%dHoGhIl{L%tOpLc5bS&$x=-03L*aj9Rw0)CmQJx(Z`+ZVM7BDr}p| zT>(i)%1Ur)EafHU$#RI2ij`}VVUs^w6RUfyUh$`=`S<{SGX=GmG#3M~qBFC;OIfen z&TIJ;22UTeOZTN+Yip4@c2WJbPvu0kbjjY*L7cVdFFFDz*psy={7Pk`aU!92kk)u2qqf|=n~Gk40|ZK;M6LU2#^;MR+D}t+YBL{89al@5ZIH71^TKjcsI6k!vBs3l$Ms@o+_&Dq!Lrm@<5d(LZGm93!UK3i!0=Q1a zm(H4<3u$Fi2|w1H&45#B-r0=^PXiswc9-CP;*Crca9F((erp|?wVpcqNk{MQOlre| z=Y3X(?mWP8+bo+27-`zj(rq-Bk?$Jh3rO4%;O;Y}ujk0=S_J!H`i%PAQs#8MqlWxw zCMn(+YY0gHh`}?~Q`?z~X|0tVHpA5V>pUXn;TCqj#}P@ymTK3bMkI8ZqQqQG5Cf7z z+HTsYyIW)Oy>SiAlyqUy(H(IbdX#6a}JI~kTnq-Ai;1NFYe7hF#snu57*3Rc~ANPn>pT(x}%h)I;C#RW`cs z<`~DkX{$`s7umbmIesggHkN@6TZ2#>uLo~j+7!i<4|%L{z##w>rHOCMogq5_uIL3< zDce&HHx5Hu^V9Xj?||v!@5Cl_g+Twt+?mIkotJe;NKMc+H75yW9AhlmPhjKsj|{WO zzj5(W?T>Zi31&b{tb+fonbgFj5711$Th!6M!5Oa~4P4&tVYy(@C!%d*;VBcDboq^& z@&(c=Wz3&fh(5vR&c-Qu&0){yB<>!RNa&mS#IHeP3QPC0t)!*X$<=#&7=HCBp7*e7 zJ$s_FPyHY=+0U(fS93xNbklcjOhYf74NsEId_v9h$XfjRZQ-Ja-)>v^Pm1z5(ofW_!QEXPYnDJb#Vfs`T1dgrL2yRq7{~)1lF>0{#n>UCpgmGs$Kv+nn*{eb zjAO;vRpxiKLVt}F8`NBB{nM?G^NaNEVo+Ej`YzR{>3>O+b$AkX>$WO+K5@%1k21n_ zv<6Y%rTa~>yOOop)?D2{JdKq(3N!b>dq<%Ort4@a#a+-lvB$sG3~o}8x?*Z8bxnG& z(xpyzL>rv&`5a7;r698rE|{F7^-P6!5j>PWN^Sf7{S2b@UALK<)c`s%k8{C<`u8<| z*>`uEh-Qhf^h`mmxw)}p?Qbfp*=#{Ah=Wr%Yhfkhx|v$PYsX6uQTm36r$P=X{_ZfM zpXb#0M8;rk88Z?25>&L>HvHHRkuN64_Q^xj3*|j)IIAqT`*dEQ-Z%kexxd6w5QHM8@ikx#jj$^2?jkV^flpMqNSy znX2Er`|55Wza9Yft}P{A51A633;ZDCs$0df500-z&JJMB13?glt~ko;zS;(v_1E=_ z5^C{Jb8U%FvL)d9vNuuzs9Lg{bFkp-tKbkVuU(?Meo3Q5&-S=z95?efGeX5viyx}9 z#_KoM$$T8@y2cZ+8nPa4`Kpn#qu&oh;Ymt>BFAL)Zeznh_8Ppi*CY$aIu$P_81MKw z4h4xz*Ir__bXic=W0u%AY#<6{ZQZd*;}wn;CdErBV~B7STXs3ho%a11EZbO{fJkG+ z-@?lITA#EMr}96L;2sBVR3p)SsJpw#Qph3Dmj+4QI#GzQ!HHOsVs^`V91M(~<^<{h zsBVW+%#J77+bwMr)~DlajGK`tH%N*D;=N7Bt*)ouk!E#m(uc&_Lev+zIsS%Ag)S2ktaGMHdCZME9rR(&s|AOua7QclNaWeWq<$7~3RiYUkJtxSYYO>j$v82qy3RB#2dHqTj*sNI>j9B|ilda&t&LjD4QSz*`br4_J5T{Zz> zZ)axq#agR8j2|((zLtfpW9H;F-1caqV@cuP3amdBj)|cW|Cr}6SA2eO5EAo|< zSIl4Q=5Z)-v2%WX6Yr5-FznSMTIbrTdPUX?) zGkU$oN=AJ!RPb|es}B&IcO-(3tCRwayvT0WDV@=m)$hEm9D!SKC8`j&Rf?Pd{%FbQ z9(PLrLU6EqVZYl^r9T$t+t#vv*;sV?N15x$?V*mac= zdWS^Fu#iU*4gG^Q5na#bU=Bh?NVs2fMveytWRAP+unog9zD}nrFSsuf$4P{riXLK%_7+N0s(dWa1?iyRg}~Pho|OAD8ZZUl{I50mQn`3|*o%nUZb#}!p3q8rFE%WTp6U(snNY)6 z5k&?PpXj?ea6FrUF9t(CE6H+B@nkQT9Se~@y@$`+Xe3K2Ugt>9BJdqHD5h*wn_dz~ z`+_!?3DK4ktnk&P(O7$X$}sY*ZMnK3dc}T<=aY=vZUVan21nxqJFV}}4@F7uK3`L= z`ujE+o1O){&jlo}7cLYptsQ? zv}2WyJMxz`RZ3+e2H@=2gtwKIhCv;_m^k(e7l~lc?VGMdfLwZ-`ju2QV`wpiEicl z#J>Fy(Dbt2$B9UZb?;g`kCc^RYq{S<#e3R!EDjOe10STKJM0P!ZLD<&Yjv9(*Y%nZ zSDSszl|-_ldIF^aG${tmUlZQ><-~PL#SQwzixHdiM9L@FjBIo4E3NWfu8cn#yQlQdyShTfiP>t3`Tv;{a+&Mdh_XJMpvx>?-B$hWSbJUPC8?0-Yg7cTP-7NLeykkO zSnhw%X)>W-t>G;9L`A+QsRKVs7J(w~Y4W|Bm|n^CWXtVl)tKA$_j4|=NbIiAeat0F z?M=MDeog;E#|15}L z$}ZI!&d?jmLc4fEc7`5Jf{x|1m)YN)A5GgJfkLrSvjVn9chqY(2v@GE&g@dvw2w8| zMf^Mk@OjqbCfK#7(2>1!<{s9=z*?S#vv$suXPr?^I;_JaFW0;V|E8EBW|aq8Khcr6 z*kEEo$!KhiI>63DWtm;cF+AlK-WKH}-6A3YRxI7|NbOm$7gVj>c5OYh)dTpX>%FKjELF1SR?YR{hZ~EVd9fPAQIKSjCBG-C<|iuW|uBC91)yUz@N-Dmr2| zNL%-tlH{U~*hSkaMf-X})FwA1ydP_Xd2FAQQ^>EYasBn?)JP@zW4Zrhc}YQu>1Pmy ze!b9{dRPM~G)g2<=jD;HN498z_skyL3YduG|&s*t=I}xEC zk?TpEuNxNYvzypo^1RGN1mW%VoEM|CSi(AICjOm;6gw%%j}1>Jrb%$D=xFrRWkQIk z43G6oV0(fl6=-kej$I}K%+Xd!_2c~uamP|smK2tL*0x8WarzD^QghsA$Y!q=v zKR|Q=r08*T9`RTa>AJSRZjRRKVRoDVOB3hw9R1>D&d}sS8nBg0s z$COzJ)q&s4HSFBsJiZiNhiMb~+ZyIPtjJzJAS$AkDIgvcrAq>jJmzLjzEU5R=+@Sv za0Hy~5otwEi1q9)tXvsMiTJ-bBI2RZ4 z=8gfvjUw%R59wKq6#ntfvI%?E2^82Z0aQkF@%|Fk?|VxkZ0Xtvxt{2P9WGhCY%LqE zYTR^uau;Jh-^A6kVdjTy6fwZ!-7puifoSJHYXF&$BkRto2vVK&a34v{fD!9PY>yAzp~bY-@80}zA$z}7&9MDHdsJ!; z((%#bBJyfa$R4_q! z+BVNrU!lU1f99kf%#cuwqFJ1fpb9}q#IIxIqF%Aq%d-W*wFV^K9tTHoa$7@?>(;(m zAayFA6>RiEJCPYOCAilO>}0{>Ye#uSCkD(pR!uh8RANWI;3WMr z-nNx2Ue#!gv6lndi5j7!f0xp=Tw4y4I!t{|_qEwVS+QV<2?PGV@UhdgfWc%{Qc>Vh zT1m>zhHTpjhGDL1w7~=~*Tj>{ssc)kdY5-luv+)XeMqrNo>69NGVI4q7&n&BSR+XO znZV#KApL-}j089Fv~SdT0ub$Nb?~nXWmoaxxas2Qvg`)iSpH+;Kkk$Tm29l!dy-S# z@Q`3iG4ojZB1O*I8ji{4m#rgTWTBQN*@4l5MZFRx9EeY%jDoY_fZnr%$NslQ?ml00 z>f`9Cph#m#WbkSmQJ&YXh%|r$Z#(cPm?UGF0V!GOk*FRP9?j3%mB*(O)4xKjV})UR zb>)jW*wJey(5pEvEsa$Cuaw~_ph{?nx_5?bq^{)K37eS;IzJ)P-7mhA8lhb;QdT%F zTmNFu8^&l%(4Iq)gZV+V2tTdqKXn(c)@U=489@V^a6rGe22$EDnCu6j14w=@O#NXJ ztUjVv(i;NR2c$+foOT_Kqv3}~K^y+nO@-eVTJ;xeY%5KnyhpCwQ%fSA%zoR31&mhI zT0aqFJeobeFuBvCeY89Uq7xsBrJ6v8E4OaoUPz zJ9vwIBYP|yt3xf{MH)ZbTt1W}hNYWjjxtZC@zyT`9{n(g)`ASRT`%(n`>quvy}gJ#kk z;dNjrMq|$2FDwYw{i%N^z^vE2=6sa4jukrB$z73G$I1MEi_7#LKj+z0kEx%aBvaFbnBQ{Nw=ls zBMC&`jmCd>xG7L+M+4?4T%&bOS_eu{Q5+8Ws!h@ia)o?Q%1cshjt{*^<7c#< za4Yfejh1%B-EPq3Ygck0d6%M^E`ait>f!A|q-@-rU*Czx$}~-Hk?1H*nmhWo&7nB% zU7ZcK+q?DeAUxa?1ozLcsaMH)0v#|~aKOXrHNZYiAW={{{f{|YH#On6Xi$nJkSDeK zSDdq+aw2;eDS+o)#8|4m*s^Cyx@2{wu%pydrKu!sDM#VrcO;VtBeZ8FzF7cw#cx(v zpjGay^HRqL$hDwb}wHTkC4? z(cRIe;wHwDa9Iy+$sKeHHjp3^Lu?fveYplS-$tsx6#Z%(NB}l>6c=N=rNAkfonzMN zHVSL?_Ko{f9IMxBirE(nGWtk%;Lc;etO2GrYIhCn&inRi9(`&Te_3;^wgU;W*?(-& z4AfxS*k(sd)8w*y?qDp-HpRN36gwSB)~0VtsYj}-+NsO$*YNIqmxCrB$}~#jmC#LM zKD{{HujJxWjrn3ue0Hb7c){Co<^G&V+A74h1{7HpCebSNel$99`!FXq}=gj<8JAj)NBFm=1O^YtxUF3Fi zuKGPmAYyyVi2Y@O&3?7;yPW3^rJ1}E5|>CQGO8!^*BoMHCyA$!2tWW^-1QF&a-0k@ zZ{lt7`0~W--)=Uie>M+7ebmuJ9JfG#hEmFMSuJcq8`~L^G*S0b|6SuCWs%}{KU?UU zNu%$o1r(f*rTt?pMYsemewy<~ERHx2v+dO+za>${JP0H8^0{EXxqui;JwIZf?4<<^ zlJ9QLkaC?d#yUSId)UEoqGgh_&~p7juNrziYTa_gi;jHCkU=Eb!+G=v&;3YF5}|#gdxuX_v1j@EwPg=&=xL zP14z6i>^;4Q2d+)OxPqPqe%>P>XOyhc`O5r{d_g8|7RQgjZ%xa>lag39FLxhJyykU z7HwPTe}M-~Xfz?daWm%s?;7pr*61mPD-5t#Yf@@rn_o>po^3&|Gyirg6MT}f(wFKz zcBYiW>aM+rhW%&KSYEk*Q%ji`3;!sQG;wuXtL$NbDKs*Vxo@YJJTXtNg^)B713i&8D|oMoR$*MT#eQdRt2&C9Xo)M{D2`VW8rBgIF#&MK!N)0dej3 zm2MaGAf1)!|L=diD`9u_+S=U$@^E_xjUu0Ibq8mM%uV52GLlp&lR!d0r|QK3`ckQ+ zY-QVugN@}(y|_6FA?u%vWa!vdHkR^Af=L=k1m@~0)nUgX3gL*pjCAWC69E6k!i}d~ z{#bLeew-60Z7*L==tYIf-z|7F@p++PcpKepLe5Zno5S$t8`ORL07KTgLINyph} zK!490%>FpocuK5OOmc@j-iO}S4n(~xYOD(Fe!wpMon;9prwdY-rDv*P_Vt2*=8SBs zekpP)Yw5M}0K04YRsx_Adr~MY)#g91@sVH6`SShBd*NaynYdVMgiFTl>Jmv}?$-I` z&AD~H4xVMK$+qHMfvM4jfzPpS!hItA;X~;LXI7OoRsc2$h>mvn_rxZ(I7E1?S)V_w z(ON;p$+PYy1b!O!S8CD(oQd|!ITmxY+Ei3`?MmE*GQZKHYVdsADe>QyV@}E>^;~mW z26*KO{(sr<<+c?C{qY(=@s6_FKP>FVedxu4xApJKIT9;9yc!m|Sn-b(rY1+32kr4G zO#QNft8dHt4d|c8{Y9HB$z-zZ`Un6D^)?e(rxdl0Dc}U{*_!d%DY$B#h;3hLbs8cA zg9lG$UwUsGsZ8-eZkBy|#R_EI+%wS-;RDHv`YVhaj^drWr{gU~VG zO#J-O=D9e`YwYyR%?a#x6NgkN;GSQ35ZV$SrYm?;r5fw@dC;tK=fkI$yt-wyZ{k%pp;rU$BSe%n2NWPU$!?Cb&h+%l_GW&^= z)1ka}Xa?EebOG<&QY2RV#~OK=+OrC2c$wY^a7J}k5iMFw}i`_cQuxBe4$%kX}E;-R8BBT)Z!4!{u|O>3WW`Gw zYbdj(FvnBb6p-cZXcE0tqvR{@Jp0F{dRet$HfmMeW5x4bC&T6=n|5zYHevUk!sFgV zf0V4PHESqmx-@WU=}zon|J+4EnIhY&Rep6C4o+c-DoA;VjeI|+{js-|=8|r2>DGL`@VDb| zDNG7z;dcvd*ya#3lK+)G;oCMzxtr^sAPGdcNcG#wb*y=6Nb^fcg0JD#QG^rX(bdm(^h?{SPM;wa5Tp08f# ze@Iz}?EiYN?3UXMQzRKdbJ=Va7;ml7Ch&lskuyiKbUAHn3V?bKAxG{EwI3vf!>97XGmT5ZL_|(Wky>pB`e$@t)APPF=D79$V zW*4^~D|f@XwvA&;m4RK5i@jY;${I_EYLy_1YHo`1O3NPA8C`D~B{8?wz;#Dm5aZ1m z5+3iCZ~#LXayD(ho?MvhWX_Pr>gY{Y^y@jUF@=RZ^l=jat^1zuNqMXyoX1e`Tb)OM z$TinPu`elQArYRDfVSU~s}5?_~MtOdG8kLq>+ z_Zurp76&AEs`@Jrg@)=V0qUueA8~%cfA?~Xhxe^Rl1rq>cSQ?T7JW14uWdJxxUSmd z^^1}2ouRn92D|HMjU+vbG}^SFP7yBj-5RCZyMPt&-)4PXR>>|yIyh`(Gmd1!;LjJr zywVh!@qcSJmOIK;4+%%9!)0Obhdi3@rS>Jdtm6C_{Hc)X%FY3Oeb_bucLmfVFBY`S z=WA#+Z)LRDMSrb!%bU9m=bF?-~4?OXmPAkx2x+JsqdtA zI(;-9IqfQ8*X%HLg?TOWK3c!q9oE+u6J>n|F~L#tI_2?6co8=ygyMXrNE|LtDq74A znby>}x>=}WG;)pzZGzAx(Mi7A^heWBFy_5J}S1ZN|^CA3DZX*8L9kV_An_R*z+< z^c2aC6xr@VSSlHQp0mLCBisi+3Y+@Kx_tj#xZ^T``je>5Wn5Nghi%r?_9Cm>C>a@d zrzCZ>F7+2TXJd7$g<>iQ@)N@jy#l*Q!rhx{WauysPzE2NhelrJOiv9)C zFqCI~)m;rGDYJ7hYQ|G&X=nGxz($njIE9zjqPJkuhRZ^7QN)?(}~}zb$-M zckyyTyar(BRU7Juqohvq96J+^$wgjAHpl9<$@b1+=?cr!#D2Z5V;nXg+rCJ6-h91= zs;fqOHHS=bqSNa2)ivzL%S0+TRx$m((9~~RG{%@F`f=zE-kohs0SPpmrVopm7;>Fw zm$uHzB#G}yLEjCBzg$y~g-6E1{JgA6RYeT)#5;e2*!`mwx^t9PyJFju>+j>TMF@0vu4sJ%{A z(hqBRSv_Tjho2_Au3U&u9I0D|s3U$nI{;VqU*B2@oLpN>-=OkZ_8#I(u_a1;IGy7^ zOw4(oO1$=jb)c2Ur;*`O6YJV6_%2d$Y|RMjpyHoiG@d?O;gQ}=*(Gbc8T})M-D$eY zW3Si9-Oflh+ZPK;noaU@5%zFL#{$AJx5}#)PQAGciz#gDU~xY$40*DA2P#yjfHAU& zep^Gv|7_!HJ3U_*#Xa#I;gS&xBLSQls~2pv2xOXr>}>VZV!wVprB*2y6cY$uZYb=r zLk`@L2ED8mM6cIt@j9r>z`WuZUJi7@>&m9=azJGjW)mjczOKjU2p@KMzmPq5$IpB=s<}c8-%Ig zqj{6IyWCeGAa?tq?LFC88}D(??C+Fh{WjW^k6j#V($HG+_AbUM4}7~{RnK>&TBRLk^@u2=tx%=c7mVg>!=Zuz@5EATR_7Izwi z%YPLKD$XWvZddw#BuacVVEGusR|CAYI6Ke99@wvNhg4>@BS(o0)QV|j9;=|DuAJ;7 z=i9r1q%*qCQvJI%*cn^pZP9~o*9eL4*Emk{n_T&5Wlmk1xAT02;; ztHBI!n~nNtq?2@)?s?Y0vM_KyO`nAjklXBaEMu-@FM9?}6Un;G8dUy~f0-6LI6>PK zhs*Bm`hQuI=)b%*anx*0R^Kb(pPDllooq4zHskr+T+^(wxy(ItcQr^KZ&jIPY);2rV z@WE^*L9xE9&WKctG0%<$)nzuScjYM1+9M(IRwDoWua|S&gR+Mpz3jZLj>g$(S5GCC zaJ67n>~1V&6aWzInU3l8LYGz0TZ@)n;9#N}IkEeRuO~eF?#-BmwG_9-6CiJRof5MD zt--HX`$}M)CA9ToO|{rX<0Fqf_CovbuHmwp({V+*w*q;`U7}pRU&9c`E#s>?;w2#! z?d*M&`DvxypNK)YqpL1M&+}fc4eCl2jWwiS^7MaeqZY;?YSD9Hos<*gk}^uer=ovS zGx9s>GGju#STpIe)c>r>^4(L*`Jp%TH@nX2WKZr@xIJY0ybU1h_hn5q$L+E+wNSg_ z_Fr$#IuAv->WhiG?;hFnHCvWxH`>fxrBGuTPLY%po7tVjkacwKB^ z8^z{~yu=ZsiBbU)+{M_~f49LIly54i$I?^br6lR@xR_6bE(@oqyNU_B@uO8Y?Mg9& zLo$}u%l#@ah>->#{`k{@DMs}yFrbg#9-2 zPIo+GHSNxjy2SWX;U9!i@v}5Hu6Vr=3p?G`pV);fDTbYwnuk>%r7I^@o#w*)Zw(0E zRt@204yN=DBcH9c(_Dg1cDAS(P=vR!^e=0!bnMdZFZ5=XULlrLNDnpJOH*m!ov=ZG z_^w{YCrHoNxJ;Dzb0`~rnnPbUJlk;-$$6(8_;JU??vHH>vm|e4=AGm3aWf7Dx?_Uk zmXw_^Cw7?dV>yi7%KfFyQ10~C0xCc1_gFq@&)+#si4U+>`H2qOd4JGa#x=q}^ky7e z0Gq$90ZFlu)Pan-QG`E#m{aL%g}d_FR#-#TVtp|=jvm$!L`qn%Z!$qj*kB1n4qH_|ayxfIjg3;C2U<{&~>rH;azs`QU{TG!A`^njP{4(n$ghk~fl zhHxd$oLy9tNTO|lMIBSPb`HYJIZnV=K=NXZf!jA}7?lB&gHf?cHVI><8XD7jm zvC4J6UUT=9YV=gsvj)sX`G!3p((mM}ek*Y9J=_U z^P$>IJ}6xlcvml2O0@%${ZYTVE!31=VgyB`!|3&uk4x1_D`JnSMzV-@o<-y(-Z5sd zwK^uIJ~eUG{!EQA?)AuyriE6oI~p!7Ydqpu?Z6$)sg_Z$VQZ}%4&HI2Ku|wz|1`oC zt5s?1ahC>BGL{}pjb+-Iq4+*uIPLMgR0TuZ?y4=+_qU)eApkNxsl7GCn1nBWTXT35 zB$UVWtsL&PO79S4$&) zSQG8X%7R@Mz)R=t;L!RveCt_b+C+Li;;Z;|ynz0GuZQe()OzmXGJDxl&7LX>$~t~W*9e{J7csM1TvDmi?dv&=rhceTC5ZBRIp^I=nMJY~ zhv}{RbxoMH<@We(I;}>FA*V>})fz`KZsO-B-JkG9?^F19PH$n8``vC&jwyy8qQ~Up z(2F$%An)*NL=LS+{8rR$V^PGO;p#^QMX+azdwzMe$21PJ&UM>mQ%yU6GFJ87Z>|km z9XFljaWnnhNn^`6K*8iLqC2v^V20?#f7d9|oyT1q)wd(!d55zQ;ZkCedKh}M-y_)> ztwyxY4Aqbvxzo5*40yX`5RZ4RR%EbC(5^|JivMlG*GKB>Y;H4M#yv==p)b)h5?6n_ zpGXq(biQemO#iq!U++^USd=?fRLGrw<$uTO^Yv!xu0;`(*AuEu$rC)8-cc1E$nz46 zilFsgjNY&3%obc`IpLQSjoY!WN>-h!=b^GW?06ecz|Jia4ai*tG$VdxT~!Zgs8*6x z?H98vLRL(*yMS&tM!1~Ziv2PNCiW&2H$HBTqW)O*%Y$6t>150j~55+L+O6}Rg zBZ@BT0UytF=bK0N|CzJK#!aU?zL<@baI*e_GdWyI^_-bY`|iI%CUOI=N1@pd6T z!29E77wyp<<`?XO8xHPorm-be?!V0GdmRl1Pxc?}Z6mi4K!bjrP;h|_rh->AAnV+{ zo-C1sg~0?~yqM!A;{&Qx6zui8-%fDsDBNcgb!r!2L@(w@sq7mRq9sx#GN#*=y2LD? z?1^vn^mi!v_t=eTmK-Z)^;Yvl{&Tvz)n67wXKG`PPjlRiW2*?wN6C1myfcspc~TwG zNP|zGsPb|Fm2?MI_utma#RUmntwA|E$E0rsf*9Q;%wapbajX`J-J7_@KJ)ED=iVCn z#8vo(UB>Nd(ZyE_1s(D4kb=6Ls>@Msfk0Wngz>dzh-SQ=(_vhjNe~QLK}co*NlBL$ z+1wSQvIe`YsBj`BD?ki-`QR`+5Hn=-~{aMgu!8eKJ;^gB}?Ap8R zs43g-#+6uNJ(M02tk>N*>}=c}qV7ar)?DVT;b4=pV0+fTy%aw!@Ntx`YHB>(S701K zY(l{*to!w??q0=V$qMX>cE+_yh)2v)vCY3GTD};m`;r%~kGk;kTYFc6gvD4%d6!yC zp=fPeGepEd#C~CeZ)@JPTH5Td!zc|XO(v(`IZgqDaFriWFr<7Tld4JA5 zH$N(Sb7(wduFyaMWkD28F#d$X>a@LOSR~E1E{HVl?(Xhxjk~)xRzTrWI5afw?(XjH z(74mMyK6%ujW(C>+vn_k_uMn*-kEu(epF>dM!f5-m9a8oMMlITn)}!=87i%+PM(pE zfNJldpJEF{15aE^O|4$Q@FnG!>h^)3JRy%@9Vw4$Z5BZCQy(Si9DIvl9D1yWUP&^a z5EmS;kZi*>jpW+-7b+7|r2YfW*lVG?;&16He=3`BD%1tT4Zl12(f?f>Rz;qPL4zOh#+SZSqo@Xpbz>{@=Q$W`5FXljyPdwGa zMmIZk_*jFtMrt61?S7!?N}O(yQwO_gIVaBZNlsq6EReaTw@JwyfX2ESAlngyCd0d1 zL?9TGe`0n@7Rf*5srf|1K1`O2@tG72dPTVkv45j^nUXENw8X5ZFIL1u7UuEXLGHu?N7H~ zUg+Xx&I-cDt7&%wA_Nff%|7mC|#b}|0tJ7J~aq&?Kt2_gm75dRvQ4VU$d3L1q}bV zZ5_z&EIbWO&Z`tXX#?GO)jwMyTnbbTRvq0kih!aTd(N$n@8N@1)^NX2qqaC z=tqeLR@zVGib=QXyXR)c39GVurm18)2D2v1S26_s-dhisKS9k0>obyYOm6(VsD)=w zOVgLLSV-Bs4K<(}n1tpV5h91Z!k(E`dY{oMHQbSjd1Y2;c32WJ34gVeg}~niEu*lp zY#a5it?8%a-1{CSXoWH?dds1{rql{f9hxCh=VJxa$u)i|f=aRQLc7ws7(%I4UTRI7 zBi9y~5;B zYQF;xTk#u2Eta%3!BRP<&g3ay2CWIsOFGP&04i z<0tG3%*T<9yH(LY?l!DBENaqkc4;l^bz-`MPNzB56KgA@ zZ=As1GDl9E;0t1O=MJsCBDC;RywGGFV-R^U#I(hJ{J=(&r!s#kt7)>nH_*}SKBu4f zyd07YFm3Q}D}!n&+0{x#bh6MU>|g*0Tz%8*tB#bvpRvl9cg`(>gC?F%1wsk%FT%9U zT+0Sx9cICS{YJqjz;1x&&hRNi_?6iH7{i$mWl%b7@bPvrxcDIe9K*n$M-|6YKuK{* z_BdemOG#XUJLP#ZXR{`8DN{C{(Q@$DAU4OCcK)HLc6bd#XuimfqLMg| zQU93E;I?^eF3EklejOZd%NW$xg&w(K{B1GDo7g4Bv^6TzQ+CUQWepKW&)*62x<)3Y zW+*KcVoBNoN7mtNzjv+4`g)J-PjQADA@8|{SHIfWG25y4PaH6gg}(E*8cVtFmA3D$ zsh`VEeX%nc=s&nsT+&x4(hPUr#AL**jcbGVw1bfzp|6yWN&!&-n*~bq_3O8S&^2E| zuL?!&LlT4qf8tv7*W1=D*}VjNju8PgA|T+uL!Ojnw9p*;m9I<_(YaX1_4DdKV(&iX;=gXIkQ_grhesh2wrW` z&`A9Ziogc6E}Bc8*Yf8tHK9?x@^GH5zjRqbvOLQ4|-jsy>s&UJ15=00^QMYQvL*s?X{BL`w7aCI#}U7zs_%D(hUSI94c0u z;gH-{-_J1RBdKLT)nNLhR2C(1PH?Qpzw+~B(;au7B*-t39X9GLyk~mLot<=}XzlKf zhMDG2v%+{NSP~MudrHZ76<-txh;r%xj;a)C6_Y{lST!M@y%LGdbBH-qy#WLXL&ZwL zBD#dm-g&}?8IOoxQ5k|i-PBgU>%B3EA8?$|Cn}d(z^^A9J7oyI0Y-7}emqV_N4A*) zH?iwzgx2~OGD6$n-9D6ESqUM zjh&l0E`v;o?RG*>I*u;E4{wXxhcRcCW>o!ur!EC0amgQ~tM5A>EExu*Z}Np_8#nJ@ zSK~<4`DW}xj>+?32hoMus^hBZVXq8g=f}=(Fh$CNheY=N+Ujt_d^uD;7-fGD%PK_{ zc&%rYrENS-n+|+2N&9v5B%<%VifoblhKlX{=BiIW2r1u}u!hGhz!ko)AzIZM z`pZ6PZLv6XDo@U@wfPF%pmMPJchFGw|4w0;&{VKG1l!xNa*e18Q-Q? z#h4|KfKzOTvw+Xaezz$wCAq=K9A)Q5CX1#Mf(pvjLqMbg;I3%Ejq<~~^)B*{EDmGv zfmVxQ-#ZXqiFy5hqFdiuToq<95K*5sH2;)rx_UZZ!nTeR8mEVH4C-T)_k!|U-`Q*X z{mme|xi-k!L&%%@+^KTR6$Vqr!&de3%~bR!@kFK{SFz2&?+c+j&epBG6PD8|#zZE* z0H(Sz67m3=eVp1K5Ul{yj`{ho&`OF0K>|K_Z37;KCut&{o<9)6_v@d_)XW9LFV!ip z`YEZEQ5*i)y!K`x#HLY<5>LH+AKJ0=<$QSQjyDZ|L^$jkmbQl;U%6QPB>Q^ajI3l> zD(yK%NM*p0tf-G%LcABfLz75y&;p7zoj1l(79}U&&K8AR8(e9PZ@?5r%Ap~V`9?Wm z&F?^;gfu&uFBo_j{HV`|14GaTuP+s_hEo*CMz2Ny-!Ql!16xH=#NkL%({1JiiIPM} z^9PzlIDHE)W(~pVRH%+qA-#b!MCgYis`orPX~4*N0mqeLtsJ|FuR{Zc44qql*Vn@D zE+waUDPVe4TCiK}ypZy|MXu0`J!TnaL^c@K0b5x%tmS9DapX1Gn4^55FB2_IeKC60 zWM74UT6qeT(OxvbUDwLphA1_H2u9TD{Zc&p&NJqq`&!APST0+HWp6eyN4EigZa60l zjb1P=xQqMl!^{Yg!*008rbJA})Cne{i#}12d%yG+XSNj{%|@rfdUk(pc_x@CCox^z zHXryd!=a?V%q5Megr}bfNT~9v>^}2WEHGgvFWTQbo4c!&Jn{Bl5z`$trXJSogj(8c z4BS%yhE$N~V*363;5& zfzf0o36*_JkQwtWSOv7$RY_PJSB1bIk>k6cwu@l$7jNVAIeS~af2U10Vt$)(Gi(YN zLJs8Wuo~3(#ydy@h#nDWkTnGkdPN)_dn6S%IjrYbb-@lXr19`y#WILetNY|S zuurj*)6~ByMtXp4WpG%g(71OyS*E+Fd1W&U_krBCR5PWz9$5`<<+AdMv+fNq!^f92 zl^rIKBjg0WDYta$Ud5aV70pfewImXtbG^LB!PTUp#}Hl_p2VgG(lFMqxIO*^0}*$VhnWB)I!^`sF;WDaRmEJ*9^C)&khOu$LVn%|c{7E2zPdZMg_YVU$F_ z4Kt1~^-mf*5f#{fYj42+M#2l98ccE?RkqZ=!8B%nDX`s)`FG=i%I%SF-I>phaExMRy)huHWJVuj9M}Se^ zvwDxAU6L+ro~zhJe|Z>?utnScq|nHstw_45{w`&Tgp%Zs8&`4jL+Owq>U_* zfi89(D}7eHUQlx{0PWgrub)m<2N2sW!%Me()UX? z`O}3|-W$+i7f6}c*bDIr*xPfYI7tPgQsNt9h_EKF`d06O3XghyuP#?{Dio%EG@8ZV zs2E!%Y7%cosA(oWI-&pcP3)KA*;lxxlvfZmdNMMd(e4+kF!3xSPgG=}j=|(e)dumzbjZ$4S+@1nhII^S>SwD+HPbF^tbC#1 zyY~0zK!LR6HK;{Mn0@STGo;YIFLAPt{*qel32j77Z*k&AME=fuop8dQxtLEp8zl{9 zieEfi{gbJm!_h%SmXrOXCY4j&j2-LU+A^0T1}!T|v3@L=Cy`2;nzGp-;x_qpwzS-# zs0x!fR-=OnE^-$?^w=$%3Fp^OoLihdU*Gumx=~<%QQVUfK<^6lr45EcnBG(T;AC|~ zv2_*tD*h;9wq>;i53o0P0XYLq?EX4(Ftvu~AY~=}>sL^aMG9yO0yvYhNZFcz01^N* z2Xg>Civqyj5@bcn%fl@!O!^;HJ+c;c*6lIb5PfrNM>)`eS2%EFuBV6XR#YA^Yw*pa zW=d_fAdMk6Hr4d`mm^1(0lm|$ zH?B4fAZT$m=BTz(BD!KewV-1ig$74XhvH#*NDWCUHCKw-vJl58^6l+fiO%KO=%N>8 z7$^EoTa{8+5xrT)G}+2Gu1!|DR8o3gb2{*owj%!;BY&dE@yl+-XKd5BRo%l<*aCO< zVZ!K9J^ABg6fpvAHWar{b|EJRjp&vlmEpY-zT7G|40WM2kL{FMNU@{7WjXxt^W-Wi zu!M|oFxA+Q+EkwFajg<&&~xflw~5tfZaADwCl)%+Sgo!89^W0JwAG^#D%hCdBHcA0 zH}5$$!m?*3E5+>d(b=1kckrzh6yfTn4FsX6FWaIP41QYG%-&VtQ)f{ldfY5g_0*}1(v0`D}#3<;+Pp4{FOk_Mp1DFy_Ko1Q9zMT zCBrQVlGjHLYQai+IA6K$j;l}7aZ!?6R;R5mIC`8u(AitdQ)H%M9Ad%^lmq3%XfZO} zAbfv;*k4~1IIuuOO7MJqVq(#4!T)2A0Q!*99?Crb5;avN!L+{aHnukUy=J#}T;fn5 zNZ4#2DlD&MW_enFhOh7%BU0MgjQ6`>-lK47_aA{J&52#(2|~VM(`K*;+Y6ten?iyN zg51D(Sq`|5jZRQX^xsZS(!%YDIYw>Qz`o@Z2@w}Sr_^p~^D`rN0o*pYvaBtK@b_5M z_J}rvgkW6_LUmf)HooT7tmrO_epouf*UxI&kws=F*Y2>wM_Vbsf2YPHd+nnU2Ux_i zp6`PX1a!xdf@+_x-Kv&7l8=oVIYJH3&1M&eGdJFhK@oF21)b9ITpgoocZDa{KV5;H zuWn&uvN(!-lGdq#pknod22C|t{8B~RA@}MP1{!r_$(1x6tQKhd+@}y;`Z3$f{dMEF zo-WD|2&?vx%W=oW!8lKh7_vg?^`SbnCmp#o^Pc7Gzncw zq@*NqgU}GXpR?X!*im9E7D_uE>Nh#Y`=thTjpE7`4cFaFa1!Zp8P8)}04JJg`N`ej=4%lpRbgZTaL-2l6F<$3U-Dfg?E5CGt7H>=6DGD&FGlLn%Z^ zVxw4Ko_9fVFV02wZ|Ztgb5A(;Z#Sb^yu~j&EM{%Ajt(ah-)J`A^xP7cUd(6c07~6* z(zQDU_76WL#6Oo_$&ShEzP{Wcr&v24G+pf9(n0^u7kFe_>2M1d{e935Y9F`|AUbN} zFO0!$z8z@0-9NC7-!*M?TAVAKGiLK?6_egLB;6{I*!NL)hdbp5GOl4%KEq#g4^VMS ziEtYcv7mY>s1k3%5d}(UgyMM=CEafbpGs|wSi+RWMX{8Eg|#rc)$M>!Q0Ox zB~?d&8Sr|&e~n&RBYTjHiIc)+3=?nS+oC48Cfv5&~N?gof?W`%W2#C1v=#VYIgU_y?8=fsWquD(K07-OsLrI$| z8B}W=SSJkG6L#pZzW$RHF5l+T9rIpwls`E=OtL^W@RQEO0pK)Ru>f ztgN!Y2}C`&1wZBsH=0w4KbFf}cEG8~ZCOPcXGDCGOATNpqFLTW zlWj=hNGNvTjm7OLXBjP1a_nK&jyXvR4@r_5F8Ow|vxP3;;<0F$p<^hQzSZ#p^CdNv z(IuU)o^}Ur(m>zvH;@XEGn74QYtCY#%%8ocpOdDvcyWiXs~;^jV!-j1N}eV9QEERw zOG@?&yS(#9TnK2dicDq9K!~g`_wSf63FEJe<3L)YGt~w!rF&1_4)f_nMDtb&mVk}8 z8FtEskvKdG81wI*VM|XLXgw^YTxk}SWK_B#SwGQUxY$!h1Ebu;mc-T!Z8F(R*pWyf zdvr)-@TfQlVS-HH@Tl-@KHgupO+sFqwDq0#h`tC$n|b@;4)-1D8F*!sTBVTc*lspi^}t#6uh@WI!=khz0{Hs)+e{mGp|T=B8Rt zm85!c?nzT>SH>G?NW%3{bS$Dodjq1pfi}1w4RH<*9K8inLeoXz`HlOK4EtMo#^UlZ z^?ICq#>+awX~jbxtQJ9JfdY%e?1>(#RK$E9!7m3DOcZ!lLOeo@1U9Yh?QO8Dx`alV7 zT)HekoVIEZx;hv9&Xvm67}($iIkjwT0+)=O{I4iiDs>P-3i? zL=Km-7>0M|VQg64SX`HyMxC0@I!rF0d(iR6-~hByM}0y|$MMKYNg6o_xj~0elV9C% z%`3iL0OzR%i~G!DSQjDa$G~34aZm;@VuCUHol&ZDvUYV(aFzcX_j%RVFZMgeqy0}d zM+$*2dOOv?3>m}}Utm6x@t+?twXMD4$#lClVd39f(FF(Y2h9^Fh~4Ul9@d<1U{@-jMMGH zh>SxJ0Q>WDIw%`Tg%9o0P^)8*$xdwpk3k0Gi0rgDt6y^E+_WUkYmzomL)dcChqwUj(QH4k^KE?FT@)2(RW0J~uopkex%XHwa~QRvG+epFG9b+!R``>@)We?<3%mC4XQy)563eCh8xu8a9gKMU z4>Hn9Dx7Fra#<6RIn2j+)e+-`(Ub{|3LARI1hZ?R#Aixv^ZBp+Z}`pWKhcXIZhi1A%|}>=_Z(y2m2+i@cYr8jp53VsWg7TQ z$_Kp+B(TuXpIYJ~nE)DkW{J=4X9w=59tNzGDYex<(6_`Rdo z^!~4%9Ik(Lax^?00i-NC%BI!;GY~wBx~nPZ?;Ke>6Uz?=MH^`T;h%7`a=^350DzWO zAX08Nc6b(X2U`bcbw?AkkGc{7H=r3nOlo*aPfAq`dI|^m`=4 zHU87<`Mb7;vx&Wng@dylDeFJ|AT~BOR(8IBxkB$N@4JwlRv?fgKMRY!3$w|GQw3l) zbFgFaFmYsIV`gOm6BP0IpkV_5k(vT5f%ZZ)KRbJANP*@;G}>H>tcs4}04t!3moq@! zOG(4b%f^h)oJK?#UeJTz!_LtT05T!7xXbi>E!v#DmG+h2jGNp7d`F34n{4GtdzPbg(D=3)95Z!4)J#LjzCxAJEbO z5Xkdy8ZOeZQX2mh^YI^;E&n_@{+FWvWdryJ{f}n_dpg{lm=O*TKZW;9+23VW8n*VPO&A;SrE=QIV05kcqIc(Qqk9s3^%v$jPV~ zcvz_EIO)j9Sw-16`2>W8g{hb&WW@z#c!Y!n{sIAqM?gSELMB8-B^00~rxo~r{CV#O zLxY7dhtP)vCkKN-1BXNde;))R00V=71P2EP`_~5w@)I-!ILyaM%zw-OyTtn%7$PJ% z7z8RLDi|2}s{g;L{l7edNs1hH679G>nozFJrOJBF|8+j{W3uQdPG|D}2yrHbt%8Qs zj-!x;yMuzkE;=7+xGqVN$8u7B3*k#y+_P(L{N)tw{~oGMGQqg-Y=k2T_q)d0PFvEk zc4&n!dXCs`=d^lQuaSF+siC0dlyAM2L){YvXzl6Vibwe?tUeeDVua8DewH6~c%7u!> z=DnRs?8|}DN?HE3{`O}vxfdSy>J8CdwOnhsq;Eg*)$L2ZKJkA|6#f_5#FXi_(=yYL z(JoYkHVXOGH_AI|##L3T4m5(q#ZLSKD%69vCnC9rK{M(eS~fLEeG3 zk<{??^?ym&5%Z@SO|8+>WZXPe40C{77Ivl6>Q~8b?3eOgQ;z%^DbGQE!OMAhYOgVB z+5Y*+WWw0TVJ}Gl?>Ftw91G74lwOh)x^h*q4ImCyvAEJGoB_IlruIDy9e=a(RmM zpJ67uc|7d8=Z_|}r=2#XiY=7X;Hc`Yz6@1Ril{tUgl&U?5qp5dPwA8=BISi@J7np9 zLL1c_Sh)Q7Pr2Ik%4!(v%~z56DG)=*jD#z-r!?6fQp(__C|=0ZvJF+X_=7br)Y7LO z-JZ9bj4n8PLk76{YtZth5l`L}cZ}e!W(1O6I7^X+B?~!4o{0kWYGe0w=mHF5T4~!E z>M8X1-(AuK1d1uCrpu?*>jwerTmhs15Dt#zd7jOZSiqq1DEJFci7z)n_$BJR*Ms6g zDXjRo0p+8U=Z@Q(pM=dnmY`LSCUgXnoVk3U56=+g&zACW2Wq8_o}y2yij!A z13Fx`scLLo(=N*zD`%6>ly@)b0`Pn;LRX(C%#_%sbZRkaVxB&2!sPue9-)#r(S`7U zA)Q4q>ExG)k3de-AjZhs(HMI!ozxWt_Ul zw9))6^|OZ&;b(dA9%b)erd=(&ROQD-@k5Ta$Iis=B$Ar;9K+R{3>Gxf$sRO| zCSUzEo1qG7*-Pl!s&&p57fKS3Nj?uCGtwg`&-PfcDJNk7rxi9FC%-&HLyYC^m&@N# zT*v$bMaK6L-5>sl$OUwa1V@6}@!Sc6cK#xOCXZWippuGHU#5O$J(BHxx=<$}<2idw zbmu*JHe7aVfTE@o_UtO+%U+w{r9W?Bi~Xp)TBM8hiz@a9DU4G@tPKn%k2;4`t17>Y#YNJL zZVqKbqqu1;`?7MbN(*2x^RS~!U#(5TCWi5!&~F^S$>Sa(x%`Q9TXbg>5xE!_F2=|p{+^A9JT_JBjbF>9 zKHiq)Yh|NyGbxJb8p>K)r`FY(_Fu!UK&EKLqiXA_3o=KE|+I2?9g~h zonxg+&WH+M)OSU${teDk=O)Vdtu+%51Tg8M#+qD|j%LkBkO5q$CzO2Zt}=G}n?&XK zmVO0cR-F7GpjZnSV|cS-&e?>}W1!-58sG-W1H3EFm^NYU@Np~39nxbbI5SM<>&(P= z1@fw}2J0}16gM!lvP0S%XbC-W=%6~k6I@Vs%5-sazl?}`m zG2v-GIr9sR7Ux+Wi!~!3#&I!&4+>xq5lczPyl0R?rPIEjPQbu;uPBaOUm6%Qy7S)- zyv0Sn}J8D#ZlvAan{=_5o&R4 zE{tFwvH(t3{X zfPdi#Dh9P*BB#UhUpAt$jccYicaXqvjzk^Hz61Qp2WjX`5D<0M$ZvQ*MIMv$u|MPk zT@w9>Oy{Q??36YwMd{X%uNw=Bh+?xYSRJM<-?Wl2CUi6jqIMcRlGBc{x}!!eDdNB| z_+(bZ!&mkr*qNZ3(yR7p2Z}vfY zrhwMCjLfk-LVa?a-zladxr`gVu?`so<-Qu<)UA(d$*N{BjV!N_yua`v5x9+Av4q*~ z3qFo&1ed+wv_74>h^4CWd`Lk&iis-lS!!fvV)hcf`;vJnEnS!B|MBo2`3l#5s?%Lz z_z`#)O*H`L`*9CEYRfcc<%)k>$<(iuM#NW8q*zyajqfT;mpUrY<+&d5&Jg$5unA46 zV63Qc^M*4ipLx4AmwqE(XPvod<;zAQV!73?{^2B$r6<7y0?S;d5E$%>5ZGSuSuiF4 z-@C3-*k^9>);Ths8cx z!A^x9)%ixrnE=0Z!7|Oo{8>V?mKBHv)>U%;8i_^C0e!6E!cN}>e6k}>R%Q{E;?frtN~ud#re0N~)nao46Qe#bgrAmC zy}7bG8T4+k&d&;Csl8MUUFu#&t3D&AeSa|txkt2=C&^&gaHCAoqyDP2!?Hay&)LSr zjxHa0$Q$!@X!(SL3y6CZJ@AQTJax&@isQA66o~YlGa@5{OOTndui~kD@L|+1`6{2m zwR-%X@}%wF@Rm~5P2g!{URcL!&9X^+jLr}YDy(QK>P?!he8H#nOp@^^k&*F=Zo*(W zD)1zic^l=Ud4QGMsRk|_aY?1ls31IpM#nqba|Eio(>e+_bZ59bQ21)JQ>dZR3~LES z#8!vD+11PHjcJ{|6!U}=;vpg7K__wYfoFZJ7V+woQRxU&63Z^45Z*n|I)&V?&9POD z&SGp60ptD2D794@SaY+H@`b*{>P9aJqB2KL_De^woi)yI-UkW9rBqf+S5G_AC%wav z+OE#{ejMSj0&loX`Bno9@wwtKK?W<1hp7O(>qdFl6_35xayev{EQA(FL}c%ip&><0 zRDC5DluWI%ZaPAWpHcF7n-UdNK)EuE>XkZVhQ-r3IY%tm6`o^8bU0BpDn70-sz{|8 z8(Q;xWn}97bNfnkct4qxSodTU-M(&_ul&&ezNoznrTeAu(dUyUwyK}&zp!JwkT z&)G%-(hn}+W~`&SO-Vqlmqd}RP)rOBXAOT98`DuY9;snA%9ecEMx)6eMr9kKYBs_8 zVcTeKwK6&*1_pd;9V^4nt8y)QJro`#s}18KQbHkXj&6xc=KHm_=CLwCY9$*K)b#x1 zizBv@XAG9;?0HTknHVIDKk$>DhNbJD`_eU{LLIQ0J~(_lNfbZd5X~J6sgc`c1})x3 zH*reb=ij;t=ty98*-`=2%%sakdC40F=-CSM)D)rIs7-n3(#}@?7_elFY?0KKA(Z@ZCT>crPxzh&Add`DHb+uV8&kN$!h?Q`ucGa}( zC5^0BgPS$C;8aarSe;F%-#&MN6h&b=(|p0N)2MSjSz7J|oH$w*igvccQCD(WW3^^Y zCTG|~)AUvN0NYJ;MP&a-^?!F-vFsq&c8tBYqA2)g-7&xLnC-)f%LN<8M=sHuPlM;?)f?&@#*kUj+!8`Q2CO8HlIEU=#|NK+` zKmI~~jCQc2fCspy6nnP~$Eb6%)7myM<5MGQ7^?(|G#cV-0B}b8YOtZidiVkDSzdNrC;V4xdDGD5 zR)Cl)>i#N}-@1r-n$bIBu7~xiV(nOUyBc|SYp5-w;c`hF7;*%)sh@%L4_P!=KZBy{ z5079v7!_c{xeHGK{onnZlE&{(Sqr%|O7u+6#EgcEzo~?;2Way!>2%mp>s1*(n<-JD zK~rDldygG+dNM6kUQIf7At~yq>n@RMm}jJqE+{DY*?b*|RElOmA^R3Bw17=JRv_BW z$@|CH&W61uN^VPz5i(=ol37^v@y2UW)k2+2Uox!)ks##Y$+Wn-`En?qxf2OlRdqi$ zCm&5RVlS&Xn8=&HsrKShn?Q47Y@`QP$pa;d4%j4ckr5AN;PW+f+nsv1}-upTkVs#5FZy0+MhUtB-Ve)OZJ z;8|OG<_KzoQ<`XTB2+R^EuzJjmqifB0Uh7LP80$(ErEMQoT4wu4!yC4iCmYn*0;$+|COP_yYS>1cR8{|>gHk)jg^aHCqdY6y(G zU)8=}X7p&*g2A{gp+#W<71^3kSNvK>Jvw)|eST(qoepIMug$S`X`vQ&b@;;H*#_8+ zx){<~e3q+6R_F9sJz-rfVuvagTrBs>`GmdK+VuUxPLw-1uu)Iz)wiwE5mAR^>2Tp# zE%)|%B-BPfMuWF*?|Wrbtqv~=0wxAP%pVed2NDuhTCG#(Rmd%V`7Ft>Q6f3M;5Oc7 zpG<;*u)dH+KLX$cx2R8D;#f5=nt%$OCc~|Q&3!pIInDEY?lJywd|+q5fd-;(XN8Y; zMSL|i1yR%7DGW-9Wq(CP#TtD+CtX?C?$rQ1Rz634t|E$U!fz3*qAy>mzoAH+Q<*@l zh{bPx;NxAVkklHZN^UkdJ&1SFn5b_`T{Mc>V(JQ@mv{#&g9)9PFVaBYx>=^`0X!AFdDUhtH$4Vi`H_j-Z*`OA{aupuvuvAu-UB*(1 zm~sZ{%RtUO|Uv83@Teryd@VIc$h$LZ- zo85d(R}74{3}CR@xX4BLVkX>1Y3ejxF>~5yE*!RP!Hxx?Vs^I}vwn}pbv{}y9#jET zbw7n#;XV3Phk~XN+b~aJu3M0ry&3$W>-TLj#^2*6k-+k z6{Nvr;Ip*Y05Si3kSFN6fz{L8Kn|=vuek=ZM{cF@QyRXv3Q{oTjqQsKZzkUk!aiIe zxArrUmu}J(%Ek0{??H}n|5;+I>6+wWGn{USwCg9i#J!lBH?A+3F7}*i2m{H2{n}`~ zZx8`>cP=TnJy$o$3C#$Ort;|lHwwA)iCIsQ1Qf}wq#3>dP~Lx zG~Z<&4T(iGC&!Czh$mI^%zAaDcLI9!D~fP?2b-s4)pHIGlAQ9FL_MfZaAvaPOWd)~ ze#soSZQ#?fMRD;rHHzOaquU1~N0)>|U6HivNs9c9ebmTzx}2x|x9+1jpybi#Fo0 z>~>tm!1P~8by>X2VWmtJ ztp;tEdNZTn8T~hDBuX=WcoWQIMCU(T;MRbQBVs|bOZ<)ebKJz zcpoL~O5ih|Y@NCLn|vy(1<3@U-=?Jsj0=DNV(RR~0%s%FKX(-Ki$tWwa=M-e|4|mM z2MMaYG&D$6lCULR3q(bOw^wn-Kj0yo}Gsv7s{R?kl;gmWO zvgD_A%!}nkWb4s|I!Qmug1Qc|K$&J~Nr-lxaJ`xm1gD#xiu;Ae+;5BGjSO`(2MJZ0 zbCWvVTz%Onk2wZK7RpHu@JIU3EnAeNq2o}ca?>Z=M5}?TbY8fM<4N(fFD&)c$+ocr)iRBy_YLPNBw16J6 zWL-x)rHUn&O#Y6J_6`VK*k+0_TON{<`iSHj-Uo~UpeRw!ye+6vxCl(K?MaFSd;m-y3Pfk19Z7KRg9L zsD#=bm)*j@xl0?B1k*W)*p&;S($EY`ZQs+372)BQa%6Ly93x7WCAWY+So8a1UJ6%V zKs&=%9^yT9w%4;1aguGV=(U}UVb{#K+BwEc`(&Nq_#rRfd7A`05p6}v zQa`ydM1qV?9eK{E^_-m_TrwGBlx?|frAcVt!BRP%q$!bIzziPKO`dbSr_#|cV+?Tg zC{nn+f8m2JDsEY`D7smN(k;eclga{)NqUL{5XZiX2`a5EsSU|R=wT5nL{;NSm~H=_ zTHRzaqiWb%*K}YhWizXfz`QiEM2yMl*n~`7hTSZOk**;P=qK-3rlu^gfou->^ciN= zz&vV};Uc@U^N8XP*_vxFNGF6}KIy`MB4Mx}&ROVrOULD$BdkIH$xEpEv^*pbB}wW= zzzu)&!kSNSLE2Nf%hJS%m>iZysU8-Snk0NEYIy`=vVpRW`}3#mS?Hg_^*#$%rD}&c z5w59p>S@sEOHk`DTuGv0>rTI#qQGSkM7`SznY#E3?eBF?(xC{8nZ9`EOCw;Q?HvFG zEl9sryR=)i!%H!iV7D>34y*v$QC}?CgU7G{fr93Pqo3cw0&>V}i2N#3f$|>bj~OCT z(Z;a$yBO@%_(u}D;|fjAaw)cu?WE6-5-%C|9U?!?Q%(53iXLo?jqKBp<5VRaP1rIc zce_h!n8q)Q3M5Yzx=T|##pq(_RMetj)frno!3#F?a_(K?J7_zo<5s)r*XsqF*Bt;? zLjj8P=?TfyZS>o=Jz!Kk=8MLEo~swZm_pH3=lMR%a${%rfz6N4mL`^f2``?<+UXn& zTIn*PF{|Y7=CRSPbkgLC%!}M)%TwWRInBPx)H%W*V{&zAEYwCkp=xv3nV3l;yr?0Q z=bwiKhS9Faw97TwY`~f~r*JzBwKn5VathvEyH2K4xzVOKlyOUCrPDVDkk*T4RhnZE zyLe=i>P74b+vqeAC2Nt6O9EBZymGKcdh=KD zuGj<*pMbH(J_(F-*)%tU29n_i6Dsz9Fpve2Vk-C>zlXy5Ya8Q6JgWS-FwW>j5PoEe> zdJY8FvY=3bbY65%+O}?AhK>zuf@GUwl~ev`uk{aYP>e9;T)KuaWlPx$OIC&@N9gS0 zq~pddQk0&!;}es15B>Y0aa>vapvI~a*z++r8JvmvIE+|rMH8xWl?L;SjrF=33Pc%N zx8RX-W9XGL?wDmcvoUj$TeiBll~w&tt&<ySg^8tGH6yq~^J{!@bh06lQM! zhhbj-OfSxLB4-E7{mStDJ1HzN8DLmtp3m9B^3ef4>NHXX6a4Zq@K@}yE^|in z#-b7gFMor9?BJaHBm>FX^U0mILLxhQyI~g7So|nv`PSvfavJCEsM_E8)_A5JOVUnc z7^@su=XHf6_@i9|u=RE+c}q6Y>3a$&@V{-f7QM0T>$}Vg>onm_gZS5M&g+f2xm_nl zQx9fn+iQe1gt6?_A2^4Jz^{1xx=_yeXweO-dXMQGd!!NQY$bUoF?9crAPOVdO1K1`M=r8oLSBf7Kg?8vRWed3e~?`+hk8 zQbGxMJzG70jTu6tw*Lntp#qBFrl`qlt}DYZyEP$e$}Vx!`I~ zL-|d(c*4iZrwE-eg|#i%9}SXZj>rV9Z(r&&21P&b1*%c++PghyzB^$-s zh_uljHXYJ)8Lp#_*AZx8q~?7n*!!*(+94*(Vk}W*Q%>EL%%v3t0^9$kexahRNI3jJ zREI>v;4-$%ATuQPDwGUv6J?pi-nBWmBkS19V;KjC!7_?I;Nw|YsHL#3<`PW&0eARo zwPfU!PETr3v}Rj_lT?PJVQdx^AB}>FsTRHhTHZGq?>6Rh-AEm7U`NKiR&GYto~X2z z38c|b8vb(Jp5B<07`)PV4V-RYSqW=7^8W$EKs&#GL&Z$gk7N}Rd&vOY&roSTgt&|VUE3=rB&lb)h86&LZLQr>V>-x zP2Kf1X}&s@OTSb6ZXUO>W_n6k58%fM13?Z;0j-BQ&4Dzoz|*mQ=v=u=jMlaX&f+1Z zRoCp+TOO*|yN7X7BThJU%806*q)9u8p8l_`hQn!wrvimXElHHK_N-MfX)P80{_uVT2 zQsrefpRi46Fshj8uA!35XU-z6a%~GXTorP3rKgU@x$w(&om*F*UAOCdcet$ZSjQb@ z>n~%iX_Zx0KupDIVK|CR(t~{LzJpi_SfCP>k7C(mXWU3FX6AgHD=!4ojSxct%a~Pu z^ewWxQ#@9MH)T&6)BgZofQSvt2Ss-g&(~nXc!^ML;s~?C(LtaWB82^@#n*UMarF5> zi~wopA~aGF8oJb-Ntv0awAq3p)nnq#I6D!KY^n(0?A2jbg#c5lP{!-N7a!elpiL+Xj<=tJh!)~0DhT*44 zftLu8ly(BiVCKZEo~cx5y1KofHgJ~U>h+^iugTTV5Sft~u4QFy1B({5iDyFWlx_<> z4)dk6nJKVk^^m~~!PA9Dj<6uEu;!p0wu4=2{xfgtlE5qcEQA{bL-H8!xjD^00RI4c`JA)*IbxwI?UuJ8C>4)X+2#&9MHJ$s~ zq;5cDi>~#Nic1v8jLrEj9&PO>(YHuHqS8 zQX-Kj8(a)3$pMG3MgTqo8x5J5Q{t}5z4*}biuKvz+c{dam6Cy~?*$iZ#~DA+W@Vv> zIhmN$C=Wx)({SSEMyk~NKM<@;cCWOnXtw352y zam-{k-l7`I@3u&BO6fhn!D4%InO|Ep_EcZVCRon zCezT0tyMXR>o0kX*{r!17RZSx>Nu00S}>JejssY_y39kK6@2m^L2t&yq0B2xO|KwU zFw0L}dm(D7M3fR!I^xqx&zya377+36G2NOHhqrF>D=C##`!5``T0Ween3{k6X$}P3 zr4e0YzsuSlJ*rMC6*FoOszcvH7ZVuT5VmH6lwW)rNxa;gsd1@h4OE703$&QVY0MTa9UXc2-ag{$tpk)V0gn z=7~BKwm6t(<;QENa>w0*g7~@fRCSYqF=gj@UWaH2^N_+kyp81MQcqf&$hyb3^e}t1 z4kv14Y&LmVETxl*l&cUnKgZLSX7H`~=|Zy95TMAe}+6-~32v@u~Q)skAKjdQSi%(7nmBW4lsK0S3}V!gG2w)jI0eRdI92qp!z z%6mr2+7G!R?Lb9$JlTXGzg zlXC`WP?!r7jjS3E!?bJ~nrhalShIg2Jy)%rafiZM1KD9}?OKX>Fn0zVOr`)_g(23c zbMcyeNusf3hx-}&voljgGXqR`#iw;@zyw#V2qIt+A5elQh}*`Gt{k~IOBVKhWgLVY zQ>Ma>HIknDc<_~v)p|+>XL+g-I$@!=Oy+O9xk>fwviDceIQ}p&c3~5n;Hc5E`vgKU?r94xSYI|a&BAV!+)Ktsqw+c zggj;gP|o`J0{avJ7L_VP@WH*hf1$yKv0$>S^6fF|Uenpb>x!ll*!#EIYi>K1Oht zH*u1o40xIgTnC>4=kc<#JB$(`aS<`ZqHi`)2&g4BFT3U>FvtU$J^|bHkim~GqU2Sl zF(8V#+QjAkR$V9?@^)`tTrIzC`z9%Bs>Rw{Ib*0v6YkF()-d_wyO+%R?XQUN%AAD? zuu2P-!kQLS}KWRO}~IZ^Id1zMBwiw9eMo zg9qf>kDB!pQDG<@k0r}^yx421$BUV-vn^RJvldyUTMWZBeOX6JnX9W+v1--2>{#jX ztbo1_yCziP-Z$De{SD%kt!zx(4=W>3SLA(Gn<*-_Ury!DF+Ps4-2n9xUCXB>OdQ5X$>F}((62T^3`l@PCjF+hg>0>BF6H*Av1yqbfI3VZyCUvZ>_ClF)()PPGVKS& zinkXp$5wmWXsjbiA_q9Ue7;dEE3Ms@pciI2@+2yI07VG2&dpE<7EaXk)yQ#+0b`DYibH%!@LjFQ3Vyip)E*p@n7Vt$E|8o zRkg7mv1J2bIdJ_a__33f)yAuctq|g7n7~r$%PcqHF}!dc&BP0}E7@Iaaz~BJ=qb<_ z1E8C-Go&V_LhJBx#0U>Bv+H|U&ND+c?!@EHYSyTx z#d!Y!9|I@={{S)YAQR9_{F_9+whICFZNxYZD==#Z7|1Se7;>G5m)7S^WlY65%JK4* z+2pJ?9bIY^HRYt8Sg^XOL&nN3oETf^`IW!4Fx%F_TnvLH8ld6ttQ<<_($NnQ?Is#l zW>^$2xhk}FDRbjLAAE*beHH5!Y?59mwlUdm=ERd@5pOh(1jtfp+kz(J7v$BjGgD5D>;&}O z_i5(L7CLZ3tW|J~&<-_TxN8+KyS4b)E3caMaQu7ThsBDXg8Bzp$4d_e{&lDPZy}?w z3)V~CHp+#bSS4$VYbpbmD#wjO>Qx{st zD;XLN@5|U9aT4#Bw|3RKplY%&iK4_cLy@jztU!wFW-Gd3GOGC!s}^ACcGVb%6{uGa z`zKapHU~7(igi?JngD@Ln&1{|B7nv^(Jt!B4Pd0zx5z%^W( zRG?3nsAE*;joN!8tNQY&xVP#Z$6SO6*9~q>Y_|B}kE3<2t2nyeK1KXnX)c!wcH-V0 zZ}z{_*CI;eP&Q~(dj4^7a_V$C?8;FLSQ+^1cumJJ6#A!}t22}mG5GrtiLvus8N7@%-e`_)$=RfVm~zP{FyR(TLu^~#z7*}NuKSieEBfO$7b zWoB0@t1TtzF};hohNO8lxgJGuQJO~e?bOI=lTOts&=`VIGgXOWD;o>oHT72Li{ZW0 zWI=X{6+oa!&iP{*C4XcfV9%)hQrgE4x9Czsr3v_2iW^ zjBLg2Sp~docDGJGvS+fmi<6}^RLhq9q*vI}_4>I93$Lf2VDjUpvMXw>9oqbJp{>O{ z^xRn_5`#{?n0Z9f@R;)Kti5RpNL>KM9O+I$6-eA7;b)w=H zO*-K=)IL>v+$QLuknC;fT|_1ggbh)U39}z+YFDwnx>#F1dWXd2=`pThkDpiaA$H%_ zaYen>94Tsa3D=(Yu*FN6mDHuTiPZzD#>R)oJmBdi5$Oz$WXbEtJ}chUg-fE@v3IRV zrQ&`VaP*T!iUU{%8JzLoSng#|1j4tH{{W4qHSXr?FuF0xbyL!G=)>1ptvsS#R4o;Y zG?uQwCb5mSYI4jH`x@;y8F@w_W%#BdF2pdo-U&QfV0^lTy|RvqXtB6l0#swy5W3%d z8NsA&?HLTX{sYNK$>P`JWX5`NE-7`#*Cw?Mlr0S+jE{L(Pz{$*KSoTy36TdBVhOn! z5qY zI)`agz?j*Q3(pgO`hS2Tk0|mMgINkrXzsYOeQMBtKCKq#Qg&4u(G;(<-a_lNYujCF zY6Cg=)Se~h?joGQlQ`Pb7yIw1@4of;{}6KZ{7wt`vnW;)LL`Sn;%8XUJf>)_2%LN zjZ!lldQi#CTNO>ahma%$zEwrrc*@{55^inU$k8^PmDBc)^eW&*=XEsdy-@CUd9DXi zBnhm@LnTBl9=TNp6E0gT4a#Fi!Y|fYHxWQZw9dZzzH<1?DlFBj&1YtJW=U;oan}Lz z)^$;}cedU(Y&w;J@mysz+r}m=Se4tS%0|5>EI~l9`!$u1d4@`G_Qn>p*LeiRp$0d( zgFJSA|;+ z#0DBR#{GH7-hc?~x$)_;U6He1xw=#mwdu--DcB|PwMjMC=ph+>eO1d0oyaVGq+YNy zU_@MU5;`^Ur{jZQuE|`Z2z^{yj4ryo6?)yyy4LuIi$HmtgT^8M0BWq+u}vnu*xmJK zV8^Bkt$=JB-AGh~jfCWK)y2xIOf6Qe+KV|>^<&f`46SL6)S32F{{S@8%x_4oHp)tt zHE_ZFq>Od3y2&45f5x?&6`%mCD7-ji_}4*BvyqvEELZNZPHQ<;&|+XCb0%nn*#eGF zky2&~DOOL9TkFn_^!6D}OO1LM`n86+fwfo#YTapxiPHELWj0p--`iq;gER`6lL_2({hz~qV~_Sq>?Mj zf}%tmHw%Z#B)qB?D-s`)V4HE^A!3|1&1@*Zn-?{8dxYuWY+Y~;+iuv|5|z*yhGom| zl5ZVXvy81;S{GSb6{Ogi&{$#Fy^wEhY8@bw$5+tXu0_r?d`My|!L?3!F>OYxSSq$G zG8A#ax=nR3Ej4yll`7PJjDjY`8r-Jk#7*ptg;(#fQ>^Mz9qvTd*Ul>>WBouHoZ<^! zcEt_IDp1PSS$`U?)^@OVkcO$8G?N96Bw|S~UkufE>0hNHwjsEgK58)i9rsuNCr* zO9I3)gE4Bds;gm5DHvN6OeMvK-J}o}KTRreS+#9IWaKYffCyM?Hzszh<7%xc!_ne6 zwh`Q<3Tz_6W^Xrf%0l&GtT-H{ks%JSusK<%d4)}@zMB649dLE=ZUvB3>k{=HD>FVdI;YPj67?>{QK^Y!c-diW6V2Tg??PLYxy5zjyC%jw zOwJ+%T{0BgutUXuEI^RJJymTnZLvdm)vg^FiUgfx&J?>ZTcU`;9J%7AI`ENSahzJQ z;hXBX%OA^IzPXLz)r+9k?gMSCiwT}5XCD*deyTJVNIn8$aK$acIJ!Vz?~w)Kao(^(uL??J?|C z!s{28jTe;zPSe)=2_`^Ns8<_m>Z(I2TgkCFZoMTktv#l#HnnTOcxpNfel>=4@2py- zs$Ty9VkBqiUOW|pE#Y~zUJWKfB#$NSxc*S~H!D(Vm zs@;OmS-!3H90LLnl)f>QWUO9YZr_;1iQIql`cguw9d@F5YOr<4miWmU_3J4@D0v*X zPqbpo*x6Bvu{6A=J#8^fRVU*+>{Oi7N*b}hLT-X_w&^h|f`fgu1I{AIipjPdwnWCz zr%n7tb;te-ScF+*;hGH`RWbp`(+xKt>t#xtsdwn>=E}6H@QjM@)v&tw^ZbCT9%2>F z+U1p|vV=8X+Pu1;ZmG@|YlAoydH2lAD{i#ZxenO=%E%};t=HLDfNbOvwJ=<$Xf~s} z7hPkk75jC_d0B5oXh}gZq{8U|RkH&p-PCtxOIFXUWjj~0kIt!BDp%9(Ccc*IPHsh{ zv{SC7DD9{%YQ>;JYPGIOv>~W?Hf_`v>Hh6;u)E5d(`0drLtFm6+djVy7A>>yQ03JJ<46O9NYm3%W zd>vk1wRr()3t`X10u~>Bcl}AIp`Ah?qRKsM9!@p!$OsIz@ir+~eS0=Aw0g$X`t>w- z@)u&a6zZw~wUt$tj5W#&IQvhs;c?4`$AeLvDBF@?RAE;|hFy!7tFNfewd15$0K|9? z{$|%p;BmbY`fap^*J{q}_5xxpV)4hR1ia1xe6Ot#ZsW7hTF&LYMylu0Ui$x>jROurrA3i0}GMK+OOO!|UT5 zn4Zsx)PuM*!V*og`zd!%P02C1c0000000000000000001>|Jncu z0RsU6KLI&k|HJ?k5di=I0000000000000000HFWc00;pB0RcY&IbZ+808kJB0s#U8 z1p^5M2Lc2H1p)^F0s{aM1QH<=A~8WxGGTEPBSKPvk+H$i5Hq3S@C6_wFhgSTQ*uy( zlA=IFW3m-AbHdU!gH&X2fP|Cs|Jncu0RaF8KLY;%`vcydFnVUI0VDT;Sul~?rk85- z+gma8n@ZTK@ASB>hGZ?*Hk2WW+RG2J#O5dprdCIj*2KWk9^$kdImT#bANDLp!{n=umg_S#r@oB(c))fM!N*9$T3nq z^##8w*Y;i~-hP#*?EFu)?eeex08A(U0P+P4&|{)Guja^LDa=^wx%6aR>S(0x4wO~o z5m+A86YBBSgi;Lgej>9)AYuOi8!^YdH~!jYkzO$M45!<%+xlED1xNih2i ziKX^g&Hc6H?}@}%Xf{xVzvEW&Y}OxpiEQ4>R=H7BcmYl@@=3GJemn&oxY}u;Y(juN z)XHLyAr`vJn)NVf;?Z|+ClTL8R|bJyhGP`NO3cXiy|fqh=}xJO!x&E(=iRj{3>wR( zg)t}RTS=qEMa_?FSMZ)r*@k7+gInKQH^n?Tm$Qfgl>2FnQJ2Za)wB{Nm(kCy1jP^e z#atVM{{R+wJuVC5TV;(IddtF$Z#=K1@+jD+<4PiEQJ0Qbv!8ulTx6VhZ0+!%v3XH! z`G!NrrFgJoK2JHcd+zvF($KBHBwZ4|&YV!!nfORhCcLvn9BgjsCO*SfB|#nN*6qZ6h4rDK?uq z^yQ%x6B8RCeSGHfpKWb$>f<;18sFK>R-g4Wm}q!9)=Zd1u(>M@{#BRC(`1E57G|uU{7MC0sGyTq zKeZH+IF^qHe#_ zoY?+!8Sq;kZqe!}c|IkY{9|O&wZn+p)`jv`SaAz84MIq{TzGY-!OF>)@LWLQ;A>?l z$ldf-`QyIu9}z-Gjlur_hrHIlUIM(Y7b33HQJF(CcnZl1+z(1qb6i#3g}M3|)+xY*a-N%&Uo8{X8}aASS5Hva$J!+(r1+wo!YHXc0$1 zwZ(twq2-upq+X#ltf(MU{mYiNtnwgG0( zL?qnHDY&L{q)2i4M&H!o!1b5>=z-OFxNgI36H2|E6@qT1Z| z*3sccZlqF_Q5}x;hZT4<~(aMJW^a{CpPl;T7%})p3S*+`wix01bB~VsN-xcrIj=Jm-!y* zcERI<^^QOVGQ1_EJRd&_jUdD<%O`3%R>6JrY>0=RLvc}GzvKS^56;(D^_H7sh*Owb zc`NR-4ytLeva979n8O9XiRngUjy1Tj$ti!_(vDUJ#>U^dbHG%RM*(RsuFbD+5ksy1x4`{_ShZF)*C6oeDP}VKr!5XNvyemp96-CK|vs_LSK~Ztaw-@yl7-2=n@O z7B{cC{{XnwSdmb75BQ!Xu?w2-VAkyGL}22&kLt;wq2((ZM92DMiW23@_7@_gg}YbJ zd-3}h28or^Oy`*HtIBg1=33N?hK1&mGrZw9O*C_1@d($K2JZWE!&vyM&(LX9f z6~^xPJ!n~js|?D+n5Qoxjg(ytw7n$rsdi|$z~axdi^P%%H*7a+&AVTmZoA7-;>6*>ATVBF^rM}# zaXczV%OV@_ZaTj^&Me3nbE6)JdA?HI99Yo0V(T*4t^ zZ(6nr3Y~JsPV0ZP_2EsJiDZ(*wX9In5^}iU0MOL1NpyG;*0&yO@ce1w*>lW>{hqak zl@n(uUt@GNG6;a$1DZ0tIneW&WiM@eHtSgzQcW_+Y~ziqWr>|4T)m=$Q%wx5nbU#l zKjN6{{{Uygv*ALaXz~i)iUhr%!2;l|Otd3@`2ol9xD zH1^WRh+`RRYWKZl*(!@@SB*Kt;q$9Umi$OPebgqFKQz9u?NAVqBx_zUI96%jIR}8@ zK~z``0HiZ6XfI|w)4rZe8U;l*$Xi-}JF*8$p2_aLZ?|a(*Y({~N3#-(6d}Gf3{M!# za#89?NhcDc&As{#9_rZ`^x9lMvxnJpWDI@Pu)_g}V%N?P+*3<6mg|=<{2(YLm#ZB| z?rX-b*S9m$gDJQ=kKV-3eF514;X)!ou{O6$)RJXX((J%f%OJ6nh5A!s4;hYcXD`B< z9j3-Ka(I)kS`#ZzW!CILVrgYw3@=;i6!Zr5rX`||+u26G`cEbWR4{G*czvKknVToA zVKQ_Sw__R0Wy;*WlKwtuX8V05-oG%8C?pAMjzBfVr^0?rz)LSGhWNdi{fR zG)JcqL}p{Jq;G1l(0=sy;wOK#f4PE+GRSPAo9zhI_PU8k?f`ef!Ew?Vp}V)y7$qI z#l2Sb{{V9l4udtN9|Q3FaO;~y4CHP4+S?4exmQQpq5& zXI#DkZBUX}Hh(&vuqzy1seOv~w8h@j|hr-7>u1KUDaWz8FQ zl>W4%Zf5nK0kpB+91r=SBtCI?GVnjH>g!4nW{0iyTFec>=UGksM=Dsc2Fy<6i>AL? z@@!s>{W(`l_;fU3#4c-UvJcjVypt8$;*K=U-aG4MHt`%J92@id43aigUM9SxCAV!I z`cRcGmAGH*d|UC9?)NV$Icd_Ez}NP8@JQ3f)MJ;(P8v9M8d zQ(}`M$(uZU+jsm{-8ZCfI~wvA(EKTJ>=mLdk-!~+;aka;2|F^6>7S(qlvo?vTEd>T zx$wOSF%dH$P^Q{)(zfh3BjMx!00kvQ&q_NBXHL>Shr);&GWL}56|}>U4fl}nZ>1I0 zU3*A)igjCN;?&zeH;7+Fy&?3X(b^nUwNvSM^&RwOiFR0#_mMHtzg=rQCo7?|!pE1& zjw1_mubhX!JMCdIQx1%)(On`+CZUR2SOnJv0I{AmL%op{;qt?aB!(IvOKru3G)-|6-$@str^88^nO^AKR^O1U8aHU_JU>Q)OZ`Bu2{+SQRAL6qpngBf zJ3OU_B7gBgOADR@uh=ZxDTiUdTtx__^E3JmzL$s6y!JqEU_tFtl5)80Fyl)M_l|L_ zZoK?HlrZ?c**~W;^Ze^$Htg~5M>38-u41-t=5eu&*5t$KRtL%P(R-Wntmu538y{^? z2Nku8_4q3k% zl*X?V%-ZG}W*n*~iaf>YkOciagR`8D(n=2Jo*pnONw-hY`n* zajXK(c@!pcJC7v?r{rtMak}5`rS-o$7)(p*!_CX< zes$!yvy%|I#VYz#xNK-KVpFjw()5^oV6>mooixAD(8J<9-XL7VD)aqxt(G8cagp{N zdH0Gs2yw9cn0+g20oh_klEmJZ>#b*w_<3*VB0iUWzI5J96tri0Go>`}u~2RVL~wtV zG_oH&zK5&hSX7wpBn-`O6T3<$R@opQ^HRjnZDzQ&&Vx#jfqd7i} z!y%GWa2V;K*W*kPGNU$r``Xo)u_R|k^_Kj7hn-?}%=>h;hZ~xU_J9EAU6jdtYe3=V z5+iWxDmXI@+_3{s3~ZOV4WF`YMtsn+Gk;062c>PJaIGG^X=Pq~M??G9t@{n@Esq*5 z{gKAAC^MsUw-22!laY{K>+Av;ivu;jD)-#Z_PfUxjHcM z2C_2kaGm;?$IMn&Z1_gdUtFJ+1(8RSIJRy>$GW_m8Rsz4XtEw%&Gn-OFV10)VpH?_ z(86PP;(xoF>)%HO`$JUzl>Y#(bTIhwoHyB#Wv1#))|-6{dAy{pC`u0*ne7)F(BdbJQ8H!eZMLYOu;d6??oW= zzg)$Cp^cB+P%Fk<+N5mjcnq- zoMN}?Ink41_r9gHKaF`gOorBNH8r)485FN|jYmErJlSofvfkCVL9$%kj_#Cj(rGk& zdKz?e8{BIox5#)f<|;_cjKrpBO8RuuWzCS=yHIUThc40!ym#s83X2mO2_StKjv|b) zP5eG1de+kQhs5g9I-7&nfvu<+S}WpN~C-MrTq@U(QBJqu=>*+ z84fSlEu!~#SNao3JGJ`P@hNow08&4gph37i{{ZkCd^2rhI_X97tC*?vM zN1nmIVneP^*IE(cy!IUSX6C&w^{t*XZLsIFIO4uPTG?X!{uTQ&pGU{*ONYghMf}YC z$G5Ft7?&__tgEH}09`1_vQ}W(i=G4Q%Li)u>&nLTHhz_rLFGXd+(s>>F&8Ek8A6W# z0P{-^?FA#%em?s9@B2*)Ge7%R>q0y}8;$ZbhqA`A%^4RwZ+d{e*Ea%35Nc#9M^no% z)8T4pt)^VjpY9y15Yn+nj0TLY_kUVc%<=^@uVUVs{)GmCr1GTRw?1{z-gXOE zcQB{IHKSO^O<6Mo@QINk*P;}3%I_S7xuYwn_v&lq1)MjHDKGQ46YzN$18 z6!}*wo!46sb?&8g;KJkV8$)1yE<&%HFgz$&i*wS02O``@S}T1=DiV-llb%z?t#55_ zei~Ls8NuUvv_5h_QQJ}AYan1Gwep@KwwXYCTQ@o@i-=1PuA_&Dq-X$|D|Of3MbHtn z)Q`*g`Ib#MGSg3kI^TXiPxLf#7&h6=G?5#hb5m^m#vxCfQa(LJG?AcbG`PPSIJ_?W zXYXS9_}7(TeC`$Xc*idBM-_o(lM36-9q8jQK5{4f*n9iC>u>upx$oiI^`$l=1~zkp z=b>*(jw=PDe^wKv&(@AR3JF8^(SEtno&mMPKW;I~i{V?!aEFXs*Td;vQGzB+J9gpv zSCnDA<_+~_9*21PP;fSw83v-=kIJ@E9i|FFWq(uh@1cg0O!?nK&nTvSt@XA}m2*QF zEDmhIbW@=C)Fb^gE`Qy7d@VyUuxH|Woof+_knE$DODMHsC7#(F1&s6;`qZwA=8{sE z=~$SyfEaihTr9A~Vwv>b1pck>sqh$?3tGh=oxeh`jT7XIiw5Iiem{+4q=14EwyIcu zx>8KM8m1XLK;*XzAJMEXHB@CbNkEBV~(fF~AwBj#+g-N%Mb3Mpj zVunIL>AguT&e5ps?QNaDbqvX>j_$wWy!L#**~YArZ5NTXsKlYNvTX|H(2lg09gWlW z5@Xs$(FXAP*4qOv>HeMf57MlsV>;?lwf_JjhHTNYo=5e15lBks&>kO+D0O2UwUeif zW=9gnZf}2usiZ(<%gHq~(!nNeJ2&Csc{TuI{2mKcXvAUNv4kT8z-X z-X_;A{s-koTp1j9qdE)xjcMkb@;cg-OO+%(jrjO~H_h8Oe>yf9B^{(cug12h0?b#L z)7w{H;qhoS{c{zl*y7>g(Ee4L*)a;c$$!?A(_w~OLg_3G>3+J@lVD=r&F5h{TiMpU zxAuOje)1pJIyjHn((I)Eq)o%xD7<;FxYQgEKd7yu4UReW( zzP8YL+!URp^*=7^%^#k?$;*yU%9asv96%hWtCJFfFFYFAqtEwT_90YDoz80BdWPeTMgaVYW$Zj6v|r`3i#( zG7!!-XS(!49qc@si*N**esPuai_}!OX$f!`s;^Bi`0MVVRo$K?-M>H1ypCliC*sGI zc`Vl{{TVv zjER~Fd7E+Z>p?Lp5>7;RTf^x_EMnvhpqV=-=|ze1n1H(F)z8+vqX7F@y(mfebfY!_ z_D}stm}%`CtIfW{6h+GNZ>=cAhQmyFN{2@F{b;5#C7Tb;&~Wh-B!RrI4tw|4>p>f1T3qYh)gsG%Mqa!NZ6K1bzA6pBgoWVVF-sg_MgqQZc=J?Hsq z_aLuBL4$1N9hVfbP3Ex!RCVX!^sJbK$tr4+$HVpALJUWn#HO*xJueTXY$o#+JCpR4zzw973 zR&5mb)-r5Dsa1U0PYm=RT)LKa{3;AUd+nXA;54X_(&fVdec!KTJ|_|pUP~eXZ&$GU z5e{?zMX>UeVa5qYgXvNQh+*+9#ZLp@-$1|c zv!6(IWcvJTXNemUbPf*b_Wf$i*X4Ti=QMnz>ErdT@8-#cA)=6QJx5VP4UJt%^K!0$ zpOL1E7nP&`08;k9=UWU!gsW(h-p9cA(8FS!XD7|L(Ek9M@;p=J#7C?$^`*mp(Oj~B zN@UXi0G$jTJGaIemrMN(c_tyU;$zl1Mwjm&O7d($+2bPB9CPm#1fKnCtW5a~Q{~Gd^9PkCcM<07pzTTCd%npX zmvt8R>)l7nH+HvnJvrW|#M^oFPuGd41Vm-Sff+qdJ5n+2N2sYY8=EVE(}?>Kv)d>; zy=plftjBSFKPt(!)VYu{c;2xSw;k8DyF-EaRLIM9%wrekqx5QQ6v!n(=F>HYfcATrVi@c9Gjsm{G%$GG*~i_= zIrvbE_KM{{)5I_9O4$C;w6LDU_O*|HO4wsO<{i5-pP$yelNffmd2~q|;A_Y+X7M-N z$@1}`gT=N<*I1?N-(F3MJ3K<`9HY|jA4(BoJkBjX?p5@>K9sRye}}~X08T~V-XBT{ zCz{2eymAf=`sqPtk0jahxA$9}7nOYLdReb=_F?dsvbikB!j2L*P)dLom|B>ues5Vu zVZ&P`Mp<{5=ly#t5XXSZgWZ3fUfT7jH1zNI8qLpz1}9iuB)4_yNd=ZCA(NJwMPgth zMU|AFRU7lIoa44MJ>yT6>9Gh(y4ag@@2!irVC~lX-D?pHu&txt%f~8{yek=px80qr zW4ruO-z<=eTb;i`p%TTMN)HC$MK_WYhQ#p7PD)%p9zx}NQk`$%S(uVfGfLBWMjBpC zZ9Ho8TQT&MX#Mofw6lZQw;IDtme~axCOZ4;DM09W(;Oq_AL-vfepHCXp_FeF>-7|3 z#a{}?vf;Eo+5;ON(MJj5<=@@xs}&gBD-I*I`O!Eh+M?;Pek0q<+glXPgp`}*%WU5x zLOfFBTiqnTKOR-H#SHjnu+RSh<@KiWhVqOtwo`1x4*CrjpTUu!;>qGcxF_J;a(-3h)A`Iazjpqwb$JFZ)%5KjA9&p#v`fv)*c)|8Nelqjy)^34Xgqv z(FaemBrUq5e$?~jIh8_>4m2TSn>2ytAaERqx|T=NHlcbBRW2iU(si)q%7Z@hfG^%^ z1`WHs3iZqx)5E8T<^KR}7R(YEV*p>!{b@^xn3UT^sNgSc;Alqf zN~Mvn)6s8{sS`F^uN&H>QkI%6;CYeGp~VB|82QkBJuF2*G$5>Qrw(t(a;R9F2_Sf+ zw{ZGeq&S`J&A>0I@uuR&6)$W;@2;Gi>{20_lhVj9TNRKvupUo|Oor8#(nf>PZYxc- zgK917TGbDeO6s7C1Lwtz`YB4tU22)0fhY{{WQ6-JcJg zZEzBYkDM*?=}d5#k0+d+_+;Qs5sQaqeKyhRKPtSJpAW=HH7ny+H^pIJiQ-r4D>NU( z;T(P6HSp`r;SwDxy zCuvVVt$9K&!f~Sm!T$hVXyn{=K5btm00iK zW#P<6f0Y=evtVWH-&~cmm(O6_X#8^c_jlGw&ff<8m*bbmy0%mK+#H-3`W`*q^{~bH z%sc3^pMzG;L!Sj8uwr{1-V`ucv9*F-Ba`H5P_Zhgqp7ICk7cK4rD|#zoDe22D|P4e zsq-5uvy<$~DY5hFW@{>s*L5tm$hk9Hrj;Bms+hpii@#-SA^w=oJNSx@Cbixxt97v= z)h=CSgo&aZ+{fWf6N};H)h)?S5$vFhz{;Adbt0N*Q)P+68x`ZFc3UG1yT^@fWrros z`rAh2YaJFGotEr^{JM&s9WT2t{HOd@Ouz-ZYHBR49E7Ts=-P0tjBywsUDjSdiLJqz zGiV!2)wVduSCYjzAXZ$@h*j<3<{RL3y&Y^hW~_@Sk7zQI+$(DMdu2P5CBGl7Y;m`J zcV<(nR$N+nUL1?8s5SRdY$X0s4Yy-&tsf&kPcru5ZU@=(6=uzX#dY<+{HPi5+hn$` z2CG6`8+lF`@rav|;qCN+_p~GWh&vkIatS{1SN{NY3`O?1Ne1`!clc2&=ddlWU7yreo__-4$0yWQpTyu> z+mq@mZ3msgHl+c+UhzUmzE zO>TA_H1MdMKx31c?y1sSi<74?r-euT(XjYX&QI|27eX~9dRAj5WhRfL&?MV|fx@}@>Rvth|2 z+fgKuZW#6%y3~-7XIJxV!uLL@tnkL^&O|TQFb3 zkYX4UYr~0;=Sj2+b-til^fSg*{4O}uuZ3?g*4jtSC=lD+#kg0Rkb%>c61T!)Nzke7 zeQ8EHb`p-xB0e7aCVaT0UF9gd$JtAW!I>F(!683B6w=_1%Mt0u!q@Q?v;$#`L1L$$ z)KVGIV#R6{-;Dt<*-sy0Md#u4rOtLZ)LY#;eJH~!>@iX5r{+7T3`}MzVr|w3;a*PR z;*~d}f29l_GHIozm;`d z$EE4y!ez~U_^+dV4ID-jNk`s9+Gg?Z@2u!pTSi03_txJGyQl9V>)t!)&wzC|H+Y+Y zKO;vIgc~eee|aBXQI&1PZ<(N?UTUj7&JbkpUgosHC zw)%9xcgm%LGqugaGpeOC9MUzePeDjx&$Swx4ip_4Ly9uq+?(`h%OEk!d+@cXEfI}< z8=gJ&g|NS$9|KY1({$}vpKEAp^Ej23dz90BKBIlpJmoBc?eHD!YrnZMJ; z4SuzjNV4wPqH(+8KFHOj+67%T?9g}{WhZ7-&D-y#W5M`q_H95myZ-pn3(wV@HLh*vq_}KeP$-H`sGvWNsGA$hsKI2RKLkl0AUD=}M zd%S4lFe5s*-owLRt$9`hdNwzb52t;3U+nudXSW9pezYcunM;el91qp1NpSE-h7#&a zbNzT$^za{NkRss-Lf+B>04nSG6}bT<-g@nO@~9+%vgRDlkn6qt>(EZ zt@1yJG#38={KQQkv}z4NP+hX`cYts5snZTv2p@HUvCDeIGokZO8{6Ab-zVKOt@Z0t z;jrs;p2QEvwgn@|JmWKQrBw;!@-TQ=wE?;w<5R<&WX*U-Fnu9e=Ca>`e8TP3oQ>l^iZ1T4-BElk4@NgT{j-ZP=9a@$au9#W85) z(kVV(G$F;fd$!|nC-bb9Iu6%gSU&Wtk1uMd#o7QAKi+rnk0-@~a;) zjErge<|s!e@c7vERva6{sI8(d&lv|VTk@fc!i<=hjhzoZ<3|;NJ2{8m!hJ6q@{Bi{ z#i!mxbiZ->(@BL<9wA8D#>0y?Pn1cdjI?nWuQ?*?ZZ@MUY~e$|bN>J}<#?wh z*>b40tScmg!1SVoZv$&o`FC=RveX+HeDgO8c1`rD_SZA#;y8EJro6GPms6(;>F=e@ z>8@enN+JYhHf!~#1^m*)F1{rFD-#?_w$HL(0cvM)b)FKw2lZ;iXKMyQ5Ir>f>l6?I zG633g)8|k%?P=Fum52wh)3ILah@ua<$gFzi0=$Y|aa>!ukIJ6GZy74*s60LuhW`NS zfA*S=Lbut%%zNt-0c!??Tpl+g{MK@-B$$Z=d)zo%T8(9VxuMJNxTppk71@qsTmFT4 zW*%fv`fRVun6D)xZyoHVv=*YfO&Ko@h4X)H0NBidbjn<<{{Rb8$Z|V!YYUF+it}=0 zZnnKP)QzBP6y}Gjo|GDJ`!mgGMqfH8+$3vif;n=P3v^}XKHJ+$)9hJL*_NEx6l1*r z9KW`Z#U9rT{B5pL;nKX>+TmCoINQUhtno|^6pM@cKH4*RO4)$ZK9%J-CsuDs18DyM zof#tDj$gct{A+6uoWeG?U+MSwQkFU4mf2W(C-bJm<3MQSK5hP9HRO1`_}fUN`5yXg zJ|Jyl^knPf-$ia#{KqOAOJ?r=NQy?Y9aCLz-Cj$HHkfLxG|njD@h4{Ivgx324*u#$ z@h|5GW>pr~>stv>M`CTn+l@qCF(hYyFEh%pi6>^#JN~_u3&7=)RnqkiP8ok5 zb+fVG?KednY9zIeTb~+%x{WEx&Sl4z(j? z%O2FS-=$!%(LQfEpZ@^6=TK)mtd_C%ikNybL>uK;Q~v<22jFTKKFa*8pqIUEqo4`#AM*u!dcJWQKRJLnm>`+l@An5Htt zDIr<8cTj?3o-?95d<_ecuL=O2PY>j*QX4aBgmLyz!{Ym1go8`{4Gcaw21e}7!{5-+ z!{T@2BkvE-zN5n89fZrQQx8gnSg+ynAo;0RgLr)@e59;+g*juHeJ|Ha2{)O=$Jmj5 zFV{*qoKzWS!|*<_?(VG448*qh;coJ4Bzu}!Y&cMsYn6v~Fx=0rMV37M*8;Py$ub+T z9&r2q$qJ!Mw`B4(ti73)x$+!-6*Rb*_1I=yzQ7GbvleNfdyjp7&L+e%I@{k^aOX2d z*={;g8C@2@`>#@YRhmhTs13q_%klhv#>5g#YiA>c*mgju@P)XH^EW}npM4i2dl@hu z03XQHM5fuTe+%nT;dn_Y$=287^QSFuHFNDeKkXllBa!!R6dwRv=}5eU7yN4tr~YAU zZT&n$vi$24kPME?z1&ywsAP)cWWADk3X2hyL#QfE`$P45jgi9@>=UKd{Qm$NFt)aP zAzJ~@FTaIKs>Rt7*CNMFMI^IXN=C>Zr=w9x%&xvaV@$!FEnC_-tSyw^ zk1ENqv!Jn5UX-s69grxrjeCM=Cc{0$4fMAT>WnP8Ax}=+=~-rJuj#isS4?Ka@BsEr zA1Z}om6vvPZPI(|A%Sr)-p!e{HHh+i2;*^~?X5YK3x?%c8(b^tuc7%+!pb(7X*5E8 z9`B_LJneYSkxBAB^|EWQ>Uh_Z&JFmZdfomsMUI^R0FaSO{Z7g6@#{wqjNgsBGM|Cy zYiEf&TsvqTy&v~|Yh>eTggnpm`;T>Ov1@3U`MF0U@~w_MZLr6)Ex367Yh#H!Y&4yR zCx?&Lh8GY?=M2M-`K+w$*myME<12SicOoe5y8`m@KW~w2BN^K**|U5&Qp64I&epwb znX;KQQ~lhjq-C=nG_c=DqmYB*v~GX$UlaM(4-tD9vxBD|G$U-MBOIN=q_-8`t@YYo z(WpGR{Hf&7$s~=DeQj($Rpe{FBTLBVtrq^47}yT4`B9C2@_oTe8t_qJOC`odQ(@m; zQ0==ClW*7STF&cvTYZ4jTFotk8@tra$s-CqwHk9Tf5NcCYC_5bFy&%uUANs&7WcxD zFKF4GE*(aP-$M?nZlsaN+q#8aqc>_PxMuFGh^@37 zx#>li+>>)m65Fa+lhTRIcA2<$RBj{%n)#R2sL)OrFa)1g^y;!LmiA-mQ)1FXnRF~p zwQSq6uC_P0p&V>CbfudD&itj1 zF9S>D{$^=TSt7lGtB`Q`yg#!&3`c7XH{L1NA?NI`CY)x%$)XeJ{{U?aJ|oUX+AA>p z4Q!=*->`c3R?Ur@w6@|q>7$fol{oZ0nRm1r-Udj-kbmk)^cAVm zMrUrlO&nc_Rosjp#Qm#+15E3iznS?{6d9V@4zv-JG^{RHmYTH|{=A)|&oTN_W$Z)< zzlR#brL_?aY8+xH%^BVtZAS$&4>*~VAhuhJ+L%0>L4P}@gdV>7oevRbxZqf5PqbDQ zo@1M1abfLWrD4@rdDUeXrGca|?Cu#)Gt1}ht&3S_k9kXQYgN}r99FRRT_d}*)$s2N zuP}ALwvJUICgPmpaZ8$AkoE0*R#Z~N@)St8SKU4J1Xxwh+cBHHxzUuub~&|GJSn!S zPU*{Tw3%~lHP3z?%81`;x)&C=vY5s!m)!@Y97A@b;od`-1qm?m|5E^#7VK_D`z?e!^yjU zRQJ)s&v|1bc20iY{`xpsnX_AQ$D}^AV|xkX=WadXnNE@?Xn!Ls072wx*4p8CTZuvQ z6|}=KpALVf4a)d^D{BXw!M|xo^!xlfsL6q4o*VtwPXqF!i@~Mu_t5^i(_$lF*hgQw zKDSDIOwz1IJKFX z@ursUzMq9hC#90kda(ShQCJ}@5xE+Jdyj=+@oySPfijTCzokUzRP1CRSax_=eiXB` zV3x{8oO`}CGPGe*2`;-XIZr=#!jdQRGsbemGL0J5z0+MQJ_1ya5IAH%D)Pd)tU#JR z6=p^g7SsK;yOp@Pk+CkiOt%evoL|-!9b-lHz z@vwx7+*gksDb~osboXmfM5~mOl%BfKMHUJyKHE|AJ7x5egZak89X5B~iM%PisuMaE zvgu`C15!q@A0>G&n=Y$Kh{bK4Tkhm1m2Bl^Wtok$a2?f%()RvIlMLa?=+T~kLta&b(Z8z~4BkBrHZKFcbLU|?T>On3PweK|$~$o$ zeZ+FFE5ibk+$_+ZbTG@g8ojKeiRNn3KGR}1QFVMF-N0b?W%JIJm zK>5^|E!>i~o7Y7=*Thyu$sEx(SL9@{)9}3@F|VA_qLH+3qg9aD+d_4t1}Zd<5JlpZ zdH7KD9G&~{zgk>8&z~n|+VQQ7)3kXTvfKqc638R6=dtT;2jf}U%Q@qEUnWxA89Cp+ zw!%^;+FHQ!w;D{jv+JJxJ(VUS3C0@~uR)3kajB?TI5*auq6o$J zq4a1?g(GJF0DFZdo;bFR7M^bTtT|L^I+A1sTTL(1x`b~bkn&<> z91js%*f{Mi_#fn6C(7fm1LHnNI`b^`k6nvc!67-2VVwX`TbI#i-v$=i~LG zGA_#(7in+Dx~0cQnI=Wb=z8+Fr;)CzO`2YQ1H9I;h?MqY<~)1<0DEYjb{R%r1IX78 zvKdn97TK@()+R0kZv{1 zBC2{}3V#{4sP_=+1*l2kjczZz)VT14aD-&X!{#X?k|jx{`^$Gw3cFdxwr<2; zJ@v2eE5yV{KCFarVOy_|^}W8xqsnt#fi~uQH8v+Hvk2twx}AO%h{BsL`y%^w9~xQp zKX*3|S9JWT;U{=V_8r&!=|eV9t_i83&HZePfA9IwM%t;UlQ=IK6FvGi`XKPpW9 zr5R6%(u9%ll?-Dr;ObB3OOEs$j(i)XVkA?c%Wn%*!r(1|4tN?7i8F?SwaD*On5kT| z#>*bOma#FXYc|p`*R5<$jsVSGwAn{@6KgqGcw zC*e|+AdRzX4;_BcO0viX}TGHVpcrfQQC93*l2XVDzJv=}DF z4@G?^??1e9i<@XDx{Rca_4QhmObRDtI*xt)X=66BUdGjATady}`fpNU5=|vCWmDiS zPcSzoIOG@gmyg1pF?_p1Ew6M#^qq#OAC5 z$o685Ww#sFB?%eKsEe1qukx&8815aTO?Vz(I>fTZ8)4taog@wSO&o^Y?Uw%lI(hB6 zA`Slj7Wh<{VsmWQW;_FmfZMXyKaFZEzzh38G-SBQ)2lCWJ*vfFHsKUavoRie2Cqmx?lT8ci5OnlQS;yw;E`KcOp&iZ}|ILIJ(tDSZ9L zf~1={9x&s&nkP{nA~qIoULe(oM?Lg04FP5NIR@JiWppGlMPYVpLp+~gvRM7 z7^Ph=^fc=*2212u9+!W0B4yji+shUAQ@yBWZk)vyQR{DT-Tk$l` zH{>cJOZq&I#-YL^H=W8GUI?{^1lTHH!;N{e?-Vb!m4{wbtt0udD@}jwULTD~6lZ#A zKN4z4?b*V)_uJ`8JE%#=Z=WxAwDBhdQTSGUPVQDD^9Sf_W<{51egfYbUF@wS48)#B z`MxzPM!|MuI34;@%BhtGN4Isss1-E<<&O8_IMYi$BO(VQD(g>nH;t{A{YuXiS+G-R z(Vk89tBc8lm$2N>)*lxPn&;TFTSpv^%7nW`2zi|=Bgz^@A>%gt#X4Bhz6WTMFtY<= z>=XpDvk31Jw>_caeUuP=+@{&OM8991Nsev@P(QG6`qo@QxAn0n;Iu^Cy!Ipi0JSIy zimpSpn4LGz0aKhr+l!dyzO6$#g!NO^UR3gWicK~v7F#F=OZC>Xn=0EkvegM1$fdnSuz%QSner-=SRTakWZ zju#Q;R?`7fgm`X<(-d_1`^Dtjz!8^VhS_GI>#q312-nEP}eT0r-**+9Py+6v=#>KgR1OBrImVpas$ zFE5Qi0P~Q!&!-!A_*No0Uo3Mc9{mkS$0EEVE8V+Cg(71^UQz8lg-d~&O9?T(TOY@?yfy! ztc~)kk><;JusJ6x&|brUsFBft9(l(dc@Ni024xwR_?d@)qAL%Fo%I7W#13|-aV|54 zeIxa)R=#PZ8&^Fqz*LAhvXNdu$(61Eu;2l?y+AVt&*3V{*+tFo9~)G2NCB0_^LG<_QT3SJylGQwvyS(W z_foJKVr|I3u{oNST>`ebugmFAi9>kPaz6g1lrRCfwYu}Ai_nN|8^@JGmh)ieW8uJ5 za$i_tk?roOaZjS6+vaKsX5KEwOox(bVfa=QzPZ`vKd)s^h%1|6HuxOZ^eS1c=BG@O z5IrksM|DbNkY$R+OA+p5Av-Qe^yU1k> z=nor?BD3JJ8Cgj$oO;^Z-${8kGeXuQE}k?JHY3*~)uv+=@_EdsP5%Hydj)Kaws#vf zC!aPyu9Ou;fEE<(doymWJ`)miN`p1W3u#+3V$;c;{{Yy$2g0nYyaxH}N`^LPn&f34 zb~t>fz<1w_u1^nCd%n#1Ms63jwY17JTG#!^@=3s}G9E*y_*UcOZoFv!0812tJd+s3G;1~aWpXVl3R+&Yir%#Ood1* z&#htl=axMtxa4js+)sIZ7n9NL~=uZ3OPWrhcP zU%WrQvU&jT_X^9h+N37ska1IL0yobI8Kc*Lt~yg;qy?8X;&H&d)s|S#gK@KeCT&70~cytxM&ilm!bu~Qw z4$XWAAI6R<%P!sA4EpZU&!6v?BBOe}Xzu7cYtu-e2u$RA3Dq|F>e+&?Anpwi0CiH=SUt;ZvJF`Y_TzLjh1 zSGK>&*r)KOH8ws>{Qzz>B1B4(6uMb%*Z{{VeVfHocX zU;BIfD-gJL1ONy|^v8{5LFSn4BksQ+*L86@@9ec?lg?o!^p~$u-%T43Nai`xMhMx7 zgRQz7QmXKeYZG^CSaLlqHNDpQ)^0&G@cmwaW2Ma#oPQA}ck8qCMKS}b@$RR5_s(yr zspAIQ88hDeIcZVhNU)R*IokgKLHN_5vpUDPxo@fBeboSd(#9pXE1KA(fHH5lvr+ik zmkS>7E0LLbT-^OCEG?GTO?@RdqcLDLn@jN|<)@7l-b^5WZR{{Tjl5r7LOtxXmf{((jIbSn(-RjiB8wO*Qd`Yc}c3~L@&+({nnU&l& z$s@OS8nm(&b~huZ?~=gf=EGc_^t)uqCol~z8RjB&);BzB64F94b|wqSy>ER^lB$?; z-b?X4El&;1m|3+(995{Z_Tr2c1a_0HLn+oshD-gM>6L-8{J)WzjezG~a`NF{nb#-O zRIeL`!{p3^jgQivN5wD)bhBLL@b93QW%67vt?9jFj978;`xXe7KRFHi1NRZ%dk;42 zU(q!jXoa3FQ2NpIpwQixZS`LB`P7Ywx=C+EeJ=XjMdzX?&O|l$irj0jD%DNQL4Bb8 z1y8d!Ln=vg%s(29dj=`pJ&Z0WZL-Q?MO!zer{`NKo6R(1RsQ0CUdqNuo2Hxzq84$Dml;d;cmTS^g8 zK^+J9pwczhQskcEepM=L&-Wizw#@1R%A(iSp^#_;GTXlNqkSzLPdj9@a)Ez6yr#Z+RZNze>hZOgTh}koCf$^!@c>`n? zacokQAbg&zZzEHCy6A#_bI2J5ZgcE4!u)LRth%k zI_v)cE^5TsTVxAs)U#F`$ku3cXbzQ$#jxL==fE8WMJ{t;EO$fHfPQt19mqceSd<-= z*~FdP{#B03`{qIv^yyG$UFi&&wdJU$3bqQu_8;2cTE)5a3Aeu0Ce-VkN;}7A<57nN zoJ6uhFR9(JAB9JY^g!4Bt))g>`N(A1)*~{F+%O~DwF>AmMHAlMH4YvES7Oa_ISkc} zV3&4f!%rS%LAxO0wIIdHF%WPbwfa=4g$0#7!dt&qCZvSBY|ogC zDc}IstTa^=k{;5=*pt%dvtP6DmL<-u-F`HTsgN-y-r9*{)oxh(G^r(ae`OGxD?f(F9@2Q|a{KR|c{cozk_}tYqRh0sBrMD(FTj-M<`h_joNQU5z?14Z5#_{x7eFi+BN*zaU{@b)GUXH z9KORWhfj?xseG;0q-ehT2t$4!N?BW2XI$EHxV0iV^RZqt;5d9~BX+utSDmR^IWu2~ zBE(RICC;brUy;9{dVP^FTPnz-+RJ13iiJQo!%pe!JnIaHQ?$$nfHj5^cA$miYkO-S zEQyrJv5-5c0BQ-a#~ipI{j;^BNW`c@Dq-IY}v*hs0GGq}oqy?%9#U<2&|$`3oR ztVDZD5-d>u2BBkP{;D5DeuYOSAdu0GzF%&Ylrb9!v&sF^H~FFn`;-g+05R3RRUjId z+#cO3WVYkW93#MLYY`~ETs(P4iPPu!QbT(Xmbk0JtmubgzRI-dL{KmhTx!kC*OZw| zZ7H!)=qK(FkCBfCwe3I?n1RQwG|zi4N?BKf3)Ss@>fg7rvX#1#Mm7uO2y@}v)*UNo zPH5)dU^uT@Y%U>(lgX@8Tc283w?x=w-Rjn;q(;o_4t42K&bPiyw>;>ZYIy$uATWr? zzLmIvS+LHng_B&qsqXqyv@Mrj-TNSOt(+H!3w>qa(wY&*xm9=%v9@uRe@*>f@36@s z)2CW|Q|T0Dz;vj_e1)!|x*M905>#LAaVyfLf?_}!l@CM8qmZd5DB270BAuhwHqpl$ zc+)Upb@X}KoL|i`u^|21a&HQ3{j2L!MyPhHX)|A^`KjeU)kx$4b*N=!CuWX#@ZnKM zFPzGwJ@xNDjbmg6;IhO$oN7`9qZ2V(^sHR{RFA@;K)!Za0|D*&Rx7~;OQySEeVIQh z!#;fPCG!r3+Wcz@Z}(#>_iBE$L-wI;%1HD`{d=guMzaE|()O$z%@W2W8DuuK$?IEn zTkS?h`24B@Ui(}-FAjIV#)}18&j^#Hy8I0howA7-H!Q%4SY3{ICAuD}f5k^GA1NuE z4RqZ(z6P#F%}$^bdjrCWRqeMASQ;|6B1b`<87#Lpzh3GAuBu#V{{W{Lq<2wynWvKD zvZD5&>^G%5M)uTqAc#)TuQSr4+OSQU8KnOJbAE+x{{UYXnBSU>ess*ev!V{BrP&;; zA{(vD^FI0*nG{aTVG=0N9;TWnmuWw4PJ{PO_4W5s;p4f;Gd-!HzulcYKEhpwP&m|g z?8s~waG?j?%)9Wvt=&mI)?KFarweybf?`eC55c6>f$}eZw=3{8> zuC%hqHc<}5eEq*lX=LoJZ6xgSTksW_<{#Q0U;VV9$nEKVwC<#A@d#o)&r&UvNgth7 z=cg)ZGVNkxay)6V5ML@A6ZNLZ-f(IY*6^UnqlK6sNPUsSdoOi1?-r=sedm+N19Y*{ zqD9PJX4?>W-_c)vY|%B@UP(_g`n^UnT~0ku=suqwObE?wG^4Cg#Wt~oakr5Rg!QM5nWeuv{w zdNJi1w|M98s1DIrO^Mgi96nVXQcLG!JCfU4o)}jl+WGK(B|Ru%Qs)o?L7%wPracl_ z7Y>%>zh=$GlFk4h+t1)?L$wA;aX~NBx`0v+!B4!Opr)H_0^#F24k6D9FPF|lH}Z{7 zN=~JTXD6!=`k4zjkixm9K}h9!v+Z(apt`%X>AR~$onBDP4P&Uuvw&!=U9wX z*UJsh(yq6&6O&HWxzuX$my&nSkop6!vr1IvcnXZ?(j(dLwI&iBG|udJcT$6{L2D04 z)*5LTna>m)Ez{vlgx!`c?&4~9&1Eb|HseW#GGt*Gy7k=r>j#F-zZ9qsuu(F0S9{%2 zC$4`wgABm3KoJ|IWQY_o{oVZ%wX|*4l`K^HFVpa;P+sM9wI_%UQj4CZw?Y*|`4zv|Hm&M6t>hb4iz};65~D1bIx>&dun1DIp`2&a(Z3&cc@81VMD6@M$*8?FExU=r??%JYS~!blj&YV~(CV$$)rWGjB&z%O z8WH@Fh>Wzbw`nb^_lf~nCd6?*`bWeTNC~>aHF-}{SCS=!dMG)4jv>BW*OpVok4g$G zWq!yf@im%L5I_16U;hAgA3coIfZbYL%Qb-4hV^+kTP?orme;8;*m-V8VM}xFzu3`D z4;|%h1RtdsF<02iy4c)*xKNcwhfPL|I#VQW#w^zW{foWYiJ#qnrAQ{Q+A7L4{@rR$ z8%$0h1L06%aQZTfyK~4ndreJ>k+|_Ekm*;J;(1cwdaKfoZF9EnQNvHNCvr$uIZq>} z8j~4_e>EApsq5&9#A4?Y1)md3#M)Ue8AXM*`|HF5K%#o=thqsrall~N^*aWesw3ml`3OFmO+WXiVn zM-Q_W*UPq*VP9opN@MATq7m9FmM}05p3P_qv_&Ilxt*TQ-8#LH)nmHHJU!84Z zVH7yED%Sp+{=PK;b9p1UYDukTkpVx*MvmJf#9H3kl0r6&TX8*O%h_4c7Zr&-WWMBd zGg~)1eTH|Fa@JVwYnt-RR`kuNUP(qrK2a-hQlyW446%@Tmdc~tD*jIL_s1{GEiA5> zn3)ap2(BriI32uaeM$>3Q%#XwQ;>13WDKFLx(}p!Q(;~#&6{(oo^xjJ9+tT*iRwn+Eow=??q)*}-; zS~(7#$flU#*@y-@R7jqo5KceJsQe64zUv_4H8g8u+}Q%0My!j>vJnrRz? zi<-hCskBPdH+kb&a1$bhGcf8;=+j8t6kOGoRkWviG0N4R*U0;;>&eUALI*plHn@iM zkL%$^R~bWUi_m`JL+O*7z*6}x@1wbxvRL1dzY$6=*d%`-$sB=^hJ(JCYM<&$>ZjDu7;oWli^F$$zSPA=Vi3gE zO{vk3TE5zO0p*8Gia+Kxz56_$?vi@S*jUp1R@bFau>v`5O10}QY)nhZlM$I}2}JH( z42ADvX&u!j$^BG1j^ZiG-#Twwx{Rcp{B9~4m+wflgS>O45VFP{Zf~Gd)9g?WVCEh_ zp-Ub3%zhu8Nh^!w8zi{vf6k5>^#DSi%hn=onI+wLa=EBxEo{zPFI$?LcD6_tW~cEq z_^1AyW>PQA{#Al$8%LLEA?sNDPxTmBYrqr!DWl96Dg)Pbczf8^(d+}gwe?2xd@5-P zyGR|I#E70@S#O?U1(jJ|gGiQ=@-P55!g(_PY|z zV&GrasaZFPlXd!5HU+-v6EBUbRvWU)yGxPjFKK89tg=4xJCD2_4~1c)A9Bt!choYv zYdqzL`$sCzsq%?ghj9H0C=Rj^g0VSwOUSrn?yO9pTYn(%T8j_^QMthD)Inw zqbxXm$VTE?<)rIh#WrGFX(=Z{exJBqjer+4ak#K|n&^jxs_hN`0OmE4BnmsIp(J0L zn;P>|u>SyXy%8tg#@Qdnj!o%c*1+q-hqk<|2G|=bTynPxSea40oRGPe_Y|V{!eX@7 z^~6-TR{Q)u{0;G`6*ps@Hi{3T!;jD3UT=CitQ#=wu>F2C{{a0@m+~ht9Wu8LU27u8 zwst$QTTc^Sa};KoM`cdx{JzD(LHDz9?pjz_2`q1@=k^k-nYjz`tdcws+;HA+5r);NZo8bH_ z_J(fIR14v8LOC0T5wiHUzY3LYZKi8`s{tjw1^f+XWBpRUDnv~Jx5}bBAot9GX3Kp( zhOt5i&HO%JXthGYdm5hsrAh;4+Qg6l0Ci)xtY0c2@5@AE1DLmDW6WRlZ&?tXq$kZc zTX6g+Po0?pwjldJ7WmfE5s_fSmRs^>;Ya@f<#7K1k3apjgA$zuca&z!s z*H7FSNhQf283-SRTMq<|tDrrV_nJ^8!l7^PFIN8m;w|DJ6|e0U_Tj}Xr@={nS%@@4 zslvRem5Dc7`X-Weu$nWHRsDPEp>1&ZjahtZ_=ytOW00-4oDLdNC?-r6BeFT6`qoeU z#t&6KvQdsCJ2_iwmgU#=-CGmor$(**ZtSlg2+rzUxN0g zYS#}Q8V*b88fhHaR9w^Ir&~)g{{W?V3Mi$eap=amtA15h^>1@m0f+mR)YG&|%0{K6 zBjsC7+_$y%hQEi!2w$qpODngPN1K7({{R%u0kiqV%sSI7?(pV1FzoxPTr1g??8?CD z;wxrjB2fLV?v)V$Z4|I!*P;6h=%Q>l;y?cYnvY%6g&&5WTJmhbLnNX=Yn+RERs%2et?O*Fbl;&m`G~t~!U&5l=1#u?nb>ZDdVx{t( z7X9?l#6qjgu~~WzPvUDWzV{K!nk6>3@~NyX>i+U zW3cxAtx-gWdlM^3uOYxx!RAzvG|*^yR3|R5i!C$d%O0;I_tLv2LVX^eW&JkMMF$_m zVwm42YTf6pUli!(`>M`OzvWuqhH{E~77(R0QOAXbG##dtK3md8VE}`yfSvyU3Udsh z6-V`riJ_i7t{eM>!1_|+Qb5}I*ulM%tvqtJXt5{=d-gv@gO$xF7MLjJIs2<+n`?oe z-k+T_NiJzH`?*`wO4&siA}88L{{Y&5%^6^sLPL2Y1BktNx&B7zwrMrB28&rxSj#4h z648{-*r^xNYuS7%I11(j=5f??p|H)eUfR8teWvtdH^c$x$GHfr8CC@KaO-czvNG)j z@8=G0jTn|dTyX-t=&zAHA^C^QKPq%t^GptC(2Eh&Qo^eqLFnwk z%|*iOCLW0Fx6+nb?`m&B8Al{J7y5D4SfpAvoaiU(j=Q!pC7 zG%4^}ft#}|(o9c)rkLpNrS3YlG|JoXNU=nESXSLMP}VPgAFI^H5?c0H!}>gltd9O? z4Xn*>({!M0Mf%f7+A52h^1MyfBiK&rWo1N*pDH^%21RZRH**hlUR1MzYs;_WR#~Fg zlA1-!8z?%5Thoj?0hDg+IOLb9td{{W_-#6*1Jpv-&f z&8`m>!}|~ALu{&ije^L1WxY?eob02teQu3UJW}t**&5o5Qg@T_{zqsFIQGxWN^9<`cC);xfcsmh*P0oPp=SDH~Rg|?Cwl#ZpWXr11#o=<8<{l!IKKXcT+-AKTk-THo zepHzj#0~9upRi_N+bP*ikB8Em4!mQX)qSH+{k7!}5}ho{eJv?)jzD%f_kAup8bx#2 zg7&v&=C=AiXJj4w{{ZLTM-?PHCE4X$@#9co6^UZ`t_LF36R#+k`0o+$rBFWZIYICz zN(^|U<$dGwspIUEvQck!PDI;L6aiW9$Bkg{#Xjkwzj5hFVot(#i;ofhDt(-xeAZ-h z%xFax&5|3i7xZ(3Q)YX~2~o$bVvZd$s^+-mz}ldbFhstl-Fenr>QP10Ta~!fdjP9I zRKMy-PZ?KgFTgi3Qd^5|)PW`geIxcDyHp{IWT`l3APK zP(s{1osa!SqD=yA7XAZYl|pU3BRsF~tX0~%%UbAJkVm4Aq1rhWH5!NRje`!I|D0IK!_*-f)( zB5P=|N5|h=Ii1%ywVQVJ{6-E?E%&gs$I`MRrZPSuAGSYT)OJ}g_SBchiHD+jQb{t~{{SyOzT^7oMnz5+!$>d2!$VQDU72?z9pKzl zaeAZq2zp6F&unn)cjP^}&(fC(4f8&VI?$69Dv_MoS+_6qufH#si3{|r#;ST<{*`$q zi93Wu{Oc_1m-~fhje{xXE6zlX;+Z)D$EyiMgXjyof~J(c9| zBfcH`VV1@-O#vijYyNb}ZN0c$@2`hCu@)oj#H4C_DE{t08lFWKym8CJmY4XN#Hx+x zrB*}!>Me?j<2LcOsBc)jM7(6uFYd6Y_KZMD0F6gcbMvBr{oH!{f5k~F?-t8$>wa~y z+Gp6sZ)rEITd`*lpx3UKH7*(`m?}Qd=Q@s6+(T{Azt~{7&hh8rxhqcDX7@_~hr^L7^vSGOO727Zr|%KF`CAK7=7)Gk<@l=81NN~n�*vR@PW z6*8`yC{`PFEykq32-PC@4SqGx&BVvwyY;PvP}x>BMs0NGYAIVYlc#X!Nr%A?Ic;}!9n{ieu^9}U zMr&Wis?kXT_vRI4o-_XdIIg3ox+LFwuwdWQ}`VMJnvpS(e*I^kE*Tq=w^T65Z$`u~xTcB)bo9qeO@Wxg3UO zKK%t2mj;$6jF!K+3sIS|2@;3&hXl36oKd1W7+ zY}BZ6d0V4hxPRMNXmb*)t6#4ZOsN=soMapLT-E|M(6pORiTYM6V+mm)DR4ctiU@A0 z0SDdntRB;{8G~DmuTHY_Qiy$PTjf(C*ck@C>sBG=kyH!w<9fwGBM#A3C%jyIYB_8y z&=G9b)vZBwK=UqM@QX;~TR#5)zgmrNq_~%q-=fwTpG~B#h<@u+Vpw*INYp{f37KNh zbQ=C9v2!QfZ7j!5Tq%T+XTJg()}y{w=OS5et8qTzO3khwE37g90I0*#J=G+7nO}A3 zGRvqN(s6GE=}i_Le4o~K8JyIT%nO{mtu&Wo{{SfAPM%IPu(B*^_}`5QBg0}Eenh6~ z{cAd5WK7(AXyi;sjg4=->3>@Fosnc?p<~*&jTxp_#6(X67`Uy!?Dx3!4NZW3(!$|S ztSU!PHqlx{zd^>Pgb``L#6_<e!?1wx9Z!8?UpdN7 zh@$1q5g`~@&n4CU^r*ZPSbdPdPFT+~!t{bE(=lybG~2rNcu;8uTsA7t zd;QziHZ<+12I_hpYX^%Kx+zEa3Y^G+h7nD?Z+gS#Vh9<5??2{*D%UFnmr#4fswapa z;s*G?PpwIbYvnKgD$3TCmq8yQPY-oU%x^0VpNkz^2WF%Ha1JGG*Y( z#@-^bvmKOpi;H?X7Wvj4+q?iNQ|R=kb^FaDkGY$j0uJT!LOX{RuPK+d z!$s&TG?Oq+Q6`1`y(t8Eb%ZZYbYnXpc;+db+q;#24Lq#gs^Ng4E-T6c@X+MehFM)M z*DP9rfX9lHnFr-XahPc#d+N&HBVWSJ9N_R7tlsM5BuqVqwuLfc7WR@mYvL*_OmXC$ zP2Zt42kjWZ5lYr^>YjA)*te5kWXsKO&Y{HcTw)m8xwuj^k>rytn&VwRmTkP}i(Bow zFk#$lEQqc<#byu>X}{a3tiiyyBNCsL4XVX&TVhmu)X|d*l124WOvF}YB^_zvpGfBD zJ1y3XE!zgvQbo$ch^eEF_u1xa^$p9}O*OKCBzTeS(A27Z2e;r4&ZkM#WyCRL2e{Xe zxVccuM_X3eVJ@T`-EDe06TII3SMjBm-ftNf4*Cpjo(2Q{maIuk%96*$M`HH9M+sHS zu(2w)&%4A_*dzlY%1z1FrALV2D>iRnwZ0XHU`SgVIp)W;@u{W~118Lfj|(8s8+$2n zvyjoitU~(CIn+%wJJUu~sXd-`cCxgCH+M?LE@f7_l_#m?MI^kF#GC3ywH=i*VuhLQ zs2q>7vSSEq?$~>)98j}e0_DG?)~DIrUSxrM7mv=KL+FdtL9&lHIeLq)#L&dckS^7y zVb4#_t$P%SoaG*w(0olXT}BcRfd2q-tRxF|mo8wSay)6AAyms{QKhOtyaM&%%krhg z;!r98Hc|Ib&30z&qVYAgpUfZ|i^jEb134nT7j9T1bL<>*g*$ zUKC=N?q$*bwS+B{s{;$zXnIk>-p36-ZGB(nml)}+c~BCUmfpKoR8XtXRi%>6(!Szf zXtihZBbL{`f6Bl4U;F<6D&C4gT1>0{{VS+7v}`$Be^&}@NBp(9h=UqESw>eMIw>L) zJq;!!jPab39_~~z8I-N^@zheQ9UkfL7NkSkWOxnz;*&#ZAO`*FY<^W7td?awJyXEb zNJ~bpY}Xx!9ehOyf@Cr7x^y(>4}0GE6mcCXaN+Nh7PjsLf0}G6p(hj=-@e*b8)6hZ zs?ok{)qY&m8s0&?JLznbwK_oeh(A*ATt;gR;=QGM!s@(c2D+d_1%%~dril5dn!4Zc4!#Gv-L%^tV4_IG->S|eiani z$n(1vEAJJtWlMp;3vvA#Tt?KA5GfYpry3J5&6-!7kxiP(YJ8zx5kkr-Cd!R!58zWV|#xR=4o%qM-PQh`$0l^trs_< z4J?Fiz3tywpYD^7d7vVYN7b_2`zqjOfAt?$KHsowM%o@#o^K{*>$4~4Sz3KL1VFZ+ zHq5r=$kx+V7XFdf+<4YpJ}IG;aZI{@(rE3V5-qiOzx-)rkIC6wTSe2_4+3WmO zqg0kI)2X+%j$`F9E~@9WpIX>4^Kt>&FhXvqhrMl$GX*sk^4Su8~WV7 zR1cws0m$ySyks=t=-Kvj{e9JkhTGA;PhmPA#-oI>Sr-$Lt;7RZNo2(c zRaD!qhm|f4#bLuJYYt~hl4)AodAAMt*zVCB8pH$Sv38T<`2%$G5v zIPqrF;aH|#)s_VI@%Yv)hJjUZ@%VGBK2~An1cn^6HRP}}NEGE;pM5M#?LAM}Hm_oM z4kXYk2#OxEcAMGCfJn@Y?QE(@KZPr<97OCj=6&?IW;^aKKFK8QZ1{m$<%eW%qW4ln z-Khb!I!Bt(9Je*JjZ6J1k%qQ~s@O z(l>@!_gy(3{4L~t-UZ0mI!Fgn`2ra`L>&f#8h zuHLHgui@h{$LkNNul{)i#OhK#q4(C+gzUiRXFn>7$%AGMd#hU2hDL$dwvKOnzBMi= zSqiq|^|eCLkhxy$4@$;ogDkQ&?4tT;DOydooOXkHqF7_QInl`bzWT#J`J-*2LIU44 zO+0YPvQ}I2(SB9`0K{<5vT!qB)}kd(CB%B(iyr#&Y+Ov>c4QpAv-=#+^ z+#WI{?qt0@iM?aDPVjVU#Ni)Aee^y&e;ysMC^P?y+XFNkbQ{&H_HJ!^Se^YyUPp>Fz>x*$P`6}ZX7TA6@h4t zilMQuD4%u(>*-OC0)-;swK`U3J4t%5(0eO3A)0pn(t-(vZc_j zo^>uCrlN?QP=EB;)_5_Jq4iwn6tUt&E|=njgX2n)XJWi0Cwi7O;G)C-02z>|E7H}S zB2{C|3fe3P8^X8>2EyZq@{VP_*D3IziY%i*KarZ+fos%(oaK=++ovC|+vPdPB0Q91 zBt(ZDpQ~*sDu4jwKmNY|0RO}QED!+z0RsaB0s;a9 z0RaI40003I03k6!QDJd`k)g5h!O;-mATaSzKyYCH+5iXv0RRC%A^!mL&OiPdV(mVL zGXkBdc#awED)xxc|*Sr)bUd3 zdzc?oVTy;uGeQ%)o@+r!z&^BO-+cHeO(J-IB|OSUy6cEl!4aEbSOd5 ztGIA?q>_+E84m`{VFUmr5e99=PQqqE1WAQ5jJ*t^_ZedSD>&#kQq?4+lg2a>?$o2P zg4pC1sjj^`%0#+_vC@m?5`ZGsgYK@}u5`)Luu7W@LJ)6yGRxC5-Dx=@K*SV-7lCZF+Kh<{QH_$k=8xJ2 zW!>6{n*d5tyQ1(YD7g_tE~wta~1)#GkOkmd-jr*5coh1 zch>j)(grBHr!p(@6mp>1|3U}`6tkWUuvF>wb*S~%LN zZ_2IFW#ifMqB_lD_av)G?VOSE*{rXnlDT3$QD8?-bF|W-5k~PD0DvZ zJ!j&9IT@njTj>x&zz+=;*mH3>wE(cu1yy=*#U81!(fWc*>%BI5O^ipSB@+5e@p_E1 zaQrOLozgLM8U2L5J_B+NUUwx!0yQ_hnIniCw-DiNtD)ZRen9Wd6x zlD9%2n4GTpGZD|Klj#l3&97N|HoM&^1;yXR76e|~&5Kg4H(nwyYt|TcQ}a!j z<*;cBjvP`f38?pKE~STmaw)OK$)Pg^`?NE7ktakfV%esuVO!v`m4Ge>aE`X5mTZJ4 z@diA~X2qJD?^B~X=9Ll2GIKfiTg5{F{8VUd7(&cKOHHZi=uwj?sxPNGqYLFhj*woB zxv{d-!%zwY+<)_>MT0C8`HBdDiD+uk%_LDn?=JLY*xwaza6~C$=FdvJ@?{&~q%4fg zCreWiK#fDiXt$N#^G+@T7Qo|ry^7(b33sBQJ_yQ7aivcgA(1p+DFR!zVDVp<1yM1^ zYo6Qc_^F{5RS#6pWom|?uL-hyQvNA0ft}}%)kVl=Z(NpWgh+xrmp>GRjB;D@V>bRQ zft*cfB*_+~&l3U`P{3-a#0;jrB}M62Zbc6Wy+{s_6mKZrn;{rZyO(L-L_NRr;%An1 z-kEX9El0XV*%p5_G75@TwXY*Uj&p6lnICUt6;8l@LTP~vSP!cPXi)4VN3B~k~66MicNcnFz*K{ei$U`w8% z`YD~kY#qvr$MdvELuYLDqs|_>v;kn3cVGP^E6>SRUR6Z~Y$H0+g}xbo2zyjFkZ(s? zm|;I^56_zD3D*`Vl0r<@Q%SN`L;9(-w!-hPsL5zw-BqTb2|2*G_x0m6dJ zvs~Wu6a-ylu(hH_e(OojR1(hSeAT_NkYHE1tHfy5qU%B=%|PnaLs7tkLQB4BFia*y zXGzqjVUdmN3}t#!DZnMUi5QQ~A%w#9Qs#7PXC%OGlJ~E__typ@DgOY|nVF#$5b+-s zfDVzDgDn?B3G5foL`sE1CfQ6T){2ypZ!VsG^ZZ2z%JHC%YWnK&vf*8dmRV&c(GumY zF|A*ikYk{o3{ZL@qpBs#?)0TFEp`@L<_%~gqA4KZ*YZ}&S+d7v(w)*t3T@A|YvGi# zQ$@Y;NR3==<|iK0*+_!uFpX)$Q9&=%3&|W-qe0|!X|mvnsCrr(aZ!}=lnkx#_p2fn zvihfQb$v@u!}p*4Ryr+_G7}x>Ly}73${e+zIRKQ+qGr_rDPiNegrGvptgTw;)S(#2 zX_*K%EkUB0*W1#j@<_{cf9)kAuUY&`3E-wD$C^KGOfWf6VhF&E*UpP;^?@a1tbefmP;tj=}388|O5n#FCi_+!p z5MaCFzW)HyX)+bAm?MUqm&AJKT+L;>?BMoG=^ZX(^ zY>c`z>uMP;K~_cy&tKw2M8QrmXv#0uph1w&gWpI1w)ozW30uUx)YS+(@%cJftVFyI zLGQg!ta3phU8U9G43-g?^Np$dX%{OA7~pF68}{oyzJKx!y#(W{j%zw{2^unF2ql-# z@~gXL$aZ$?{Y~CH+5L9K7^??wOFbyJs5c3^Z_a5E&P9T6sA7&;B1d#`ZAGx~B1M;u zY}@=17!fA2e4gLR9n@z5_NZ=>DF~WQmxr}TYz7b{+ju3HYOuvOlV}B?lHDkQYHAMg zr}&lD-UK1QWWA_lEHQjRU+h)yV@?v|jXP9=abizz$;~&yQ@AuWA8u;N;qwnw$Wc3> z?vC^liMSS4iPsdDNKW>z{APdaWE%9(S^y=G)}Sg*#s0cfLRcZQ8gAV9b7ErR`qmu~ ziw5LAj8r9yp*PN^?^VJL0$gzDy4|_)L&PZqWTfgf78SWkczEYWNNI=3Nw}HZdMnfT zs8&WkFTW4`+KNX081Nmx6&PShEOWOH;KT}2wZzMjzdF!3B(n~GfMjDGJU>0?vw|&& zCz{bzW6}sj*|ix>GxK)TpPDA%hOorL#Fpg$015RXY!yBT!fpw??qF$0$&i~tkDI2Q zMWv$JHW1tUrNA9OHSih=hXzaSfXHqi;V?z`G0JQ%cue`vD2+WsmSP5L0gE{2Ri-C#51JN zRB%zA^QDIt;DGZ{V#_lvqADnXQJVz~$(FlW(xUuI=-;yOul=E7!M0h49jFu8GY~G@ zQx@84IvTdxB=FMcOc8il9Te$MnkE3NS>xjMFWMclg__8*MRCS*muHgkQ&kQl$9{?& z81)EqZJFmZ{{UMxpb`;}s8(4MAb>tiMp7A1DgOXc4}*ig)~O~Y z?w|c4Av}%Yn4)#2EMQ_&Exi;h;4ZDYPI+GQQ1_$5W^vN>JMDJ`*xy@K!4kx8pUU@| zjr}@4Hr#8`rb$hM3{T_eEYz_c7W_1!v4Im$^1V=eB^O$5r#g74UW2!t&K11yp6}@X zYGcdNIyRjgHEf_UE7*H1_^mYYxh2n2CRQrLj?Hl5M%|KHV%;b1 zDAc=(bWxo>!`IVWd}+5?!=lzAuTP1~Rfmvirp^?mSF{)#Xq$%qWl23E zxuLV0E#-Bb3tkzbWdTqN`O_z{)g$HK$mA5{to@BdET+kw=cn?D9$-QsmS4@$(dN; zyf182yho~Yep$AZu%jmnX*vXYtKvi&GjER7IyKBB%H(N2sDUZcEf^gs(!U{HaQn?9 z39FnDJI1`}SjHJl5RlT(ssbmOlw|cnBo38$b!s5(Pcdy>x&i%3RvHYgwZpVjV<%%W zSlb#i01%c&ueGS$Nx{NG?Yu6O&@zam?!K?dQ*mQl9GFwZsPsJi7Os&EGSEKej0LP{ z7PHf>5h0|^>-1F004592*P62QK4AX6#T zDjyrkfatpO(vd_lvnR=G(>Q++$@Tcql`bG~JwB~L7alc-LuV~~)Yr?C4%gHBcR*6+ z-Si*rt6;_@=ZkT)KQ%5dkiOLTev(byCC0_}`}v-4z;#CWniiIB$4=w7_fVC(qkMi% z`KU%L5m35-zizLU?V|u+n-{7gx4OHa)s$y5tVDXA^ajqq3D=MBH1ijzyS^z&Q(@RN zcek3=mt4;KsN3+D{dGOBk3e%%5@f__zBrWJ-wG0_k;WDz^!KFT7_!WmXL=ubNdAu$ zyoznCSb4NY<5I4qju(!}@l!Y`d7p}t=9Un)Cb!`AM&o|jj|-hJ(SwVOSO|2v=9w1h z58D_HwBjHba;*GUP7rmFTfGV_E&v_j^H}hwrTu&#<0!aZ58;U6gy4q!{{R3W0kKgU z_L9x5j~a1X(FN#z51FUH5qA)N9dTGWVPtV<4L9pg08wV<6VX!4naIi>zEJ5?5H_X* z$aT3!SP}+A{{Y}f%&-|<*Q50f4)U2K@y7?%Mj%+UF1CKrS1uBFqhZ5jiZTfxPaxZW z_@dyZg_kI6ywl|7OVsn@Qy95J-pIIWo0F6N)QIMvL)AT>AR?FOEcSM#X_%f-o~j6T ziNfXKx}-pt<@)JDNI3QYrkAw=REZbB{Cm};{A*e8{M4tcHCrb^Xc*bF9US$hY%Yw0 z+Yb0Ob0ljj%*L)`_%63ufiW`cPY8p1zzXUfn#aux;!u4S>bq3WX^=_K`=k_;8(#HU z<@P-&Vv19)sF{L!qmvNKNvxkllL8Mong#PVA+8;LbhDkgo73Dj=+e{xB&H-f(e`F+ z4aFFOZtBtAXF}U^a~JbP%3;~YZ2jt<+M*GjsHsGw60OKs?dq> zq<$Hn@(!n}j{yiK`4bO+H66?uAv?q14x{3~$UIOOo_Wacz;#> zqOJ|M(eW4-0#S91Z^oXeYCQ?R0{Up6!tQ0!H|AoD&ny->rtbStB0ybfQGr8%1e!+`bT;sASN9gC1qUmxeWI5D1I%YxH$dAZXq2ZW?Mskz6(4{ z%-Jo}c%qjQdmd^|iHoK)m>sFDnqpR>_VkL7>a5D)k*7~~UEYx{0#vbx;)@dkJC*1{ z1-)bXPvU5`t~)w9cxdqL?@_zI^+flz4{goQ>a0O$N`DP8Td?~JurSjEz50!Tj%h|A z87B~2_tuGllqtPz!!82k%`V?qdvwtKwLXHw;SP6v^`sp{jR@NA_#%p!RfLyjV|tOE%yl{W z{wNAJT8Hxdm4b0j`wI-qQyxkeSgOQ+Cu&QG45TJwN6I&)EHe8_X4+7Q8)FIEL+n%_ zzchUKC;F?P34aIjx6-Y23njWPj$`{2ctF44-)>aOL)y9xI7)TwynBN?gEYem#jE=A z*VParwVvWMJ8R;tb@Bw=lsl$`_PnO)=GyN2EgCOejIljqwKMT|waU6h%-sj(ujC@+ zC*aYL?g8n4$yZzejo;Dvsk0K3VwcPAra395G>(OuxXmxE0%Z_eVQ!u3=z;@s&wou@ zc!k<-btq5C+6X=3~2*bP#KA6ew}0CfX}zRK^^Y z$ivU{Rr(JT$m=y_zC|nAj1dG5^4u+&V~R#+#-SQ8eu+cGf3!F9rB9rMoaNMZl|gai zbku?~7%uF%$Eu0I#3FXoa&16UHu>XAZ@GFHB@p~xI25w+7fxT0#U_iWxW2I7q4_}s zawAo2NrX#wqaLkB!03Nfl9?wi``o>hSdF=ezB0{41)j-`lYUQBj5H%r{{UW+mgF3X zts>7SoN{qWe(Ya#wdH?xFt~CZ!>21e)E3Ad+n>wmgO^@h+-|?)CYWv?&kydPH3@yh zbt(5+2&`v=K$!6E{{V)NaKAo&LuxG3ZY;$2Q`_WwT?RXC?zKm7Pp@y)dLJ{G+`lbV zt!w`PYWW&t6N=s2>}vf}J7!l68Z14Y&1sEiq^}@)d8Pb@>|Lj25T~7)a8M%GyViqO# z{TSI%Tc#t84<6Npb_v;Z(v-xj5Z|};tWe7~vfsdoCC~MXsGoFIqAx@iAC%mxSF^>~??kN!Y-sd*ijvZT z-7UvcUx>NHFge}&sFrNYhT~yVcI>oG2E20d-nzkQ8s{`>UEtAqAWUibrX{cJuV*&) zRF;IZ6JNm4No-kgM}xH~i#33S=3;9x6LS(JS|fGcA9el`-gk6gx8{lf3Ak6~P;jLl zE}fZhEugJr_o&uYofvFNzKg@xM~*Utx(zOcroUz?}RKl2aB%6mEH~mBsz^r z97C~igH6;4@)?#`g}C=aiaRQuaowoZl&)S@crjJ(|>YX88_5*Js5xmz`QU`c?XbFWC*BG%_AqjmU2LTZ$ykEzsWq!u71^ z@pGp}tsUq{xr>XJWTZOGD|o}YowZ_6${(1kYJ$sQYwU4m^b!UZj?ba9&1HxiI^dqB zPgLQSL?kqa;l)9xrVsiGdeAX%59tplH9wi#s@#9Z)dX&WRsyeH*?EPXwEfu5lN+E+5_v^3KsOjKO6w9CP5ZtwPHXig-5dXaR&RjRgWfLk@Bmu=rb|-(K^u@V`Bj@cDe4c zm4)F*jg32W{tHaFB?0~XRHeBY0I|}7n295N4^!fdibUJQ*l7t5NTYich+%lB#E_cU zkIfaJVRsZ{mKyNS%@M_l!{XwNz^BTgPLNu198C?2MAG!tB_mN0jw*)gU&nB zE73U2gR(tJBskevCx2n>LXd@v2l81xsJRomD9duto+ze51gXSEJWz2hS@mg65E9&$ zmid|et53RU22*GoV?AlB7KM*----xhxxl_!-h(lW2{m?Y5kr{@J<&ZrsY?CnBIIq* zp&}y^!a7FXAI&VqPbH!SzecWl@^k${9g7>+?$)zy`Gq zTG_&3VizA5&H708lFv%-CQgC)c$r^>Z zl7zSs5Mu*Vo5fljUr2e`$%|1b*PDxY$+a-}cy7Okib>+#g?xP2`-utMGXDSrhW`NS zO^xdojc7$kCwI)Xu8RDCZ9!ZdEFgY%P%hq4VJIFgHE493NZwv@$`JcmNp^r zIB}<%zik@htWF$cr0cMB+y;lLV44`}`%hzh z?_TufL~mv4=Aa-Yf@$qAjn@Iv50->1^TPo2G|E{NxqGwG6h_+kH$^s6(&B7huw#oi zreR3hZ6S`|nl6e1-~uttNs$b@qoFu*RA~h2{>s9Mr){ z2qeTa9qLQ|0vX8P%?JU4cs_{jN7-D)pgyUfWD#C3-GYJ-f|#LW$rp~*cIeMuWJ21| zfLzxhI9)1bi(H0@HVTiZk*N#=nM@fZz)2 zmvV+?Vz}+MqJHXC-ywnL4Z4-aTCt?Q1}KLLgX4eIcof)VEg;zfUqS8_7664JfBBTW;@0Um?1_+h@Y z^b%;LlH}r@eF2(vy#A?gt&@Dgqs+bP6mj0$@j~YT9ZErS9;PNY;ZLGp zW?6mus5IixU`bDP7HAz}tcW7eGLML>y9Kak`gE(j+9q`s@idN|zEHE85n@&{*?Keo z0JWP#IDwdUKXXCtOQbQ{{{Tu>-UeJ9*|(~N)mlKXPS1jzQ2|WMov&C>@LKTnR$K+6 z2pH2j40ChBZWeAQ;cd3uS?jGptibB;}9>ejy5N}sW zo7SY6F$!Wv6v}tfbu`W>E>ym<`qC#T-@=qV6g^gpv~yBIs9Zn8TRhZiAiGaa<53%K zWO1oKcQLlnkMDDONJ~6BUz?{Ch;#y2hp}=`i-$(H;%d$mykwr*Ebq$)`0Uhz7LrI_Ldb2^t+~ z(O2yfJ`H@)1g)TUhMPV`7bTcb@HeT8R(`vJ95<@20c``ZCbel zkChRLqRymInZMr={eI~+0Xet86kuv+Xk3kSTC%JxgC(_T9rA>ef-~BVENmuE?9FNd zu(pj2Psn~M$Bf3o0|Qc_!LkQ0!k7?Z_=4VMp|V%F)7SArp!gXjJ&H8j2Z|2mlEROh_@+KV#%Ab*>{GI}D(37G{{Ut{jwkQG6k{D}72jg5))^;U+vPxB zvVdiW^M7yg9dwA2T6L>DnTZ+>C^rCGR|YYs@sulMM&nqtp}TIsxu`H#N3Tv2mpnT> zgQhKdtMIqI>ALk+yW*n!ZsD`&Bqjba^&eF0BUV_|rd?`L-6QNaccHmyAVX72i&3yl zMnFwtpE#w60>jHU9f{W4(qtxLOD6*z>sh(!x6u9NH0&b=ba);rB!-;>#@mYGgwtkZ z-~CEj1Eks1_^TiSSd%i0t4L+3!4p4UnoOP@DCd%GFGa3L32#Fy3FHp<|2M6pG9UvoN2bxSluOdzA z3UKojIdo`{I2c|83C~!hM-iT33=aBn~BbUbw=l6PohEVLzNWuUN&@AWi+7>V{~cjl)8Rw3erpx;{6y&EK9J2Z8m+lHd{CS;yRXe^kV_NNR3w`lL;V^@j&uYTfhn4X0Il(pALn z-o?JdfNZQqw=Cb{^&m)Ye`&`@YeV=qJD-X^pj#pTnQcDn#$I7fMLhL+ucMSiX|q;6G*;WtXTAF zG>06v2RCXCM>Yke`GHOB4U$1OMaI{sd(dOtiL>_9P`zo1X>W_(ZB7Wmih{(;%8pnv zaj~Gjx2OfkaJnTSS0FosA#sf-ycfq!}Xm z(#xk}r6eS*vF)t27v@i(lTN(M_R38u%qpjjF}T`>t0VAi&74$~n+4Z!^Np!5>Vmub za-rx^&%}Qwv^PZR8DtvnG^0qcT*ZfTLrpyVgbzK2o7S-@8FozujC%ac$UnIe>vnv|)kgJdJtVu+dN!BC@iDI=Q&fVy0Ts5NJw#s;!% zr-uFJjB^$GZ#9S6gBOWTG}dbEpaYp*`K1sexe!^svDS$?fOfA&mgU%kQ{alRxKh|g zeW^r}QoxA65$cGf^pJ+*Oez*kmD2XR(RR_0+COhJYEA6956uaNN+zZM0C=q-2zv+V zRuAAcz~1{%2O2a@C$^# z2FB}(R5fvkS{~2`AHj?w30ly< zMb-`J$i@&V+(#^Y)QC=&arvbu9@>(?oRE+wnAL-Wf2084JpLIP^EXs)?VVqrcX>;ZXTtX)4M zw5bFKPuW+F8mvDtWOG0}3@;;X*7V^kUN;u=E11nIGs!GBH#eb~G6F+FTCZ2AiLjX^ z{fiXMLNhFFwP7Q6;bn5AywenBh@7h8o*eH&ZG4^|;!BY^H4igT^&xDQW$jJMG#K)kbl%SRvLVWy`M$X6xPTRTu6Pyez5UpAHq@5U^kG1(# zq*jaQodS!jaJnA}tN0@uj%CoHu9Z2YAnY{N!shMms%&I=e^Q~Gy*a0C83JCzFPf3G zoUe5T(oy0{H#1@HYBit~Ai^DCOiOd~2ycf?J64XG%e%_Jj2YUbSad zS1%36{ZS+!g6ch-^w!h{IjN4bs&(1xO(o6mdq)os_%3e=W#})8P13o<%@=O^l=UEE zF>eFzXrUw)$9+fdAIyOGnzLpyYeZ9Anl2YJh|A$LaH2#a;R{g+Y(iazMSGN*JPq z1Oc8`nnFon$rCTNsXk+7{{W1`^KapxK*P2yV_)v9od_V8N=D^JJT^q?^c+KsQCXp5 zX03+VRN#g8bU0#dt$O?q)3x$5`?M-`?@hfWURR*xwCuL_K_8%w{7UY9|Bls z<~;MDLqnXWkvWvf-+GGQPnPaBbfPSos+Z^4*REsfwQv*p9?tY%S_&A^(tXy5S1{?s z`u_k$pQH}}?W8oc_abOSomb-YHYb22eVp{ydbl)8-4S)z>55 z*Ooj}63aJzhs`92_CdPOA=#uFrnVan(UO+Dj!ZQ2{Hfg-g@qs-liHX@eIdWG@SvQB z*h&%ZDpGva@&~BGiR@FDwzo?>99y0fZgbL^z?rlNf_l*1D{$>L@Y9L%=B?i)OKfZ!I~J-EADaEe1IRwz&?1&V8M zclRR2p%jW2cZcFqptwURJ^B9T%suzWy>sVgCX+v&y=U(?uk3gBTI=~FjW*^aCcV@C zsYd`U`;oTOg-#8QKEu>^3q02ZP3fpDAVWn8)-D1`4=m+zB6{CEAO#Hs5?#z~^5@tz zky=hRpL&y0{EW58kQ?}B%boB?5F4I8CY;xDF4MAJ@IWbFB8xpe_qIffa^9s_pRVSl zc@Cd`bb2=?5R7S6bb?4om$Pc7V}OYbM=tv2&NB6XB&r1~fAT-WXoY9}<=D+%GJw>J z^o?X9qCD!qtBRZ79XpzgqstmAZ&hwI5=x?k+CCOQTI1(FzfuJDLxQS=QbIl5yI8HJ ziy7sq`1s(h*C>?J7-rH>riJf}Tv4uTV8d>81)JrvX(@eSK$ZT8l6{{lmbZ?Y%2e2r zb)mHw;~X8ox0eeIqhyBu!?;RF&B+lBtcg zhsL6Y20X=Jc|t$N2PMBIu$mh!u$lUq#exgmk5u5!%87h}9WbG$k-WQdhKAcj;Iy^S zXE5z=udOzw#ikT9$9g+%7mg05X7$E&aCO~PJ{c*cbyT*-%M6?rJN;a960ZDl;Njiz zY>*wKV5r6w;5(1TeJ#E26mO)SC90JEN#7SFgujnu!Nnnmu2 z*QY>Kzq3&LPCgW8U;q|{#i^GJd$M4z5!Fa`yCxPmdB;_P7&_^xfaQ@%`IeZ@~^bhc5EYc`YnNfFtCs^FrLbRuHHiBEyvSka=% z;UKsZ<1@>A6l_rJ{BbeQhHFG2N1Rg!g&ic^nLY9FquR&dq=CBvRW!^Y?}_Et^ScF{ z^nAx+YX?2mo@qz?$~{wh=UQ_br7}=&Wlo^n7ZzA@zwyza!vPVV;V&lOh$wFIdBClJ zr$}@h%3={tC38ilRW(;AxK_gtK_!@B)>aNDEDQeiCaM1AGXWn3s|JqUa=<8-E_&O6 z5S7lQ)DQ7CYT5;L->67suUfXZx8>vs=E`dQ2a9{YUo7_=6xVkxr`JNtcZfvS9-tn2 zLWpADJ{~K@D|WB+I2rA7IEQ_hlC?ac430|0PBEK~R%QS(pzZ@BST;9*7TzvmR@o|T zHft~VUY{1;>w$FFm);uWBK6k+*KTHU?dn6>sST*(k_fTs4g(vvk2_|-)9h3_=-N8m zwRFY>opI(AuRBNkebxq<(sdApFVw`YrCdBrGIdR_CT6LV$_(Xx?&G&ju)z0FCH^vK zjYfuasfx1UCjZbQRf+kYh9@X(ebU6@+QNWTHW?DcX&XkYPIKF$zrt-BfGVDoZH5IHC893 zE)P)BKtD_J4?v*E7OX`6wP25c>3cyY?$;L}9CyU*Br03=#>i%W%KY>2(T&1)*8J8Z zC6sk|zVpzg+X7M!mN7S;MnOcAgld0N^GI3YEs1zF7+D}g6 z&69_P)BJep4qC5sQCm6opVfb-iB2r4GI?1=8I+QoFkY?Xn2m9CP~#<=p(5IaT7#|< z7Gkk`7GGjuL+M*Nz2fOkBx7J-lAE6l9Q~E^d7oe}ronb4EesCDpV-h1tRE_{X4UzKo$Mg!F{SO{L%d&gwg^J?npWy{Ccl=p4kCU>HF{RG&XF)i0MI zM)+Z;qzb~{%~0}^c>`@6&aNHptVgr|MEg|k-*@Rs8rW&5Jn#A5lbla8+lAi+qy3=f zR;|s*^7isYvtE#aaF!5R6Px98tTpvy)>eLl?9DK#z_&WKrrE@9E^?-3B;{3FuW$JT z{jrDF+T!)$^(8@i`x-VAqhj;ca?D=duVCg{nf$Ec6Fy}gjfL4vm)dqI3Lm}E95wi^GEk{l8&aT#x*{Y_ELx2^b&|%x zT%RFn)R?ebUTQotbLJ%JDRvxm3hqH28$P<7K2<53jYB|W(#RBm2n%u{QsaajskGr# z4eBrIRBYoil+V(6TNJ&uE#>bpgR=^n6$SbBbP85#vno{zdg6uQ5h^x8{%c%Pwo3f_ zL4WPjPc$DmeFd7QVUGBmFO8J7@qV|Ryh1_n&r^ZW~koLK(TXOAYh|9-FzO)SRI);x}5KZ z|7KymC?!*QtICzCa#*`Awa6)kJnT_IFMeNVy>%1ILzcWTy7%+fBXwCjkM+^Qe99Ohk@vRu*|;q*h}{MFKV{^0)$mnCh%?uJYt-iIfs0 zSO|P)iDVOlTK~S)=9G~$J|^k{!>Te>-{QR05~Pz_{*s2Z!O1buAN{Dm%8W|y{SRPf za5V;s>G3BoXSR7GUEj=M0}RWdtE-g}$IfGzY<5VNxnYim6Ep|=A|R zI!3IY72jwiaeW@) z(~a@e=1*mL)+JfY##~;r4gkJe)IXOmX`io0o2R@dBS5fkgevDn*_he!gM3-@G*In) ztX&;*7G#Z=18VI?r^KDBZM$sx_3%X>r+*>b`~CYrTTeSJGLBOihH!I*b;)O&i*AOu zskMlNvoN^6r9S>0W07!a;-z2=@vUqIT8~GDo$KjX7$f7^!Py#@aO&eDJ3z?7C`B7L zGHMKwdRCDg2zH&1&C3QGx26>&-AlMoWuz+TM6T?`sG_ivbC64eI0W%>A(blR7B>@M z69r2kUy4rF}@#Jx>PVyoyc1 zSDH$xG^_!dGEdmRVaXAkc_kc$K5rY^N0>d~kghs=Yjs3S{Q+6PITzsjY zUjbV@QyZ`~b|Le_U8Mn-2#N4g^7z`$*wZ8H^QE(MGusJ_UT|xE8@QNyG|a(G z7Qpe^!fexU{JtmxTP|*6;C-BvChw%1G@2^hg`_`a=@MukH{a>u6j*%XGD`P>nqpCp z>v+UrH0P;nq?T1)4XF7@&9Mws~ zgA%jk-sis1w&>GiQc_h3xg1gRIN&bQ5lL8GJM?RPaL)O0$NT@uP!3^Qa_(D>(7y(_2Bb3LzHd`bmJi|mO`c9J`JS4_VI<9CCQ9>o2cVs&-;-HVZ|15x+1dm z?~3G66+RTpMsA3WECyHbWO`vQm@tNrkBcik>X z@{Fv!E<1#)gQmm8(?~UVvffNoWU~wSm0qEq>#)L&Q26`tC`2&1`5FaP4}Q)e3&|4H z*VX0ddvju!7!>|J62yE64{d+pP>Q(OIKQE`?sJ0q(FQ1&d@(gLGntfDKDxhQjM+N! z(?LO<*){)uV0j%{Z06dUQbJuxDLJz=?oUm)#~d_NjhPM0uT&cOg{7 zbu`PkdD85KbP#wXBpClu;N7IXVH{Qm^z7SsQ3>m!q#n$RZq|a8qwxMgYFIE zk_0h7)@BOLGES%?<9@p5*8F^NlQ_vMgTryW>7^G+GpQ^+U=~Yxq==9Vxyos9!V4g+I#7P(ydiGf3AyO186yjQx z;q7qLGUGvHbg9#quw*vL!$@oK%Ng-fk}O_o3Y-Y_cnp-R&`H)OCNfi^U?oo|1MjZ% zep)30$Hx{?6TJ93f8Z-Lz40()9-k2g@n}?T@}G7d9;7?OZ4uWK*GN{omce#_r0vkh zv0GMxAMW)gWvW*)pF5{hfyl>U0S+0%Y$BM52rpF#-iOX4WzBer2E7`VR&2CRJuCoA zA7!s97d)!0-8lM=fIsk8=k^e?TAY)8n2;GE(H?M!C$5OPAD=0}C7> z`;8K?Bv~R1%L(8Om%vXKNi5z-tXL6@MQ1}=l^E>e*M%;Hhs+5fK3`SUICZne65>x>q z4iC~d&VK%wfZ`WZ zo(mJnsu}BC^1?$+&n7M0$ghHs5}Kjg%FPtb7}B7#Ib%h#OqZEQ8}`3*qq%(`rs$O9 zXpxW0fX=s0F&^2|@)xtgbfJBw+0$gl(@F=VYTiI0X7bu*; z=^l5)&@R|LNPx>`XRy>Qt(yGjCUM`jQVeK)tzXq|TIk#SC3zt6y|IrD&Pd4ly@PM)g8vYtRN*C zI0)5@{(z5sr~P1rIinu`@>vm?bxUkebN4ToZTuvu&Qg3HD?d5<)#!~)@`Zdrz?;b# zIYDeI!Mx?I7bKZ7Hb#$5UzD?gVF+-AVk539^v-N2zA`-i#*kl05Xn!Hzzq<}(9r3z72c$djZl4aKOCBlUqPC&djT+=ol@)w)u(GNIN z59XdKeX4Q3O5JrsaezU*XawA2PCXWw;`-5vM0RY?ov_17u3M5XqqklK&B?(u3ho%9IQoHOMsV<>8-hG4~<1c_XU_%!2pR2J6`ou#45 zax<6nZ0|dQuoEgh=jJ^}W{i^>MukZMq}hFlodGsi(KweXhMi}hlYaWNd8JrjA(%Bd zfVs#iLh;C&i?U0TofU0}^Rv}&r=-{tA*kq|&Vv<3v`w<1FWc(kMDh(AU&xeSy{UX* zKy^Vk90Xf&0=+Bnc-HIu*e=yrux?c{bh|8eareF$A z)Ig4X6s()n8y<1BtDM}|b85O^^hqiRNQA*RX0b?=F5!nxo z)=`gyl|c$$XR`6p8s5{ZQ*bsJhALe~5Op3k zHwuh#3F^5yY0h6{r9-{9FFfPrZ{;YFVRP_|b|Tn4whM_M=KrwrK04=QKC8AuaEi7A zKEH|^8X!~2M$@wskqceH6w8S_YApGw=)IIP1P(snHJ=c4xmYP42D!;}08s za@iQmttubi&XNB7hJ_jr?^@#uu+6Ux4^5n(uGq>ulH{&Jx;&EA8ELF18Wq>Ca1&#f z%BbSt?d;rug|;a$@N2!y*HDL6#@ajaa_u28U!AC`Omu{q7)4#L79fEN>))I6pXhvl zFwT(Lgu|Fk0<9QJf#m3C0g!T58C4bSslnG@B%6y4q5L>16u7nAxDzA;6!UYX*x^}t zQU;9W#veb{t2~tnwDh@d?N$U{$~8)ooK%;&N8?tUwa|tCSP1l#(_s_K)~EbEIzn#h z`?}HI*D^c88q1{xFZQTcCvlP+VUEvnvxAj@kB)*7X1uBDO^u90GHz%BW9BpXuL zO#Aqf=I($ajXwWbcG0Qnt#s*T4rUr!}w8Y?;Thblv5?hwH^)UDW;R5{vl)?4Fnag{SH#cdkg# z%B50aT-@NV%GD-bw@`>Ir^M3(hw8<`Yi^^?OAVt?j=GB&4E_ z?5hjZq5o(>jb&2w%GNJ(PyZhvF@#X)^ir|hsF(x1owy7!6k5rt0 z2<5D3+r*zArMeeP^IDFvNV4Hos?c~S?Gb}b$6@ADc1$w6kiaRfFdvY6((CVHIpc?> znz4eN4?r0!&t=xkb_=YuRueA=7n?vYwQ?>7vPjhDMK?q7n%k+KUHyEv5g@qJN;__upzKuOHU?m^``HcI&x4+YAj>f=b>mA z!eoNErB1w*Fi^@>_(4->Je@)Q@(-&MQ|0&hQHcAwSro?GWO2jWGSu4Y6l9Am!C-Yq+&-c%> zCY!agciq14SP6w=f803^R$g34j-~t0@n*_;t3%7bk33Whs8fYL(t;U=;bzLErYS4V zK=+;Y_@tYSry@Y+@eQ zBteu%W_synPZMK}`bMqfY_QTA`tGNj{oiV4MqQB0l&>;Bq|{uz=+!764Q*4}o~&ZG z5TWH;R;hgg$Z_1mPRBS}7^3!aloCC8Ujji(j`X&j>rIF|s%w$QU=GJ6h46+BoaleF zA~{bOr))#KhX$;80B#_8T@H%Rk}zdGTDQevNH_#Feyc!LMV? zBP`ItgmUPDYk$tY#Bhf=y6Yc+qT$gni{=mo8!XFm#iq0Bf{e7erh-AYU(se!%N6ni z{a0J>vwIM=6A}lrik~j%-*%clY-o za+cc)-@F?P>0O>d-d*Jgve`H1k}pm|Rd&lC$*!LXcugp3o{v=Yw;@BF>~FDYgwlP% zpEXmg@0)kRYwsfL{0*9O2}rtL%Urx3`1z2YsFt%p)wS8>$oFw-$HJ5>ZTVGZX;DT* z)!8lGqSDoqPmy&r{ZBXFN~sql&sd#$g9+rZ42dRCEtSNC*V zp7j1BiWdDmY}he|f<6f?6>T%{v@E!g7;k0&HfL^} z(l+iw3s7;v26tK%Vqa?%uow{r`0MggZQ@w=bqS;rZjY_buNcxt9n6Ozw@v%ae2bc- zx$^aUL4}e~!KKv_llqqNCpaPwYde*UGR<}W7lW3g`ymm&mJHFZ>D?V zDOXmlq#f_Fn1~2hdy9GeSZaNu-EG4NC%NHBet{P4dcEZbP7X2ed)knE1xu$6c6#H8 zoR^5)@BYCrN0)j9gL}vyXyIM!W)5bT>hy_>!0^v50yW4w&py?GsHkJ@=TcSn^^@Ex z$CB9rSM3Rw0<8JW#S1mj@5j9{tGB*;;+H<_XdxC@5|$_$H8{ai+Fwl*3VcUGeFKsw zG*tKOU>+jM;|D!wM51kjYOzo{kG+RJWnU0JP^9fayDG(|EcpQ`Z)&m0XxUpUY`NB- z3TL`~+?bleEKPGQv7O|s5q1g1 zF3CXhQc?|y@w-n87c=&vIn6V<0(_5l0R#>{XHKx2I6e(1V-QpU@bk>&&@`a6OXjc|HoWLUCO6 zadL;3)McC5?l(^$k{<#^*f&l*a=)Lou-!KjK61HQt{)!&Sg{LH3W|;!DTsLtD}y5m zPf_Pmc1d$qif7OTLv4cFeMedyYiBm2nqz^KGjXmTiGeD2*bR$X^IeW30>8q}Ybmf) z32APU14nb|Bx6d#?&e!puburU1MzU7?R_7sgFcw7PXieaAoxbNu*th5%x{%Yc5-H! z*O}A#^W|_w2TENNjwKH%tT`ahms>q{@t&-=o<3w7NhUXxNskW9)1;;Jb>+%3fQN8a z!0YrWRjnYQW1TBSLiR3m14}w3w$O;>J$gw+GW}MOk-%^Bn^HKstwJtA3e&b{vTQNA zQB|VxC>FX+SJNp#j-s9-Q62|>L{;k>4K&g-*qO1kI)2wi1mRD&0zZB2j^0YqCdp&c zu#94h=|B3&DYDx4ME#1HS&!K{KbCHMSGC}s5PhVf?b0$VNixe1$ zfuao=R2zx9*30>L>8#rVjQ8Blh5pPatZqcwW>`_$cKYumgS81%UYELPWL&Xp7T1k2 z#wKo7_+~nSn_$$9WgSh-Buw@F@HQfP!L*8evD#3M>txGxh)VIIJ(Uy#&MP~u9GQu?Xe z{!=yUYeri(Rq1$t%Y9W}M4u%=M{M9|IkfuY1b$%`FD6s6yT4BCTVBrWlq03V7}6Yp z0Eat;oKSD|77Bt0U%xJxAo4jAMz00~k^RUo+scK%%=>3Tg&)Yx>ZZtvm@6Ve4N?qa_+zx!Hc+r4yP{Ej~i#93#C zus|uvYF-UQ4ZuGwyt?=#4{Bx=Z@S($hCSl zpBuXpcAuou>w3xx)cfRyIy5TDmV7XOHya7#!w$5)R6|*G)rl`B8{3!ErIs^dDvpU) z`dM)?uNGHhTq<3KT4znXZibW`hd^@UVQ7mEp$yr9X|H5*#pyLCNIv-dRD3{G;(Tv7kv6{v(uP z7t?)SQ%#o*@3sIt?X@O%3WKD|sZQgt?Wf7ccqevRGftGu$R?%w#qUaJ&8Vq%6R}BA z0#$DC)bmdXLr)|y1;stt13!bWAAQip4}921BsfUlP8|ei!mVS~rfs!(l|PMpFNR=^ zV3a(d_u?Q&v#;5oz~1r3Mm9VY%VeTvJ_I=OWyrnOOKhAvom=N;gMKSGDX+b`KoY*x zlX0uL6=k)yeZ>*?tbFMlU9FPo{)x>F)0{-gQ3Bb0nf&~r(xd^TYU{>-15Yz(jL`5a z%)zlR9D-vX{P{w{5vOyphrh{pa~rR-I1c)v}HsD}bE00y-qci^UtTH62DK z>WH+>gPilRHTUmheJcI7oZXf13eBq6V|z_=H$S0Eg3Zp*%J*tFj~^hHw54$G=@mF zef{B97aBA$Ggk}z5vKV{;zQN0!-t{caMkO!gYp{*iNy0&NB;phQr(cRG+GY-FH0u^ z976XuHAhvI`4N~7kKQe4d5aL>_pDRJG6`>`Kz1F@r4${v%)osyTK#RVXrZ^+>n2=@ zjeI#YY(3HRCY?0V+a=6=Rn=d*Z+JD3#I3uONz-113H)uTGPCa15&oVkGXV5(`8p^M zj;X$Yrwj5{40H`r8J~P_)i2w$ZS!R5KnjUw^1ZCW;t2C%XQyoc#pfLsok~>s!T}2Q zj@VzzzpLyH&o0NX&$hE9R`e2p=-8f2vqYP}D~>=^fH%`0~1>vyYq zMLJtUUzR@9%^OL{uEFz+rV!BSMR5thY*Ct+gv5nJD!p*rE#fe81vUWS`x{5f3cxT_ zE`T35f1vb-QbxM4^=&$opoa-Cb8iKn0&mjYrCSy4#i7y_%<)mo2h&IETJvE+TW|CH zbjB0QugfK-&FG>#H|8n5fY!!R{;X=?z4ZJEDW{DfQtJ)eqZ#OPR~$vU7aWIK$xBq+ zt7OxceM<1Jj+?zg2gEg>E4v+QkUK`pk&hMLZg&C=APt-PSOv`ls+tQJ>bs<{+Ov+M zu@M?psPWUdR@8H7teVKu{#U6{Yks?%nfZA56za8teAS zPH%+0-#btgGbT>B$x+v*Ea6jU=(#ixI9ER)h#P$M0XfP)WWr`izSJ4^-cGBg)j~~H zp$fVc1;=6IGE4c87F{p7UP_!G=rbB>DSl4X*2_MrvCbbOkCnKD=(CcirGLPLwJ>EA#WskVOOkT`+dz~F}wP* zU&ggox&@i6=h0hd3lV~pCT;ikqoStC{A~V}+6=nw45Xawg!Of^p)B&f3NHM~9yw<( zU|z@%B}UWT*%Wk>Tb50DPzws9s)WDJKL88Y78ahG+O)p$(OFRdb5p|crCxn>zru^D z)1pBPBVYPzDl)dPs}C0YfWkUwqH}gqs1xMEpAFOymX+-S<%|kdwIl-f<5cqbJ?gWE ztPhMQgoG}IPf|A+zEa2F*($L#LoKCYjV0X48yY&&HV*PcL+tuH8@6R-nw<)hm-KVJ!O_-M(LZNz*-#3-CT5YOBQNlu%F={!kba)5RxsNdfm1 zukp$h1<0zkhE}SGga=sjf8i=mp`~Ox(`JWEGmj|x{q~ieJ(Yu*)g|dlLCfmW-l(LA zpL3OP=FWcyOEmG|FITzdko*?Y1S<%(<65Qs0l)3tN}?+U!xPF!DNm-J{hFJUGzlto8+b#47kvLk-b{2e07|=_{@d2eDs~JLg5sv`}Krq0n64sE! zAwHvLYX3`@rc*BpRD;yi7uEiLk!1@;cUQB{{pT+{frB22^}A@X;}{F%0=@1P%f|BP zi+2f&)@Q+we`bAVfYeis5jS7QB-fn?_=HV0GYSO&&mU-x5DQFkfE&Ri%^` z#j0k;PI_>Pq1maynjbRef?+%OHGOW<4sSt>-;&I*7#&-3I;mu2wA0TK7eqP*JOY92 zKH}3`E}o7?y?guzFy77b#(Dd^ai=hDL}lYpmDAbZHw{2W(cZ<8RHNew7APHC=O?>d z>xiFMz*0X2Ik0yZ>w7J);vzf#ou{VAr7>qC;U+90Z0i#=Uo0`R;V=7=RPomeO1Vec z`Dv)daxAf4_acr~1R3X%)VMp2)yE*Z7n71Re!?W{jWx4GfCKMgO^`paOEZybp=SBq zPNc6mJS9Q;^OkRb$))La(6~&%lrR1BM+7#~>6=8W%obA`Y4rCU0$K!S<&Zan;2R74 zm9QEqdIB-Ygej+gw}F^pUIFPOmUye#tYoaaVPOecey#l!k*tD%9D(LL*@1FpI1T8$ zL5(=82rz-iD6XGjc4Y+#jfTbj0L86}IvU*(b~XB=Y!sHU5l3r#4$Mn#+u{#QsB47h zU}GLXSHb~g5nOFkYO`#}4o#KejNX4{GkYnTro#c1rN%XRzL3IG)xM8X{> zFCx|@NFJ^)RU0r*?_3&w{imjIvkzVS{YTrfrkKqIqzu>v%Db-%g-ROJ3hyVE^@=J^ z+ibOnfjDg*FRarExRWmk$9K$W-Y-PI7g#;T%bvo!bo5+s(3Ba82u%sXS7J|%yjO4= zo-qlQ>7HjuRlfdl4#O8jQk$6!&=sVmSB%Z4k$XejOF$XfLzF@%!p`sHVH4t4zpc zr#@pGUqHIUv_NGWClPMow5Uh&u`LQQ4nl)(?3?%0N5#=4ani7el zP9$kFHz4D@r*arN$m)okTMWeOn8OE25l9QtyYxY4rCuCUd{oegv+4?Z=szon2v$WW z{!GS|TPEPqT8%=DQoR}^po}-SNeu_;$@v|Ef8F>n_^J?f+-wOD~ zX3#3k;eu_&kprCePV1CHnsCo0J@WG%-d3t8A-`Ym3rkU=s|LVQ=|Q> zWg3nh7Fv7f<5Jc!H%5VhN1N7OjwCgl^i%Via+*T3kg0(D)Pg;^#~6OU;Wl~K7!Paw zwvNGdAxo6+LGgD9;IePo56moJa_)?nBlwlIQ`@Sp2js=syuub7ii#yD$Ff&@W0!Yx zuQo4ZBD7iSIGx)CdB}!+p>zPzu<8P?>t#>Nhp|MPB#b{+4sxRyZXfN0F!hqDmc4(_ zTqZj=QhW}t#Oq}m1ZdWIOum*FprggjzI&BV zg9+C66u=mLl8VdP;^^+MddGH!!eotqU#p|-aa?Kq(`*vDeqhIX-{e3%0kPDi^ zp5SgUw~yzHAk!kS*$nzh-lt38V5&NtuI?k2&Te=&b zK0W_2J9i#6DQX;0Fi8Iu$cb69kw;_J?tYJpBP#R(uQJ1TxE@H?k`bz6f*?e)=b`i? zl{_;dGl_;so3nkjhUSI{r(F~UajpQ_y1Etz5x`?5N0n3b%B009D1j44*z)bS392jc zmXTXy+c$}v)D>LD8LNo{ZQX&}aD-#ML{OfR)Ln^N7EKCIQ6)M1llpCG&bUS8GZ+r8 zUVh-Zmc?ZZ4f>QuW;J&3@wSD11osqtG(tFX3Dy8x86(pmBGo@cf1ck%IX|dB!Ax`x z19%8vGpPl7Zof75wOOi42Gv$n>V}`^UCi>H7Slu-XAe6y^tpq7_7bhrCGu@p_dG8d zm@IsXws~Q{qj5#`X=}0evNr#oHG!P0ntI||_glA~EC*>b-ESvYAW&wmmXGmmgjACP zRy}HRmwDjh?qXC46KKpq{N$wK+THJ^ zoWr*Rc(T(<(>+OFNPv7JW}jeZ6>oUT3qLetQ}G(=HDRweDb$#^uRN?5VrVqQ3!Mg} zCN}V~wXJWIhs4I3BiUpLY9rl;Jm)qQLzF8@2`XAtA`b=vI+_?Z$i=Yk@I%@gIHt0wmPA0uzKie^$iX4L? z|CcDU91s7Q;|=9KQ9)nBGbk+x$Mdx8cS0@XVN9i5XAAY!m?;YI%f>Coi$boBwF5E= z!rwX&K`+5UK>{EHPyhe`2=V>@^yvllg#JG?l$Y4)Wwnz1KdR7cJkIM$#u?=QlPZG) zK?fw`bJolJZz{UTyD`=+EKqPiv@qy@RYTE0bFox1xU71Z!2eYP0AzxBueE@UJ)oZd zT|)+WMw1~2;S>%3PZ}K%z#jxC)L=|RqVfPj{wGZy*n|WIp^#Yt0CW+YLH~CRM}$wA zvm_j+B$|vLD8efT03iR5`FP6U?8HI(VnCq^kYEi|8Gwi_khT85x`Tp61n_xn5jLZd zkWc_4LmU7!4uSzV|0AM-J%6Bv^fC5oL3c56VEDkTSm5j+S(EaAM0yNVkQ}Qg0NgV~ z)gw=)D+Aop7D0){nMP=;j3roP{HhXs-s57!Sbjnmo=pqepga!tLh!9{fqYo7X!0E#US@*C40I2mboEKQ& zLRm<1FK9aq+&=&)L_#ocBrbvwupG!c0M$F7M3Vxqd@K$U9MJ!Rkrz%@_#fkGkd8VC z37aHT&Y2)0YCy&5yV{O z&;dv)fDm;ML_uUa64Zw*feZkG)Tju0003ENApjhbKqWWK8ye4Q6%VoQV}t=944OEI zsUprGGA7VE6p9qdE1MwUj>XH1=%N7r&xq<&hz9bZWOUf5JGg)%Wr<`t2p~uzxEC=Z zBEeDkP*b=cxr%yRY56H0D@@1 z&M*W30PIYn76t>5Ccym(oR`r+fngEQFyo9Cv{42Cz~n3$V01^KqEnY>KnF|@Ly^X) zd!c#jLJd{qltJayK^!s`ZehXnI0YaG&>q!&EB^63!brN~W|Yhcf4OgL0KnRqu3C8RQz zfb&5)+#F88P{`$6{37zifPXECKm79aYsc1d(%?mOm3rg3IWTxHj~T1%Dfu5@DO1`E zG~+tMGFGm6AQI+&Cq~;KV*d>_?M8QqZ1^UD%ZfKca~+N-CCT?E7Ys%HA%0cxY6?Z> z;wnn&G46rLb^`m`tUKWO2>(I)R|u;a&rjOBOE7mqCMRv_#|?dB4Sbn9PH~^I&0~xY zsCk)E?W}SnXsr2B2~)$OQ~Y9uS0vx1*D$!Qg2A9yrN@&GKh{9M?u_G>j>Pu7_4cKi zUwRQ1>ne4~uikeTXz%0oop4TfL1jN5Yvq6C6;1O{;C%ZDhk2?$g|aAm9S<3&YIioA zp%Jk=g~|#@afqO;x3Dm49gvYZPe>IFa#1I|+X;+^D0}?*R(!uNqTMMBWodUZyq zR&t&ynt2r=vZrkTk$RoY?^ubC!rOZuL9{=3-h{fv$-gxA@R^*?z5IEgqN>n0JmWfc zsN3#&PjxmJ?CF4|-I7xw02nntc=t&`Hl?^h$ZLIkE*48aG$@sb_LaH&hGh}?^q$FV z6l5AQ-K%ceB_mQOcO*6{`K3pu(I*%HR9yS`C1bv4fyj@3t1I=S7nxu!+P>gBwf$;o zM!husUr+UDkDTQJI6(n1Yp-+=ycl4l+<#+j6kXRIL|>eg45aYnXvKH3k(r?%al}CQ`SR zbTaVAh$u?RPe!iZ2r7AB2zrb>b8u6U9>Ta~e9U71JO63V&QF1h;|In+0PYS?)=eJ> zZ?J0dClB2#>yjC9vAHOf$~0uSXk>{ZhjQ2HyO7yi4F+fzwF;G@3=!S0F=a@#nRRK* zw4*}45sk9GJ~8BNYZFF2utB7%66ZZdl<(HD%fw{@?Zu<^Q-urxJjVJ&UXtw`GmuS8 z(3jWk{UzT!L-`;|4}TSk}%YJ zfUUxg?Td)#bYP=S3tXFvyq+$e3_;4ae%jm7N3Ui-(dx)O6YB?C$)j;B&53X0kCu^e6ssOYWys8R4}rR<=_H=K?!ZXw*@FAWy$g+mN124f7oX2J`p=Ht zr=s}rgzq1sYM>GoY%?D|Oy9lcd;DY;4t%9Tkb*|XyHC&%?r0KV#q^L71ID`Mi~0jR zcW@UDVNIE{$vP8AaL5ZR{s-`t64-G22MEGXLcqGWkB%d5y00k;z&<}=nKpelS8G>S zGgSGPL=ANbYrXg22hK8rbgeuL(T%RO!;mRzhTFcLuIS%@fDOPEB6+TfHaDx|-LEl5 z>ZtpVkpQ(kOHF*Yi)VLSjQX$`ll!BbVaQW1Hh;>amZR&3)L*()MoY#>&Gjv^WtqJ9Z5lh(zd^m zxiyQ;pAJKHt>12<^p*l+FQfD%*HF@CjqMu8SJgky&pXjPGWs8&F$%#>`o$F}c@4p!wX9Rz}!d96xRkw%5m4h9H+$A-|81SVOo_4t!9xE1y&tx=8Ir~2y)QVU?9 zC7tUsGUBkx-d$r>{R6aLzxXub&a&JDt`F&2Bbma#p_Au=azi4*_H%Uh$)%|l z8%x^$7`{AAD=TO(QLWPR`}>wV7VLOdFsh07Gikxkr=(UbK%<(9cy+ni-TJc51H_xH zW?MCHwoo-KqnC0CRUh(|I*i^H)JddPEBA>7%9oN2%4zMAA8NG4?<8DcsR7Ez+@`pn z!@%^xob2HZ-X4B$oHZ1d^$vN4@V40hE~p?)pS|zY(K$jD3PU2RgJZ}Om9uU`Wse8N zcF{vJ%G?Aa!v7lpb3ly0@5ST}1BnF~?@#?X&d(5x2d@TnJ2fI8jn2c6tl#2|q6IEIDzmcug02xFQ3XoD>Nl2>lfPM-y~oGHUn%tkNb^ zhYQ?XFbJJ5yZuIFASrYnzthA)Nh*|Lend~#JlN#*l<7S`;P2410jj)X_fn{|veJRl zw8xRbT6!6wv3f1(%mad<*fa}#%e`@Ad4c!}4#rgY?kkBDz?l>&6%i*YUD!4sA^czA z#t-g>fd@9@BLM-;`aWC6D2|pUQJ~S1{X8iIW!naRf36aH zQ4XvX_N(j7c@sK6JpuOdDeXRrqu{F#4F3SBDOFGC3I6zp@%TvX$4Q&{JWm42ay*h^ZzHkOqDeg1T(b{hTSyzs*Sh0B$Dj zoWUWnM!@KMI8`D{{U@X#nx^I8WT^vyHg=C)yYqxcCkcuIf*53;=NN6l-G@Ru4f!gM z7LlKhUY|_`0#1QQBW~gq`hNR4fm{NE+6+auG?%2ecu*8TK_dx-Cmb6oE~pRz@)X_#ugaA}K zq5#qrSLWlx?Kvp|6`iR&(|E1E{D(5DDsksqu1YXn@;xM@d2NCO@HDJoLeH%k%|~ql zio+VumyH6kLsqmnNGNoC@tznZfwR~_S{I?cBXdjP=D2kSBgkRexs9%pW{wP-vLy6A z&`}pA-gcSDqS9`Hh1mX%n85beu_978N#6+d6Z$|QQy18mjo|jB13O~9J@#G@ZdsTL zRGZN)2taS@M0$tFM<7nx*5mNtg9HOSdmZBSho6rPpd7R9;8=2Yh#pH%2=55t%mO+c zD)*B+;Tao+MgYBA`0Dk@F<69j06&frn-CCHaco>e&p|$dU3JRd)dh8nwSVej!buP4 ze~H9{E1m*g>Gn6hJoaRFk@EJ_yABbF)|v*elu?!%oDTQMZ9{G?CsXyyXKp1{iA-S; zSJKFk3PAt`Djcx+P8tHr>DHN@1Mkij6Io8)x}%P|4$vw|sz7!HTO}U!{{ZF&&J7qo z0{ZNuy$S?*VukphyTJPXfCvW?!7ES(h6HGhLAeSh3tZjb6`S2U9xJlvoZ1G(1Xt%7ZHiLHuKfYU6Qg z8UaIvXPa`ro({`}!51HcdKY25F$w69qJB^LHQe})6BAKE@OxetvieW}-JqZOcxr}x zK&lF+zdQ-T$29ezx_uu`R`J0B4~xhj&&kJiTVy+paf~`scyeu+##f|e9;) z5xY(EhjPd2Ei$wmO1WnxspL9PF3J;LJHaj%&|EC0L%W*sJW{u~WvT`rG~3C%{{Yei z9bkTnzVTLtbVGyOI&AlfNXYrOD8GL%@u>ZCsjsi%27l3AJDlnSL9d~ESm*pRD(Zs_ za-S)&{5%RZ^BWNsHzz}P=ZMOIVSbFxH7u^y$`*X`C&R;K@hT66qSsbg)Bz$KAQ=PW z{!^b34Pk%Z^C_Wvu_5gK&12Z@~1vRKZPC~LeNbSOLj@5| z3`CC9(0w%A?cq5Ij?I9%R0X!BPBkK!bYw8;swfw4C_CMd1MEE{8}{OZ^kHDlBt+iz z$GZ}TE4E&dD|d!Eg2@KIPp_~2BKNWoTOxZF^n}=N2AM;__C4{N7|kw$ zCNfZki1zSh0tBHDN+yaec-@AQW%ddHwo7_u6)zs&wCwZ#H&VcPWdevyQ0bhkFk&VQ zN^O8dUK}_S+hy;fp zR#gIly$lqd%5gui5jxjAy~F1F#8j&({DKC5oNzby1rCoJ3@^$fPy+~iAR^C( zQ|UOMRe{3cGE`QCJzaCScz~pn3}gtU?58jF>#cy!1qlchoSEu$$b1A*Ao?9cn@))| zzy(=sO|1T>;YStGkW#qgn8{1kBAw7_(^+F*OL2* z7ZUUdRY+k-5Drqm3Bj1ZRulAc+rvqAZ^ReV%;H=HLq0Y}KOy`70MTxvUi&bwSA&Yu z)C=}sB_>AkcQ7CoC0z$33qfEfzl3@=ty$oP2LKi)FGn9=un`GEzt}sN{3O!DPuXFO8^4SkE7Fx z%(laH-Rw)zounR0NmyLf&7+rV!AAc8Lz$e4Ts zkiHo^ViUp+_g@zQlm$rOnO6?O!+0KB)f-#bx}G0Awc_6kP!woe`Ex`t#x9fLqQN4d zMDo1Gq6L)V*IU9A-Bc=%$kFx4DBz$2FzpOc#9#;N4doCCCIKCr$%w!kY1JFxTjO{^ zLV#2&1QgZ-BnDE@LPXoVVU!3iMa<#8I$+&2D651~jM>hrC4Y+R!R1mDtp-@oz^XF4 z+J@}ZSF`XWIFoLMENu!Gz$_-jqJnwCP>sMEkS}_E$hQOy0E6SkoWu;<(vKkg2ds+D zmFYS+puHKw*z>TzK|j}IcZzyGSL5zg{WPRm}xs-<#z0AG=toS12k@R&Ogl_r|J(n4N>H6{!rNZue<5{gP>S__47 z>BE#9Y9*jcBz&F|iH5;CT`?izLvlQ48I?yaBe4(ruNbKE$CW8nM)1(N7YG{A7f9S=b-l# z==m&wliZ|^0X8LNQk;Ylr@+09PAsoRO=0uw2lh~~6yad*#))yEwK?KQV=u`8=y$GJ z#BrSsb_Kl(TsSLZQS9E3R?+pp9fo+;TNTmxeyuX5h%JZ!Cq27)T8Zf*jf8Wmk(*?oL{V z#MEn4P!%gzq!9>0vt0nA*gIY;Q`;oS_CE?2*Pn@`7WU}^afM>AIB)jkuX}J(34E>X9h}P zSE>bvYtU80j<%(Uyzs-NR-)m;5bUh2SVG5R9T^!0Og6L(2$X(HyqTq{D*Rr)s%SgF z$f%zYr77!!@O8%khIRh<0--8n{{Z9b7)YPNG&}9`0v(6f6aN4R@YFqa%tf$0?t?(A z3U`&1_9FzX15FLfTMh%r2s+$l6+$ScyFLLKC~$mU7RhiTV9vuK$2DgU+{1*e5(#0$ z*`u58JSqwnvMe6JX*kBc8iCR(885${5UNM#hw>vQEUrNeP%EZCMEZURaMYQwdE=<_ zNv^ksxR4S$M^20p_=fzRSm{qXsb%F!~4h&N2|GXeQujQUh$^1-M)c=-s;$ z$qB)6HE9SG7z&igc83Fd3LTfMOd;A~dDZwsV1vOwSkpLyEot9SP?NOdHX@9K`IG`F zqVO9+ibKyBD5JG*EN2gtYDp|T=sxe1{KIg=3l^B2_AZo^B0Kg}ffjuDO>ctSEun@bU28$rhpM|Pgl7}Cm;k`gwa;k=8Mak+WqoVjV zNMtB6R;Gcq38^BL81_-vH7e=ZgiZiu4$V%*6YvY*b0m9M+w?-IC%%DP+z>C{U*b2h zcn!+zyi#7b##rxxs&omREdXPv6X%3h6*XiFzPt_VW)X=Sf2&nJovYf!3ldJ;*JMc& z&bn5GR0nBjPP!ijRvg6zq`xnYhbY$(nqjFIAoZj(U%YwRJt9Wx$_L-Xn|{=E5SZz>T^38(Y>DD z6UTB8r*UV)S+~ArfHohY^#1_A4qn_-_x}K~cxLOCh7e*<9o+S4Q4n3!Uhi*v=<>!@ z(*j>5M?=3SAaqyITe^)e`Ec!|k7YyGtoeN4EY7VV9qWEBCtw8CP#}PXgW87_HA$m*=81uBB{J*kt7_p)HLn%Zh9A50tiN)-HmLv@@xV0o2b zu;xk-A=o`KwYiD;;y}%29{`8CH|u~i|+LjZqY$U2@JZ00@#)6QnTf!}GvM0T)7G<4^q|oJF57 z2tI&Nqc6OaxY$a}Ural^KE~MuExQQr{LVGuDBUJuEfBry6_?MkW(!{ey6^YcMCeQf z4W&!ik5)WdS_)2f`21@$H1OE`j6 za#~1hAl{EEStkzqeUY{4)Yp|xWuXh2Xb+o_7~)&gc4j_gIzAIe5#~?O;@sd&5F;^D ziEBXAIZ=ph#dwKyM@}6M; zg7`(C``xF|NI;cz>uh2Gk%Hkq9+D^Q`24U^-xl`A6k{qdq9U09CO+ z1pSA6RCJM0Pf?RX@sL<38xRceKj9JJzLs8~P-Ibc^1%eR(h1nlfM_VbUE^?RaJP2^ z3Y;Fm-bGqrI?$k6YY^Tp5QV5P1qC*i=gx4{8(Rj-iehyWW8V;TDhmoj=Icr8hzuhQR&1{;@76a zd+5Z`LD2r`x-bicbtci%7{)yEAF0(Y+|*I5ED6kRlPmlYu^bGimAd zps_z{lEfaa7oM^B|Dxg>y1*%5jknxvJ33IyIi zL7Rrg#av|7Lf?Vew4=p8Y>@C)pfv1n0-&f3zMh~j#u+CEVHCJj#*Ehda2FSfLzAom z`|-!6G!B74{r>=f<*Sp}DJ%3xeSTbn(Cpe$BpvBd_@sUe4!&mJEeg`gh(NAR57tsa9oO>nRkSUX|4@T_c%cX^4P=BEg2n|vO zTE}K+3fsePK#>wPC>Ys%D)OK-14_`M#fe4}l9~Z52p$A7gfF3*(xpUY2nvBfA3Prz z3liJ=3$*?537wCOhY2)p&v+E7a>Lbbev_<_o0NSjB4Kn;yg>eTG#y26UGmSAIG_YR z6uF!4e1b<{L@|SZeETB~0KiJJr?E@#*IXw=SUSdf&4#lD&JrR-9uUze^1VCeTXM-L z4vsk1Z5NjBF0E&8N_Ki!o666}bOA#CO31VUeVgy1(1Z{Ov!&E(WS?huq3-lF<5#Aw zTim%fHIDFRcEC|o02#z<&_K*@$N!IQ;jekS$A06v5!)3SCmb6qMIyIQH)VC965(f;!KDxV=- z!-IjV5L0C!=xLRTojzc3leI{WI-irubkpTu8b4^vCF%#Fi$=8MQ-Fa`0XqKK=&<5P zi5H*{5fjwQ05DRkG{{MVrdf5(WML~Fms>mgU$ydYo?z!n&$A!HC88HbOwtD?-D}f~ zJIX^c1XgzpJ9Nqmn(j`kWLEV?nZw9nP*kxMXaIWk59rm@Re>D*@9T(!>N4u=NLqPW zTA3Uy=hqcKueIYe5%_Md>3DmAlp0?~nmu6elr%QSRf@Ya#%D0fMP+;6gbe!riEf%0 z6kh^|><%NwGG%VUffujO1n5g)^fZ&#K(342$pQDw}?Edf<75vhj-3CBEi&2Gw0_ryhfES zGM?5F^ej7a(ddN&#f9=}@HtbNCm61sbajI5ClEg_Km~wyI2K& zgEf@k6?~fH;S5qHodiI*06ra*fk-HO@BDSnwcsQWqBx)1WLw9s6C#gdXWV0)SWCJ| z!1|9x8OW7P(ttE>#w((s$uy>PbP^c@nd=-bH7*2BVE7$Alq$58#l?9>0PLk`>EMhU z>kR=23o!5#T8kKluN4boca^9^NH~W7lE97!2%>6hLm^#BvPPC;03aD_aLAhol1$nKqS5I z^bY$JOcybt}wAYIQqK7F3RhHSs;Z$CBja2Z4aX&XWT2{{S}5G)mDh zV6dD5LhT(cM4;adEjs50MvSKR`beR-iBm%rN;m+xt&R((fz*?yVm3t0@0WK@RH7aI zJM3o*oCHMzy|EP4a1x7h^D2$7ugWHwY|iVG5JTu$ACUzIfjor8??82& zru|T-V3s=#f5(+Di>y_NQ)Ak8ISXjc2^N<|ED^I2L?VsOUfZduHB5NJj|)If()bbV zl?WCoj*4)*eR=oBg2~$r2&SGm%e?lM%v5ZYw}S?Dwcv)kDOF|KFo%vH3I{+?fJWa2 zd(j9otKWdye=v|+%o(zPJhKD&WV%_ossxchLp$NRnMLMtUtv6ZBOmox?VWYmX zey0M`f>8DiU!z|u$WV1&nqwyU{jspiNhw8$>v8bBlK%iZ>PM*-bfTjU4|A;@Uoo(L zrX$5+VxW0`mWlUV;kQi^l@Ze&xn9hdqR=tj;uwHGV zZPRNXcz|t+MFB8~+Y@~}uUNt2I~7tIyY%{WA7O|2b-=U|SzZTU0|(gNB%0H#=pVK% zDEY{Q7nGycLn@Lc-UHxL9PIMISA2Acvd~lP2u5{Lq#RC32IlUVC*v>68&)U0dUh;3 zboC?8L+t$?g6X{ws|5!bRu^~plz8#1Fj)kw=<)2mLCMl_!J+XQH{Kfp&_TCUEHksc z`#lhz|mw41G0`EZY$CvMHfcDRwZTdbIir!p}f-@?K zM`{Ly=>lOOmE-tPBxAfmrwE*uRZZ3JI!lepA27Bc-9B45o>zjX_4!sI()!9RE+!Qp zgR#HYgh>#T7MA;ipah<9U>>bk%UH~4hq7D*$4m$&mx}F0eN<^y1;7um<4Y~Qs@~C` zF!6f&uBwwUyBDV5=}%7h2WO&WuwKnjhS|}^RA>N(1!t*I%=e6{1rX0>th4O-?UmNIF6XQGOrKU4b-W|gXJ9l zT+?1ZVHfHo@SGx$Vhd0nfIi30Yo)SM0o6kSD#Mq;giwo00ScY(M+dgOqRHg%P&D&{ ztK@KbsbC?(LKSs_laKcERoSe0I*GApCL4zqfV0Dgd)$!f!k3|ZIMNP$^V zZtkTfFsg*E$B{lX^s(QjWn8s|p4B=Hlmg5^`XZK9l&$Ar^MMec-Yp}Efx|)C`YReQ z;MfDN7+{w<#MlP6!L`UjVJjc_P==Ui2*^VT1w=Z9a}g7OjI2j!hhh+aJRLXzLMm6g zB>}#2Jxnrrcj>-Vx!W z1fji;W4=(*Sc_#XLG&T9xdj|9T&LM74@hB0F$6EEe5#b*xGzYq#3!bb6LOW`;_!Y> zLdleB>AzrEIPNqtRewvQKA)F}%W6lq-qCg5z2H9$xI3s-+d-?rP$5LC(fQ#G*y1LX zaRKqeW!S_Qr+A;s%sH)av|RusdmlI*0i~o}2E#vGb}ES*L-#K)Xy6tCM|DPT7zQP! zkd_2-@$sM}85Lh?iYNtwd&H&I6r9%5sFnFR&Y#*60k>ckio&^b)$+{Wm>L*dqIevP z2(%86hqxRSac?9lc&vEk08SYCy+p58xwGZ(EC`4iP`5}C-)P<)qLF$beeC=)()HyS z95B6s2dHv*%S2$k6`C(}^3n+_eXvx?DZR`~xB~i+nMNq*dBc+{Mw)=c*7oZ0L8zNb zbrGFoT3Mp$w3g^=0AO{|(eep2-LZm!W_OdDVJ{X~FB*|?yQ^54xiFw!nlHpNh1Qk? z`b;3c;BKrCz6T~V+dW{xmx}21xPcV|(vbB|Y0n24FzIARav6A}#gF+cCvjDg`l%mG zVDzjEL>tiXt$v9feSHWkJ>}DOu@`6tA-gW( z@#WVGbKlSYp?E>4uElG;T}t~PpA|!fH%zc3d z_EuO{V)9p8gx@!+!rsyN;vp%pIlr(zME!=aK@qEU9anmH2)7n%2K=dU#=yKYqzPlx z7PsUqY!&ndI2uz3jRc6z^)xWM6$a4gaZFQsY4ioVyAX49SY1KjZ&8&M;3%(_u#WREI+(`+K zSn_g}zyuG;L>s3hs;4vnr0Hrs9$WQsferhw@MW%sxTjG*?<9yc03X_$&u?1_*oVPSHr^2nX=Q7#}Y=Jz+4~a!?%sry4cH zno~aLo{ICZ6jyP0tpVKn@^WX)bLKkFk(R`QAbkr6BZOVSh@6^8=>l2^hN=ecmh#go zk)V~7{2MZGv>Z0YYXQ{`C<(*23uSX-<}altW=#|&&SUnx0J+= zg7-vd`5}x|Bm|#j%<0Typ^HQqlwF4C&KfMpu@cB=6umN-}tNJ0nB5DlJ$hGFk_8}WH)*zA#A zeTUKXj|Ef984=uZX^2G5WS)f( zkOUw!xXX0!Op$NKMLx+jt40mJy0Xg()-3( zyc9KGqMr8$mRBJ5hW!AaBf_Z}L4pBn8LUG*3!`>lKdbf-eu z-)$WYP9hp+lo)#er^(yGd@seiHl;A+pE=a2=#=^(8(0KcM6wOwGuwY>4|^Kyx~4FA z^Xraw&S#qN*kdxEYIj79^r)16WgM4fMjK<)7#wWnK(JRa4&ns*GRz% z%76rfyOb)l(X90%0To#!iL2q~0MV=r#V@sd)5wAaZ86&=D-0iGQ`r=;mF zoN}&RvLEHaPV9R*VQJ*)kal~;XLUK*mS8^7;ClU(>32w{Vb>v)P*6dLxR~|m{{Uz* zMUw}EzvsTk!oGX0TrX@hVIGr!@sgDs09;uYNuqJ-BpM==jhQOyQA9|~u!0WB1GXbH zNPzeTo?}csXHb|hkRXLK#8ecW!4PUQVt3>{@zSWRCZH_`>StpFmQqeCR^SyYm za_Oao8}*LpR}Ae?9~PK!skLBRYu`NpsFqkg441wk?A0%^Dncfk4GO3r@eM~ttwrp+ zI8nPK-ku%q zfp!;9!Ojb49Ilj|Ir8w@u-9=w(G_J8cH%Z3;HiOLQC=x3%Ge@hPF=?37?a9za*5o} z_$l-)h|NCniRj0^76V36jM`MC_c1~Gy3-pYFX25$ zDDals=@9P-6Qae9<${o{)->@;jb(UGrHFJfpunblZgEV8@gUWSz$jQI(~++LH^)wb zXoqCGBDF&GpU?JS)B~DR zzoXlDucWrA?FC+xY^5l2uJK}z31n!^c%?kVv&4@_;W6Xku-sKcCx^Wn#Bczx`HVV$ zu_41b$Y=<~*r|5`n;j5YM6?g(&uyy+@L_TX)Fs90OTY#&`9LZvG^8ex5UL>x9Y6{K zeRj5Rvx-Ye0TZt0Ox_PmLRhhno1C@O2con-zP&fkiV-WmXB3@Zve62tMG1gP`00Y5|+w;ZbN)mJkN{9a<2J{OhSctBN%`>=uM5dI5;1~Ea7-NF#vNV4o)9>ID)B85d^_1=;E!BH=U zP^uvkDaC>4`J=`a2*x^i98Uf?;dq&V3NIT!0QHi?71jwtEgRXiJK%vk$N+=2zAGF= zL}8UvM<>Yq7}9gM&ZGDeW-tyKA~z&MAxLSb-Ukjaf@KhBW*2+1sDN{GqQ1JL`1+i^}v`N8gXi5XcE7c+OTM%*a5@H z6l2x)l+DB-%&u z#i0)Cf`%9iCO760rp7j{{{Tz%%FPVcVdj#WvWp^QC*m5ke_(<#XDZ$V=i|9 zc8}i%PK<)A4mF!B5L7DVqQxqpq>%+m1~3U-L1-L;ZoA~4Yb3eU6m3-~GVaH+|27v4`P>{6Iq1etELVY3H zV@SScu7rjWHbCxYj zyeZKIQYbD80ssjFTYV-vB%DJC_JL{6o&-#Th%Qd1OBc2aKAr(ap?YCZda|>)FGD}D z*@d9^q3IhvE+ye~P9MCpqEvUOP69;SRH&455HYxs;3{5G0)SW2LPa_r+@VN-H5QZE zfQ@b~2DKAo(yI}$cH~&8X-W;-j1R%XRMikqmnP|@dan;S*Z5`BIyY7At%Eus=<3+n zosx5PAOnm?L^C?hQ$s|4<^F*J1vqW3P#_fy0&A}I++-@ZNf6C(DJJG;2ztohWj}*} z@+bhxgYby<6XS{D1P~l>=^OCzla%z!E)|}Nr<3o8++}7Bzns5^k>8?Z7h@p!W7Nm8 z!u+K_k>aERf}%`29Shao7(0%Y*eyx~06RH!%)qbk7R-;(c?;w=t_%MFN}N)Nb&1q{ z@(ZXaC_xz%Q{$01vPnhp(fi=wu9#OF)Qjeyd#eY&Mi2i0Up!e#rLzOSslQi@OYDhB z4^crqkH-Z;iIxaa?JUVSLYfT`vH*g{9jCnZF$@&L7K7(N9AUdSuN6ZO4G^TH z2ddAGUNB-rV8KlRojePh#05S{$K^?^dj&F~gjUe`Pr@6%rh45%PcKlpkVkfFhM#lW4I-H`x0uy%Yx%hlu-ab}vheBO&Q6eDB zop88P)j)7+en4>7gY!G7s7kq|e4V$8ENbO?PonGDJaAIQ(0e~eJqBry7J}=G@NS3E zobk@)X)TOV3Jh&8F$$xy<90+MP-Bjm07q@<`6i!_pX?=AR3rogx~s;h*}=%f5ZppV zk%kfo&3}Ou;c_kqhwLTrf_W|t@&(fL4=jc_26RmjpvOoYNF3@Shrk#?+jZk~nj>hk zi_rIvXCPEA0DlN88E%m|A$3V@fom>=3ZT#nNo5jtGgWT3mHwh;h`xaPXbXQFaWHlr z?GI!tR%-DNZu$VQog*zO2eXik=){nCsIS`dIH|Q6AAMen#OqOCk{@OR^}s!dF%|Ra zJ$m7ghsqO4l#Kax;2t(kfUXLrDI0155_r82w~%&ui#c>DPL1V$&mz`W8>#mEj($AI zu7vP`@uAm;d&M-Wl-k?R=aV<7Y6L6m&d2J#ljDdVmjPI&c4QXx1W#NlBw()_b{emZ zH`v9Q~j*^yo`PIA};oiI<2T@8z@s)mW$C3-boZNq z=4(YqVtpMgH-uY*)D2gJI_j5+?BM}ji5PEBj~`^+m@>Vk+6s!IWOT0t3!oNvNEbQW zkU~XQ_V8*1LM>JM!23>$iHSSkMLu9m@81O4kTsQWK@;%vCO)xN3aASU^>dpV>q%J! z(V)M+ELvqz3W^~#Og=fTSttlahtisQ@^th%{{Y}SR|8%PKUo<;KE)(oc@>c%A#fh+ z^l#4;z9f9AA8>y>a^b_ug3xTLxOGc3iIW%_wm=|DdERM|Mv8`$w&E9Am*(O@>LopN z++G}^w@}pd7A1}`90vE5?QwOCa)Z2}bwNEgl*c#VM+3_}AJHm!aM@Cz58HXR>p&Bi8=_%!Exq-G9e_CD99#^0F~Yu-}q-7XXc*R!q z^;$fG+SFUit{*YfZ5OV>Ob%mdZe;CLfeKtNxGy&=R%0;<3`HZY8cA^8Y3FPDy_ z3spL+%?TKV0uY$7TOY?94wIQhKBn>^AP^0O?4Gan!2pPlNyiN)4HPPRZw-bF5sH0i z2KYP;Bd(4R`V!AhzOK7y-rUXKn@BZ^!M>I$WgPWKP#>2B={ z$x3JEfi-XdM@I_6@LbEile+Xm?{r{)syF@cgN-O8e$W&-e-tij@*`R^2y&qB2Uv4s=zRUZo=a}d9rDdp9)VAI?Ffu- z=!>F%gU$&L=mimmC{wP8jt>)50u=_j1v$yViiJHGPcXR8I(xt_eqeh)-$}jg1MB6zcYW)VmNa4NyN6GnJi7Y{L#~AN;FS8t zv+5kH{QAW##_Tp`h~^a&6LQfJFAuU6`A&5}u+r>%) zLx@q)Y3aEa1U95#rkK*##dPv*A_Y~$c$j7vu^09S6%DcQ5Q7eOkILJq1L4>>(I}wP z;-M-5YPti6r=_p>NMokWl{d)5PwYcd5D$cLIgoOO@gizo_78)AEg(^MXB`)$#?fpp z0I}{W`eOD8PA8$Ww$um77-r34`8e{upW3<~v{e(qRgx&iT3V<|a8@pD3DI~7uWPjl zTRD~pjKTy7-*5D&UIHX=5@1?;4@vz)!SDtgLeVGU$wwHaGPfgQo4XY~h@hJ5fax|} zLuU~RoWSc{xKtYUeW8~sIC-6xGXJMej^T_)E()M3K1MG9C z*-WoP?>MS7M_@$%0O0fJSqzy>RyzQFco6hry(AitC(L-p6XB_QyQ{A#az*N@*sMEd z`i{8^pavGYb=u$qzoA3v82VoMQdnggc0H<+e0TCZaF`3)qoj2`;^Dv3 zT%*v8e{nG^gdTwd_&=*IqZEOHvsBmbgu`|t?^s56Qux>})GpInCJbY0 zwZ|d?IoD7J4v>LvydkR(YJv!iF8s%qj^`^uQ?F5MX~k~3HWOY2VE#NgdbA%t7U=7x zCQ_nN6XA#+Y8PekgF5-*=D@k~c$?zhnKDrtwY#EYaFx z6+JzzIi^`d0K`%Bo*1)%RAhH;tmr|)j7sq+(Fg&A3|`rgsmtnZ3W7o@y5y{_f)2}& zQZx1V_!Ii11QmKgLCUM8z=!n3(`ligUy&PdBHj+>9E~xaeE$GON??@SAC-N)rkoU@ zH0MJ8Xl%}9=~K{m{{TJu;wGFWXs7V;-eZ>!flB>wu{6?Iu3(MpSvauFJ`)qz>Pnu0 zP9d*Dzu=#)1#c;fh1!{Vqd6yBJrh=-RQMG?9BUiP)^RP^r)KXWj&>!AU8Qeb{?!)0 zD2)5S&kx5Sz|3tI@irfRydS|)YT7*#vN_)_m1_nASG+CwClQ&}%IZ$2=g8j}g2>Ky z75-8FIdoD~ILB6wcKo+GI6e}AqQqq{2?bhb`TUS1q4^83x3E87yDq3Ft7&~x#GF8r>EzBcr;F*wyFq} znx9gRC(El3$w9_T!&FiE>gxDA_&SZA(u)4P^Wewq)P>+1EdsMt=bHP0gVs%?dpRg5iJ_2(Vm2~ zK{r8YY>hm)Nwf+A>UuTBQ3 zhJXY92ld8nOPQ5JIv>B?tUyj{0EU9Eh2Tpik1cup{{Ws)r{7c6*Vi)UX)VQJqX{id zUUbxSNU%M}-8`H&ZGkGF4`TyA?BN_dcHI?9%tZ%a@%95&nM{yzvrH0c*--;K`%` z$Rp4>w9fd-!eH9z?Hck1UKDyn;U}PDC!%}7VN|v0o+MosJ1;>o3d1x454qoL(&D2? z4b+=`U%po|0Idtq1)qZBCnV`CjO`=rV(s|i0?HsH4D>`#6Z*JgRnZ8Q6M7QvU+4-< z9hW;WqQ}hyJC&^fs*BiHT@rW6U`lEP9^j#0k5JUqRq-;UpxP(56)AP5%PU=qB&0jd9M#Nt%cqck2I(k|yD#Dv@AjU<{LpC4@ zN2q{+2tft*6`#-iTr9s_KrX=|WTYq#y14S}R&Ykh^^x+S@AMPVEC;8>ay}ef!PfD# z`ok4sUNxmF#ZT~$+02zvpdd_N*vRlAc3fybUjG1(qs3nC6kGABA#(6Bm?X(2CV~;e zkc$oIbpZEM^l?S7z-ntyDHnC?XCx?_(_soz4}dmaWXcMPp%0ah-!6(-yqLb5I}mno zSH#e;DBZu}`QxZMLI^i5WQ7!$j5E>BxS~c=Z>BtZg09-6zSXzyf-Bo-TwF(%{W%P% zszXv}4?L6SgBxkrO1~TYTx@nQW-3bbZ0#lBH!!S#Y8Z%Tezk(%8$?6io9{}tAxGT; zYTB|2&&Mk2oiYLR2)hyHam(c=>|9j@gj=b)c6M|rM$r1~m;GQynGZ!$=64 zm5NNGdgZ+WLiwZHYNhhqtNh$K^amNr2nMPQQ^#lk>W}Je;3Vk%Y5+Rsm;0DgS zAaOt@5Ab1OY9x*DOD33)!^Ac8B-k_?MDa$V-$!s90AniarOm0iMbnY0gw=ihuZJeI zsQZqF?`?j8_Vc!lr}O;08)t|^iZe<6{rh*nVs@HoYQA& z&HiE%lYp#pi4g~_3P~qNTu$y%CMbIyf(fTc51mVzO70AD2&_~(M{JTT`7R`*1t$Ud zF=AugBzb1+e!=t;@s02>@O5yEA1N8JX7f#1H^z^PLlgJ?lQ-FyiRboDheTdD2*$ew zxWG}N(|~iwDir$hD<`-L35yV=0_Z~y^|^z|Ye1mUcb0*-M3hhg01N`N*+3UO1OEUO zu0)iuSiyaql=~ch2aJt7;5nw;dNTt+f+tbFn*>@=Iu0(C*#N-@j+a3Ai0?-*=aTIw zK&pqY<-uT3elO@dCH2FI69JuLr~d$4PRj;-Gn6ZDK(DS>|K(LZ@DIb^Mbr`S~QF^A&*nESDs0FqB zGw-W;c1RZ8(X9z&x>4cg*hn`4fCD@@Pyu3~Q&TNHy2|mgghk#UcvZekWvgmN5P}Fw z&WTlc)=)VN6?k|N22zoLA!Xx)G7nj!WB_C|(aDp# z-gQn3jnJH|s?n%3(sz{RHM9h4=aM`N6mvdR{O=6WIG=*hWr~FD2)M|C9%x~7V~T-a zzSAKRKS6g&9&0<~JPpcq=YreLUXCk{5-&tUGNfMoMXp?{NH-22K@@BiLjM5EX6=$G{fs!?lrltro~!F$cqT57 zb4rUZLV`qtdy+~TPn4V@475@m`9=Cp84_YuADMbSxVpsP?jF;lO)u94g!Q<$*7G(J z2t|^m*q=tct3GNytZJb~PD5dpC_@=^HvWzdp`0|U;e+)!4E)g{S@1R5^l+}cp36X} zfK89Hl2Qe2sUKMw>chG{asL3U z`1d-IKC{b7TJ^#|5Aw&45@m{jP|;u6le{?uaHd-jACRwH){m?sMgWsLOp0~9F|w|u zU(LK&DGL%$VHAo$Sn|F}5*u#9E{KcuSQv;h8d8;gGwB4N7qH0uLYmMbt6U&}mw-Wb zC&(w9B{4GbQp{+P+;|0h#*rcv8b}NRylo0Bk#wvX7Y}%uHrY`3X9^Mt*7s>-5CASx zuZ<_f9!EAv?`GG155>To#(Lauf^ng|D;W}XjSUJ?wzNlqQ!AQ{7fcaK9^OrCBU-1l zU>(8laUPGJ0$orkV^;|{?pQ~nNBH5OYiQGjf_T$9PAgTEr0Aty*Llahc`6ZA)xST} z1~fPfrwZlfyW?v!SXc^643`p1fuKo)q+aCazN^PR4P>9LusNk(q3{_i(#YR5ly04w!RGWKMS2CVV-lTYBi{^HSncS<69t+;2$n--qBB6;Kqk`> z9Y2DHYGYx1vi*P}MN$WVg@4IiT=C$0j8BhS!W0ZT>FE09s;N*|Gb=>hnEB6Ml>(^; zLhW>^=OQ|+n__U%u1t5Eu=LjdJn6CraTa!X?i-@9}WQ! zLiW~VP)lE)6Dp7pNFNPepLhQ;?$(yL^7kV8RGIR5s+aAVN3DHXQNSo zJ{AYs`{ab%7y%EE?0l{=%qu`jcne9$NS{ei`uaLc%s75ghovFZhj^iYt%@a&L?~SQQ2zjY1cs5K^|nwaYAF1fVVZaRtkgT=r zL7;t2AL!yqY7ALB;GK6PPwY!(4aw-*71PBUDb1?tg8Sc(L*x$liPxrvkl(YUbqAd} z6)%F37zO(k;<@C3wlUo#bQLr>04OIEgVQeaV{1R=Rd1UgH0%-bRK6nB@`=UK1;gY) z9#(DC_~_L7Gvk5c&@o^(6CI#z94wToN64CS(-elZ)7sJV&8H5o6byqKo9_$gP*wbG zaFC&PqB~H#ZuloA6eo})uwqmvCo>*F5R}3IJPsuxwWwk6z4RdLjnT^xyLJZBgl=#z zDf7{g07TZ-$Z%bb#;8_n0nwY+1(m%`S$%RQtpMXC`w!drIaVyT5PoV)>yuZU3zDx@ zU&jC>#&UKh(0-g*q)Py|Ko*C|FDFzTkSQM<55I>RqUdEvekn4GNOI!_;5S1=hpQ?# zjVw!5$aV%h09|Dy2&ROwVK(RBD*8;C9vD;Ng%gCSDPT0<+y<$q-xF|JbmgL9SI4D} zG{XfA6NFADM-_zqAtD}=C1X~6gH;A#xFt*hHA}{ebzmm|D}N(vIlM8#F$lrfAiA6= z!w*1#{2Vu$GDc}c=`?T=fSegyiW;ce>g`Sj;k(-F#jD0D_FLvY1eKMyY9KTmbX-3|_`Z zMl4SGHHdky0o8y~DmYSKa9H%<8D5twYsO$WHdV&-eZ4BVx?q<3*dc<6M4UJTRn@A3 zM~j4B8b}W+p%fOT34wuB$TfdJ0^&X&q*V^7 zU!!lPhPy)qPNMg|_%_(eSs~ZDj?f%})eUML46vPeXg}pDc4~YD@+ThLaNw#XUXWoD z)yTYkD=3OaxP&KpU3eS5f%F#(LBEjb>zMAJq>N=@hK(lTAR;jzI6a&P*8b=EanlGT zN>lGA>BAHVoz$o7;iCkFs2}M5I4Y9C@DKRoaWmio714>_i1eI*kN|53Q$?ZjvXt1( zV&gg_nIz$QJM3g2`vdpRo=z1@A0%~!w~N*aF@2ZJ7X5tA03sF`00OIk4O}asz+@8P zpIrSX%Z4a}NFYbqXVe4JlgZP8eNUJ^{<*vGi9sI*--z#w%~(Y3PN0Fk7vq*?B8G5! zUf}xhvebkl7A#?X0G})c!(|}s0F?SnN-c%}aAcr_aaujOxg*g&WF&0UFP=xGEe5f+ zi6mj~vzamJj2K*fGe^X~b%X*{B#^3(8$uEKUL*wO@W6O8C35CUs4P)Vn2o6XawOcntt4N3R^03*T^h8k@FFg(t)h`PW!$fXr1 ztZU^QDswHWJ*EsjA;vF|k;_~>iN;v>RvpwLs{kMQwiBfB7CgYd`je1BjObdlhgL#!8Dq=WVXaCp(gjN9U!J(eOzjlQ{3 zp$^yn0LquLKZ=z>u9t&VKnkE9nPd7-=l(~LiJB1|I0vXFXo3Y;OvoL8LMxzheezf^ zXTi$nUe#f+ih2l@b<#;UiL5%|x}Y;f0tphhG>o#q0Q*FLd{6mCAA{yO^}=rnroGnS z`QVF&5|BcCoEOWNN)k_h#lUiEc-5a&Uz^16bI8v?XhU%-c$|?151~W%HhrHwJ(du2 zqUwL$$js@EG7VPl_vWfuky=Zs?#|Qk#jd16yFCnR_w$PmQ>GM+Zh_@BINN{+q=hxo z_*cBo%V7l(N(DDZ%M~*LwJ-_%=abdyXG&;Rz7v)_)KrPzLWG_dz6FW`359mCz~2OU zmQ3t+U<2X}Ux$U=siG}9x(%D@0 zha47s=)e`JS;XLrqEJtORup(lC6;zaRDt@@%eMNn5#U;{ohI;Y=BS!sDCGG+o(&N2 zY9SGuf8gX_I|tOiio7qLZW1&+_ncf%B1kpL5* z9>wf?{(x$V)d1iqB0ZWQiT#6CRj@3p;qvrzZ6(y%ORC=5mT4S9?A##f4X=2<)#Z{i z=V51cr*T~-G7O>&h}8)efD1Yev|HC~rYV`5pp0zqeo2N%EYwDxl?WWstG!(_rcBYv%le zdzCM(q->xPMTI?i%&Ffrq%?-0VB{>RBDSDqRc23~9_uks0v_sF^Sy8u`0_x{HV?)7 z;h#W;#S?a+^7)po&@3;amALos8za<{rLac6FN{?i<(`5jwWeu0?shXg!E(*3^6=fq zv1lA-t^9oQdwJNNMo_QS```!=QxQgXNc*vPk)wnnPJs{WBUe2rp6R&R4 z$e>#H-@X#s9ZC@EL0^DWL8G60xj- z?J-L^pmR!&k$0j`0mhG_I;A5`IE@d~?rDur}s8$javhq6%EdIiQRtG8tAt7$- zj-Hh~aMC5{jZe9X_U2`Nik+KTDfGl5+kNR8w@gC%Fx&k+)Ivl4?|^Es<}8ToH|K_j zN}9*@3@(90dmbfh%r}&-s6xFfg%(6I#6=!N_iFpV%?i>ahl2uV`S2_x*+O)YYWjgZ z`AR7(Jmw1<6QsAXXFgmjuu3nfl+$s398xlHu@(3LeLNLQ`$(~v zpc2c!IV>n~3R~l|^l%r>+gJ9rKC8onUOEb}$PJf0U|n&XyBK{u++$*UDICtSoHUH$AN zP;W}3)h_%;BPp5Q1?hqDU!FjS0t`&D$Qq;P$tc1BKk92)gAaJl;6G{|g3Y-V>WTJ9 z)~tUOP;!za;l7c94v@c?>4{)o(vr7CRv3Zxt{_#^Rms%FLgeYdCx9T>2Y?(A)i-){ zJ5WC#I16e*7)$kk`8haw(CRx1Ni(U%x&jnMr%jXYaCvS96@s9cSnK8B9O2PH4WxRt zuYxkr3@_QA)DL0`fK~>t3=jZ#}AXM*> zgqLcUiqR!K(Rr#h37 zJQ^&a&t#~bi2g&`U0UD`h_MX&2ZTU_5j1%)5{%k2$Mzc@6^2MFE$|A9&b1~9Li1+= zW<(>(h<>;wcUh=xG!4T?jE@})Xnw`};$%kBYvfBmUScCxZ6vHV04lu;#ZUkN(nz zK#G}O_$pF}Q2;O6a;ip|Xz8AgKW7|55;XWK75hV$O>G1VVXM*)md;QL6-2#K`5(TU zGN1_4Avdu~7F2q=Jxq&uDq}M?JV!iMB|HJ*2Z@#yd_ej}|3n2C3Zb zj0>>TG-$UU(4fyjucs1-mky8`YHzC?ji1yk^RzW7ZN+oDmG>|(w0H9^ER zq&K}L*xGTIbt-y1qtme21rexjWCoVi1jAI}!m(s^YMAZom_7=8VHu+Q{1D6U1sij= z4faQp)fh>zO;B{x-!4&;fsA|v{{Y=MP955^f0-YXg7}63h~JN&Cq4fF1&MNgXZYX; z0hDFQ&>ea>lg8WHJNpkG#Il8L(flre6MV_&-fmP$!d7 z!FPD?DgOZ270sg^I9FmCC||&qZhg5F#9-BjJ)rqM{8pY20*vVrp0&p@T}lN@s^!`) z_!3c~#8AxxxgVYs%cX!nEcsZo&J3VdZ~?r+U9FRaK6Nl;Pz%+kk3mv(vU|}5_z%`E ze^_?aN_^1+&OYTLEHpN6ABP;=m}SPD42GY+1r0+wlkzXo&dS7Ufusih(0uXlYpf`W z;t+TI@gIN=q7C?cSH1vp2P$#&R>QD(2DFz30k9-I@x#Ca;2IccSMEXqdqGVAvKSFX z1_Q77QS~5Dz!MLVTUx$AI02BLDmsF-%28%XNg`5Q?fx4kE>VkeE$Gu`^LP#gSXeCsGHkWiRAwP0*JM?6F-xbD!D9B zfeO4${K0TTS`ZdH5o7%d^`COcD^F0?!@g=tAsa`DGzA1*;*7w8qkukD5BCl?JlVy% zDCjmd@OH4*76Jl#~@xYA@dwD{~+p6vy9bB5^q^S%8-O2RMu%fbm22$HJJT z%*v3o(CJ<1;>Exbr*E^f;rif}{UT5kL=*3dEH9qik4`^)Hn$d_qwap{c08QWirq&J zg)HlU76)>KZY$CG@E&Xmfg=duR;bsw#Os(3Xqs!mW^!s<0MH%+BVVWbB!>ut2gt&Y z;pT%VF$Scc4Usft-WJh4n{`D;qg1c9py;-#4AKX5oz5C4LaZ1j2N38dPHh#5;|Vc} zr8*n<=*WQ(bTd`n-V1txA!0G#j>h}_lwleYw|PJgg9)OgC5of^hrGf0sU8v>(T&Q$b5?nl}8m}u?>1=GIbZ; zJi0<@ASXyg@%RVB)25>U$xte5cp~&GM`Ggt019V;kXHlF{1y28@ZbiNoKOyl*GQw^ z6=J90o+g(cOS6#yv*|Du=!>Rz!zN-yh=`O6^+ez3dRMCfHvLXF>n}o~Uz!m8aVWl| z#H>1-r28>XY$H%g4c?m+&YL((ooj0jL^|$4wlCZBaWi0nx9ZeTOjp)dEFTlpG`R z;Y3f@YLXxZ~K$uy zI7kks-oO+~OWX+Ys;`s;GX-AlQuSv|;J%t@h$P!@_DwLSLEu!KHrM7LkX{(DvCtln zaR7D2C&$$q`H_mo!7?c(K*<2lcMe0)p}fnGKEVQz-X4|%Z)FJ=?6Msx-AxCe0SKQT zeeZXJ71EC{C)ob!i*!c zL>M(?fS)%wJ_=Fk?v@0#k4w(jfDR21v4$T{9c9B*SrKy79U0BL_Em%!6f`iih&`8x z-nj<|r>8i+;pPiB%TmskM6E454FG%)Zz2yau=yaydk_Zmzb$Lw(O z!YqB@gWqd&-v*VLe5oiu)%@^z@`0HyA4Fjv*BKzJ+7s9Y6w+S?#=Fe%D}zD3A3SO4 z#VA6sLd%K#wQlcBSAZ+{8n&wE*pb3wS*@qYAmfmwa0uVh9DLdeS;`A_unCnS|kqW zVMpx7F?#?N1R6wXv|>YoI!v$wL8MfHKrIyvwS>em9oZOge}5aeU}6q@UmTQz6@s() z;wf!_ru=mk`gzUA{{UDT_7oq4_&DMfL0DFNxyBY^FMV2;s8c6?Eau(>=n+exuaTlH zNmR;oX<~f?&5(PUN}sV6f*p_iA1E|RflsAaemK}PQx&y9LM%UgANP@y!YCU?T>5d) z%%gBC7*zAYF)<*{Nh|a-^!|s=K%|J0)QSX&>&}2<*P*twQiR5K@b7@OW(!?K7$n)s z8zJklKwvg>I{6MLm7&s$LStYLzQOS51~Uaa3hqL^Nr4Ula1om7Gl06fl}>~BKVR6I zBaufWKMzUs_Iai#h)EpPLk6%E;v5uv2tn=s-vs`P3h;OJDXa!Si3-~e;F^8|4;&4I zyY2Yk%f$uG3Zz`K^}w(YL=-G2tbDH=x4;+@Cedo_M7+WaIKk3k?tk^*31JCajr40+ z?}K6rkyrvam;xQz#PG-i)i%_rIN5A|W06Rq@x)<;~B#vf*CFq0W=sEESi5%4VQ+R^by6*O{BHxWocsT;A zyl;qKJ)G)9SPhW$h@-(c4;2fPMQ3FD2WC{j(k4GDP5Zp>yhlY3@O(f^!f4MJktX(I z?MDUpFf(pY^%ec6plZzWc;`*w-S&*HA+7tf$<-M zjY!Y|isEpqjJT|Wq!yGRMc`2tMDL!&{5149S`*6a9|DN{$Hx};94_Si0Q)W>h1Vg5W0ODNcpe^rtNd~kh+sh2m!cVT#|^g%64t<-IsiU6e!pFZ%J#o+EJg(V zfYIZ$5TMV2aQw&d#qSE@JwAkb3b5ppH1cT@j7p^3+7>2VRuKw0=&c-ggXS3^;sS}3 zKJY{autPwqE`1ScUL`d=Q#Rt8y)Bc0m}?DStPH^;UW1YPIW(w#VvneHFzZVI^h*B# zv-=XH3e!tS(W=~-97jQ&VkSrm37wvm=RLOWh%0AF<}dU#dI*5D`$OCWsZ_|vQTQ7n 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%0A6FCOd%gjUpnyH_`i+2)^I0D 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

- of -

- - \ No newline at end of file diff --git a/test/testdata/chromium/html/header.html b/test/testdata/chromium/html/header.html deleted file mode 100644 index 213ec4fc..00000000 --- a/test/testdata/chromium/html/header.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/test/testdata/chromium/html/img.gif b/test/testdata/chromium/html/img.gif deleted file mode 100644 index 6b066b53edc654a8a3037f2ed5787607a67fea4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29685 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

p00D}zTu$KmEJRkzASh)(@K7-9wp~2 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

-%qte=8FS)zy{Z??EX)jmlqiI{9V1867- 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 I2?Naj58Q}%!2kdN diff --git a/test/testdata/chromium/html/index.html b/test/testdata/chromium/html/index.html deleted file mode 100644 index a19f166e..00000000 --- a/test/testdata/chromium/html/index.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - Gutenberg - - - -

- -
-

This paragraph uses the default font

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

- -

This paragraph uses a Google font

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

- -

This paragraph uses a local font

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
- -
-

This image is loaded from a URL

- -
- -
-

This paragraph appears if wait delay > 2 seconds or if expression window.globalVar === 'ready' returns true

- - -

This paragraph appears if the emulated media type is 'print'

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

- -

This paragraph appears if the emulated media type is 'screen'

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
- -
-

This paragraph appears if JavaScript is NOT disabled

- -
- -
-

/etc/passwd

- - -

\\localhost/etc/passwd

- -
- - - - - - - - - - - - \ No newline at end of file diff --git a/test/testdata/chromium/html/style.css b/test/testdata/chromium/html/style.css deleted file mode 100644 index a32c9a71..00000000 --- a/test/testdata/chromium/html/style.css +++ /dev/null @@ -1,29 +0,0 @@ -body { - font-family: Arial, Helvetica, sans-serif; -} - -.center { - text-align: center; -} - -.google-font { - font-family: 'Montserrat', sans-serif; -} - -@font-face { - font-family: 'Local'; - src: url('font.woff') format('woff'); - font-weight: normal; - font-style: normal; -} - -.local-font { - font-family: 'Local' -} - -@media print { - .page-break-after { - page-break-after: always; - } -} - diff --git a/test/testdata/chromium/markdown/defaultfont.md b/test/testdata/chromium/markdown/defaultfont.md deleted file mode 100644 index 14c83035..00000000 --- a/test/testdata/chromium/markdown/defaultfont.md +++ /dev/null @@ -1,3 +0,0 @@ -## This paragraph uses the default font and has been generated from a markdown file - -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \ No newline at end of file diff --git a/test/testdata/chromium/markdown/font.woff b/test/testdata/chromium/markdown/font.woff deleted file mode 100644 index ebd62d592e7ff4cfed3020332d996b90ff24dc8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12644 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 O(-;7vnZf`p2LC^-w-1v5 diff --git a/test/testdata/chromium/markdown/footer.html b/test/testdata/chromium/markdown/footer.html deleted file mode 100644 index c355f721..00000000 --- a/test/testdata/chromium/markdown/footer.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - -

- of -

- - \ No newline at end of file diff --git a/test/testdata/chromium/markdown/googlefont.md b/test/testdata/chromium/markdown/googlefont.md deleted file mode 100644 index d8dd4f23..00000000 --- a/test/testdata/chromium/markdown/googlefont.md +++ /dev/null @@ -1,3 +0,0 @@ -## This paragraph uses a Google font and has been generated from a markdown file - -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \ No newline at end of file diff --git a/test/testdata/chromium/markdown/header.html b/test/testdata/chromium/markdown/header.html deleted file mode 100644 index 213ec4fc..00000000 --- a/test/testdata/chromium/markdown/header.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/test/testdata/chromium/markdown/img.gif b/test/testdata/chromium/markdown/img.gif deleted file mode 100644 index 6b066b53edc654a8a3037f2ed5787607a67fea4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29685 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

p00D}zTu$KmEJRkzASh)(@K7-9wp~2 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

-%qte=8FS)zy{Z??EX)jmlqiI{9V1867- za{`K;Mx&l_eyF>03n*WEF8L9=g0$~ETy+y5VDx|pm?HgYX9Sn}{7wjHS&8%17$v2wA=3mW=%0?!vK{7G z#gQc`M@{ix`xS4!R2jLVUcfTw<>5?ckg$%alW(1+i&Ett8bz&oJ!50#Rs+7Zp{Bn#rm9#pw1=i^_apZl9z z1KMf8EH{94J%F_tSqdt`1<%L_)=BF)_1Jse*Rcd7Rtm|9 z`e)#nt%m92$RYjPb6QfM#eO}*E0UkaJ{?VWagYB-Z=aUco~fEReZ9yv8zv?~Ekhjx zV!xcx^}1T04Evv5>Pmq60k#sXRQlx#q-M>T@N*)Ii>D*O6SW{*a)FuaX8>#+F@{Ii z6SzTha{&N4fI*7JlXJx)u}8VE!3t@9&lok?0(j3~j;Wl%IU-XGX=Nblp?XMOQgN%% z6A}z*!p{&LQo3rramMdno?drICS3T&Qr>X@n_hZ#?dtTBTIs>XF)%Kdz|QZA09xC^qN`Jc3!g!GyPHQ5dAEAvu2V4s0{uKGjXeg~IZn8C-&MKa zo^NIf6*<4BJN{Z_Y;N^ELgngF2yfIc$ZBs0Ig!P0TGq)_9z*7DbmtWdgm~CTY|=<< zrG4*4oeNrKx>Z(GWlObLumFTh&bD8ViW@B{bZs^zTm5XI|d#)U3pSvt@p%gB;l0vmyc$uEY zz=>{;Y0V0Jc&x?3qor+H*NAs$l6ksvP^wC@Qm$6%L^FTYk8kgYQT*p=V*j&4wV983 zR#Y5xY0$huT%eYnrfF?e0CI0~8tYO^$_jR{UNO}t!^u5jb+V@PF&+nP6BuY`X zf7D-6WLbRxC11Md?{1ERL0UBBP_Z1|iqBIkgWKzIan>3^K&*MRM!CJ?|LPi9FY}fq z9u>c86_Bx0#~Mqa=BX^og;UXBJ~!O#fJ)KOGw@;|Hv-B3tW(HEdo zeMCpW!SdfVJ0x>b?Ta3#5J)pS{<*`Zxp-H;0Ka_%S;Jme#zp=I3S<$z>*0W4RWf zx;@Y3h_0E_qiP{yRnno#NM(1b;?*K~w|~ntn730+`eJQJ%*I+yO`Sp4%{u&u3{>zE z5%wc)6ju9wDby3hi&Gty^_-efvG~?*siDB>ud-~*D`Onmxo8wu?Nx?hH&T}@;N}Ga zOxt0zc(6Th^!@o)?G5+B1i{B9;j2Y~Q1gPM$!&Z2)t5TYEb_t*LN5kwtW_o~=UWn6 zMX%-a5AOCNZuQA(IA{xT?6jjOzBCzHALEn}q1ovx2#A8oNOtaG+mY3%6v6F3Shk>O{?3En=82JPW7&p#O=KXz$>C-u+R| zKx@5ISE|a;-t|*FJ{SgE8UXSNIAHzeTJo(w1j6+rKp4BT*iHQb)j9}-Q6TPRf>{o&Hwt3H`H zWn^*b1MLFGerA$?n#PbTxOrg|?&osx;f&2d1G=C5SbUEwOrbT_>XXxU%qhR>4=^3A67 zd^(o+?D)35eydY<|Kfyxe3v=hg_4fGoUh8R65X3IRmUY?ytw3xHE(#)Od~f*u0D`_ zdhI+|GRV`xP6@9 z5#g6<2MFG>NPx>d{DYb>pwUBcN9(5csCcG?42Lt0$6TQm1z)Cr9g8&jgHlt~AWA-1xNpyuG%Da+eCz1ntyR56+{tLqaQrD*!k@ z{n|I>Tl<|^Nn>z;Y)n(f$DK>@bHxiuWMw7pK(8Lw1*p>X&z3SxoT^o{*x|zycZNFP zas&snmO>5tDy@7jE7HiR!@N{MD{4h<%-(#Y(Ay*;Fn-JS+vt=39xaVuUF4D?2sueW z!-)*k-b-&64_A$GcJ_;_v1SY^w}BGWPY%3SCn@MVX=Xs+)hV)W=j%V7x#bCd{5pZC zJ6VibOot;)P1{CPA_T}}uF#5MGR3-xPUH0y`(+kYGI1;O~+4|YW` z{l`gDN9R_PN6$tO3kwB`G{nqduLOH(06T5~W|Ae$DOkAH8R+q6&s0%_W@!xV0s^}8 z#%Fuh9jc(|RcYcxzsM+BGnWf7aE&0nm;33w&&R71VDr9q!V6zAZ#`I6#qYGnk z5ov7|Wr4B0Q2e+zlm9$!Ou-+2iQ@FCoq(onc?=^@hr}W?F zTl@68OB`QZp}Yd5mD?kJO&Jk+=C6mzAy*bW7J0qM-pA&lum-jxMu3)OJ7&KoX%mrB zoSn{J^*HrC(1ho8OOv2fDLC_pdyN2sIjvg4Sc*qy=G&#^7F`=}`WKL%kGhz5ezJG{ zG^s-2#!OeQd?lID!7r946%Z>aW2^uXT8lCu1S96*GEYv-FRy|C8*Uwtz0Ln}P$#K| z17pNpD##clXlzL^2E~hyXO2&Pk4??zIeUNH%S`9&`#@VlXa=qsa5aJN!}w}aHz!+; zsMMcLz*m~&OsLac@SoiK6Y|CI<9@rAyR+l=E^zTna3*OuCJ@TM3bMMyU#nc~wvYIA zVL{7#$8(vvSUpZup1mU>u8BY>EIk&fI)(}^W zDuH|pR7LFXv5ecz2dv0g6ET{xF79NW+N=IfDHAawPYG=jnh9ss^~mV;*&#V5U>$s= z?~L>SFx)sL(idPrf1@K`FxmvL(wo3z!Mn!xF}uSBRgf!l&m=$R+g_kmxH2$(gnw&9 zec_2~<{9u3Q0Ne%y^#J|WNn=(7_sy?7+)yPHMy<{4ep+p^urf4Gg8T`zocoEtn3vX zr;*qOuQ?IZJ}ZA|@cCt?%Yabq8qdXDC)oU~J#02@l8|2nh3?G`5$U75bji?L7g{Dx z##uWX@>lekd6{N|LIXXHLs_6j2re`8EM~IJmFQY0c)8u#ru(Vw5WQb%>&svMhQ0}P z-0+p1-lMMZ?vWaiiw9zzmoLt{yvg*VEu+j9OBl6lBuQH~Hdv#sE)%8Cd+z+7tB%MbcchCw&^B ziiMJAPnQOM-XX^jLkd&?K%C-D@zoodL!nIN+_kYteD-f_ktE^qm#OI)53AHWE`+89 zi5=LpZMs+>48D>1$e5;O|2|(~EUTwBcfVYmT=eOF4&_kJqdmiq0zHi5cy#rZKc1nu z0&;VxKKNUEOk1{R>jr<5TUevWkg(_M0D+zeGOzCtf}SjYliAWf<}$|#si2-&cdZomu2P9BNz_%M7G)<5%@bylm0eOD^I+#pEOo_slYEG}7^$bm=?lc&-MF-0 zcFO&7FGfU#P@-cozUaPBcF80OJ1SlOV6%A7lR@3;6?b3I5ez9wNlCJHlq-yCpS43E zo+jrMgo^Z(jjK@J6ROhH+ESE5F`AlBIwdb4s7;<7zy^{aTLdpGn?4hTciR^|=)=@aq-@{lK8{K81b5vh0M zn0ZMzLz$HYFqtrLw2OT@6yty=I^ZQ=+rbi@dOwekE0Zb`X#B8jF=1f473+~9(43kB z-(B!vEwbw7y(l zP}B=Z(pnW?+!s6J{doNv@mt_I^peG;Q&41{m1z^Lk)Hh76>>3_(<*8C&ap`;5i|2b z!==Rv>dssrDs*sa0aQFi^x!b>X!&aRk(ng#@Ue|V4abWtXsGI>mP4`|25!xsd1OCD zhR`whp^!{4#6R=Kw@Et~vYg?5@qM*N(~!c@jn^-pbnZ_bPYqx7C1iY!z?||*V}g^X z(^~dP&c3suzN;#j4zPT_eh`uWz{2J$ea?7f-B`rjJC~ng??>iB<~*n6F%}R^`4!nK zQ`U^z;2=#<#@h#cN}a78DG2g=iQAa|025U`x;-QrIB`-Y2_YQqIjyq~sXHk5JH?M-Zk~ z?h>4_0_K#b7K`TUgRd^b<_!Z5z5je92_ga}8Ir~p7Ku)JTWB)I!L?*Th)U8F-TF*M z#;k0TDBdAs*0&{jD-Rt!=$(@@FCf%NbMZ3WusvCvrB4ZnX_A?xfw~|G^{)blbc6dN zQs8?jMKIZ92JNMYxSS*VNl&=n`>EW$B^M73bAz0NgG~its*4fvZ6NUi+4f)9xK`ko zfZ3M=#ul_H+A9`D)0^08Ui+KKiH9OdU*A~H9Lrj~l@J#s@q*2%KP{R24BI-caP>Uz zLKGnz3~4JApD|Z@u^U%)3OzLJc&DTJiUohu=UqMRj3D*9Hx(y#yF^Z7hppXcZG ze1FJE{1KXWM9NhQ}Wc*~e_8|BIAk{Ix$Yep|>;c0z69eE6q{x3&|oQ(fJL`YE29CYj~K7MbS?*`pL>ecJZSdnqzjqP8%KH+QZ*mQ4HGHpF2j!OoYTny zjptpi1KS5{hjr?w)NtBpnJ;!viJ)39k7QM56 z?{mYtPfRLRb$wmM^;)+;K?cjAj{{LGap#Rzhmz^N4B#QW!x zD?67E-(u{-Miv)$0d;Bm+L)1Ovu}p})?(n||!bgoVs*9%!YRLBR(tdEHwRk1y!$b)R{^enc1j zw+9D63iPU>)z-}&Hd9N6ujm#1xg*fKbPT6`l`?&2o7$-d$Brzl3j&A?c-HJV0eJi& zYmljt%wOqe0oI!YxLhA_yqgZ7giLUW^&krX@(-Fnv56=puw+uuU=v8VnFdw$d=NS8 zaMuKo*d%C4rru2bYXR!r4Y#-klcbb>iIx?FG&w{h6rj=48YC_Vx#$XXpZ(iv-kg>M z5`2(@3(UD=PZrk@Inp-!@!ebRgI{PDyWX0s%&xy`h1 z>iP1mBH1Kg_{s~;IVhmjVR*S{{s1Bng{_aMD-Nl&1lq>Mgck3YBkk2YTXk3xw#;~* zq8q@auZ2BH`=kYcGscD6ZTS)nW`aO8{UPs2XxoKeJ9~lu4uBFv+1}+4uHN_8EvBm0 zuSIWX87gF0Z1qC9#t_TbWKC$}&nGuzL+VxTK9F;>A8%xu#S}i`1f(OR$i3hmIeTWh z{%7~5&D;#$yiT>?edfT8(#s&4gKaM`aa3Vm^i=6Ktg-#xS~+d!$R=55;|L?HvEHOJ z%O&v^m%Qr;#=%PhWLA5p`I3pDuQteT|2nSVQdtzfHs`A9n5tBzR25J}BAmr;SjZ_#+`Sd;K7FlFWRoMz1BwB6b zUXqmK_@L>Dm_}SUgv(~Ic$Bob(n!O`2je1x(4SS%`KB}ZRrRd6zVXBLQ;y9QtHc>e zBdF_ZGW!IUcGZm?mwxI&7SCmd4F38nRHl^7Xp)nPTsWOt6-lK%(kSMh8%*}#h}K-m zvaFW}AF%T1g~5tPot9@eL&8#{;;2!TQI87qblkoYH?``r5owrc zf|2Tj|6NSYFrUe4D7%*=|VhpnJVPv z9&S-uOrEgMT2=(Fz6+?af4$|Zo zr;H};qGc{@3L2N|knglLCy4k6x-$%}-@4Q!kH4OKCaU`AP`#z+(a|K(B0iBw2yiO1uNe z2|n&4_-Zo_g_|b|SdDTE6JA`EnHgeQ=N1TOzZ36wPc9bd13Zj(&r?uYH}-a!Wx)d3 zQ7!@i7;8MWRifBtqeeb5uWY4}kQF7-Z?2AaxV_aTqe`|c_yPcX3@3JIcOSldr*rW26NJsn}^I-$7UpSIO%k*$%RACBr7Y0SJ=lyy9v{7v-$!YIR$we*5^N;`doukd%a|=7HdpO2 zp(i3({-dB0>q=Re{&2`9xFlkI2tExGG9DxrN_O!FM{!&UkZ(%ozfOo*!X$DF{`=Q! zS5XzcG%Kb!zHoj- z1v>6cmB`*3(sUXl6g(4^~2{ z$SO59_?y#Aqh8smYe#`;->qx&9cP`i;Mfc#b&V}d50jlFxtKo*%Gh_o2Pt;0zSkiM zGwNFm7Jj~l$PSoP*Ka9vpL4)PTp^<78dF-AYKv*l`fJ;Ok)ONHgncy{h#bdM*uemt z&Rg}mzrZQz>s;TNGhCf`yMbS*SSx z-6YiAcL^^~JHjj{0xVB7WUYtfc;;$&JadkS=|{V`Nnlykm!~giIq&!8QBJcQ_Djlr z!wMu9Hq?Bxaz!vhlh8KiDLgO z5UfxdtE|T$$_QyH`sN@e^rZ%+?1CHMqQ7As_FkVfbV!U;dI$32o{16%lI7Q|rW`*6 ziA6A!n4(pu@+6Z%-dCUNYtJ0CpWs&>uC=|1^Mtmv?eXWnTpKUJ8dSxHVz~9A6`Hk! zIln|Qm5Ic$Ahn6H_!<>W_!NR;xz{KCp~ON~b~^p?(Bm5tV{UaSHP$>vYXn3~f3YX@ zRizo9Ut+akl&omL9<4>8oGfrLceK9311|Q?UODM?=8FmDb)yf#`j$Rc3L>?4^Gd3= zZO73>+SB$@XiU(P(j;rbyw60Xw$iFWW?HPh4MZbwP%Ylkn(P60>`9TRmjz!|LCaGb zHzBBfyOlVR#ALg0rHe7}2fiu4rgp7Rc7ul)v#69!V zFWB?~{vN0=cZZB0Q>lx+(Dy^1|Vu47*R^p9A7B0%abpW;xT2wEGsutl$Rm#VX zvX$zGFF;tyiy{g^;i^HWH9W&4t&gp}!t1OG7COfSy1_O9vm_YNp~*AqSD=d#q&lov`&v6qC;&?3QZ$ zpgAj4zno`i9qBHIF{7vImypEsQi2tSE9atR9QraYu;`aJQ%aKk=c4uZ0I;4U<@HKc z2u=ulz}5lKWU?&lFwv5Y;@>%=aD}Q;U%GX|n(+)VgbaW^U`c2syL~^TpBnnteejsp zvvkFkdyAC~oDbb9BFuySj}aV~`C)u70o7|8+`O5+RjXF1bK8*RxM!{D-DEXP+=N#m zyK!jtMsn-cNzTV%2utY^&x?bLUZ>qc_ERlWm4pM#%a_NHXzda^6th=4m1x3Dvh@}olyEZryMR#?D|E9#h5gKnvid-JgBH7WB?yF0(9z_u zFbpeuPZe~}M!bJN{3s8@PB99q0_)Nwg2D2ZCNNkmNF|aZrxj+@Vyk zK=|K$+B+jhs1GV!XRE{o*&D8CWk7Ws32w7#kr9Lc>sd9;6J;x^=rj%-7LUoBtq>DZ!=VMW!vpu#?w2^Hr+eCW9Z%T=3HX@0b099!1rGr-a>q68ymR_M7&Gbvt{e)FMN~YimVII1uZGR@rSp&VYg?W>v|V zvFs|$q&qsk;muyJv|1HXjsz^?K3H~MUne`7Phws8U^)7lrsK|K>Q)W}^}My_Ae7b7 zHnH#sV-(wQmQ%7FrMOu(Hd-PSQZE zSs{(;V5V)RvK2C$_8j9|cLkfM!&y1W>1+LplDf+~?Oq!U8gPQ}uorGmwtyyj%x^Y=;%kNFiqzh%S#Q*CZv~)L_(h2|YV*M|QB6`xp;GgV zA7wbpfzktEJ2awIoY7g9 z7P8WX&1<4h!}K{5I*WL%5U&$jGUS9DP*o7OR`rEL)%-gzY$O2{h%qDY6=XYz`wH60 z7HRi#Pfe(3wy&L9B}<{ZYC?jYexN9`JnvR3&7u*JMI2@BgK7?4*eyBb%OK{%*$dvO zYlGLU>cvK@Ty;;)0tENnhPmoDLFsRJ_gqG{*6Fs zma7R>4WUI!TnfCS6&xwz)nS#L)}9#>i+MTjPrYAv9zCXOuFljEtHSmq8AQnduGgtD z7=OnwB;-NeY5o2aDpmpvooHR2oDSQfr!P9EM!pIYZzvcqY6VV6R_as9(&)eJ&=P#> zKfG6xHGeW*(KB0-w>l>jr#66@U)8B<(1jNuRM39BkR;Gm4gS%@5ltgQK2d9{3r0ZS zau7P+!Hzo+ntM)&Gv4~}{fA^}eMbh{=O>&RmX|;*>$E|W@e_FL< zAcUt6yR2=G5cP;E20Cnm8CGt~dk^?3{X>h=cc*(lRww87PrO;}dX$Uq6+Hn_%R9-7 z>|hsf2xt6?3-YCK3|PK*__ejHdDw;HTcPf3E7L~$#Q@kMbG4y=$+(so0DSQ$j|O%&uqt*T*lltaJLB2#(H^@-ijRJ5qme2;>2r@QP(~pJfW7ky$Kc8)s{MzRk01bm!13>+vB33EZtf@J?F4I@z9S)h$6XDobJy& zP4`EW6(#q|(q9!3o*eB^>h9M+f>JG)SEx1B)M1?f+drnzO+KhRF41pOIW=%n{!YSB zMEa>@{RiW!4f1M43+rIK@9GKaW^(_K-DZ^0?i^epv!plMq5Ghe^oy!A_?#8KmXSDN z=kA8$mA4T4MT$mV2|nBSen_&AWWgI$n#Z)=I9_}rn0G(bZnZJqypWW073pJLF(bLP zs($CKz{^?su`Rn!(X{6?pLN3@q>e0LGoaSCC(y^~lz4Eb6`&0SHMy*d&1T9@i3^{l zUPLE<9{Cy9%aFbNnTD7_!bdN7-YMPsf>#-WYYm^7*o8p4DL1Y51}CuZ>R7B-C`D`VL_ zxy`4-hM)CM`o(DtbhxfPGet3as&(duAK?$_X150);6blw{Yqu5i|pW5nIW@DBrRg? z>}|SKxhfVN*wV=^?C;R+O4oWIud>^(!+*+1jn2J2k%Znf*c$Z};p3JZQesw(N>yX%g>^$5%-sBQ0h^&(>C_;88#BG9Y9>s}ntQX$eMPevPS`8Of(GRO_h`l(Zn zIe)9U_fc7A{U@CaH$xS3eGQVgBG7BcEXiF1VL~R12yyiS^;>DDo%A$a`C&yPUc9Hy zAd(6RqnEeUluqd0Qwf@+Sy`&IFzQu#4+2i+81$quR^FYo8f6m7v~ zf7|W1`widTWHNU6^_kT;N70FdXB=CH1HHIk`*&j+p~-Q(Sm6ElogNWr?EB6d*->*; zPro231Sxd1Dtd>CwtR~OR8?rIG8KW|-#;G_@Y?}wCh;%7RRe&TfShlKM2Fc5e@}xF zgJly>{3TD=V(Z>Kwh7&$B60n*$B5uXWq0oTlLpY`$biW1t(z>HzZ~4=_e04Xwwjsg zC9px`Z2kQ#7o?y#N!$+si1z^IArfu8Bcg~~PR(GyzmtH?EsrEPK=;GknKWRY6B>Ra z5>)Jx0nbJOW6u!b&0wB_747HCy_-02;*A{;%|4~U@p_1<1*ss=LSPU{dV>jGt-Xr@rVG85K6vyIEh4X zadP~}&F*)9xh9V>*syjwobDoLqt_jH!stcwe;kHLi~%3O0(v(~nERAGgI7Hb8dYP{ zEP=$o>y|J8JF>mNPcL!E(_oX(nGOva!+>H$EM~8QmV>PFpa>|*!QrpQ^9pOzA+M{T zO^d4Dn>@RB!3US91_I*J-sE@n6!v=JrrJz;Z?XJwmfJI4Ep19n0R2uU+=3!t1rfwR z?^M8?Jl#_)4JG3vhB=CHXe~g=H4a*f9 zC3~2vXRacY@wdJ*5$ZG&LNNf#6Gn=U;ihD3{~lMVu67GpX?ij^VM(xhQJ=GOrgtSU>LKN?Xa6ck0$HIVmrsrYb$SVcC37@pg9>ChE9too|%|kxiyI}rKTtG@y>j(z^W4`D(;be=e+lx)EDs31_I-ZG;5KZTf zPm=v@@(ui>4C?;`lAk!I$jRw)8*~uTCIN4u0!;n$eoT?@c~2Ln^Om5}4AkiU1J$9( z6UYC+h(JmVzv0IPauBvl=ixd{r>Q>Oo&!v;7!)N|i-6;csJv26uRTa%Dbw8Z00H3_ z5dExllPtc<-d|VM?*h!+lyg7ySedLrpd8wU&4@`&)%xdbR@(T!ghFV`P$nnOkHRMc zt&BEWW;yUdXW)g#Nz9G~^5ZI0$`X`?z{}FDS2y4mIsAOJI&YuH5g^;~BBC{;UQR_y zDW(g!bHb&-P-~FPZFa2{HHPICv6)*V!7@U%re8nM<-?h?Frk*<)>o)Hg>tUa1zj-G zf-_p@o#sBIBrY9>E-H74k^%3|Nb)61NFMMh=;c5=67Pya+$S_i)dfE$83v5*A>qi` z0n#hCN)_U;NcUKFN+msm3?*u3GAV9*NXes5ClA}?dWE6xh#rjT^YdBPgDF8oURAxN z^8I=namu%n_GMcg^#BDy9-zFB`tHaqzrPJd08qNb)O<<JC(2Q6lGdQM zqt4z&JYLH5Eth|01hqS4l6ykXOUkw4bva1f=)i%47UV7-`#pj;@lM0!U!QIp{C+!X z1W4YG=Rcho+x}By%_2oV#XnA|F55UsGltLd;#fmk?KTUWw=^F(+0j^bUCfDgmzLftFQv zgHC#Vxsq?5zm}#O*y6}`E;>`C%@PL#V*mD`&2Ml2Zx<%+Dd2L1Gm6nEg=uKMQ4Zti zuWOQyqo>Yl1_x!>aE7M`n}%z~r}Ox`{v!|HLxq4N&GPQ6KdLQ2ZCZ=g&?mDbf|HBS zs-gCM3jVehqK`O!L4~5y%580cCz9Mkd3W@0sUgF(dttM+E4q16}zr$Ss_K8fQOU1k-5<=)%; z%|X1pU>9aHnV37WJshl73T)$##}U_yvZ%UNPPPKs-%EPXp0OFWk!2FLyieod7t#HatTp31 z_cwchRab$Q)<44wpbR!JYa2CmntPREouatg?X2HX#s&2v9tz5m#Y5+d95FATwyi$4 zL+(lK#vt+QC3-?wyw&5`y>lGCIe*qn>bL))|#Hh#*Emt#I3J-hLhOUwCVKTM1SbDExg- zuK(Ut@H|Rd`_lTyG@FFe1+zZev)fL$8Xa@A*4p=Vt--r-2peJDQFg0qCj2}*kate- zZJ(qy!|u1V`+8FF!8`aUD$K&#=chGU2#N!^onn7EGN5WyrKB)!3BTT}7MghWfB*%% z91@}%qOHZRPss#Fmhf_W2Ti?((EFg79TQ2|^%VSBCB4BMp`DUM7mSVP25+ zpRnyk^$-jEh!zlHw*bw|!!*&%UQ}JsmSjUW!m~ERWsQ@4x?q&A!c5{>+n1N;2GYIQ z0{8Pthyk4`Dgu#|Gp~unuOV6vO1&$igxvlc`5C`YM@3{zG!3d87+`Vg5@0`5J5i+6@~Btokz5E5xVh= z_wCBJ2}PB7$y3CTOR9SMEEwa9ovkk4dDocAI0J8qv=7sYxhsP2nfcb0GWYGw?ypFV zeHHFz;w?Q881%_~3Bnu^W>O2%bMZ(H;5394?e-^dgtKp#N~~60xf|wvnk#b|rF&G; z5^N-y;C-w=iEZDW(kDV)+7)&hQss+<0f;AC>SFfzmFlMTYGZE72PmH+5|0ZxeRlsh z{D%DoBc1wP^%U`@JptFnsEQmi&H>7OB`Ub)q`vM9|Jvr-Qxy0pBnd#XLI6d^D}_31 z<^2T|w!HC=R-_=Ih%Rn8jSxuRgns;?YEFV3EbS^bm7qVZC`geYQ4KLvhr zUu95InC6`jXpNGP^Z7u)yDK6qf^P!lT%tC?>M>% zL!OHJ7wZ$3mGsW`(|HA9JFVc8Yvp@`@n_-;GVr&3k`!H4VSngxoz{tZKhL5P)!)6d zZ=XB2w3@!pf}@gjW%o5MuS*0gAJhzlKnZJtj>KT09_SOkTOVT#u}Z40MCY@Dxi_A( z==hcmuR~GP$S!5e!!OPW794)$86znht=0%2t=$kw0)BBlBz~XqDVNWf&fg(*td?7M zc*UMmUBvRyy`Cc}L)BvIskT`;lLNu-7tO|VU`A$=NnWS?-A)>D9T+wLUXz(lt14Hx z8W~Bditd9?@8buB z#ZQKUaZpRWR>g6Nj*kaGL_>V2-U_dY7RX;BG%R3;&`rV3kexJN;FWm*JCCO;5b#=C(Ck#7<#-!J9nEzGvY>ikX zD-k~jnqqp;3Q+rbz6TG{s%3}}*{Ys<)nP0@nA8u|Yh2K$ua(Fj0Zt5r5Fsprij3~b zXA$K63#85i&nM-EaBm9i5iB=$ zw^|VLRD@<8T%bu@4iZg{U=1>GBm+ZCeXZt}#2KhQK7e1WAG$p&I~SVK3AOv*IQ)X8 z27eC>Zh76xdw>vTwG4~cMAaI{D!vTUysIQM7$bZCjNr942$%trq?)At3NOw&;T!kl zqmn^dQ^_%A#WGUBV^!+yf^$Qlq55U=}fX;pT;blRR|@@=JC{S6Xl~S zed72#Yv^@nauuXIgNu_SnwH1ZdL!P0&^HKPX$kEb;gWQ&;mN!Ltu;aaAt^P&zoXVN zWtGPef*;Q8aa;+1VTrr1^C&WSBqP?csZjFnQ>nb<;E#EB;Mrg)B(px8+w{^uZ z;6S0yO8Czi!5Qiy)N%RRUa9c>BRD}c=X<`YkA@+kX>6={s13@O3bW5Od)xe!P!F42 zLCgFv=nqUO)AoX{hR`2ZRh4ECkf*i`fP!T)s#&(AI@oN2GeA&wX^vbR$WCfXX|&Js zdJSEbmP#s9bn5RLd3VH`?&n$zy~3~XZqOqt=Q+wo)2U8fql?1daQOlNb>=@+zmh1I zHg)2!qyGtXt6Q{;m8f6N(8@yC1bkOWY8z!k{{6ec9K~ou5(K}&5Wj+aO{@mKzl6%9 z8k>k(W?<$sHsS9U;PxSmN_&DHXn;0!Y9PP(I}h%494VHf@sssW+N(-QvoAg7om9E`%kM11ZI+2VSME4r|6 zFK#`G<2vY;-qt-u|Mv9Lypv^VSi(A7p5kM;FK3eTU{Md}@)3Hu0PAfzG9*WoXX#y- zm5TdT-K1l8Jyq{SjKL0#e|epsXLaG@_GM#Pbl!@`G65!)w1}W6B@%AV{KAVi)asxl zwUmps=fx702A8>GOK{_pGgxn$+ft%>W-(3oLwarz)cgygWu{Rgyqd~YY9}`CyJ#ap z^4F2l*IG4wfNvL#q;IU+47S~Anhg!Ps}-LfdM5L%ISlTOyIwKxb0FBMVwD;$FdHY|vY}l6fCrIrYO+@q5F+1|y8wzQv$B_}(sPwgS!hXx=SpPM zAN~AX${HZvwIOYuU{+?JF*j}D-zK_9nNh($^;goH{vkaaNTpVwzw=<;mFE3G#fa7A z;G-=^3rNDc20~s8yA==XX=8y;(n0|WyB8l}hyz!);53jAZF6bW?dm4iUs4I(AQY`w zErdl$`?f=7Vx&$4s1H{92a3qsu)2^`7(UlUnyZ{FxfTUPJ-L45KU<`0TM2erF=uQ` zM$4lq_M|ca9wLfz`w^rvBjxqI6r6}QTIz{5lB)g+A2mJ559l&`m9N;e_t{|33o3A> zb4BXYs`?oMbRm@UKd8dx;KLz$x{UoJtpWVXJrtsbs#UBH6O>1VUgU#_3ug3wIY>`f zlJ0zD78c8(T5Bw&<^q86cSYhhx4=en>_Rd{*b&7iGQjI>RlfS7yl$RdlP`_ja zY~J^W;?633XG>J<>_XXZpmeHJ)%50AUdlL3S)Hm7v-0r#khGL^B8njVZ+XmQeffBP zXfG2B)Nd3P!++ZR?~0&S0$1x>hgJorgSpCzJ{VXzdnkt*J>o`)%lxcUO=yaLDa&8H zxu+y>LLnq;5`O-ib80}*PwJPAyVCa=f^YWB5RXlVa&5XiFqc8n&*B%C`m-dGkYDjm z|Mk`Jw=`e4b>%5tqr>rkBbO-q1m2H6=~PD$u{St_-8V)P9A3G_<}J z&?}pAJxk;GyTJl8Ko`8H>3wT`#f`s>z|GXJD{l4F8mAiHPBmiz?HcLMLXr~CV<~Lx zJZ5O=SjJ!EX??4+pYTm$&kzkN?{D^9IY2BA7pjHI2!N%JJS+zS@(OJJ?zuPFjEE#U zMv=QEr=QLZdo%$O|7SD8Q5Z-8c2luJnMBoc5n%oI=$9YT_I0*hIUD*ZT?uDDzgzO- z!U5?X+fRQphHEF&)#DNh7^}w^2mpo`5p;&SbiG9GL#pxy;jL)f%~7Z~P?s+KlCE2` zdeh8pUjmflI#tl{Tn$j)n<4pe>!O5 zw%UMKC`Uc0D|3Kz0lpd1S?PITHZE+Wm_JZEVSQXotC{^PjhI%na7u7y^5Yi={c{(o zN;-c>f%jy6{U|^PC#FiVGBO=n*Er`pWQ2y{>4pD*&{ggU-`6em5%@dGHBtYhIt0!Y zymtf|QVCGFx;4G#1cqd^wK&2VfgLWAGl68B`Qo5OlYT@-kN&An1FgMBc_`w2tyd!= zL?^$YDm}n_rW(Zc>uDJPszU(QB1dVuOFyTSirb!}6m-@!;`UV>+NQ!}EeyBB`>$YW zG1bix$xpR6SDC9F3e5ZaZ!W%e$MXJzOEkU=R)hlaxMh6R(Sc@=7U8XXPP!TRAV|0# zdRBd`U~n-e*Rk?o877^!4xP}1c1md_^BV6w|lURCPqVlaVX>f+G4;z06O~f*cp5${mj^OsJ_cr;3d}d72mqX)Euy63_VtjR7GP7W(eHeIsaMz92KBtb;h+1t_nk&pSWEQa*J+?6>Kh} zs~TtPF&*Or_W}mVcX;H)H)iZJe|E9-y5s|aPkFG9;&G-QpM}Yun#H<52&yXdy z^QF4q34Cxr%P=DD`^AAtxG*8sF+1~FYp_@A#+~|0se9LRKR-#VMqXjsz5DKV=xf%P zo*I%ZA0mMU9~T6GZ8LTklgx(hS>v3HMgN*3D$0I`yZrq}$SQ===QaZb5C5-{*cfoz zuTvzFudMHuJ`oZkg|ogtMH0uZ@k@o(%GJGMhZRUEPGN4R*eBQ;!Iulak0=Wn{C=v| zD~(f8Yx7L}DKzh!oKjq_rtHd)19&D$aB00_wETev!x{58wB;)fylQvPKFmVzuDyWL z)wh$@O{U)=W=%gOyXlyMq#Io1eI%KSbU*YNJ}9!$KKi1ydMGtam65c*?#4+<68Hb= zdypBMol-!eG{1yo}=EInL z-Y|i>EUPcLm2KYg7F#BRBPrc?GlKL!b>cdxY@=mN9G5?f{I%JlnYk z=(p?bYXijd+eGCNje4l6j6VgTLqsPFOSi7$nuF=Fe7SLpxl}-Nw)W7$E1oMKu0|5a z%WWc5ctv-@y#v&gd-B~`?v;lR6`peI0aARQmRY4Vw<(6WbHKITGxuMCBmI5GFKBiHwb_%?bF^U_$$!Ydt2ka5ADOyGa&` zVTEbD=-LgWq$2>EwKv0t=9&?`fHX4g?&8**XI6f)r%oblrWcag{|BcgB|w#$59Uo+ zN$B7Wb#42N+Kww-UU34lIhW%xC;tm^ zs`#-_6Mq2GyZ*(fq-VgAAuwT-_nV|wXTi|Z&R-C`-L5z6OQM*eAro#lzV-i5({Rb& zToU`{cx+ru_gQOe%e|uR{Iecy+pf~f($Bv@Ph9=-upm`H;-z9E%vav~79R*c1n I2?Naj58Q}%!2kdN diff --git a/test/testdata/chromium/markdown/index.html b/test/testdata/chromium/markdown/index.html deleted file mode 100644 index faa522db..00000000 --- a/test/testdata/chromium/markdown/index.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - Gutenberg - - -

- -
- {{ toHTML "defaultfont.md" }} - -
- {{ toHTML "googlefont.md" }} -
- -
- {{ toHTML "localfont.md" }} -
-
- -
- {{ toHTML "table.md" }} - -

HTML from previous table

- -
- - \ No newline at end of file diff --git a/test/testdata/chromium/markdown/localfont.md b/test/testdata/chromium/markdown/localfont.md deleted file mode 100644 index c0aac6f3..00000000 --- a/test/testdata/chromium/markdown/localfont.md +++ /dev/null @@ -1,3 +0,0 @@ -## This paragraph uses a local font and has been generated from a markdown file - -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \ No newline at end of file diff --git a/test/testdata/chromium/markdown/style.css b/test/testdata/chromium/markdown/style.css deleted file mode 100644 index e937998f..00000000 --- a/test/testdata/chromium/markdown/style.css +++ /dev/null @@ -1,28 +0,0 @@ -body { - font-family: Arial, Helvetica, sans-serif; -} - -.center { - text-align: center; -} - -.google-font { - font-family: 'Montserrat', sans-serif; -} - -@font-face { - font-family: 'Local'; - src: url('font.woff') format('woff'); - font-weight: normal; - font-style: normal; -} - -.local-font { - font-family: 'Local' -} - -@media print { - .page-break-after { - page-break-after: always; - } -} \ No newline at end of file diff --git a/test/testdata/chromium/markdown/table.md b/test/testdata/chromium/markdown/table.md deleted file mode 100644 index 057f69b3..00000000 --- a/test/testdata/chromium/markdown/table.md +++ /dev/null @@ -1,7 +0,0 @@ -## 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 | \ No newline at end of file diff --git a/test/testdata/libreoffice/document.docx b/test/testdata/libreoffice/document.docx deleted file mode 100644 index e745b3e5ec71e96fa1c3a306a63fff8f0237dae5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91571 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 diff --git a/test/testdata/libreoffice/protected.docx b/test/testdata/libreoffice/protected.docx deleted file mode 100644 index 840d00d5632f950382b3403b8104d31174f62714..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 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 diff --git a/test/testdata/pdfengines/sample1.pdf b/test/testdata/pdfengines/sample1.pdf deleted file mode 100644 index 0a0b284fabbf8819a1b88185dea5fba64f7e3e34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208299 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�*vR@PW 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%0AF<}dU#dI*5D`$OCWsZ_|vQTQ7n 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%0A6FCOd%gjUpnyH_`i+2)^I0D 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 GQU4DG17s5b diff --git a/test/testdata/pdfengines/sample2.pdf b/test/testdata/pdfengines/sample2.pdf deleted file mode 100644 index 0a0b284fabbf8819a1b88185dea5fba64f7e3e34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208299 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�*vR@PW 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%0AF<}dU#dI*5D`$OCWsZ_|vQTQ7n zhyM5g00aZh0cO+&8BVXyAdkrWC=aXrJ@G7wA5e?A(Y}06EndJkFJnt^NIS>knq)In zA$w&J?-PbDkDLM2fSaB@a7+$~co>34NO&Awl;Dk4bgc)m5oR=-q<~74?CcNM9E_=u zw0MK^A@}_@WSF{K5QMp~_mSYd2@NtT_|f^|7zIK_L1JT_c<-00N-9*uqLg=aCLHT& zSFnY`0zO>M;!J~7DMPJTy~ppJ`H8@iG=n~8Iti190(E=+etBG=)~w$U--hL(?Nrzlw+9!Zci&)c*hj`Ho#$IjI-+D&?!zBtdk7DRVn`6-{0!8tDY+ zW~gxhq#UM6p@BdM5I^B^=qO?(3|1y&Hq(*N!$<%i42GAlo-h;v2m+DS>0$Emuo(mW zT`%yw0RuueeV;ek!TX9U{0O7@;x%Y6h;|*fK=_N!x4xaBlfl7AgZc9!|hS$mqHx1J`Q{)toDUaHc}M zM!rfPC8_#{^Zklq`wfV^4wD_7@`9aYM*^Q4sAqi#QX0{KESu&k1ownZr1%H=2;en%$6Dwyh4(mf5%-w6C|2wI-P1!P#4q#@^<$`Pl9h*^qeMVEUcYEPK@5h z@ZqPS8$nglnF;xL?E#S}L}d7Hyc(p;VV%B1;haB%1~XZ{QJ!&Bc$x?o{{X)5m6Npq zBP|ZFAi>oJUDX^kEYeU|w>at?1qLfSkpBRDwIOK=uCGF^yajC%3iLi=;zUuPk-rCH zc#Rb@1`u*IJtNntLXnz$az3GZ2!2QWxMReD0fl~5Tk<>QDy~x&PtzWB@f3r=eJ|ed zEW!;;uZ&Dq{LrYy5{t4KP}TxeZxqMqJOb}PEIgBiJa8bl53>G0JQFGN9_1YhPcIuJ z+XfEr8lU&@I{+6)iTNiR#Y4DN1hn;sDMEs-8c@7=+Hf?UJ;njX7HV5kr z7v<_5I=AL4tLW0N&3Hy5`jP-qdlx1Ft1LzOf#|^^Qe#b*`Zyx;`fL1!`B3)ph_<&k zu@#LdR9xXESz%olRsg;U@Pu1#i9)J}ZvC9UHURhqX=P79(3^5d<_5gvL9la1A<>MA zgrlUNXUU#2sD_1hIH`?8esw> zEi6(%oxDK>0@R3`SyGr%@iiwch!@#t>_M!Pr=?C;)E0cJyxs4E*Y*%dxb(BCdc$}~ zh%B((>?mH~uL1#Ns}>V38Y*IHCTR;j$*e;A`|xD(wjv^(DIUh@)}B9URD_n%ugKmb zzYn}5?VaJmd86|AxXXrX#L2sX8mWRfot$ApMpN@|@ZkzJ4L@$Da#M*m5N?eIS43?& z9J(w8gd`LI(C}UgS4hGDDTow{!0d9bNHMGxpAPGJ&CwV;MB4ZP{TcG$T?Cq^w`d+-hnCce))ey6cp<&> z-wJSfy=srk`VORf*a*1z{(kDK03j?7dJ|vTaSh*!ssly@fp46MKM0BR{f2y=rAsb= za5V-5p5gT49P!X5(Jom z(6glMPxPGfntCt~(ii^#E(c1tv}}>=ugY+?y$c$NWXbz^I3b476QS`#c)_icNG$4q zv+ILgXY#>*3cMM}!L~ofe}MSo4G=~QB$S4_oMgYGH$;91&*zjPgYRYOWV$~ZoLUi= z2|!#0YM~u3RiC~^gT(aabjd6Qe=pYt{745_UrkrFRD|c3`NG3zYoBi&tG(g_1HMK4 z@Frh73(`_AY+L*mfWnW^f9`QeHCbjYx@>p8NQ|KftM;ze87J;8n{d*SE^ zgGchmr|gJ4Vve;UjZae!o1K8soJmi>lp2_+@^R^IawPjBq+EA;V^vE8xN5XvJ65#W|1c(p$Kr@zO3zK2c zW4{{w@Gguz!=V8W+hOMx{Xr7dgI%pU>W)2jKhPi_2l@V(004#Y{{SClIY_9^QsGv( z829fQYA{{&sS`{(ZQ%nj6g~p$ll{0o5SaeW%5aKUDwnjK7}!bDauq~m8X!ys2`5R> zsM83b^hl2I^)c&&0i?~H3!uq|x9eI48i7aT zmgL(`$i$loCimi;dkaT_(SAlBUoQ>v8E6lE4DYL#tz@==JnerxL%;)Ca`m$Jg2TH*&3>hWsg|Djv9GmYk?GjCw&<4DMkBWD#})LA1;OVPD+{= zNs;dG1a-nRhL{#QGp@%qcV`$92?hN3l4*ehppqknx4hWDJs@LJgoj_tmO%w0;4d>1 zi4c1WXKnTHBepD+?W=xVbU4XD3hK*9;|IPxXM(ZB`Z2|vO~@T@hM4_vpYJgL0K{=> zqzfcDIy~Q#gwv`*gGy*Lb)s^8AVBlAE&zQ6Lp1N4oR0 ztY0%p5AYuN+D0?+wb}2M;n7!EP+>reF$I=s#wIP%(&FI@iVo^u`!FyP)qn?R?ck9ftZq@MV@5<d~m_LuV7$hP_KsVsO9JX**#O=*#j6M0r_=SWq ziw)_0H-HwZkO)RO$-CEc#nC?^2vfLq-`^E80XQE{&^AzO!GX47$~__@CkkrCEykae z@Es}S_g4f_5 z!{?Qbh$J7AVZSejf@64**nVH$zZ^O{#R_VAK=|435`}|{L8A|2VVj_V2*zT72_Dyf zUNx$~rUmy``1;~=!{Ejn>7l>lg?mRX(Ek7r>ze94*e3Zc_rleM;!>*?9V(v=3H_sC z0zhgbK`TxWOt5yMQ5u07kyBxriICH=PlXaAWL8`gNEJ9!NDl8FLIa8l(b=Fay71fj zVSHg?1F@OZcqrB&SFF(b0fk>LAB7_LT3_413{4ae0ax|uFA>4OHiJQAUHB^D%irNb zl#v(U?el|07q^_*Cs_g;I1aV0eT+;x>ow!RsjS7YB$i0|dGZG27ZdVb^S?LKKBIsxdlzS6&4JKoTIk)gbeJrLSjX^*N*gGn(J-UAgPQb4GpSijO3Ihih z;@ei|CN~wJWdSsy*Xx*IW<(t*SK=HHvp2Z?hX7Q+^(LzM5_4G|w*U^y319$m#DIzs zS4Q&&=5x>29U2HOlPULj=Tl&-Cr!eIjpatbrF6{wm!%619gz$YMGf$ezID$6L>l`& zY)$N@@D%{7=Nd1hTUpylCsJ35Uau4!g9;DF612xvf+$h`bCJR0o9Z}0p@$zvf&}tQB-d>90kL>}>VJ?#tSIrE5 zcsMm+x_jDaZwZg~HSEoMwt6IH}>Fk}HFTx(MMJO|FWJ2+ac{ zN_CRVMC>L~rSDqw(j z(7t2(ytXeLiK`ds!d?*VQqjZcDi^;(6z_NZ*=;APf zNkzTE6C3k)j{3SD^i7{h!PCnDJL-ka+s@=As5~mP%>x?MXZqSOhrI#P=p>w z(&a`|u0bdnoyVOF`M_H_l*4hNjB(T61_1q{6H>ChB4c=DO>47<Ku!er29e&^A zgI1TsK&Z$DHFV?nL?!OYwu<21oGmy)0UZvDUtsrmYnrAj@6T81J~%&Rsw+l5hvGtW zDhQemm$g&f$K!~|>IS`!YOQ(^+e(B4evM@)csG~Oc2z(fxWDM!IJa34Bu>UQFz_}%1|0)eDM zARVk3c=U6j5Z3&NpI>}h*R(28-c(&D7yPgSny<6?4jh%>4=;eI`~lz#yCP6?@KOxz z_;?vl5CMQ6UUBiuZ$n?V`Mf>V=m(-lq3|_)a9-J>2JOxGeYt$?8t z7v#Od0nY*$%C#OGIeuo9sw?Vf7K;UV#Tx`}TEzJIVFL0l1(g=h5L)pe1p59cA+#gC zJS!O&aEWflkIb)plFs1>yE;%l?iA+FIjj~4!6=d%_lZyQQeOj6*V4XoU(Cm=y}h^l zVE~k6tUbdIb>D#EfU5(w=J_;B9hCIs-Z}!3QuO_s!iBvb$&vmzWq|-dK0l(Oxzrvl zq!65xP+7#AYJ^qTyn6iLAM(rwPs0&^Jnh>Ur0hrdM;@LYP!myxW*b5Xi8F<^sFz$E z0SMM(S;>Ua#DDH2N2EmM)xER=CuFbZdDOwPYCrf>l$m8zR0l!y{d>i73~e^ws29*b z99(J63&on@e6h{|P@Sv@GF@Pm^g7O_0PmIvK`+_Bh`P-KN`8Np_;7{Y68^<{eD5ZR zky0ZWS$QF$!>n7Bpa!va3`Zmg{ zHb@md!92daK=WcIf`T148UnofI(rTRpeqt5yjhbFC*ZKGuczJSG>eeNkA}?KMbVWj z3OKS2pebt?va#AMgSdKvqTrS!&kS~wmhl9RPR2{~__ISj) zz5ayNf~oLn&nf=^wxyMX6HISnly1#=pQmkNBjhXY%is4?KUEE@ir~x#Se&t>QySev zogV<@bc|aXz|P(VPyy~fz|NlM5>Emp*Rrf*GsokMD~O5`15c8EIalGx8uTof{>K)k z!mBTq1^h1tv-SW#?BcXzWhhgxmEp_y5Rl!T7dj4g!(Mi=jOi(qdh3%}52$=X;PkBc z*0041CCKE6cmOc_Qt^*f`X+Xw1 zU1`@kk3-nJZcxl8e84UT{SThm?l7j?AUWnhf%fVIVQv+a7RmQUMls)s* zKBzCq{Bc-HfBdJlezSzbZ$zx51(93AjfCnjYS{pUKEI)m_CSUtY1Z704=9$LLhvy` zDSW5o;=Gb^4zvgH#K6j?^$+0lCo>kTu;Xb zF=@(URN6a#GlX=zDeydYKZYOv1jmdjhgBeCK=|u`wp9i|5+V3-pft^mghTJV07^oC z_pbMtc16M3y)PY9P#CljoB}p&-CqyCa;|5O5uyqCaOh zsGkD?GvJ4#b_>l{T#n$g^CLLfkdj=jSj!Ba^oi9FK-X%Zb;knH;sr>4rT#;dqdc98 zjVESyxp>#QakPQ+oAvs%g!_R6gEH2bTFwIlgd1Rocf%+{INFd@zMayIJfDEE?A~LZ zi$6v@r6HHZ(4H-*186tu2b~n#kNlg$9~vhJ2eni7H_OQ5+@NH=jC|yC@A1_Wl&NIj z4lJ*w+Ez2C8dXm@-H*RFTs264{%{CVy?{s1{{SJt%7gT0AGkO*c_Bm-^V$6PtW=wU zPsKmm${`0`1a+&=ILuJ0XP>(M`HwIqcOq3M%;r^*mazTcxd(m$lLw`nT{!*}SW!BZ zh1;Vz#-1tAMgRv`NZtrzIAXzH%>4j){UXDcDZ&zuES$}&Dd(+>5)*;?BQ3@B7*R-FwgB%p{Y{WHOUUmfZ+R za@pw`rbgjQ&cAX}%_c^QZmQ(`}IZF%}` zacJiTp%>8PGUfH2s6?^k)3wo`kF^6ynjkQb2?yd)S;-yklTt~rLqkd6iLeS!I^IvAD}jAE2-POy}e zd-d3P#J{r6pt3v*Wda~1Zg{5}=T(cbVifaj zoSr-m!c95IH;yA^>}%DHf8C7*K0O4JE^I(<_Z9g6DwslKY(f@QUgp;U*-lkOZ%ZWb zwn~;@xgQ@4fg3;U3W@@#l~zHky*i$wWX~!|*heDarOf-Gi-W7gZqi5XG3c&BH8shu zK3N|zR)i0z{NpHOks{PgrO#hc(JW_FF#J&s%;@snVzr^U&$olSpeedLQw_L02lLRV z;$G{h=dR*QzZ+&V3C(so=WB|PMhuhRIu=3QZYogc@ZXGojuz2s3^-GH1}Z3gs6fb$ zD9G(3ku5ERS6Z#cJN|xmU>rbk{lnLNKMdA{lN6>-nZai-u(Z2S7E3uEhzeIsbKd4c zhnffSSS#+3%7aq))Mcg>hG(u{UCwH2P_7Rli9r>G)kCm7l*>+a2mh2)Y6l60_V@2% zRkJ~PE#cTO5`r#2Va{J4gXT0mY)+AiH;Dc7&lnW16H`210a`thLn8br@*n#H)<1NS z@fo0B_XEHWU_{y%w?7v%QaGxbkceRIuq6z5L6upH8)#2Y+!Mq4$l)aR#BKQO55dVD z&00O)+z$^6uoPRFYYPD#;^HV+BInSnbGx~#ja;}%0A6FCOd%gjUpnyH_`i+2)^I0D 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 GQU4DG17s5b diff --git a/test/testdata/pdfengines/sample3.pdf b/test/testdata/pdfengines/sample3.pdf deleted file mode 100644 index d079b89242260e3967ad2e2a43d6940e58e9fdc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 224175 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�*vR@PW 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%0AF<}dU#dI*5D`$OCWsZ_|vQTQ7n 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%0A6FCOd%gjUpnyH_`i+2)^I0D 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 diff --git a/test/testdata/pdfengines/sample4.pdf b/test/testdata/pdfengines/sample4.pdf deleted file mode 100644 index 5fc57f1403a293b2f5145fe3e39d172f1a796422..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8025 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�*vR@PW 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%0AF<}dU#dI*5D`$OCWsZ_|vQTQ7n zhyM5g00aZh0cO+&8BVXyAdkrWC=aXrJ@G7wA5e?A(Y}06EndJkFJnt^NIS>knq)In zA$w&J?-PbDkDLM2fSaB@a7+$~co>34NO&Awl;Dk4bgc)m5oR=-q<~74?CcNM9E_=u zw0MK^A@}_@WSF{K5QMp~_mSYd2@NtT_|f^|7zIK_L1JT_c<-00N-9*uqLg=aCLHT& zSFnY`0zO>M;!J~7DMPJTy~ppJ`H8@iG=n~8Iti190(E=+etBG=)~w$U--hL(?Nrzlw+9!Zci&)c*hj`Ho#$IjI-+D&?!zBtdk7DRVn`6-{0!8tDY+ zW~gxhq#UM6p@BdM5I^B^=qO?(3|1y&Hq(*N!$<%i42GAlo-h;v2m+DS>0$Emuo(mW zT`%yw0RuueeV;ek!TX9U{0O7@;x%Y6h;|*fK=_N!x4xaBlfl7AgZc9!|hS$mqHx1J`Q{)toDUaHc}M zM!rfPC8_#{^Zklq`wfV^4wD_7@`9aYM*^Q4sAqi#QX0{KESu&k1ownZr1%H=2;en%$6Dwyh4(mf5%-w6C|2wI-P1!P#4q#@^<$`Pl9h*^qeMVEUcYEPK@5h z@ZqPS8$nglnF;xL?E#S}L}d7Hyc(p;VV%B1;haB%1~XZ{QJ!&Bc$x?o{{X)5m6Npq zBP|ZFAi>oJUDX^kEYeU|w>at?1qLfSkpBRDwIOK=uCGF^yajC%3iLi=;zUuPk-rCH zc#Rb@1`u*IJtNntLXnz$az3GZ2!2QWxMReD0fl~5Tk<>QDy~x&PtzWB@f3r=eJ|ed zEW!;;uZ&Dq{LrYy5{t4KP}TxeZxqMqJOb}PEIgBiJa8bl53>G0JQFGN9_1YhPcIuJ z+XfEr8lU&@I{+6)iTNiR#Y4DN1hn;sDMEs-8c@7=+Hf?UJ;njX7HV5kr z7v<_5I=AL4tLW0N&3Hy5`jP-qdlx1Ft1LzOf#|^^Qe#b*`Zyx;`fL1!`B3)ph_<&k zu@#LdR9xXESz%olRsg;U@Pu1#i9)J}ZvC9UHURhqX=P79(3^5d<_5gvL9la1A<>MA zgrlUNXUU#2sD_1hIH`?8esw> zEi6(%oxDK>0@R3`SyGr%@iiwch!@#t>_M!Pr=?C;)E0cJyxs4E*Y*%dxb(BCdc$}~ zh%B((>?mH~uL1#Ns}>V38Y*IHCTR;j$*e;A`|xD(wjv^(DIUh@)}B9URD_n%ugKmb zzYn}5?VaJmd86|AxXXrX#L2sX8mWRfot$ApMpN@|@ZkzJ4L@$Da#M*m5N?eIS43?& z9J(w8gd`LI(C}UgS4hGDDTow{!0d9bNHMGxpAPGJ&CwV;MB4ZP{TcG$T?Cq^w`d+-hnCce))ey6cp<&> z-wJSfy=srk`VORf*a*1z{(kDK03j?7dJ|vTaSh*!ssly@fp46MKM0BR{f2y=rAsb= za5V-5p5gT49P!X5(Jom z(6glMPxPGfntCt~(ii^#E(c1tv}}>=ugY+?y$c$NWXbz^I3b476QS`#c)_icNG$4q zv+ILgXY#>*3cMM}!L~ofe}MSo4G=~QB$S4_oMgYGH$;91&*zjPgYRYOWV$~ZoLUi= z2|!#0YM~u3RiC~^gT(aabjd6Qe=pYt{745_UrkrFRD|c3`NG3zYoBi&tG(g_1HMK4 z@Frh73(`_AY+L*mfWnW^f9`QeHCbjYx@>p8NQ|KftM;ze87J;8n{d*SE^ zgGchmr|gJ4Vve;UjZae!o1K8soJmi>lp2_+@^R^IawPjBq+EA;V^vE8xN5XvJ65#W|1c(p$Kr@zO3zK2c zW4{{w@Gguz!=V8W+hOMx{Xr7dgI%pU>W)2jKhPi_2l@V(004#Y{{SClIY_9^QsGv( z829fQYA{{&sS`{(ZQ%nj6g~p$ll{0o5SaeW%5aKUDwnjK7}!bDauq~m8X!ys2`5R> zsM83b^hl2I^)c&&0i?~H3!uq|x9eI48i7aT zmgL(`$i$loCimi;dkaT_(SAlBUoQ>v8E6lE4DYL#tz@==JnerxL%;)Ca`m$Jg2TH*&3>hWsg|Djv9GmYk?GjCw&<4DMkBWD#})LA1;OVPD+{= zNs;dG1a-nRhL{#QGp@%qcV`$92?hN3l4*ehppqknx4hWDJs@LJgoj_tmO%w0;4d>1 zi4c1WXKnTHBepD+?W=xVbU4XD3hK*9;|IPxXM(ZB`Z2|vO~@T@hM4_vpYJgL0K{=> zqzfcDIy~Q#gwv`*gGy*Lb)s^8AVBlAE&zQ6Lp1N4oR0 ztY0%p5AYuN+D0?+wb}2M;n7!EP+>reF$I=s#wIP%(&FI@iVo^u`!FyP)qn?R?ck9ftZq@MV@5<d~m_LuV7$hP_KsVsO9JX**#O=*#j6M0r_=SWq ziw)_0H-HwZkO)RO$-CEc#nC?^2vfLq-`^E80XQE{&^AzO!GX47$~__@CkkrCEykae z@Es}S_g4f_5 z!{?Qbh$J7AVZSejf@64**nVH$zZ^O{#R_VAK=|435`}|{L8A|2VVj_V2*zT72_Dyf zUNx$~rUmy``1;~=!{Ejn>7l>lg?mRX(Ek7r>ze94*e3Zc_rleM;!>*?9V(v=3H_sC z0zhgbK`TxWOt5yMQ5u07kyBxriICH=PlXaAWL8`gNEJ9!NDl8FLIa8l(b=Fay71fj zVSHg?1F@OZcqrB&SFF(b0fk>LAB7_LT3_413{4ae0ax|uFA>4OHiJQAUHB^D%irNb zl#v(U?el|07q^_*Cs_g;I1aV0eT+;x>ow!RsjS7YB$i0|dGZG27ZdVb^S?LKKBIsxdlzS6&4JKoTIk)gbeJrLSjX^*N*gGn(J-UAgPQb4GpSijO3Ihih z;@ei|CN~wJWdSsy*Xx*IW<(t*SK=HHvp2Z?hX7Q+^(LzM5_4G|w*U^y319$m#DIzs zS4Q&&=5x>29U2HOlPULj=Tl&-Cr!eIjpatbrF6{wm!%619gz$YMGf$ezID$6L>l`& zY)$N@@D%{7=Nd1hTUpylCsJ35Uau4!g9;DF612xvf+$h`bCJR0o9Z}0p@$zvf&}tQB-d>90kL>}>VJ?#tSIrE5 zcsMm+x_jDaZwZg~HSEoMwt6IH}>Fk}HFTx(MMJO|FWJ2+ac{ zN_CRVMC>L~rSDqw(j z(7t2(ytXeLiK`ds!d?*VQqjZcDi^;(6z_NZ*=;APf zNkzTE6C3k)j{3SD^i7{h!PCnDJL-ka+s@=As5~mP%>x?MXZqSOhrI#P=p>w z(&a`|u0bdnoyVOF`M_H_l*4hNjB(T61_1q{6H>ChB4c=DO>47<Ku!er29e&^A zgI1TsK&Z$DHFV?nL?!OYwu<21oGmy)0UZvDUtsrmYnrAj@6T81J~%&Rsw+l5hvGtW zDhQemm$g&f$K!~|>IS`!YOQ(^+e(B4evM@)csG~Oc2z(fxWDM!IJa34Bu>UQFz_}%1|0)eDM zARVk3c=U6j5Z3&NpI>}h*R(28-c(&D7yPgSny<6?4jh%>4=;eI`~lz#yCP6?@KOxz z_;?vl5CMQ6UUBiuZ$n?V`Mf>V=m(-lq3|_)a9-J>2JOxGeYt$?8t z7v#Od0nY*$%C#OGIeuo9sw?Vf7K;UV#Tx`}TEzJIVFL0l1(g=h5L)pe1p59cA+#gC zJS!O&aEWflkIb)plFs1>yE;%l?iA+FIjj~4!6=d%_lZyQQeOj6*V4XoU(Cm=y}h^l zVE~k6tUbdIb>D#EfU5(w=J_;B9hCIs-Z}!3QuO_s!iBvb$&vmzWq|-dK0l(Oxzrvl zq!65xP+7#AYJ^qTyn6iLAM(rwPs0&^Jnh>Ur0hrdM;@LYP!myxW*b5Xi8F<^sFz$E z0SMM(S;>Ua#DDH2N2EmM)xER=CuFbZdDOwPYCrf>l$m8zR0l!y{d>i73~e^ws29*b z99(J63&on@e6h{|P@Sv@GF@Pm^g7O_0PmIvK`+_Bh`P-KN`8Np_;7{Y68^<{eD5ZR zky0ZWS$QF$!>n7Bpa!va3`Zmg{ zHb@md!92daK=WcIf`T148UnofI(rTRpeqt5yjhbFC*ZKGuczJSG>eeNkA}?KMbVWj z3OKS2pebt?va#AMgSdKvqTrS!&kS~wmhl9RPR2{~__ISj) zz5ayNf~oLn&nf=^wxyMX6HISnly1#=pQmkNBjhXY%is4?KUEE@ir~x#Se&t>QySev zogV<@bc|aXz|P(VPyy~fz|NlM5>Emp*Rrf*GsokMD~O5`15c8EIalGx8uTof{>K)k z!mBTq1^h1tv-SW#?BcXzWhhgxmEp_y5Rl!T7dj4g!(Mi=jOi(qdh3%}52$=X;PkBc z*0041CCKE6cmOc_Qt^*f`X+Xw1 zU1`@kk3-nJZcxl8e84UT{SThm?l7j?AUWnhf%fVIVQv+a7RmQUMls)s* zKBzCq{Bc-HfBdJlezSzbZ$zx51(93AjfCnjYS{pUKEI)m_CSUtY1Z704=9$LLhvy` zDSW5o;=Gb^4zvgH#K6j?^$+0lCo>kTu;Xb zF=@(URN6a#GlX=zDeydYKZYOv1jmdjhgBeCK=|u`wp9i|5+V3-pft^mghTJV07^oC z_pbMtc16M3y)PY9P#CljoB}p&-CqyCa;|5O5uyqCaOh zsGkD?GvJ4#b_>l{T#n$g^CLLfkdj=jSj!Ba^oi9FK-X%Zb;knH;sr>4rT#;dqdc98 zjVESyxp>#QakPQ+oAvs%g!_R6gEH2bTFwIlgd1Rocf%+{INFd@zMayIJfDEE?A~LZ zi$6v@r6HHZ(4H-*186tu2b~n#kNlg$9~vhJ2eni7H_OQ5+@NH=jC|yC@A1_Wl&NIj z4lJ*w+Ez2C8dXm@-H*RFTs264{%{CVy?{s1{{SJt%7gT0AGkO*c_Bm-^V$6PtW=wU zPsKmm${`0`1a+&=ILuJ0XP>(M`HwIqcOq3M%;r^*mazTcxd(m$lLw`nT{!*}SW!BZ zh1;Vz#-1tAMgRv`NZtrzIAXzH%>4j){UXDcDZ&zuES$}&Dd(+>5)*;?BQ3@B7*R-FwgB%p{Y{WHOUUmfZ+R za@pw`rbgjQ&cAX}%_c^QZmQ(`}IZF%}` zacJiTp%>8PGUfH2s6?^k)3wo`kF^6ynjkQb2?yd)S;-yklTt~rLqkd6iLeS!I^IvAD}jAE2-POy}e zd-d3P#J{r6pt3v*Wda~1Zg{5}=T(cbVifaj zoSr-m!c95IH;yA^>}%DHf8C7*K0O4JE^I(<_Z9g6DwslKY(f@QUgp;U*-lkOZ%ZWb zwn~;@xgQ@4fg3;U3W@@#l~zHky*i$wWX~!|*heDarOf-Gi-W7gZqi5XG3c&BH8shu zK3N|zR)i0z{NpHOks{PgrO#hc(JW_FF#J&s%;@snVzr^U&$olSpeedLQw_L02lLRV z;$G{h=dR*QzZ+&V3C(so=WB|PMhuhRIu=3QZYogc@ZXGojuz2s3^-GH1}Z3gs6fb$ zD9G(3ku5ERS6Z#cJN|xmU>rbk{lnLNKMdA{lN6>-nZai-u(Z2S7E3uEhzeIsbKd4c zhnffSSS#+3%7aq))Mcg>hG(u{UCwH2P_7Rli9r>G)kCm7l*>+a2mh2)Y6l60_V@2% zRkJ~PE#cTO5`r#2Va{J4gXT0mY)+AiH;Dc7&lnW16H`210a`thLn8br@*n#H)<1NS z@fo0B_XEHWU_{y%w?7v%QaGxbkceRIuq6z5L6upH8)#2Y+!Mq4$l)aR#BKQO55dVD z&00O)+z$^6uoPRFYYPD#;^HV+BInSnbGx~#ja;}%0A6FCOd%gjUpnyH_`i+2)^I0D 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 GQU4DG17s5b diff --git a/test/testdata/chromium/html/font.woff b/test/testdata/chromium/html/font.woff deleted file mode 100644 index ebd62d592e7ff4cfed3020332d996b90ff24dc8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12644 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 O(-;7vnZf`p2LC^-w-1v5 diff --git a/test/testdata/chromium/html/footer.html b/test/testdata/chromium/html/footer.html deleted file mode 100644 index c355f721..00000000 --- a/test/testdata/chromium/html/footer.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - -