feat: add embeds metadata

This commit is contained in:
hubert.lenoir
2026-04-03 18:23:27 +02:00
committed by Julien Neuhart
parent eff9444294
commit 3187980ead
24 changed files with 848 additions and 24 deletions

View File

@@ -17,6 +17,21 @@ Feature: /forms/pdfengines/embed
Then the response PDF(s) should have the "embed_1.xml" file embedded
Then the response PDF(s) should have the "embed_2.xml" file embedded
Scenario: POST /forms/pdfengines/embed with metadata
Given I have a default Gotenberg container
When I make a "POST" request to Gotenberg at the "/forms/pdfengines/embed" endpoint with the following form data and header(s):
| files | testdata/page_1.pdf | file |
| embeds | testdata/embed_1.xml | file |
| embeds | testdata/embed_2.xml | file |
| embedsMetadata | {"embed_1.xml":{"mimeType":"text/xml","relationship":"Data"},"embed_2.xml":{"mimeType":"text/xml","relationship":"Alternative"}} | field |
Then the response status code should be 200
And the response header "Content-Type" should be "application/pdf"
And there should be 1 PDF(s) in the response
And the response PDF(s) should have the "embed_1.xml" file embedded
And the response PDF(s) should have the "embed_1.xml" file embedded with relationship "Data"
And the response PDF(s) should have the "embed_2.xml" file embedded
And the response PDF(s) should have the "embed_2.xml" file embedded with relationship "Alternative"
@download-from
Scenario: POST /forms/pdfengines/embed with (Download From)
Given I have a default Gotenberg container

View File

@@ -9,6 +9,7 @@ import (
"github.com/moby/moby/api/types/container"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/exec"
"github.com/testcontainers/testcontainers-go/network"
"github.com/testcontainers/testcontainers-go/wait"
)
@@ -138,7 +139,7 @@ func execCommandInIntegrationToolsContainer(ctx context.Context, cmd []string, p
}
}(c, ctx)
_, output, err := c.Exec(ctx, cmd)
_, output, err := c.Exec(ctx, cmd, exec.Multiplexed())
if err != nil {
return "", fmt.Errorf("exec %q: %w", cmd, err)
}

View File

@@ -1262,6 +1262,68 @@ func (s *scenario) thePdfsShouldHaveEmbeddedFile(ctx context.Context, kind, shou
return nil
}
func (s *scenario) thePdfsShouldHaveEmbeddedFileWithRelationship(ctx context.Context, kind, embed, relationship string) error {
dirPath := s.teststoreDir
_, 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", dirPath, err)
}
for _, path := range paths {
cmd := []string{
"verapdf",
"--off",
"--loglevel",
"0",
"--extract",
"embeddedFile",
filepath.Base(path),
}
output, err := execCommandInIntegrationToolsContainer(ctx, cmd, path)
if err != nil {
return fmt.Errorf("exec %q: %w", cmd, err)
}
fileNameTag := fmt.Sprintf("<fileName>%s</fileName>", embed)
relationshipTag := fmt.Sprintf("<afRelationship>%s</afRelationship>", relationship)
blocks := strings.Split(output, "</embeddedFile>")
found := false
for _, block := range blocks {
if !strings.Contains(block, fileNameTag) {
continue
}
if !strings.Contains(block, relationshipTag) {
return fmt.Errorf("embedded file %q missing afRelationship %q", embed, relationship)
}
found = true
break
}
if !found {
return fmt.Errorf("embedded file %q not found in verapdf output", embed)
}
}
return nil
}
func InitializeScenario(ctx *godog.ScenarioContext) {
s := &scenario{}
ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) {
@@ -1300,6 +1362,7 @@ func InitializeScenario(ctx *godog.ScenarioContext) {
ctx.Then(`^the (response|webhook request) PDF\(s\) (should|should NOT) be flatten$`, s.thePdfsShouldBeFlatten)
ctx.Then(`^the (response|webhook request) PDF\(s\) (should|should NOT) be encrypted`, s.thePdfsShouldBeEncrypted)
ctx.Then(`^the (response|webhook request) PDF\(s\) (should|should NOT) have the "([^"]*)" file embedded$`, s.thePdfsShouldHaveEmbeddedFile)
ctx.Then(`^the (response|webhook request) PDF\(s\) should have the "([^"]*)" file embedded with relationship "([^"]*)"$`, s.thePdfsShouldHaveEmbeddedFileWithRelationship)
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)