Files
nexarch/dms/internal/batchsplit/batchsplit_test.go
patrickandClaude Sonnet 5 75fdf9fb83
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
INT-06: scanner-anbindung über hot-folder
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-20 19:47:41 +02:00

112 lines
3.1 KiB
Go

package batchsplit
import (
"bytes"
"errors"
"os"
"path/filepath"
"testing"
"github.com/pdfcpu/pdfcpu/pkg/api"
"gitea.perlbach24.de/scripte/nexarch/dms/internal/testcorpus"
)
const sep = DefaultMarker
func pageCount(t *testing.T, b []byte) int {
t.Helper()
p := filepath.Join(t.TempDir(), "x.pdf")
if err := os.WriteFile(p, b, 0o600); err != nil {
t.Fatal(err)
}
n, err := api.PageCountFile(p)
if err != nil {
t.Fatalf("ausgabe ist kein gueltiges pdf: %v", err)
}
return n
}
// Referenzstapel: erwartete Aufteilung je Stapel (Seitenzahlen der Einzeldokumente).
func TestSplit_ReferenceBatches(t *testing.T) {
cases := []struct {
name string
pages []string
want []int
}{
{"zwei dokumente", []string{"A1", "A2", sep, "B1"}, []int{2, 1}},
{"drei dokumente", []string{"A1", sep, "B1", "B2", "B3", sep, "C1"}, []int{1, 3, 1}},
{"trennseite am anfang und ende", []string{sep, "A1", "A2", sep}, []int{2}},
{"aufeinanderfolgende trennseiten", []string{"A1", sep, sep, "B1"}, []int{1, 1}},
{"eine seite", []string{"A1"}, []int{1}},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
parts, err := Split(testcorpus.GenerateStack(c.pages), MarkerDetector{})
if err != nil {
t.Fatal(err)
}
if len(parts) != len(c.want) {
t.Fatalf("teildokumente = %d, want %d", len(parts), len(c.want))
}
for i, p := range parts {
if got := pageCount(t, p); got != c.want[i] {
t.Errorf("dokument %d: %d seiten, want %d", i, got, c.want[i])
}
}
})
}
}
func TestSplit_WithoutSeparatorReturnsInputUnchanged(t *testing.T) {
in := testcorpus.GenerateStack([]string{"A1", "A2", "A3"})
parts, err := Split(in, MarkerDetector{})
if err != nil {
t.Fatal(err)
}
if len(parts) != 1 || !bytes.Equal(parts[0], in) {
t.Fatal("stapel ohne trennseite muss unveraendert als ein dokument zurueckkommen")
}
}
func TestSplit_OnlySeparatorsIsRejected(t *testing.T) {
_, err := Split(testcorpus.GenerateStack([]string{sep, sep}), MarkerDetector{})
if !errors.Is(err, ErrOnlySeparators) {
t.Fatalf("err = %v, want ErrOnlySeparators", err)
}
}
func TestSplit_InvalidPDFFails(t *testing.T) {
if _, err := Split([]byte("kein pdf"), MarkerDetector{}); err == nil {
t.Fatal("ungueltiger inhalt muss einen fehler liefern")
}
}
func TestSplit_PageContentSurvivesSplit(t *testing.T) {
parts, err := Split(testcorpus.GenerateStack([]string{"Rechnung-77", sep, "Vertrag-88"}), MarkerDetector{})
if err != nil || len(parts) != 2 {
t.Fatalf("parts=%d err=%v", len(parts), err)
}
if !contentHas(t, parts[0], "Rechnung-77") || !contentHas(t, parts[1], "Vertrag-88") {
t.Fatal("seiteninhalt wurde dem falschen teildokument zugeordnet")
}
}
func contentHas(t *testing.T, pdf []byte, text string) bool {
t.Helper()
dir := t.TempDir()
in := filepath.Join(dir, "in.pdf")
_ = os.WriteFile(in, pdf, 0o600)
if err := api.ExtractContentFile(in, dir, nil, nil); err != nil {
t.Fatal(err)
}
files, _ := filepath.Glob(filepath.Join(dir, "*_Content_page_*.txt"))
for _, f := range files {
b, _ := os.ReadFile(f)
if bytes.Contains(b, []byte("("+text+")")) {
return true
}
}
return false
}