2018-06-18 15:26:29 +00:00
|
|
|
/*
|
|
|
|
* This file is subject to the terms and conditions defined in
|
|
|
|
* file 'LICENSE.md', which is part of this source code package.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package model
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
2019-05-14 21:14:53 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2019-05-16 23:44:51 +03:00
|
|
|
"github.com/unidoc/unipdf/v3/core"
|
|
|
|
"github.com/unidoc/unipdf/v3/internal/testutils"
|
2018-06-18 15:26:29 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Test loading of a basic checkbox field with a merged-in annotation.
|
|
|
|
func TestCheckboxField1(t *testing.T) {
|
|
|
|
rawText := `
|
|
|
|
1 0 obj
|
|
|
|
<<
|
|
|
|
/Type /Annot
|
|
|
|
/Subtype /Widget
|
|
|
|
/Rect [100 100 120 120]
|
|
|
|
/FT /Btn
|
|
|
|
/T (Urgent)
|
|
|
|
/V /Yes
|
|
|
|
/AS /Yes
|
|
|
|
/AP <</N <</Yes 2 0 R /Off 3 0 R>> >>
|
|
|
|
>>
|
|
|
|
endobj
|
|
|
|
|
|
|
|
2 0 obj
|
|
|
|
<</Type /XObject
|
|
|
|
/Subtype /Form
|
|
|
|
/BBox [0 0 20 20]
|
|
|
|
/Resources 20 0 R
|
|
|
|
/Length 44
|
|
|
|
>>
|
|
|
|
stream
|
|
|
|
q
|
|
|
|
0 0 1 rg
|
|
|
|
BT
|
|
|
|
/ZaDb 12 Tf
|
|
|
|
0 0 Td
|
|
|
|
(4) Tj
|
|
|
|
ET
|
|
|
|
Q
|
|
|
|
endstream
|
|
|
|
endobj
|
|
|
|
|
|
|
|
3 0 obj
|
|
|
|
<</Type /XObject
|
|
|
|
/Subtype /Form
|
|
|
|
/BBox [0 0 20 20]
|
|
|
|
/Resources 20 0 R
|
|
|
|
/Length 51
|
|
|
|
>>
|
|
|
|
stream
|
|
|
|
q
|
|
|
|
0 0 1 rg
|
|
|
|
BT
|
|
|
|
/ZaDb 12 Tf
|
|
|
|
0 0 Td
|
|
|
|
(8) Tj
|
|
|
|
ET
|
|
|
|
Q
|
|
|
|
endstream
|
|
|
|
endobj
|
|
|
|
|
|
|
|
4 0 obj
|
|
|
|
% Copy of obj 1 except not with merged-in annotation
|
|
|
|
<<
|
|
|
|
/FT /Btn
|
|
|
|
/T (Urgent)
|
|
|
|
/V /Yes
|
|
|
|
/Kids [5 0 R]
|
|
|
|
>>
|
|
|
|
endobj
|
|
|
|
|
|
|
|
5 0 obj
|
|
|
|
<<
|
|
|
|
/Type /Annot
|
|
|
|
/Subtype /Widget
|
|
|
|
/Rect [100 100 120 120]
|
|
|
|
/AS /Yes
|
|
|
|
/AP <</N <</Yes 2 0 R /Off 3 0 R>> >>
|
|
|
|
/Parent 4 0 R
|
|
|
|
>>
|
|
|
|
endobj
|
|
|
|
`
|
|
|
|
r := NewReaderForText(rawText)
|
|
|
|
|
|
|
|
err := r.ParseIndObjSeries()
|
2019-05-14 21:14:53 +00:00
|
|
|
require.NoError(t, err)
|
2018-06-18 15:26:29 +00:00
|
|
|
|
|
|
|
// Load the field from object number 1.
|
|
|
|
obj, err := r.parser.LookupByNumber(1)
|
2019-05-14 21:14:53 +00:00
|
|
|
require.NoError(t, err)
|
2018-06-18 15:26:29 +00:00
|
|
|
|
|
|
|
ind, ok := obj.(*core.PdfIndirectObject)
|
2019-05-14 21:14:53 +00:00
|
|
|
require.True(t, ok)
|
2018-06-18 15:26:29 +00:00
|
|
|
|
|
|
|
field, err := r.newPdfFieldFromIndirectObject(ind, nil)
|
2019-05-14 21:14:53 +00:00
|
|
|
require.NoError(t, err)
|
2018-06-18 15:26:29 +00:00
|
|
|
|
|
|
|
// Check properties of the field.
|
|
|
|
buttonf, ok := field.GetContext().(*PdfFieldButton)
|
2019-05-14 21:14:53 +00:00
|
|
|
require.True(t, ok)
|
|
|
|
require.NotNil(t, buttonf)
|
2018-06-18 15:26:29 +00:00
|
|
|
|
|
|
|
if len(field.Kids) > 0 {
|
|
|
|
t.Fatalf("Field should not have kids")
|
|
|
|
}
|
2019-05-14 21:14:53 +00:00
|
|
|
require.Len(t, field.Annotations, 1)
|
2018-06-18 15:26:29 +00:00
|
|
|
|
|
|
|
// Field -> PDF object. Regenerate the field dictionary and see if matches expectations.
|
|
|
|
// Reset the dictionaries for both field and annotation to avoid re-use during re-generation of PDF object.
|
|
|
|
field.container = core.MakeIndirectObject(core.MakeDict())
|
2018-08-03 21:15:21 +00:00
|
|
|
field.Annotations[0].container = core.MakeIndirectObject(core.MakeDict())
|
2018-06-18 15:26:29 +00:00
|
|
|
fieldPdfObj := field.ToPdfObject()
|
|
|
|
fieldDict, ok := fieldPdfObj.(*core.PdfIndirectObject).PdfObject.(*core.PdfObjectDictionary)
|
2019-05-14 21:14:53 +00:00
|
|
|
require.True(t, ok)
|
2018-06-18 15:26:29 +00:00
|
|
|
|
|
|
|
// Load the expected field dictionary (output). Slightly different than original as the input had
|
|
|
|
// a merged-in annotation. Our output does not currently merge annotations.
|
|
|
|
obj, err = r.parser.LookupByNumber(4)
|
2019-05-14 21:14:53 +00:00
|
|
|
require.NoError(t, err)
|
2018-06-18 15:26:29 +00:00
|
|
|
|
|
|
|
expDict, ok := obj.(*core.PdfIndirectObject).PdfObject.(*core.PdfObjectDictionary)
|
2019-05-14 21:14:53 +00:00
|
|
|
require.True(t, ok)
|
2018-06-18 15:26:29 +00:00
|
|
|
|
2018-07-17 23:53:28 +00:00
|
|
|
if !testutils.CompareDictionariesDeep(expDict, fieldDict) {
|
2018-06-18 15:26:29 +00:00
|
|
|
t.Fatalf("Mismatch in expected and actual field dictionaries (deep)")
|
|
|
|
}
|
|
|
|
}
|
2018-10-03 14:56:23 +00:00
|
|
|
|
|
|
|
func TestFormNil(t *testing.T) {
|
|
|
|
var form *PdfAcroForm
|
2019-05-14 21:14:53 +00:00
|
|
|
err := form.Fill(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Test loading and writing out of merged-in annotations.
|
|
|
|
func TestReadWriteMergedFieldAnnotation(t *testing.T) {
|
|
|
|
raw := `
|
|
|
|
6 0 obj
|
|
|
|
<<
|
|
|
|
/Type /Annot
|
|
|
|
/Rect [0 0 0 0]
|
|
|
|
/P 99 0 R
|
|
|
|
/F 132
|
|
|
|
/Subtype /Widget
|
|
|
|
/T (Signature 1)
|
|
|
|
/FT /Sig
|
|
|
|
/V 7 0 R
|
|
|
|
>>
|
|
|
|
endobj
|
|
|
|
`
|
|
|
|
_ = raw
|
|
|
|
t.Skip("Not implemented yet")
|
2018-10-03 14:56:23 +00:00
|
|
|
}
|