Merge and extend FocusableAnnotSubtypes tests.
Instead of testing the 3 related APIs separately, test them at the same
time as they can naturally be used together.
Also add some FORM_SetFocusedAnnot() calls to see the effect of calling
FPDFAnnot_SetFocusableSubtypes(). This also reveals an issue with
FORM_SetFocusedAnnot() when it comes to focusing popups and widgets.
Bug: pdfium:1507
Change-Id: Ic8ee8bb897b0f92f02c6c0b55f286f735ee84cd3
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/68530
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/fpdfsdk/fpdf_annot_embeddertest.cpp b/fpdfsdk/fpdf_annot_embeddertest.cpp
index 8067026..029718f 100644
--- a/fpdfsdk/fpdf_annot_embeddertest.cpp
+++ b/fpdfsdk/fpdf_annot_embeddertest.cpp
@@ -22,6 +22,55 @@
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/utils/hash.h"
+#include "third_party/base/span.h"
+
+namespace {
+
+void VerifyFocusableAnnotSubtypes(
+ FPDF_FORMHANDLE form_handle,
+ pdfium::span<const FPDF_ANNOTATION_SUBTYPE> expected_subtypes) {
+ ASSERT_EQ(static_cast<int>(expected_subtypes.size()),
+ FPDFAnnot_GetFocusableSubtypesCount(form_handle));
+
+ std::vector<FPDF_ANNOTATION_SUBTYPE> actual_subtypes(
+ expected_subtypes.size());
+ ASSERT_TRUE(FPDFAnnot_GetFocusableSubtypes(
+ form_handle, actual_subtypes.data(), actual_subtypes.size()));
+ for (size_t i = 0; i < expected_subtypes.size(); ++i)
+ ASSERT_EQ(expected_subtypes[i], actual_subtypes[i]);
+}
+
+void SetAndVerifyFocusableAnnotSubtypes(
+ FPDF_FORMHANDLE form_handle,
+ pdfium::span<const FPDF_ANNOTATION_SUBTYPE> subtypes) {
+ ASSERT_TRUE(FPDFAnnot_SetFocusableSubtypes(form_handle, subtypes.data(),
+ subtypes.size()));
+ VerifyFocusableAnnotSubtypes(form_handle, subtypes);
+}
+
+void VerifyAnnotationSubtypesAndFocusability(
+ FPDF_FORMHANDLE form_handle,
+ FPDF_PAGE page,
+ pdfium::span<const FPDF_ANNOTATION_SUBTYPE> expected_subtypes,
+ pdfium::span<const FPDF_ANNOTATION_SUBTYPE> expected_focusable_subtypes) {
+ ASSERT_EQ(static_cast<int>(expected_subtypes.size()),
+ FPDFPage_GetAnnotCount(page));
+ for (size_t i = 0; i < expected_subtypes.size(); ++i) {
+ ScopedFPDFAnnotation annot(FPDFPage_GetAnnot(page, i));
+ ASSERT_TRUE(annot);
+ EXPECT_EQ(expected_subtypes[i], FPDFAnnot_GetSubtype(annot.get()));
+
+ bool expected_focusable = pdfium::ContainsValue(expected_focusable_subtypes,
+ expected_subtypes[i]);
+ EXPECT_EQ(expected_focusable,
+ FORM_SetFocusedAnnot(form_handle, annot.get()));
+
+ // Kill the focus so the next test starts in an unfocused state.
+ FORM_ForceToKillFocus(form_handle);
+ }
+}
+
+} // namespace
class FPDFAnnotEmbedderTest : public EmbedderTest {};
@@ -2383,87 +2432,72 @@
UnloadPage(page);
}
-TEST_F(FPDFAnnotEmbedderTest, SetFocusableAnnotSubtypes) {
- ASSERT_TRUE(OpenDocument("text_form.pdf"));
+TEST_F(FPDFAnnotEmbedderTest, FocusableAnnotSubtypes) {
+ ASSERT_TRUE(OpenDocument("annots.pdf"));
FPDF_PAGE page = LoadPage(0);
ASSERT_TRUE(page);
- // Annotations of type FPDF_ANNOT_WIDGET are by default focusable.
- EXPECT_EQ(1, FPDFAnnot_GetFocusableSubtypesCount(form_handle()));
+ // Verify widgets are by default focusable.
+ const FPDF_ANNOTATION_SUBTYPE kDefaultSubtypes[] = {FPDF_ANNOT_WIDGET};
+ VerifyFocusableAnnotSubtypes(form_handle(), kDefaultSubtypes);
- EXPECT_TRUE(FPDFAnnot_SetFocusableSubtypes(form_handle(), nullptr, 0));
- EXPECT_EQ(0, FPDFAnnot_GetFocusableSubtypesCount(form_handle()));
+ // Expected annot subtypes for page 0 of annots.pdf.
+ const FPDF_ANNOTATION_SUBTYPE kExpectedAnnotSubtypes[] = {
+ FPDF_ANNOT_LINK, FPDF_ANNOT_LINK, FPDF_ANNOT_LINK,
+ FPDF_ANNOT_LINK, FPDF_ANNOT_HIGHLIGHT, FPDF_ANNOT_HIGHLIGHT,
+ FPDF_ANNOT_POPUP, FPDF_ANNOT_HIGHLIGHT, FPDF_ANNOT_WIDGET,
+ };
- constexpr FPDF_ANNOTATION_SUBTYPE kFocusableSubtypes[] = {FPDF_ANNOT_WIDGET};
- constexpr size_t kSubtypeCount = FX_ArraySize(kFocusableSubtypes);
+ // TODO(crbug.com/pdfium/1507): Popups should not be focusable.
+ const FPDF_ANNOTATION_SUBTYPE kExpectedDefaultFocusableSubtypes[] = {
+ FPDF_ANNOT_WIDGET, FPDF_ANNOT_POPUP};
+ VerifyAnnotationSubtypesAndFocusability(form_handle(), page,
+ kExpectedAnnotSubtypes,
+ kExpectedDefaultFocusableSubtypes);
- EXPECT_FALSE(FPDFAnnot_SetFocusableSubtypes(nullptr, kFocusableSubtypes,
- kSubtypeCount));
- EXPECT_FALSE(
- FPDFAnnot_SetFocusableSubtypes(form_handle(), nullptr, kSubtypeCount));
+ // Make no annotation type focusable using the preferred method.
+ ASSERT_TRUE(FPDFAnnot_SetFocusableSubtypes(form_handle(), nullptr, 0));
+ ASSERT_EQ(0, FPDFAnnot_GetFocusableSubtypesCount(form_handle()));
- EXPECT_TRUE(FPDFAnnot_SetFocusableSubtypes(form_handle(), kFocusableSubtypes,
- kSubtypeCount));
- EXPECT_EQ(static_cast<int>(kSubtypeCount),
- FPDFAnnot_GetFocusableSubtypesCount(form_handle()));
+ // Restore the focusable type count back to 1, then set it back to 0 using a
+ // different method.
+ SetAndVerifyFocusableAnnotSubtypes(form_handle(), kDefaultSubtypes);
+ ASSERT_TRUE(
+ FPDFAnnot_SetFocusableSubtypes(form_handle(), kDefaultSubtypes, 0));
+ ASSERT_EQ(0, FPDFAnnot_GetFocusableSubtypesCount(form_handle()));
- EXPECT_TRUE(
- FPDFAnnot_SetFocusableSubtypes(form_handle(), kFocusableSubtypes, 0));
- EXPECT_EQ(0, FPDFAnnot_GetFocusableSubtypesCount(form_handle()));
+ // TODO(crbug.com/pdfium/1507): Widgets and popups should not be focusable.
+ const FPDF_ANNOTATION_SUBTYPE kExpectedNoFocusableSubtypes[] = {
+ FPDF_ANNOT_WIDGET, FPDF_ANNOT_POPUP};
+ VerifyAnnotationSubtypesAndFocusability(form_handle(), page,
+ kExpectedAnnotSubtypes,
+ kExpectedNoFocusableSubtypes);
- UnloadPage(page);
-}
+ // Now make links focusable.
+ const FPDF_ANNOTATION_SUBTYPE kLinkSubtypes[] = {FPDF_ANNOT_LINK};
+ SetAndVerifyFocusableAnnotSubtypes(form_handle(), kLinkSubtypes);
-TEST_F(FPDFAnnotEmbedderTest, GetFocusableAnnotSubtypesCount) {
- ASSERT_TRUE(OpenDocument("text_form.pdf"));
- FPDF_PAGE page = LoadPage(0);
- ASSERT_TRUE(page);
+ // TODO(crbug.com/pdfium/1507): Widgets and popups should not be focusable.
+ const FPDF_ANNOTATION_SUBTYPE kExpectedLinkocusableSubtypes[] = {
+ FPDF_ANNOT_WIDGET, FPDF_ANNOT_LINK, FPDF_ANNOT_POPUP};
+ VerifyAnnotationSubtypesAndFocusability(form_handle(), page,
+ kExpectedAnnotSubtypes,
+ kExpectedLinkocusableSubtypes);
+ // Test invalid parameters.
+ EXPECT_FALSE(FPDFAnnot_SetFocusableSubtypes(nullptr, kDefaultSubtypes,
+ FX_ArraySize(kDefaultSubtypes)));
+ EXPECT_FALSE(FPDFAnnot_SetFocusableSubtypes(form_handle(), nullptr,
+ FX_ArraySize(kDefaultSubtypes)));
EXPECT_EQ(-1, FPDFAnnot_GetFocusableSubtypesCount(nullptr));
- // FPDF_ANNOT_WIDGET is default annot subtype which is focusable,
- // hence 1 is default count.
- EXPECT_EQ(1, FPDFAnnot_GetFocusableSubtypesCount(form_handle()));
-
- constexpr FPDF_ANNOTATION_SUBTYPE kFocusableSubtypes[] = {FPDF_ANNOT_WIDGET,
- FPDF_ANNOT_LINK};
- constexpr size_t kSubtypeCount = FX_ArraySize(kFocusableSubtypes);
-
- FPDFAnnot_SetFocusableSubtypes(form_handle(), kFocusableSubtypes,
- kSubtypeCount);
-
- EXPECT_EQ(static_cast<int>(kSubtypeCount),
- FPDFAnnot_GetFocusableSubtypesCount(form_handle()));
-
- UnloadPage(page);
-}
-
-TEST_F(FPDFAnnotEmbedderTest, GetFocusableAnnotSubtypes) {
- ASSERT_TRUE(OpenDocument("text_form.pdf"));
- FPDF_PAGE page = LoadPage(0);
- ASSERT_TRUE(page);
-
- constexpr FPDF_ANNOTATION_SUBTYPE kFocusableSubtypes[] = {FPDF_ANNOT_WIDGET};
- constexpr size_t kSubtypeCount = FX_ArraySize(kFocusableSubtypes);
-
- FPDFAnnot_SetFocusableSubtypes(form_handle(), kFocusableSubtypes,
- kSubtypeCount);
-
- int count = FPDFAnnot_GetFocusableSubtypesCount(form_handle());
- ASSERT_EQ(1, count);
- EXPECT_FALSE(FPDFAnnot_GetFocusableSubtypes(form_handle(), nullptr, count));
-
- std::vector<FPDF_ANNOTATION_SUBTYPE> subtypes(count, FPDF_ANNOT_UNKNOWN);
- EXPECT_FALSE(FPDFAnnot_GetFocusableSubtypes(form_handle(), subtypes.data(),
- count - 1));
- EXPECT_FALSE(FPDFAnnot_GetFocusableSubtypes(nullptr, subtypes.data(), count));
-
- EXPECT_TRUE(
- FPDFAnnot_GetFocusableSubtypes(form_handle(), subtypes.data(), count));
-
- for (int i = 0; i < count; ++i) {
- EXPECT_EQ(kFocusableSubtypes[i], subtypes[i]);
- }
+ std::vector<FPDF_ANNOTATION_SUBTYPE> subtypes(1);
+ EXPECT_FALSE(FPDFAnnot_GetFocusableSubtypes(nullptr, subtypes.data(),
+ subtypes.size()));
+ EXPECT_FALSE(
+ FPDFAnnot_GetFocusableSubtypes(form_handle(), nullptr, subtypes.size()));
+ EXPECT_FALSE(
+ FPDFAnnot_GetFocusableSubtypes(form_handle(), subtypes.data(), 0));
UnloadPage(page);
}