blob: f3043983c263e71c83757cbd1986abf475599f3e [file] [log] [blame]
Tom Sepeza310e002015-02-27 13:03:07 -08001// Copyright 2015 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Nicolas Pena742977f2017-04-13 15:28:20 -04005#include <memory>
6#include <string>
Diana Gagedce2d722017-06-20 11:17:11 -07007#include <vector>
Nicolas Pena742977f2017-04-13 15:28:20 -04008
Diana Gagedce2d722017-06-20 11:17:11 -07009#include "core/fxcrt/fx_string.h"
Nicolas Pena742977f2017-04-13 15:28:20 -040010#include "core/fxcrt/fx_system.h"
11#include "public/cpp/fpdf_deleters.h"
Lei Zhangb4e7f302015-11-06 15:52:32 -080012#include "public/fpdf_formfill.h"
Diana Gagedce2d722017-06-20 11:17:11 -070013#include "public/fpdf_fwlevent.h"
Wei Li091f7a02015-11-09 12:09:55 -080014#include "testing/embedder_test.h"
15#include "testing/embedder_test_mock_delegate.h"
16#include "testing/embedder_test_timer_handling_delegate.h"
Tom Sepeza310e002015-02-27 13:03:07 -080017#include "testing/gmock/include/gmock/gmock.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
20using testing::_;
21using testing::Return;
22
Diana Gagedce2d722017-06-20 11:17:11 -070023class FPDFFormFillEmbeddertest : public EmbedderTest, public TestSaver {
24 protected:
25 void TypeTextIntoTextfield(FPDF_PAGE page, int num_chars) {
26 // Click on the textfield in text_form.pdf.
27 EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
28 FPDFPage_HasFormFieldAtPoint(form_handle(), page, 120.0, 120.0));
29 FORM_OnMouseMove(form_handle(), page, 0, 120.0, 120.0);
30 FORM_OnLButtonDown(form_handle(), page, 0, 120.0, 120.0);
31 FORM_OnLButtonUp(form_handle(), page, 0, 120.0, 120.0);
32
33 // Type text starting with 'A' to as many chars as specified by |num_chars|.
34 for (int i = 0; i < num_chars; ++i) {
35 FORM_OnChar(form_handle(), page, 'A' + i, 0);
36 }
37 }
38
39 // Navigates to form text field using the mouse and then selects text via the
40 // shift and specfied left or right arrow key.
41 void SelectTextWithKeyboard(FPDF_PAGE page,
42 int num_chars,
43 int arrow_key,
44 double x,
45 double y) {
46 // Navigate to starting position for selection.
47 FORM_OnMouseMove(form_handle(), page, 0, x, y);
48 FORM_OnLButtonDown(form_handle(), page, 0, x, y);
49 FORM_OnLButtonUp(form_handle(), page, 0, x, y);
50
51 // Hold down shift (and don't release until entire text is selected).
52 FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Shift, 0);
53
54 // Select text char by char via left or right arrow key.
55 for (int i = 0; i < num_chars; ++i) {
56 FORM_OnKeyDown(form_handle(), page, arrow_key, FWL_EVENTFLAG_ShiftKey);
57 FORM_OnKeyUp(form_handle(), page, arrow_key, FWL_EVENTFLAG_ShiftKey);
58 }
59 FORM_OnKeyUp(form_handle(), page, FWL_VKEY_Shift, 0);
60 }
61
62 // Uses the mouse to navigate to form text field and select text.
63 void SelectTextWithMouse(FPDF_PAGE page,
64 double start_x,
65 double end_x,
66 double y) {
67 // Navigate to starting position and click mouse.
68 FORM_OnMouseMove(form_handle(), page, 0, start_x, y);
69 FORM_OnLButtonDown(form_handle(), page, 0, start_x, y);
70
71 // Hold down mouse until reach end of desired selection.
72 FORM_OnMouseMove(form_handle(), page, 0, end_x, y);
73 FORM_OnLButtonUp(form_handle(), page, 0, end_x, y);
74 }
75
76 void CheckSelection(FPDF_PAGE page, const CFX_WideString& expected_string) {
77 // Calculate expected length for selected text.
78 int num_chars = expected_string.GetLength();
79
80 // Check actual selection against expected selection.
81 const unsigned long expected_length =
82 sizeof(unsigned short) * (num_chars + 1);
83 unsigned long sel_text_len =
84 FORM_GetSelectedText(form_handle(), page, nullptr, 0);
85 ASSERT_EQ(expected_length, sel_text_len);
86
87 std::vector<unsigned short> buf(sel_text_len);
88 EXPECT_EQ(expected_length, FORM_GetSelectedText(form_handle(), page,
89 buf.data(), sel_text_len));
90
91 EXPECT_EQ(expected_string,
92 CFX_WideString::FromUTF16LE(buf.data(), num_chars));
93 }
94};
Tom Sepeza310e002015-02-27 13:03:07 -080095
96TEST_F(FPDFFormFillEmbeddertest, FirstTest) {
97 EmbedderTestMockDelegate mock;
98 EXPECT_CALL(mock, Alert(_, _, _, _)).Times(0);
99 EXPECT_CALL(mock, UnsupportedHandler(_)).Times(0);
Tom Sepez6efc0ad2015-06-02 17:11:18 -0700100 EXPECT_CALL(mock, SetTimer(_, _)).Times(0);
101 EXPECT_CALL(mock, KillTimer(_)).Times(0);
Tom Sepeza310e002015-02-27 13:03:07 -0800102 SetDelegate(&mock);
103
Wei Li091f7a02015-11-09 12:09:55 -0800104 EXPECT_TRUE(OpenDocument("hello_world.pdf"));
Tom Sepeza310e002015-02-27 13:03:07 -0800105 FPDF_PAGE page = LoadPage(0);
tsepez8e120292016-08-03 14:03:35 -0700106 EXPECT_TRUE(page);
Lei Zhangd27acae2015-05-15 15:36:02 -0700107 UnloadPage(page);
Tom Sepeza310e002015-02-27 13:03:07 -0800108}
Tom Sepez6efc0ad2015-06-02 17:11:18 -0700109
110TEST_F(FPDFFormFillEmbeddertest, BUG_487928) {
111 EmbedderTestTimerHandlingDelegate delegate;
112 SetDelegate(&delegate);
113
Wei Li091f7a02015-11-09 12:09:55 -0800114 EXPECT_TRUE(OpenDocument("bug_487928.pdf"));
Tom Sepez6efc0ad2015-06-02 17:11:18 -0700115 FPDF_PAGE page = LoadPage(0);
tsepez8e120292016-08-03 14:03:35 -0700116 EXPECT_TRUE(page);
Tom Sepez6efc0ad2015-06-02 17:11:18 -0700117 DoOpenActions();
118 delegate.AdvanceTime(5000);
119 UnloadPage(page);
120}
Tom Sepez0b133982015-07-28 11:23:22 -0700121
Tom Sepez396e8722015-09-09 10:16:08 -0700122TEST_F(FPDFFormFillEmbeddertest, BUG_507316) {
123 EmbedderTestTimerHandlingDelegate delegate;
124 SetDelegate(&delegate);
125
Wei Li091f7a02015-11-09 12:09:55 -0800126 EXPECT_TRUE(OpenDocument("bug_507316.pdf"));
weili0dadcc62016-08-23 21:10:57 -0700127 FPDF_PAGE page = LoadPage(2);
tsepez8e120292016-08-03 14:03:35 -0700128 EXPECT_TRUE(page);
Tom Sepez396e8722015-09-09 10:16:08 -0700129 DoOpenActions();
130 delegate.AdvanceTime(4000);
131 UnloadPage(page);
132}
133
Tom Sepez0b133982015-07-28 11:23:22 -0700134TEST_F(FPDFFormFillEmbeddertest, BUG_514690) {
Wei Li091f7a02015-11-09 12:09:55 -0800135 EXPECT_TRUE(OpenDocument("hello_world.pdf"));
Tom Sepez0b133982015-07-28 11:23:22 -0700136 FPDF_PAGE page = LoadPage(0);
tsepez8e120292016-08-03 14:03:35 -0700137 EXPECT_TRUE(page);
Tom Sepez0b133982015-07-28 11:23:22 -0700138
139 // Test that FORM_OnMouseMove() etc. permit null HANDLES and PAGES.
140 FORM_OnMouseMove(nullptr, page, 0, 10.0, 10.0);
141 FORM_OnMouseMove(form_handle(), nullptr, 0, 10.0, 10.0);
142
143 UnloadPage(page);
144}
Lei Zhang79e893a2015-11-04 16:02:47 -0800145
Tom Sepez4d071792016-02-04 16:53:26 -0800146#ifdef PDF_ENABLE_V8
Lei Zhang79e893a2015-11-04 16:02:47 -0800147TEST_F(FPDFFormFillEmbeddertest, BUG_551248) {
tsepez8e120292016-08-03 14:03:35 -0700148 // Test that timers fire once and intervals fire repeatedly.
Lei Zhang79e893a2015-11-04 16:02:47 -0800149 EmbedderTestTimerHandlingDelegate delegate;
150 SetDelegate(&delegate);
151
Wei Li091f7a02015-11-09 12:09:55 -0800152 EXPECT_TRUE(OpenDocument("bug_551248.pdf"));
Lei Zhang79e893a2015-11-04 16:02:47 -0800153 FPDF_PAGE page = LoadPage(0);
tsepez8e120292016-08-03 14:03:35 -0700154 EXPECT_TRUE(page);
155 DoOpenActions();
156
157 const auto& alerts = delegate.GetAlerts();
158 EXPECT_EQ(0U, alerts.size());
159
160 delegate.AdvanceTime(1000);
161 EXPECT_EQ(0U, alerts.size()); // nothing fired.
162 delegate.AdvanceTime(1000);
163 EXPECT_EQ(1U, alerts.size()); // interval fired.
164 delegate.AdvanceTime(1000);
165 EXPECT_EQ(2U, alerts.size()); // timer fired.
166 delegate.AdvanceTime(1000);
167 EXPECT_EQ(3U, alerts.size()); // interval fired again.
168 delegate.AdvanceTime(1000);
169 EXPECT_EQ(3U, alerts.size()); // nothing fired.
170 delegate.AdvanceTime(1000);
171 EXPECT_EQ(4U, alerts.size()); // interval fired again.
172 delegate.AdvanceTime(1000);
173 EXPECT_EQ(4U, alerts.size()); // nothing fired.
174 UnloadPage(page);
175
176 ASSERT_EQ(4U, alerts.size()); // nothing else fired.
177
178 EXPECT_STREQ(L"interval fired", alerts[0].message.c_str());
179 EXPECT_STREQ(L"Alert", alerts[0].title.c_str());
180 EXPECT_EQ(0, alerts[0].type);
181 EXPECT_EQ(0, alerts[0].icon);
182
183 EXPECT_STREQ(L"timer fired", alerts[1].message.c_str());
184 EXPECT_STREQ(L"Alert", alerts[1].title.c_str());
185 EXPECT_EQ(0, alerts[1].type);
186 EXPECT_EQ(0, alerts[1].icon);
187
188 EXPECT_STREQ(L"interval fired", alerts[2].message.c_str());
189 EXPECT_STREQ(L"Alert", alerts[2].title.c_str());
190 EXPECT_EQ(0, alerts[2].type);
191 EXPECT_EQ(0, alerts[2].icon);
192
193 EXPECT_STREQ(L"interval fired", alerts[3].message.c_str());
194 EXPECT_STREQ(L"Alert", alerts[3].title.c_str());
195 EXPECT_EQ(0, alerts[3].type);
196 EXPECT_EQ(0, alerts[3].icon);
197}
198
199TEST_F(FPDFFormFillEmbeddertest, BUG_620428) {
200 // Test that timers and intervals are cancelable.
201 EmbedderTestTimerHandlingDelegate delegate;
202 SetDelegate(&delegate);
203
204 EXPECT_TRUE(OpenDocument("bug_620428.pdf"));
205 FPDF_PAGE page = LoadPage(0);
206 EXPECT_TRUE(page);
Lei Zhang79e893a2015-11-04 16:02:47 -0800207 DoOpenActions();
208 delegate.AdvanceTime(5000);
209 UnloadPage(page);
210
211 const auto& alerts = delegate.GetAlerts();
tsepez0fa54b82016-08-04 12:07:28 -0700212 ASSERT_EQ(1U, alerts.size());
213 EXPECT_STREQ(L"done", alerts[0].message.c_str());
Lei Zhang79e893a2015-11-04 16:02:47 -0800214}
tsepez8e120292016-08-03 14:03:35 -0700215
tsepez32e693f2016-08-04 12:47:42 -0700216TEST_F(FPDFFormFillEmbeddertest, BUG_634394) {
217 // Cancel timer inside timer callback.
218 EmbedderTestTimerHandlingDelegate delegate;
219 SetDelegate(&delegate);
220
221 EXPECT_TRUE(OpenDocument("bug_634394.pdf"));
222 FPDF_PAGE page = LoadPage(0);
223 EXPECT_TRUE(page);
224 DoOpenActions();
225
226 // Timers fire at most once per AdvanceTime(), allow intervals
227 // to fire several times if possible.
228 delegate.AdvanceTime(1000);
229 delegate.AdvanceTime(1000);
230 delegate.AdvanceTime(1000);
231 delegate.AdvanceTime(1000);
232 delegate.AdvanceTime(1000);
233 UnloadPage(page);
234
235 const auto& alerts = delegate.GetAlerts();
236 EXPECT_EQ(2U, alerts.size());
237}
238
tsepez8ca63de2016-08-05 17:12:27 -0700239TEST_F(FPDFFormFillEmbeddertest, BUG_634716) {
240 EmbedderTestTimerHandlingDelegate delegate;
241 SetDelegate(&delegate);
242
243 EXPECT_TRUE(OpenDocument("bug_634716.pdf"));
244 FPDF_PAGE page = LoadPage(0);
245 EXPECT_TRUE(page);
246 DoOpenActions();
247
248 // Timers fire at most once per AdvanceTime(), allow intervals
249 // to fire several times if possible.
250 delegate.AdvanceTime(1000);
251 delegate.AdvanceTime(1000);
252 delegate.AdvanceTime(1000);
253 delegate.AdvanceTime(1000);
254 delegate.AdvanceTime(1000);
255 UnloadPage(page);
256
257 const auto& alerts = delegate.GetAlerts();
258 EXPECT_EQ(2U, alerts.size());
259}
260
tsepez6cf5eca2017-01-12 11:21:12 -0800261TEST_F(FPDFFormFillEmbeddertest, BUG_679649) {
262 EmbedderTestTimerHandlingDelegate delegate;
263 SetDelegate(&delegate);
264
265 EXPECT_TRUE(OpenDocument("bug_679649.pdf"));
266 FPDF_PAGE page = LoadPage(0);
267 EXPECT_TRUE(page);
268
269 delegate.SetFailNextTimer();
270 DoOpenActions();
271 delegate.AdvanceTime(2000);
272 UnloadPage(page);
273
274 const auto& alerts = delegate.GetAlerts();
275 EXPECT_EQ(0u, alerts.size());
276}
277
Tom Sepezfb7021c2017-05-31 10:29:25 -0700278TEST_F(FPDFFormFillEmbeddertest, BUG_707673) {
279 EmbedderTestTimerHandlingDelegate delegate;
280 SetDelegate(&delegate);
281
282 EXPECT_TRUE(OpenDocument("bug_707673.pdf"));
283 FPDF_PAGE page = LoadPage(0);
284 EXPECT_TRUE(page);
285
286 DoOpenActions();
287 FORM_OnLButtonDown(form_handle(), page, 0, 140, 590);
288 FORM_OnLButtonUp(form_handle(), page, 0, 140, 590);
289 delegate.AdvanceTime(1000);
290 UnloadPage(page);
291
292 const auto& alerts = delegate.GetAlerts();
293 EXPECT_EQ(0u, alerts.size());
294}
295
Tom Sepez4d071792016-02-04 16:53:26 -0800296#endif // PDF_ENABLE_V8
Nicolas Pena742977f2017-04-13 15:28:20 -0400297
298TEST_F(FPDFFormFillEmbeddertest, FormText) {
299#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
300 const char md5_1[] = "5f11dbe575fe197a37c3fb422559f8ff";
301 const char md5_2[] = "35b1a4b679eafc749a0b6fda750c0e8d";
302 const char md5_3[] = "65c64a7c355388f719a752aa1e23f6fe";
303#else
304 const char md5_1[] = "23baecc6e94d4c8b894cd39aa04c584c";
305 const char md5_2[] = "499df95d477dfe35ee65b823c69743b5";
306 const char md5_3[] = "8f91b62895fc505d9e17ff2d633756d4";
307#endif
308 {
309 EXPECT_TRUE(OpenDocument("text_form.pdf"));
310 FPDF_PAGE page = LoadPage(0);
311 ASSERT_TRUE(page);
312 std::unique_ptr<void, FPDFBitmapDeleter> bitmap1(RenderPage(page));
313 CompareBitmap(bitmap1.get(), 300, 300, md5_1);
314
315 // Click on the textfield
316 EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
317 FPDFPage_HasFormFieldAtPoint(form_handle(), page, 120.0, 120.0));
318 FORM_OnMouseMove(form_handle(), page, 0, 120.0, 120.0);
319 FORM_OnLButtonDown(form_handle(), page, 0, 120.0, 120.0);
320 FORM_OnLButtonUp(form_handle(), page, 0, 120.0, 120.0);
321
322 // Write "ABC"
323 FORM_OnChar(form_handle(), page, 65, 0);
324 FORM_OnChar(form_handle(), page, 66, 0);
325 FORM_OnChar(form_handle(), page, 67, 0);
326 std::unique_ptr<void, FPDFBitmapDeleter> bitmap2(RenderPage(page));
327 CompareBitmap(bitmap2.get(), 300, 300, md5_2);
328
329 // Take out focus by clicking out of the textfield
330 FORM_OnMouseMove(form_handle(), page, 0, 15.0, 15.0);
331 FORM_OnLButtonDown(form_handle(), page, 0, 15.0, 15.0);
332 FORM_OnLButtonUp(form_handle(), page, 0, 15.0, 15.0);
333 std::unique_ptr<void, FPDFBitmapDeleter> bitmap3(RenderPage(page));
334 CompareBitmap(bitmap3.get(), 300, 300, md5_3);
335
336 EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
337
338 // Close everything
339 UnloadPage(page);
340 FPDFDOC_ExitFormFillEnvironment(form_handle_);
341 FPDF_CloseDocument(document_);
342 }
343 // Check saved document
344 std::string new_file = GetString();
345 FPDF_FILEACCESS file_access;
346 memset(&file_access, 0, sizeof(file_access));
347 file_access.m_FileLen = new_file.size();
348 file_access.m_GetBlock = GetBlockFromString;
349 file_access.m_Param = &new_file;
350 document_ = FPDF_LoadCustomDocument(&file_access, nullptr);
351 SetupFormFillEnvironment();
352 EXPECT_EQ(1, FPDF_GetPageCount(document_));
353 std::unique_ptr<void, FPDFPageDeleter> new_page(FPDF_LoadPage(document_, 0));
354 ASSERT_TRUE(new_page.get());
355 std::unique_ptr<void, FPDFBitmapDeleter> new_bitmap(
356 RenderPage(new_page.get()));
357 CompareBitmap(new_bitmap.get(), 300, 300, md5_3);
358}
Diana Gagedce2d722017-06-20 11:17:11 -0700359
360TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextEmptyAndBasicKeyboard) {
361 // Open file with form text field.
362 EXPECT_TRUE(OpenDocument("text_form.pdf"));
363 FPDF_PAGE page = LoadPage(0);
364 ASSERT_TRUE(page);
365
366 // Test empty selection.
367 CheckSelection(page, CFX_WideString(L""));
368
369 // Test basic selection.
370 TypeTextIntoTextfield(page, 3);
371 SelectTextWithKeyboard(page, 3, FWL_VKEY_Left, 123.0, 115.5);
372 CheckSelection(page, CFX_WideString(L"ABC"));
373
374 UnloadPage(page);
375}
376
377TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextEmptyAndBasicMouse) {
378 // Open file with form text field.
379 EXPECT_TRUE(OpenDocument("text_form.pdf"));
380 FPDF_PAGE page = LoadPage(0);
381 ASSERT_TRUE(page);
382
383 // Test empty selection.
384 CheckSelection(page, CFX_WideString(L""));
385
386 // Test basic selection.
387 TypeTextIntoTextfield(page, 3);
388 SelectTextWithMouse(page, 125.0, 102.0, 115.5);
389 CheckSelection(page, CFX_WideString(L"ABC"));
390
391 UnloadPage(page);
392}
393
394TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextFragmentsKeyBoard) {
395 // Open file with form text field.
396 EXPECT_TRUE(OpenDocument("text_form.pdf"));
397 FPDF_PAGE page = LoadPage(0);
398 ASSERT_TRUE(page);
399
400 TypeTextIntoTextfield(page, 12);
401
402 // Test selecting first character in forward direction.
403 // Navigate to starting position and click mouse.
404 SelectTextWithKeyboard(page, 1, FWL_VKEY_Right, 102.0, 115.5);
405 CheckSelection(page, CFX_WideString(L"A"));
406
407 // Test selecting entire long string in backwards direction.
408 SelectTextWithKeyboard(page, 12, FWL_VKEY_Left, 191.0, 115.5);
409 CheckSelection(page, CFX_WideString(L"ABCDEFGHIJKL"));
410
411 // Test selecting middle section in backwards direction.
412 SelectTextWithKeyboard(page, 6, FWL_VKEY_Left, 170.0, 115.5);
413 CheckSelection(page, CFX_WideString(L"DEFGHI"));
414
415 // Test selecting middle selection in forward direction.
416 SelectTextWithKeyboard(page, 6, FWL_VKEY_Right, 125.0, 115.5);
417 CheckSelection(page, CFX_WideString(L"DEFGHI"));
418
419 // Test selecting last character in backwards direction.
420 SelectTextWithKeyboard(page, 1, FWL_VKEY_Left, 191.0, 115.5);
421 CheckSelection(page, CFX_WideString(L"L"));
422
423 UnloadPage(page);
424}
425
426TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextFragmentsMouse) {
427 // Open file with form text field.
428 EXPECT_TRUE(OpenDocument("text_form.pdf"));
429 FPDF_PAGE page = LoadPage(0);
430 ASSERT_TRUE(page);
431
432 TypeTextIntoTextfield(page, 12);
433
434 // Test selecting first character in forward direction.
435 SelectTextWithMouse(page, 102.0, 106.0, 115.5);
436 CheckSelection(page, CFX_WideString(L"A"));
437
438 // Test selecting entire long string in backwards direction.
439 SelectTextWithMouse(page, 191.0, 102.0, 115.5);
440 CheckSelection(page, CFX_WideString(L"ABCDEFGHIJKL"));
441
442 // Test selecting middle section in backwards direction.
443 SelectTextWithMouse(page, 170.0, 125.0, 115.5);
444 CheckSelection(page, CFX_WideString(L"DEFGHI"));
445
446 // Test selecting middle selection in forward direction.
447 SelectTextWithMouse(page, 125.0, 170.0, 115.5);
448 CheckSelection(page, CFX_WideString(L"DEFGHI"));
449
450 // Test selecting last character in backwards direction.
451 SelectTextWithMouse(page, 191.0, 186.0, 115.5);
452 CheckSelection(page, CFX_WideString(L"L"));
453
454 UnloadPage(page);
455}