1 #include <QtTest/QtTest>
2 
3 #include <poppler-qt5.h>
4 #include <poppler-form.h>
5 #include <poppler-private.h>
6 #include <Form.h>
7 
8 class TestForms : public QObject
9 {
10     Q_OBJECT
11 public:
TestForms(QObject * parent=nullptr)12     explicit TestForms(QObject *parent = nullptr) : QObject(parent) { }
13 private slots:
14     void testCheckbox(); // Test for issue #655
15     void testCheckboxIssue159(); // Test for issue #159
16     void testSetIcon(); // Test that setIcon will always be valid.
17     void testSetPrintable();
18     void testSetAppearanceText();
19     void testStandAloneWidgets(); // check for 'de facto' tooltips. Issue #34
20     void testUnicodeFieldAttributes();
21 };
22 
testCheckbox()23 void TestForms::testCheckbox()
24 {
25     // Test for checkbox issue #655
26     QScopedPointer<Poppler::Document> document(Poppler::Document::load(TESTDATADIR "/unittestcases/latex-hyperref-checkbox-issue-655.pdf"));
27     QVERIFY(document);
28 
29     QScopedPointer<Poppler::Page> page(document->page(0));
30     QVERIFY(page);
31 
32     QList<Poppler::FormField *> forms = page->formFields();
33     QCOMPARE(forms.size(), 1);
34 
35     Poppler::FormField *form = forms.at(0);
36     QCOMPARE(form->type(), Poppler::FormField::FormButton);
37 
38     Poppler::FormFieldButton *chkFormFieldButton = static_cast<Poppler::FormFieldButton *>(form);
39 
40     // Test this is actually a Checkbox
41     QCOMPARE(chkFormFieldButton->buttonType(), Poppler::FormFieldButton::CheckBox);
42 
43     // checkbox comes initially 'unchecked'
44     QCOMPARE(chkFormFieldButton->state(), false);
45     // let's mark it as 'checked'
46     chkFormFieldButton->setState(true);
47     // now test if it was succesfully 'checked'
48     QCOMPARE(chkFormFieldButton->state(), true);
49 }
50 
testStandAloneWidgets()51 void TestForms::testStandAloneWidgets()
52 {
53     // Check for 'de facto' tooltips. Issue #34
54     QScopedPointer<Poppler::Document> document(Poppler::Document::load(TESTDATADIR "/unittestcases/tooltip.pdf"));
55     QVERIFY(document);
56 
57     QScopedPointer<Poppler::Page> page(document->page(0));
58     QVERIFY(page);
59 
60     QList<Poppler::FormField *> forms = page->formFields();
61 
62     QCOMPARE(forms.size(), 3);
63 
64     Q_FOREACH (Poppler::FormField *field, forms) {
65         QCOMPARE(field->type(), Poppler::FormField::FormButton);
66 
67         Poppler::FormFieldButton *fieldButton = static_cast<Poppler::FormFieldButton *>(field);
68         QCOMPARE(fieldButton->buttonType(), Poppler::FormFieldButton::Push);
69 
70         FormField *ff = Poppler::FormFieldData::getFormWidget(fieldButton)->getField();
71         QVERIFY(ff);
72         QCOMPARE(ff->isStandAlone(), true);
73 
74         // tooltip.pdf has only these 3 standalone widgets
75         QVERIFY(field->uiName() == QStringLiteral("This is a tooltip!") || // clazy:exclude=qstring-allocations
76                 field->uiName() == QStringLiteral("Sulfuric acid") || field->uiName() == QString::fromUtf8("little Gauß"));
77     }
78 }
79 
testCheckboxIssue159()80 void TestForms::testCheckboxIssue159()
81 {
82     // Test for checkbox issue #159
83     QScopedPointer<Poppler::Document> document(Poppler::Document::load(TESTDATADIR "/unittestcases/checkbox_issue_159.pdf"));
84     QVERIFY(document);
85 
86     QScopedPointer<Poppler::Page> page(document->page(0));
87     QVERIFY(page);
88 
89     Poppler::FormFieldButton *beerFieldButton = nullptr;
90     Poppler::FormFieldButton *wineFieldButton = nullptr;
91 
92     QList<Poppler::FormField *> forms = page->formFields();
93 
94     // Let's find and assign the "Wine" and "Beer" radio buttons
95     Q_FOREACH (Poppler::FormField *field, forms) {
96         if (field->type() != Poppler::FormField::FormButton)
97             continue;
98 
99         Poppler::FormFieldButton *fieldButton = static_cast<Poppler::FormFieldButton *>(field);
100         if (fieldButton->buttonType() != Poppler::FormFieldButton::Radio)
101             continue;
102 
103         // printf("%s \n", fieldButton->caption().toLatin1().data());
104         if (fieldButton->caption() == QStringLiteral("Wine")) {
105             wineFieldButton = fieldButton;
106         } else if (fieldButton->caption() == QStringLiteral("Beer")) {
107             beerFieldButton = fieldButton;
108         }
109     }
110 
111     // "Beer" and "Wine" radiobuttons belong to the same RadioButton group.
112     // So selecting one should unselect the other.
113     QVERIFY(beerFieldButton);
114     QVERIFY(wineFieldButton);
115 
116     // Test that the RadioButton group comes with "Beer" initially selected
117     QCOMPARE(beerFieldButton->state(), true);
118 
119     // Now select "Wine". As a result "Beer" should no longer be selected.
120     wineFieldButton->setState(true);
121 
122     // Test that "Beer" is indeed not reporting as being selected
123     QCOMPARE(beerFieldButton->state(), false);
124 }
125 
testSetIcon()126 void TestForms::testSetIcon()
127 {
128     QScopedPointer<Poppler::Document> document(Poppler::Document::load(TESTDATADIR "/unittestcases/form_set_icon.pdf"));
129     QVERIFY(document);
130 
131     QScopedPointer<Poppler::Page> page(document->page(0));
132     QVERIFY(page);
133 
134     QList<Poppler::FormField *> forms = page->formFields();
135 
136     Poppler::FormFieldButton *anmButton = nullptr;
137 
138     // First we are finding the field which will have its icon changed
139     Q_FOREACH (Poppler::FormField *field, forms) {
140 
141         if (field->type() != Poppler::FormField::FormButton)
142             continue;
143 
144         Poppler::FormFieldButton *fieldButton = static_cast<Poppler::FormFieldButton *>(field);
145         if (field->name() == QStringLiteral("anm0"))
146             anmButton = fieldButton;
147     }
148 
149     QVERIFY(anmButton);
150 
151     // Then we set the Icon on this field, for every other field
152     // And verify if it has a valid icon
153     Q_FOREACH (Poppler::FormField *field, forms) {
154 
155         if (field->type() != Poppler::FormField::FormButton)
156             continue;
157 
158         Poppler::FormFieldButton *fieldButton = static_cast<Poppler::FormFieldButton *>(field);
159         if (field->name() == QStringLiteral("anm0"))
160             continue;
161 
162         Poppler::FormFieldIcon newIcon = fieldButton->icon();
163 
164         anmButton->setIcon(newIcon);
165 
166         Poppler::FormFieldIcon anmIcon = anmButton->icon();
167 
168         QVERIFY(Poppler::FormFieldIconData::getData(anmIcon));
169         QVERIFY(Poppler::FormFieldIconData::getData(anmIcon)->icon);
170 
171         QCOMPARE(Poppler::FormFieldIconData::getData(anmIcon)->icon->lookupNF("AP").dictLookupNF("N").getRef().num, Poppler::FormFieldIconData::getData(newIcon)->icon->lookupNF("AP").dictLookupNF("N").getRef().num);
172     }
173 
174     // Just making sure that setting a invalid icon will still produce a valid icon.
175     anmButton->setIcon(Poppler::FormFieldIcon(nullptr));
176     Poppler::FormFieldIcon anmIcon = anmButton->icon();
177 
178     QVERIFY(Poppler::FormFieldIconData::getData(anmIcon));
179     QVERIFY(Poppler::FormFieldIconData::getData(anmIcon)->icon);
180 }
181 
testSetPrintable()182 void TestForms::testSetPrintable()
183 {
184     QScopedPointer<Poppler::Document> document(Poppler::Document::load(TESTDATADIR "/unittestcases/form_set_icon.pdf"));
185     QVERIFY(document);
186 
187     QScopedPointer<Poppler::Page> page(document->page(0));
188     QVERIFY(page);
189 
190     QList<Poppler::FormField *> forms = page->formFields();
191 
192     Q_FOREACH (Poppler::FormField *field, forms) {
193         field->setPrintable(true);
194         QCOMPARE(field->isPrintable(), true);
195 
196         field->setPrintable(false);
197         QCOMPARE(field->isPrintable(), false);
198     }
199 }
200 
testSetAppearanceText()201 void TestForms::testSetAppearanceText()
202 {
203     QScopedPointer<Poppler::Document> document(Poppler::Document::load(TESTDATADIR "/unittestcases/checkbox_issue_159.pdf"));
204     QVERIFY(document);
205 
206     QScopedPointer<Poppler::Page> page(document->page(0));
207     QVERIFY(page);
208 
209     QList<Poppler::FormField *> forms = page->formFields();
210 
211     int nTextForms = 0;
212 
213     Q_FOREACH (Poppler::FormField *field, forms) {
214 
215         if (field->type() != Poppler::FormField::FormText)
216             continue;
217 
218         nTextForms++;
219 
220         Poppler::FormFieldText *fft = static_cast<Poppler::FormFieldText *>(field);
221 
222         const QString textToSet = "HOLA" + fft->name();
223         fft->setAppearanceText(textToSet);
224 
225         Dict *dict = Poppler::FormFieldData::getFormWidget(fft)->getObj()->getDict();
226         Object strObject = dict->lookup("AP").dictLookup("N");
227 
228         QVERIFY(strObject.isStream());
229 
230         GooString s;
231         strObject.getStream()->fillGooString(&s);
232 
233         const QString textToFind = QStringLiteral("\n(%1) Tj\n").arg(textToSet);
234         QVERIFY(s.toStr().find(textToFind.toStdString()) != std::string::npos);
235     }
236 
237     QCOMPARE(nTextForms, 5);
238 }
239 
testUnicodeFieldAttributes()240 void TestForms::testUnicodeFieldAttributes()
241 {
242     QScopedPointer<Poppler::Document> document(Poppler::Document::load(TESTDATADIR "/unittestcases/fieldWithUtf16Names.pdf"));
243     QVERIFY(document);
244 
245     QScopedPointer<Poppler::Page> page(document->page(0));
246     QVERIFY(page);
247 
248     QList<Poppler::FormField *> forms = page->formFields();
249 
250     Poppler::FormField *field = forms.first();
251 
252     QCOMPARE(field->name(), QStringLiteral("Tex"));
253     QCOMPARE(field->uiName(), QStringLiteral("Texto de ayuda"));
254 }
255 
256 QTEST_GUILESS_MAIN(TestForms)
257 #include "check_forms.moc"
258