214 lines
5.7 KiB
Go
214 lines
5.7 KiB
Go
package lib
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"image"
|
|
"image/color"
|
|
"image/png"
|
|
"testing"
|
|
)
|
|
|
|
// TestWatermarkPDF tests PDF watermarking with a minimal PDF.
|
|
func TestWatermarkPDF(t *testing.T) {
|
|
// Minimal valid PDF (empty page)
|
|
minimalPDF := []byte(`%PDF-1.4
|
|
1 0 obj
|
|
<< /Type /Catalog /Pages 2 0 R >>
|
|
endobj
|
|
2 0 obj
|
|
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
|
|
endobj
|
|
3 0 obj
|
|
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] >>
|
|
endobj
|
|
xref
|
|
0 4
|
|
0000000000 65535 f
|
|
0000000009 00000 n
|
|
0000000058 00000 n
|
|
0000000115 00000 n
|
|
trailer
|
|
<< /Size 4 /Root 1 0 R >>
|
|
startxref
|
|
192
|
|
%%EOF`)
|
|
|
|
label := "CONFIDENTIAL - Test User - 2026-02-28 - TestProject"
|
|
|
|
out, err := WatermarkPDF(minimalPDF, label)
|
|
if err != nil {
|
|
t.Fatalf("WatermarkPDF failed: %v", err)
|
|
}
|
|
|
|
// Basic checks
|
|
if len(out) == 0 {
|
|
t.Fatal("WatermarkPDF returned empty output")
|
|
}
|
|
|
|
// Watermarked PDF should be larger than original
|
|
if len(out) <= len(minimalPDF) {
|
|
t.Errorf("Watermarked PDF (%d bytes) should be larger than original (%d bytes)", len(out), len(minimalPDF))
|
|
}
|
|
|
|
// Should still start with PDF header
|
|
if !bytes.HasPrefix(out, []byte("%PDF")) {
|
|
t.Error("Output doesn't look like a PDF (missing %PDF header)")
|
|
}
|
|
}
|
|
|
|
// TestWatermarkImagePNG tests image watermarking with PNG.
|
|
func TestWatermarkImagePNG(t *testing.T) {
|
|
// Create a minimal test PNG (100x100 red square)
|
|
img := image.NewRGBA(image.Rect(0, 0, 100, 100))
|
|
red := color.RGBA{255, 0, 0, 255}
|
|
for y := 0; y < 100; y++ {
|
|
for x := 0; x < 100; x++ {
|
|
img.Set(x, y, red)
|
|
}
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
if err := png.Encode(&buf, img); err != nil {
|
|
t.Fatalf("Failed to create test PNG: %v", err)
|
|
}
|
|
originalPNG := buf.Bytes()
|
|
|
|
label := "CONFIDENTIAL - Test User - 2026-02-28"
|
|
|
|
out, err := WatermarkImage(originalPNG, "image/png", label)
|
|
if err != nil {
|
|
t.Fatalf("WatermarkImage failed: %v", err)
|
|
}
|
|
|
|
// Basic checks
|
|
if len(out) == 0 {
|
|
t.Fatal("WatermarkImage returned empty output")
|
|
}
|
|
|
|
// Verify it's still a valid PNG
|
|
_, err = png.Decode(bytes.NewReader(out))
|
|
if err != nil {
|
|
t.Errorf("Output is not a valid PNG: %v", err)
|
|
}
|
|
}
|
|
|
|
// TestWatermarkDOCX tests DOCX watermarking with a minimal document.
|
|
func TestWatermarkDOCX(t *testing.T) {
|
|
// Create a minimal DOCX (which is a ZIP file with specific structure)
|
|
minimalDOCX := createMinimalDOCX()
|
|
|
|
label := "CONFIDENTIAL - Test User - 2026-02-28 - TestProject"
|
|
|
|
out, err := WatermarkDOCX(minimalDOCX, label)
|
|
if err != nil {
|
|
t.Fatalf("WatermarkDOCX failed: %v", err)
|
|
}
|
|
|
|
// Basic checks
|
|
if len(out) == 0 {
|
|
t.Fatal("WatermarkDOCX returned empty output")
|
|
}
|
|
|
|
// Watermarked DOCX should be larger (we added header)
|
|
if len(out) <= len(minimalDOCX) {
|
|
t.Errorf("Watermarked DOCX (%d bytes) should be larger than original (%d bytes)", len(out), len(minimalDOCX))
|
|
}
|
|
|
|
// Should still be a valid ZIP
|
|
if !bytes.HasPrefix(out, []byte("PK")) {
|
|
t.Error("Output doesn't look like a DOCX/ZIP (missing PK header)")
|
|
}
|
|
}
|
|
|
|
// TestWatermarkDispatch tests the main dispatch function.
|
|
func TestWatermarkDispatch(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
mimeType string
|
|
data []byte
|
|
}{
|
|
{"unknown type passthrough", "application/octet-stream", []byte("hello world")},
|
|
{"text passthrough", "text/plain", []byte("hello world")},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
out, err := Watermark(tt.data, tt.mimeType, "test label")
|
|
if err != nil {
|
|
t.Errorf("Watermark failed: %v", err)
|
|
}
|
|
// Unknown types should pass through unchanged
|
|
if !bytes.Equal(out, tt.data) {
|
|
t.Error("Unknown MIME type should pass through unchanged")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestWatermarkEmptyInput tests error handling for empty inputs.
|
|
func TestWatermarkEmptyInput(t *testing.T) {
|
|
_, err := WatermarkPDF(nil, "test")
|
|
if err == nil {
|
|
t.Error("WatermarkPDF should fail on nil input")
|
|
}
|
|
|
|
_, err = WatermarkImage(nil, "image/png", "test")
|
|
if err == nil {
|
|
t.Error("WatermarkImage should fail on nil input")
|
|
}
|
|
|
|
_, err = WatermarkDOCX(nil, "test")
|
|
if err == nil {
|
|
t.Error("WatermarkDOCX should fail on nil input")
|
|
}
|
|
}
|
|
|
|
// createMinimalDOCX creates a minimal valid DOCX for testing.
|
|
func createMinimalDOCX() []byte {
|
|
var buf bytes.Buffer
|
|
w := zip.NewWriter(&buf)
|
|
|
|
// [Content_Types].xml
|
|
contentTypes := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
|
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
|
|
<Default Extension="xml" ContentType="application/xml"/>
|
|
<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>
|
|
</Types>`
|
|
f, _ := w.Create("[Content_Types].xml")
|
|
f.Write([]byte(contentTypes))
|
|
|
|
// _rels/.rels
|
|
rels := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
|
|
</Relationships>`
|
|
f, _ = w.Create("_rels/.rels")
|
|
f.Write([]byte(rels))
|
|
|
|
// word/document.xml
|
|
doc := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
|
|
<w:body>
|
|
<w:p>
|
|
<w:r>
|
|
<w:t>Test Document</w:t>
|
|
</w:r>
|
|
</w:p>
|
|
</w:body>
|
|
</w:document>`
|
|
f, _ = w.Create("word/document.xml")
|
|
f.Write([]byte(doc))
|
|
|
|
// word/_rels/document.xml.rels
|
|
docRels := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
</Relationships>`
|
|
f, _ = w.Create("word/_rels/document.xml.rels")
|
|
f.Write([]byte(docRels))
|
|
|
|
w.Close()
|
|
return buf.Bytes()
|
|
}
|