Tests added for Action handling of enter key press over buttons.

This CL contains embeddertests and pixel tests for verifying action to
be performed when enter key is pressed over buttons in PDF forms.

Upon receiving OnChar() event for button widget in
CFFL_InteractiveFormFiller, if pressed key is enter then associated
action is performed, e.g., reset form, goto URI.

Bug: chromium:1028991
Change-Id: I58826bb3f5650bf9997803a312a7f875ed14905c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/68010
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Badhri Ravikumar <bravi@microsoft.com>
diff --git a/fpdfsdk/fpdf_formfill_embeddertest.cpp b/fpdfsdk/fpdf_formfill_embeddertest.cpp
index 4ac3022..af0df63 100644
--- a/fpdfsdk/fpdf_formfill_embeddertest.cpp
+++ b/fpdfsdk/fpdf_formfill_embeddertest.cpp
@@ -21,6 +21,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 using testing::_;
+using testing::NiceMock;
 
 using FPDFFormFillEmbedderTest = EmbedderTest;
 
@@ -538,6 +539,7 @@
   EXPECT_CALL(mock, SetTimer(_, _)).Times(0);
   EXPECT_CALL(mock, KillTimer(_)).Times(0);
   EXPECT_CALL(mock, OnFocusChange(_, _, _)).Times(0);
+  EXPECT_CALL(mock, DoURIAction(_)).Times(0);
   SetDelegate(&mock);
 
   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
@@ -2672,3 +2674,48 @@
   DoubleClickOnFormFieldAtPoint(CFX_PointF(22, 22));
   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
 }
+
+class FPDFFormFillActionUriTest : public EmbedderTest {
+ protected:
+  FPDFFormFillActionUriTest() = default;
+  ~FPDFFormFillActionUriTest() override = default;
+
+  void SetUp() override {
+    EmbedderTest::SetUp();
+    ASSERT_TRUE(OpenDocument("annots_action_handling.pdf"));
+    page_ = LoadPage(0);
+    ASSERT_TRUE(page_);
+  }
+
+  void TearDown() override {
+    UnloadPage(page_);
+    EmbedderTest::TearDown();
+  }
+
+  void SetFocusOnFirstForm() {
+    FORM_OnMouseMove(form_handle(), page(), /*modifier=*/0, 100, 680);
+    FORM_OnLButtonDown(form_handle(), page(), /*modifier=*/0, 100, 680);
+    FORM_OnLButtonUp(form_handle(), page(), /*modifier=*/0, 100, 680);
+  }
+
+  FPDF_PAGE page() { return page_; }
+
+ private:
+  FPDF_PAGE page_ = nullptr;
+};
+
+TEST_F(FPDFFormFillActionUriTest, ButtonActionInvokeTest) {
+  NiceMock<EmbedderTestMockDelegate> mock;
+  // TODO(crbug.com/1028991): DoURIAction expect call should be 1.
+  EXPECT_CALL(mock, DoURIAction(_)).Times(0);
+  SetDelegate(&mock);
+
+  SetFocusOnFirstForm();
+
+  // Tab once from first form to go to button widget.
+  ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Tab, 0));
+
+  // TODO(crbug.com/1028991): Following should be changed to ASSERT_TRUE after
+  // handling key press implementation on buttons.
+  ASSERT_FALSE(FORM_OnChar(form_handle(), page(), FWL_VKEY_Return, 0));
+}
\ No newline at end of file
diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS
index aefc38c..ccce208 100644
--- a/testing/SUPPRESSIONS
+++ b/testing/SUPPRESSIONS
@@ -343,6 +343,9 @@
 # TODO(pdfium:1466): Remove after associated bug is fixed
 bug_1449.in linux * *
 
+# TODO(chromium:1028991): Remove after associated bug is fixed
+reset_button.in * * *
+
 # xfa_specific
 
 # TODO(pdfium:1107): Remove after associated bug is fixed
diff --git a/testing/embedder_test_mock_delegate.h b/testing/embedder_test_mock_delegate.h
index e9bd70e..06f144f 100644
--- a/testing/embedder_test_mock_delegate.h
+++ b/testing/embedder_test_mock_delegate.h
@@ -16,6 +16,7 @@
       int(FPDF_WIDESTRING message, FPDF_WIDESTRING title, int type, int icon));
   MOCK_METHOD2(SetTimer, int(int msecs, TimerCallback fn));
   MOCK_METHOD1(KillTimer, void(int msecs));
+  MOCK_METHOD1(DoURIAction, void(FPDF_BYTESTRING uri));
   MOCK_METHOD3(OnFocusChange,
                void(FPDF_FORMFILLINFO* info,
                     FPDF_ANNOTATION annot,
diff --git a/testing/resources/annots_action_handling.in b/testing/resources/annots_action_handling.in
new file mode 100644
index 0000000..bbf1a48
--- /dev/null
+++ b/testing/resources/annots_action_handling.in
@@ -0,0 +1,47 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm [5 0 R 6 0 R]
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [4 0 R 5 0 R]
+  /Tabs /R
+>>
+endobj
+{{object 4 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /Parent 3 0 R
+  /T (Sub_LeftBottom)
+  /Rect [69 670 220 690]
+>>
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Rect [69 360 220 380]
+  /A <<
+    /URI (https://www.google.com)
+    /S /URI
+  >>
+  /F 4
+  /T (button)
+  /Ff 65536
+>>
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
\ No newline at end of file
diff --git a/testing/resources/annots_action_handling.pdf b/testing/resources/annots_action_handling.pdf
new file mode 100644
index 0000000..70e62f7
--- /dev/null
+++ b/testing/resources/annots_action_handling.pdf
@@ -0,0 +1,59 @@
+%PDF-1.7
+% ò¤ô
+1 0 obj <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm [5 0 R 6 0 R]
+>>
+endobj
+2 0 obj <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+3 0 obj <<
+  /Type /Page
+  /Parent 2 0 R
+  /Annots [4 0 R 5 0 R]
+  /Tabs /R
+>>
+endobj
+4 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Tx
+  /Parent 3 0 R
+  /T (Sub_LeftBottom)
+  /Rect [69 670 220 690]
+>>
+endobj
+5 0 obj <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /Rect [69 360 220 380]
+  /A <<
+    /URI (https://www.google.com)
+    /S /URI
+  >>
+  /F 4
+  /T (button)
+  /Ff 65536
+>>
+endobj
+xref
+0 6
+0000000000 65535 f 
+0000000015 00000 n 
+0000000094 00000 n 
+0000000157 00000 n 
+0000000243 00000 n 
+0000000371 00000 n 
+trailer <<
+  /Root 1 0 R
+  /Size 6
+>>
+startxref
+554
+%%EOF
\ No newline at end of file
diff --git a/testing/resources/pixel/reset_button.evt b/testing/resources/pixel/reset_button.evt
new file mode 100644
index 0000000..1606926
--- /dev/null
+++ b/testing/resources/pixel/reset_button.evt
@@ -0,0 +1,10 @@
+# Check the checkbox
+mousemove,145,220
+mousedown,left,145,220
+mouseup,left,145,220
+
+# Tab to reset button from checkbox
+keycode,9
+
+# Press Enter to reset the form
+charcode,13
\ No newline at end of file
diff --git a/testing/resources/pixel/reset_button.in b/testing/resources/pixel/reset_button.in
new file mode 100644
index 0000000..6f93570
--- /dev/null
+++ b/testing/resources/pixel/reset_button.in
@@ -0,0 +1,97 @@
+{{header}}
+{{object 1 0}} <<
+  /Type /Catalog
+  /Pages 2 0 R
+  /AcroForm <<
+    /Fields [5 0 R 6 0 R]
+  >>
+>>
+endobj
+{{object 2 0}} <<
+  /Type /Pages
+  /Count 1
+  /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+  /Type /Page
+  /Parent 2 0 R
+  /MediaBox [0 0 300 300]
+  /Contents 4 0 R
+  /Annots [5 0 R 6 0 R]
+>>
+endobj
+{{object 4 0}} <<
+  {{streamlen}}
+>>
+stream
+q
+2 w
+.1 .1 .1 RG
+.8 .843 1 rg
+n 136 211 18 18 re B*
+Q
+endstream
+endobj
+{{object 5 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /F 4
+  /Ff 2
+  /P 3 0 R
+  /Rect [135 210 155 230]
+  /T (checkbox)
+  /AP <<
+    /N <<
+      /Yes 7 0 R
+    >>
+  >>
+  /AS /Off
+  /V /Off
+>>
+endobj
+{{object 6 0}} <<
+  /Type /Annot
+  /Subtype /Widget
+  /FT /Btn
+  /F 4
+  /P 3 0 R
+  /Rect [135 110 185 150]
+  /T (Reset button)
+  /Ff 65536
+  /A <<
+   /S /ResetForm
+   /Fields [5 0 R]
+   /Flags 1
+  >>
+  /MK <<
+    /BC [0.0 0.0 0.4]
+    /BG [0.9 0.9 0.9]
+  >>
+>>
+endobj
+{{object 7 0}} <<
+  /Type /XObject
+  /Subtype /Form
+  /FormType 1
+  /BBox [0 0 20 20]
+  {{streamlen}}
+>>
+stream
+q
+17.2 15.95145 m
+17.2 4.027746 l
+15.97225 2.8 l
+4.027746 2.8 l
+4.027746 17.2 l
+15.97225 17.2 l
+h
+f
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
\ No newline at end of file
diff --git a/testing/resources/pixel/reset_button_expected.pdf.0.png b/testing/resources/pixel/reset_button_expected.pdf.0.png
new file mode 100644
index 0000000..e36c30d
--- /dev/null
+++ b/testing/resources/pixel/reset_button_expected.pdf.0.png
Binary files differ