1 // Copyright 2020 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "fpdfsdk/cpdfsdk_annotiterator.h"
6 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
7 #include "fpdfsdk/cpdfsdk_helpers.h"
8 #include "fpdfsdk/cpdfsdk_widget.h"
9 #include "fpdfsdk/formfiller/cffl_formfield.h"
10 #include "fpdfsdk/pwl/cpwl_special_button.h"
11 #include "fpdfsdk/pwl/cpwl_wnd.h"
12 #include "testing/embedder_test.h"
13
14 class CPWLSpecialButtonEmbedderTest : public EmbedderTest {
15 protected:
SetUp()16 void SetUp() override {
17 EmbedderTest::SetUp();
18 ASSERT_TRUE(OpenDocument("click_form.pdf"));
19 }
20
TearDown()21 void TearDown() override {
22 EmbedderTest::TearDown();
23 }
24
CreateAndInitializeFormPDF()25 void CreateAndInitializeFormPDF() {
26 formfill_env_ = CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle());
27 CPDFSDK_AnnotIterator it(formfill_env_->GetPageViewAtIndex(0),
28 {CPDF_Annot::Subtype::WIDGET});
29
30 // Read only check box.
31 widget_readonly_checkbox_ = ToCPDFSDKWidget(it.GetFirstAnnot());
32 ASSERT_TRUE(widget_readonly_checkbox_);
33 ASSERT_EQ(CPDF_Annot::Subtype::WIDGET,
34 widget_readonly_checkbox_->GetAnnotSubtype());
35
36 // Check box.
37 widget_checkbox_ =
38 ToCPDFSDKWidget(it.GetNextAnnot(widget_readonly_checkbox_));
39 ASSERT_TRUE(widget_checkbox_);
40 ASSERT_EQ(CPDF_Annot::Subtype::WIDGET, widget_checkbox_->GetAnnotSubtype());
41
42 // Read only radio button.
43 widget_readonly_radiobutton_ =
44 ToCPDFSDKWidget(it.GetNextAnnot(widget_checkbox_));
45 ASSERT_TRUE(widget_readonly_radiobutton_);
46 ASSERT_EQ(CPDF_Annot::Subtype::WIDGET,
47 widget_readonly_radiobutton_->GetAnnotSubtype());
48
49 // Tabbing three times from read only radio button to unselected normal
50 // radio button.
51 widget_radiobutton_ = widget_readonly_radiobutton_;
52 ASSERT_TRUE(widget_radiobutton_);
53 for (int i = 0; i < 3; i++) {
54 widget_radiobutton_ =
55 ToCPDFSDKWidget(it.GetNextAnnot(widget_radiobutton_));
56 ASSERT_TRUE(widget_radiobutton_);
57 }
58
59 ASSERT_EQ(CPDF_Annot::Subtype::WIDGET,
60 widget_radiobutton_->GetAnnotSubtype());
61 }
62
FormFillerAndWindowSetup(CPDFSDK_Widget * widget)63 void FormFillerAndWindowSetup(CPDFSDK_Widget* widget) {
64 CFFL_InteractiveFormFiller* interactive_formfiller =
65 formfill_env_->GetInteractiveFormFiller();
66 {
67 ObservedPtr<CPDFSDK_Widget> observed(widget);
68 EXPECT_TRUE(interactive_formfiller->OnSetFocus(observed, {}));
69 }
70
71 form_filler_ = interactive_formfiller->GetFormFieldForTesting(widget);
72 ASSERT_TRUE(form_filler_);
73
74 window_ = form_filler_->CreateOrUpdatePWLWindow(
75 formfill_env_->GetPageViewAtIndex(0));
76 ASSERT_TRUE(window_);
77 }
78
GetCPDFSDKWidgetCheckBox() const79 CPDFSDK_Widget* GetCPDFSDKWidgetCheckBox() const { return widget_checkbox_; }
GetCPDFSDKWidgetReadOnlyCheckBox() const80 CPDFSDK_Widget* GetCPDFSDKWidgetReadOnlyCheckBox() const {
81 return widget_readonly_checkbox_;
82 }
GetCPDFSDKWidgetRadioButton() const83 CPDFSDK_Widget* GetCPDFSDKWidgetRadioButton() const {
84 return widget_radiobutton_;
85 }
GetCPDFSDKWidgetReadOnlyRadioButton() const86 CPDFSDK_Widget* GetCPDFSDKWidgetReadOnlyRadioButton() const {
87 return widget_readonly_radiobutton_;
88 }
GetCPDFSDKFormFillEnv() const89 CPDFSDK_FormFillEnvironment* GetCPDFSDKFormFillEnv() const {
90 return formfill_env_;
91 }
GetWindow() const92 CPWL_Wnd* GetWindow() const { return window_; }
93
94 private:
95 CFFL_FormField* form_filler_;
96 CPDFSDK_Widget* widget_checkbox_;
97 CPDFSDK_Widget* widget_readonly_checkbox_;
98 CPDFSDK_Widget* widget_radiobutton_;
99 CPDFSDK_Widget* widget_readonly_radiobutton_;
100 CPDFSDK_FormFillEnvironment* formfill_env_;
101 CPWL_Wnd* window_;
102 };
103
TEST_F(CPWLSpecialButtonEmbedderTest,EnterOnReadOnlyCheckBox)104 TEST_F(CPWLSpecialButtonEmbedderTest, EnterOnReadOnlyCheckBox) {
105 ScopedEmbedderTestPage page = LoadScopedPage(0);
106 ASSERT_TRUE(page);
107 CreateAndInitializeFormPDF();
108
109 FormFillerAndWindowSetup(GetCPDFSDKWidgetReadOnlyCheckBox());
110 CPWL_CheckBox* check_box = static_cast<CPWL_CheckBox*>(GetWindow());
111 EXPECT_TRUE(check_box->IsChecked());
112 EXPECT_TRUE(GetCPDFSDKFormFillEnv()->GetInteractiveFormFiller()->OnChar(
113 GetCPDFSDKWidgetReadOnlyCheckBox(), '\r', {}));
114 EXPECT_TRUE(check_box->IsChecked());
115 }
116
TEST_F(CPWLSpecialButtonEmbedderTest,EnterOnCheckBox)117 TEST_F(CPWLSpecialButtonEmbedderTest, EnterOnCheckBox) {
118 ScopedEmbedderTestPage page = LoadScopedPage(0);
119 ASSERT_TRUE(page);
120 CreateAndInitializeFormPDF();
121
122 FormFillerAndWindowSetup(GetCPDFSDKWidgetCheckBox());
123 CPWL_CheckBox* check_box = static_cast<CPWL_CheckBox*>(GetWindow());
124 EXPECT_TRUE(GetCPDFSDKFormFillEnv()->GetInteractiveFormFiller()->OnChar(
125 GetCPDFSDKWidgetCheckBox(), '\r', {}));
126 EXPECT_TRUE(check_box->IsChecked());
127
128 EXPECT_TRUE(GetCPDFSDKFormFillEnv()->GetInteractiveFormFiller()->OnChar(
129 GetCPDFSDKWidgetCheckBox(), '\r', {}));
130 EXPECT_FALSE(check_box->IsChecked());
131 }
132
TEST_F(CPWLSpecialButtonEmbedderTest,EnterOnReadOnlyRadioButton)133 TEST_F(CPWLSpecialButtonEmbedderTest, EnterOnReadOnlyRadioButton) {
134 ScopedEmbedderTestPage page = LoadScopedPage(0);
135 ASSERT_TRUE(page);
136 CreateAndInitializeFormPDF();
137
138 FormFillerAndWindowSetup(GetCPDFSDKWidgetReadOnlyRadioButton());
139 CPWL_RadioButton* radio_button = static_cast<CPWL_RadioButton*>(GetWindow());
140 EXPECT_FALSE(radio_button->IsChecked());
141 EXPECT_TRUE(GetCPDFSDKFormFillEnv()->GetInteractiveFormFiller()->OnChar(
142 GetCPDFSDKWidgetReadOnlyRadioButton(), '\r', {}));
143 EXPECT_FALSE(radio_button->IsChecked());
144 }
145
TEST_F(CPWLSpecialButtonEmbedderTest,EnterOnRadioButton)146 TEST_F(CPWLSpecialButtonEmbedderTest, EnterOnRadioButton) {
147 ScopedEmbedderTestPage page = LoadScopedPage(0);
148 ASSERT_TRUE(page);
149 CreateAndInitializeFormPDF();
150
151 FormFillerAndWindowSetup(GetCPDFSDKWidgetRadioButton());
152 CPWL_RadioButton* radio_button = static_cast<CPWL_RadioButton*>(GetWindow());
153 EXPECT_TRUE(GetCPDFSDKFormFillEnv()->GetInteractiveFormFiller()->OnChar(
154 GetCPDFSDKWidgetRadioButton(), '\r', {}));
155 EXPECT_TRUE(radio_button->IsChecked());
156 }
157