// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/accessibility/browser_accessibility_auralinux.h"

#include <atk/atk.h>
#include <memory>
#include <string>
#include <vector>

#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/test_browser_accessibility_delegate.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/platform/ax_platform_node_auralinux.h"

namespace content {

class BrowserAccessibilityAuraLinuxTest : public testing::Test {
 public:
  BrowserAccessibilityAuraLinuxTest();
  ~BrowserAccessibilityAuraLinuxTest() override;

 protected:
  std::unique_ptr<TestBrowserAccessibilityDelegate>
      test_browser_accessibility_delegate_;

 private:
  void SetUp() override;

  content::BrowserTaskEnvironment task_environment_;
  ui::testing::ScopedAxModeSetter ax_mode_setter_;

  DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityAuraLinuxTest);
};

BrowserAccessibilityAuraLinuxTest::BrowserAccessibilityAuraLinuxTest()
    : ax_mode_setter_(ui::kAXModeComplete) {}

BrowserAccessibilityAuraLinuxTest::~BrowserAccessibilityAuraLinuxTest() =
    default;

void BrowserAccessibilityAuraLinuxTest::SetUp() {
  test_browser_accessibility_delegate_ =
      std::make_unique<TestBrowserAccessibilityDelegate>();
}

TEST_F(BrowserAccessibilityAuraLinuxTest, TestSimpleAtkText) {
  ui::AXNodeData root_data;
  root_data.id = 1;
  root_data.role = ax::mojom::Role::kStaticText;
  root_data.SetName("\xE2\x98\xBA Multiple Words");

  std::unique_ptr<BrowserAccessibilityManager> manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdate(root_data),
          test_browser_accessibility_delegate_.get()));

  ui::AXPlatformNodeAuraLinux* root_obj =
      ToBrowserAccessibilityAuraLinux(manager->GetRoot())->GetNode();
  AtkObject* root_atk_object(root_obj->GetNativeViewAccessible());
  ASSERT_TRUE(ATK_IS_OBJECT(root_atk_object));
  ASSERT_TRUE(ATK_IS_TEXT(root_atk_object));
  g_object_ref(root_atk_object);

  AtkText* atk_text = ATK_TEXT(root_atk_object);

  auto verify_atk_text_contents = [&](const char* expected_text,
                                      int start_offset, int end_offset) {
    gchar* text = atk_text_get_text(atk_text, start_offset, end_offset);
    EXPECT_STREQ(expected_text, text);
    g_free(text);
  };

  verify_atk_text_contents("\xE2\x98\xBA Multiple Words", 0, -1);
  verify_atk_text_contents("Multiple Words", 2, -1);
  verify_atk_text_contents("\xE2\x98\xBA", 0, 1);

  EXPECT_EQ(16, atk_text_get_character_count(atk_text));

  g_object_unref(root_atk_object);

  manager.reset();
}

TEST_F(BrowserAccessibilityAuraLinuxTest, TestCompositeAtkText) {
  const std::string text1_name = "One two three.";
  const std::string text2_name = " Four five six.";
  const int text_name_len = text1_name.length() + text2_name.length();

  ui::AXNodeData text1;
  text1.id = 11;
  text1.role = ax::mojom::Role::kStaticText;
  text1.SetName(text1_name);

  ui::AXNodeData text2;
  text2.id = 12;
  text2.role = ax::mojom::Role::kStaticText;
  text2.SetName(text2_name);

  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.child_ids.push_back(text1.id);
  root.child_ids.push_back(text2.id);

  std::unique_ptr<BrowserAccessibilityManager> manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdate(root, text1, text2),
          test_browser_accessibility_delegate_.get()));

  ui::AXPlatformNodeAuraLinux* root_obj =
      ToBrowserAccessibilityAuraLinux(manager->GetRoot())->GetNode();
  AtkObject* root_atk_object(root_obj->GetNativeViewAccessible());

  ASSERT_TRUE(ATK_IS_OBJECT(root_atk_object));
  ASSERT_TRUE(ATK_IS_TEXT(root_atk_object));
  g_object_ref(root_atk_object);
  AtkText* atk_text = ATK_TEXT(root_atk_object);

  EXPECT_EQ(text_name_len, atk_text_get_character_count(atk_text));

  gchar* text = atk_text_get_text(atk_text, 0, -1);
  EXPECT_STREQ((text1_name + text2_name).c_str(), text);
  g_free(text);

  ASSERT_TRUE(ATK_IS_HYPERTEXT(root_atk_object));
  AtkHypertext* atk_hypertext = ATK_HYPERTEXT(root_atk_object);

  // There should be no hyperlinks in the node and trying to get one should
  // always return -1.
  EXPECT_EQ(0, atk_hypertext_get_n_links(atk_hypertext));
  EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 0));
  EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, -1));
  EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 1));

  g_object_unref(root_atk_object);

  manager.reset();
}

TEST_F(BrowserAccessibilityAuraLinuxTest, TestComplexHypertext) {
  const std::string text1_name = "One two three.";
  const std::string combo_box_name = "City:";
  const std::string combo_box_value = "Happyland";
  const std::string text2_name = " Four five six.";
  const std::string check_box_name = "I agree";
  const std::string check_box_value = "Checked";
  const std::string radio_button_text_name = "Red";
  const std::string link_text_name = "Blue";
  // Each control (combo / check box, radio button and link) will be represented
  // by an embedded object character.
  const std::u16string string16_embed(
      1, ui::AXPlatformNodeAuraLinux::kEmbeddedCharacter);
  const std::string embed = base::UTF16ToUTF8(string16_embed);
  const std::string root_hypertext =
      text1_name + embed + text2_name + embed + embed + embed;

  ui::AXNodeData text1;
  text1.id = 11;
  text1.role = ax::mojom::Role::kStaticText;
  text1.SetName(text1_name);

  ui::AXNodeData combo_box;
  combo_box.id = 12;
  combo_box.role = ax::mojom::Role::kTextFieldWithComboBox;
  combo_box.AddState(ax::mojom::State::kEditable);
  combo_box.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "input");
  combo_box.SetName(combo_box_name);
  combo_box.SetValue(combo_box_value);

  ui::AXNodeData text2;
  text2.id = 13;
  text2.role = ax::mojom::Role::kStaticText;
  text2.SetName(text2_name);

  ui::AXNodeData check_box;
  check_box.id = 14;
  check_box.role = ax::mojom::Role::kCheckBox;
  check_box.SetCheckedState(ax::mojom::CheckedState::kTrue);
  check_box.SetName(check_box_name);
  // ARIA checkbox where the name is derived from its inner text.
  check_box.SetNameFrom(ax::mojom::NameFrom::kContents);
  check_box.SetValue(check_box_value);

  ui::AXNodeData radio_button, radio_button_text;
  radio_button.id = 15;
  radio_button_text.id = 17;
  radio_button.role = ax::mojom::Role::kRadioButton;
  radio_button_text.role = ax::mojom::Role::kStaticText;
  radio_button_text.SetName(radio_button_text_name);
  radio_button.child_ids.push_back(radio_button_text.id);

  ui::AXNodeData link, link_text;
  link.id = 16;
  link_text.id = 18;
  link.role = ax::mojom::Role::kLink;
  link_text.role = ax::mojom::Role::kStaticText;
  link_text.SetName(link_text_name);
  link.child_ids.push_back(link_text.id);

  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.child_ids = {text1.id,     combo_box.id,    text2.id,
                    check_box.id, radio_button.id, link.id};

  std::unique_ptr<BrowserAccessibilityManager> manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdate(root, text1, combo_box, text2, check_box,
                           radio_button, radio_button_text, link, link_text),
          test_browser_accessibility_delegate_.get()));

  ui::AXPlatformNodeAuraLinux* root_obj =
      ToBrowserAccessibilityAuraLinux(manager->GetRoot())->GetNode();
  AtkObject* root_atk_object(root_obj->GetNativeViewAccessible());

  ASSERT_TRUE(ATK_IS_OBJECT(root_atk_object));
  ASSERT_TRUE(ATK_IS_TEXT(root_atk_object));
  g_object_ref(root_atk_object);
  AtkText* atk_text = ATK_TEXT(root_atk_object);

  EXPECT_EQ(g_utf8_strlen(root_hypertext.c_str(), -1),
            atk_text_get_character_count(atk_text));

  gchar* text = atk_text_get_text(atk_text, 0, -1);
  EXPECT_STREQ(root_hypertext.c_str(), text);
  g_free(text);

  ASSERT_TRUE(ATK_IS_HYPERTEXT(root_atk_object));
  AtkHypertext* atk_hypertext = ATK_HYPERTEXT(root_atk_object);

  EXPECT_EQ(4, atk_hypertext_get_n_links(atk_hypertext));

  auto verify_atk_link_text = [&](const char* expected_text, int link_index,
                                  int expected_start_index) {
    AtkHyperlink* link = atk_hypertext_get_link(atk_hypertext, link_index);
    ASSERT_NE(nullptr, link);
    ASSERT_TRUE(ATK_IS_HYPERLINK(link));

    AtkObject* link_object = atk_hyperlink_get_object(link, 0);
    ASSERT_NE(link_object, nullptr);
    ASSERT_TRUE(ATK_IS_HYPERLINK_IMPL(link_object));

    AtkHyperlink* link_from_object =
        atk_hyperlink_impl_get_hyperlink(ATK_HYPERLINK_IMPL(link_object));
    ASSERT_EQ(link_from_object, link);
    g_object_unref(link_from_object);

    ASSERT_EQ(atk_hyperlink_get_start_index(link), expected_start_index);
    ASSERT_EQ(atk_hyperlink_get_end_index(link), expected_start_index + 1);

    AtkObject* object = atk_hyperlink_get_object(link, 0);
    ASSERT_TRUE(ATK_IS_TEXT(object));

    char* text = atk_text_get_text(ATK_TEXT(object), 0, -1);
    EXPECT_STREQ(expected_text, text);
    g_free(text);
  };

  AtkHyperlink* combo_box_link = atk_hypertext_get_link(atk_hypertext, 0);
  ASSERT_NE(nullptr, combo_box_link);
  ASSERT_TRUE(ATK_IS_HYPERLINK(combo_box_link));

  // Get the text of the combo box. It should be its value.
  verify_atk_link_text(combo_box_value.c_str(), 0, 14);

  // Get the text of the check box. It should be its name.
  verify_atk_link_text(check_box_name.c_str(), 1, 30);

  // Get the text of the radio button.
  verify_atk_link_text(radio_button_text_name.c_str(), 2, 31);

  // Get the text of the link.
  verify_atk_link_text(link_text_name.c_str(), 3, 32);

  // Now test that all the object indices map back to the correct link indices.
  EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, -1));
  EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 0));
  EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 1));
  EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 5));
  EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 13));
  EXPECT_EQ(0, atk_hypertext_get_link_index(atk_hypertext, 14));
  EXPECT_EQ(1, atk_hypertext_get_link_index(atk_hypertext, 30));
  EXPECT_EQ(2, atk_hypertext_get_link_index(atk_hypertext, 31));
  EXPECT_EQ(3, atk_hypertext_get_link_index(atk_hypertext, 32));
  EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 33));
  EXPECT_EQ(-1, atk_hypertext_get_link_index(atk_hypertext, 34));

  g_object_unref(root_atk_object);

  text1.SetName(text1_name + text1_name);
  AXEventNotificationDetails event_bundle;
  event_bundle.updates.resize(1);
  event_bundle.updates[0].nodes.push_back(text1);
  event_bundle.updates[0].nodes.push_back(root);
  ASSERT_TRUE(manager->OnAccessibilityEvents(event_bundle));

  // The hypertext offsets should reflect the new length of the static text.
  verify_atk_link_text(combo_box_value.c_str(), 0, 28);
  verify_atk_link_text(check_box_name.c_str(), 1, 44);
  verify_atk_link_text(radio_button_text_name.c_str(), 2, 45);
  verify_atk_link_text(link_text_name.c_str(), 3, 46);

  manager.reset();
}

TEST_F(BrowserAccessibilityAuraLinuxTest, TestTextAttributesInButtons) {
  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.AddState(ax::mojom::State::kFocusable);

  ui::AXNodeData button;
  button.id = 2;
  button.role = ax::mojom::Role::kButton;
  button.AddStringAttribute(ax::mojom::StringAttribute::kFontFamily, "Times");
  root.child_ids.push_back(button.id);

  ui::AXNodeData text;
  text.id = 3;
  text.role = ax::mojom::Role::kStaticText;
  text.SetName("OK");
  button.child_ids.push_back(text.id);

  ui::AXNodeData empty_button;
  empty_button.id = 4;
  empty_button.role = ax::mojom::Role::kButton;
  empty_button.AddStringAttribute(ax::mojom::StringAttribute::kFontFamily,
                                  "Times");
  root.child_ids.push_back(empty_button.id);

  ui::AXTreeUpdate update = MakeAXTreeUpdate(root, button, text, empty_button);
  std::unique_ptr<BrowserAccessibilityManager> manager(
      BrowserAccessibilityManager::Create(
          update, test_browser_accessibility_delegate_.get()));

  BrowserAccessibilityAuraLinux* ax_root =
      ToBrowserAccessibilityAuraLinux(manager->GetRoot());

  BrowserAccessibilityAuraLinux* ax_button =
      ToBrowserAccessibilityAuraLinux(ax_root->PlatformGetChild(0));
  AtkObject* atk_button = ax_button->GetNode()->GetNativeViewAccessible();

  int start_offset, end_offset;
  AtkAttributeSet* attributes = atk_text_get_run_attributes(
      ATK_TEXT(atk_button), 0, &start_offset, &end_offset);
  ASSERT_EQ(1U, g_slist_length(attributes));
  atk_attribute_set_free(attributes);

  BrowserAccessibilityAuraLinux* ax_empty_button =
      ToBrowserAccessibilityAuraLinux(ax_root->PlatformGetChild(1));
  AtkObject* atk_empty_button =
      ax_empty_button->GetNode()->GetNativeViewAccessible();
  attributes = atk_text_get_run_attributes(ATK_TEXT(atk_empty_button), 0,
                                           &start_offset, &end_offset);
  ASSERT_EQ(1U, g_slist_length(attributes));
  atk_attribute_set_free(attributes);
}

TEST_F(BrowserAccessibilityAuraLinuxTest,
       TestTextAttributesInContentEditables) {
  auto has_attribute = [](AtkAttributeSet* attributes,
                          AtkTextAttribute text_attribute,
                          base::Optional<const char*> expected_value) {
    const char* name = atk_text_attribute_get_name(text_attribute);
    while (attributes) {
      const AtkAttribute* attribute =
          static_cast<AtkAttribute*>(attributes->data);
      if (!g_strcmp0(attribute->name, name)) {
        if (!expected_value.has_value())
          return true;
        if (!g_strcmp0(attribute->value, *expected_value))
          return true;
      }
      attributes = g_slist_next(attributes);
    }
    return false;
  };

  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.AddState(ax::mojom::State::kFocusable);

  ui::AXNodeData div_editable;
  div_editable.id = 2;
  div_editable.role = ax::mojom::Role::kGenericContainer;
  div_editable.AddState(ax::mojom::State::kEditable);
  div_editable.AddState(ax::mojom::State::kFocusable);
  div_editable.AddStringAttribute(ax::mojom::StringAttribute::kFontFamily,
                                  "Helvetica");

  ui::AXNodeData text_before;
  text_before.id = 3;
  text_before.role = ax::mojom::Role::kStaticText;
  text_before.AddState(ax::mojom::State::kEditable);
  text_before.SetName("Before ");
  text_before.AddTextStyle(ax::mojom::TextStyle::kBold);
  text_before.AddTextStyle(ax::mojom::TextStyle::kItalic);

  ui::AXNodeData link;
  link.id = 4;
  link.role = ax::mojom::Role::kLink;
  link.AddState(ax::mojom::State::kEditable);
  link.AddState(ax::mojom::State::kFocusable);
  link.AddState(ax::mojom::State::kLinked);
  link.SetName("lnk");
  link.SetNameFrom(ax::mojom::NameFrom::kContents);
  link.AddTextStyle(ax::mojom::TextStyle::kUnderline);

  ui::AXNodeData link_text;
  link_text.id = 5;
  link_text.role = ax::mojom::Role::kStaticText;
  link_text.AddState(ax::mojom::State::kEditable);
  link_text.AddState(ax::mojom::State::kFocusable);
  link_text.AddState(ax::mojom::State::kLinked);
  link_text.SetName("lnk");
  link_text.AddTextStyle(ax::mojom::TextStyle::kUnderline);
  link_text.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, "fr");

  // The name "lnk" is misspelled.
  std::vector<int32_t> marker_types{
      static_cast<int32_t>(ax::mojom::MarkerType::kSpelling)};
  std::vector<int32_t> marker_starts{0};
  std::vector<int32_t> marker_ends{3};
  link_text.AddIntListAttribute(ax::mojom::IntListAttribute::kMarkerTypes,
                                marker_types);
  link_text.AddIntListAttribute(ax::mojom::IntListAttribute::kMarkerStarts,
                                marker_starts);
  link_text.AddIntListAttribute(ax::mojom::IntListAttribute::kMarkerEnds,
                                marker_ends);

  ui::AXNodeData text_after;
  text_after.id = 6;
  text_after.role = ax::mojom::Role::kStaticText;
  text_after.AddState(ax::mojom::State::kEditable);
  text_after.SetName(" after.");
  // Leave text style as normal.

  root.child_ids.push_back(div_editable.id);
  div_editable.child_ids = {text_before.id, link.id, text_after.id};
  link.child_ids.push_back(link_text.id);

  ui::AXTreeUpdate update = MakeAXTreeUpdate(root, div_editable, text_before,
                                             link, link_text, text_after);

  std::unique_ptr<BrowserAccessibilityManager> manager(
      BrowserAccessibilityManager::Create(
          update, test_browser_accessibility_delegate_.get()));

  ASSERT_NE(nullptr, manager->GetRoot());
  BrowserAccessibilityAuraLinux* ax_root =
      ToBrowserAccessibilityAuraLinux(manager->GetRoot());
  ASSERT_NE(nullptr, ax_root);
  ASSERT_EQ(1U, ax_root->PlatformChildCount());

  BrowserAccessibilityAuraLinux* ax_div =
      ToBrowserAccessibilityAuraLinux(ax_root->PlatformGetChild(0));
  ASSERT_NE(nullptr, ax_div);
  ASSERT_EQ(3U, ax_div->PlatformChildCount());

  BrowserAccessibilityAuraLinux* ax_before =
      ToBrowserAccessibilityAuraLinux(ax_div->PlatformGetChild(0));
  ASSERT_NE(nullptr, ax_before);
  BrowserAccessibilityAuraLinux* ax_link =
      ToBrowserAccessibilityAuraLinux(ax_div->PlatformGetChild(1));
  ASSERT_NE(nullptr, ax_link);
  ASSERT_EQ(1U, ax_link->PlatformChildCount());
  BrowserAccessibilityAuraLinux* ax_after =
      ToBrowserAccessibilityAuraLinux(ax_div->PlatformGetChild(2));
  ASSERT_NE(nullptr, ax_after);

  BrowserAccessibilityAuraLinux* ax_link_text =
      ToBrowserAccessibilityAuraLinux(ax_link->PlatformGetChild(0));
  ASSERT_NE(nullptr, ax_link_text);

  AtkObject* root_atk_object = ax_root->GetNode()->GetNativeViewAccessible();
  AtkObject* ax_div_atk_object = ax_div->GetNode()->GetNativeViewAccessible();

  ASSERT_EQ(1, atk_text_get_character_count(ATK_TEXT(root_atk_object)));
  ASSERT_EQ(15, atk_text_get_character_count(ATK_TEXT(ax_div_atk_object)));

  // Test the style of the root.
  int start_offset, end_offset;
  AtkAttributeSet* attributes = atk_text_get_run_attributes(
      ATK_TEXT(root_atk_object), 0, &start_offset, &end_offset);

  ASSERT_EQ(0, start_offset);
  ASSERT_EQ(1, end_offset);

  ASSERT_TRUE(
      has_attribute(attributes, ATK_TEXT_ATTR_FAMILY_NAME, "Helvetica"));
  atk_attribute_set_free(attributes);

  // Test the style of text_before.
  for (int offset = 0; offset < 7; ++offset) {
    start_offset = end_offset = -1;
    attributes = atk_text_get_run_attributes(
        ATK_TEXT(ax_div_atk_object), offset, &start_offset, &end_offset);

    EXPECT_EQ(0, start_offset);
    EXPECT_EQ(7, end_offset);

    ASSERT_TRUE(
        has_attribute(attributes, ATK_TEXT_ATTR_FAMILY_NAME, "Helvetica"));
    ASSERT_TRUE(has_attribute(attributes, ATK_TEXT_ATTR_WEIGHT, "700"));
    ASSERT_TRUE(has_attribute(attributes, ATK_TEXT_ATTR_STYLE, "italic"));

    atk_attribute_set_free(attributes);
  }

  // Test the style of the link.
  AtkObject* ax_link_text_atk_object =
      ax_link_text->GetNode()->GetNativeViewAccessible();
  for (int offset = 0; offset < 3; offset++) {
    start_offset = end_offset = -1;
    attributes = atk_text_get_run_attributes(
        ATK_TEXT(ax_link_text_atk_object), offset, &start_offset, &end_offset);

    EXPECT_EQ(0, start_offset);
    EXPECT_EQ(3, end_offset);

    ASSERT_TRUE(
        has_attribute(attributes, ATK_TEXT_ATTR_FAMILY_NAME, "Helvetica"));
    ASSERT_FALSE(
        has_attribute(attributes, ATK_TEXT_ATTR_WEIGHT, base::nullopt));
    ASSERT_FALSE(has_attribute(attributes, ATK_TEXT_ATTR_STYLE, base::nullopt));
    ASSERT_TRUE(has_attribute(attributes, ATK_TEXT_ATTR_UNDERLINE, "single"));
    ASSERT_TRUE(has_attribute(attributes, ATK_TEXT_ATTR_LANGUAGE, "fr"));

    // For compatibility with Firefox, spelling attributes should also be
    // propagated to the parent of static text leaves.
    ASSERT_TRUE(has_attribute(attributes, ATK_TEXT_ATTR_UNDERLINE, "error"));
    ASSERT_TRUE(has_attribute(attributes, ATK_TEXT_ATTR_INVALID, "spelling"));

    atk_attribute_set_free(attributes);
  }

  // Test the style of text_after.
  for (int offset = 8; offset < 15; ++offset) {
    start_offset = end_offset = -1;
    attributes = atk_text_get_run_attributes(
        ATK_TEXT(ax_div_atk_object), offset, &start_offset, &end_offset);
    EXPECT_EQ(8, start_offset);
    EXPECT_EQ(15, end_offset);

    ASSERT_TRUE(
        has_attribute(attributes, ATK_TEXT_ATTR_FAMILY_NAME, "Helvetica"));
    ASSERT_FALSE(
        has_attribute(attributes, ATK_TEXT_ATTR_WEIGHT, base::nullopt));
    ASSERT_FALSE(has_attribute(attributes, ATK_TEXT_ATTR_STYLE, base::nullopt));
    ASSERT_FALSE(
        has_attribute(attributes, ATK_TEXT_ATTR_UNDERLINE, base::nullopt));
    ASSERT_FALSE(
        has_attribute(attributes, ATK_TEXT_ATTR_INVALID, base::nullopt));

    atk_attribute_set_free(attributes);
  }

  // Test the style of the static text nodes.
  AtkObject* ax_before_atk_object =
      ax_before->GetNode()->GetNativeViewAccessible();
  start_offset = end_offset = -1;
  attributes = atk_text_get_run_attributes(ATK_TEXT(ax_before_atk_object), 6,
                                           &start_offset, &end_offset);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(7, end_offset);
  ASSERT_TRUE(
      has_attribute(attributes, ATK_TEXT_ATTR_FAMILY_NAME, "Helvetica"));
  ASSERT_TRUE(has_attribute(attributes, ATK_TEXT_ATTR_WEIGHT, "700"));
  ASSERT_TRUE(has_attribute(attributes, ATK_TEXT_ATTR_STYLE, "italic"));
  ASSERT_FALSE(
      has_attribute(attributes, ATK_TEXT_ATTR_UNDERLINE, base::nullopt));
  ASSERT_FALSE(has_attribute(attributes, ATK_TEXT_ATTR_INVALID, base::nullopt));
  atk_attribute_set_free(attributes);

  AtkObject* ax_after_atk_object =
      ax_after->GetNode()->GetNativeViewAccessible();
  attributes = atk_text_get_run_attributes(ATK_TEXT(ax_after_atk_object), 6,
                                           &start_offset, &end_offset);
  EXPECT_EQ(0, start_offset);
  EXPECT_EQ(7, end_offset);
  ASSERT_TRUE(
      has_attribute(attributes, ATK_TEXT_ATTR_FAMILY_NAME, "Helvetica"));
  ASSERT_FALSE(has_attribute(attributes, ATK_TEXT_ATTR_WEIGHT, base::nullopt));
  ASSERT_FALSE(has_attribute(attributes, ATK_TEXT_ATTR_STYLE, "italic"));
  ASSERT_FALSE(
      has_attribute(attributes, ATK_TEXT_ATTR_UNDERLINE, base::nullopt));
  atk_attribute_set_free(attributes);

  manager.reset();
}

TEST_F(BrowserAccessibilityAuraLinuxTest,
       TestAtkObjectsNotDeletedDuringTreeUpdate) {
  ui::AXNodeData container;
  container.id = 4;
  container.role = ax::mojom::Role::kGenericContainer;

  ui::AXNodeData combo_box;
  combo_box.id = 6;
  combo_box.role = ax::mojom::Role::kPopUpButton;
  combo_box.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "select");
  combo_box.AddState(ax::mojom::State::kCollapsed);
  combo_box.SetValue("1");
  container.child_ids.push_back(combo_box.id);

  ui::AXNodeData menu_list;
  menu_list.id = 8;
  menu_list.role = ax::mojom::Role::kMenuListPopup;
  menu_list.AddState(ax::mojom::State::kInvisible);
  combo_box.child_ids.push_back(menu_list.id);

  ui::AXNodeData menu_option_1;
  menu_option_1.id = 9;
  menu_option_1.role = ax::mojom::Role::kMenuListOption;
  menu_option_1.SetName("1");
  menu_list.child_ids.push_back(menu_option_1.id);

  ui::AXNodeData menu_option_2;
  menu_option_2.id = 10;
  menu_option_2.role = ax::mojom::Role::kMenuListOption;
  menu_option_2.SetName("2");
  menu_option_2.AddState(ax::mojom::State::kInvisible);
  menu_list.child_ids.push_back(menu_option_2.id);

  ui::AXNodeData root;
  root.id = 2;
  root.role = ax::mojom::Role::kRootWebArea;
  root.child_ids.push_back(container.id);

  std::unique_ptr<BrowserAccessibilityManager> manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdate(root, container, combo_box, menu_list, menu_option_1,
                           menu_option_2),
          test_browser_accessibility_delegate_.get()));

  ui::AXPlatformNodeAuraLinux* combo_box_node =
      ToBrowserAccessibilityAuraLinux(manager->GetFromID(combo_box.id))
          ->GetNode();
  ASSERT_FALSE(combo_box_node->IsChildOfLeaf());
  AtkObject* original_atk_object = combo_box_node->GetNativeViewAccessible();
  g_object_ref(original_atk_object);

  // The interface mask is only dependent on IsChildOfLeaf. Create an update
  // which won't modify this.
  container.SetName("container");
  ui::AXTree* tree = const_cast<ui::AXTree*>(manager->ax_tree());
  ASSERT_TRUE(tree->Unserialize(MakeAXTreeUpdate(container)));
  ASSERT_FALSE(combo_box_node->IsChildOfLeaf());
  ASSERT_EQ(original_atk_object, combo_box_node->GetNativeViewAccessible());

  g_object_unref(original_atk_object);
  manager.reset();
}

TEST_F(BrowserAccessibilityAuraLinuxTest,
       TestExistingMisspellingsInSimpleTextFields) {
  std::string value1("Testing .");
  // The word "helo" is misspelled.
  std::string value2("Helo there.");

  int value1_length = value1.length();
  int value2_length = value2.length();
  int combo_box_value_length = value1_length + value2_length;

  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.AddState(ax::mojom::State::kFocusable);

  ui::AXNodeData combo_box;
  combo_box.id = 2;
  combo_box.role = ax::mojom::Role::kTextFieldWithComboBox;
  combo_box.AddState(ax::mojom::State::kEditable);
  combo_box.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "input");
  combo_box.AddState(ax::mojom::State::kFocusable);
  combo_box.SetValue(value1 + value2);

  ui::AXNodeData combo_box_div;
  combo_box_div.id = 3;
  combo_box_div.role = ax::mojom::Role::kGenericContainer;
  combo_box_div.AddState(ax::mojom::State::kEditable);

  ui::AXNodeData static_text1;
  static_text1.id = 4;
  static_text1.role = ax::mojom::Role::kStaticText;
  static_text1.AddState(ax::mojom::State::kEditable);
  static_text1.SetName(value1);

  ui::AXNodeData static_text2;
  static_text2.id = 5;
  static_text2.role = ax::mojom::Role::kStaticText;
  static_text2.AddState(ax::mojom::State::kEditable);
  static_text2.SetName(value2);

  std::vector<int32_t> marker_types;
  marker_types.push_back(
      static_cast<int32_t>(ax::mojom::MarkerType::kSpelling));
  std::vector<int32_t> marker_starts;
  marker_starts.push_back(0);
  std::vector<int32_t> marker_ends;
  marker_ends.push_back(4);
  static_text2.AddIntListAttribute(ax::mojom::IntListAttribute::kMarkerTypes,
                                   marker_types);
  static_text2.AddIntListAttribute(ax::mojom::IntListAttribute::kMarkerStarts,
                                   marker_starts);
  static_text2.AddIntListAttribute(ax::mojom::IntListAttribute::kMarkerEnds,
                                   marker_ends);

  root.child_ids.push_back(combo_box.id);
  combo_box.child_ids.push_back(combo_box_div.id);
  combo_box_div.child_ids.push_back(static_text1.id);
  combo_box_div.child_ids.push_back(static_text2.id);

  std::unique_ptr<BrowserAccessibilityManager> manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdate(root, combo_box, combo_box_div, static_text1,
                           static_text2),
          test_browser_accessibility_delegate_.get()));

  ASSERT_NE(nullptr, manager->GetRoot());
  BrowserAccessibilityAuraLinux* ax_root =
      ToBrowserAccessibilityAuraLinux(manager->GetRoot());
  ASSERT_NE(nullptr, ax_root);
  ASSERT_EQ(1U, ax_root->PlatformChildCount());

  BrowserAccessibilityAuraLinux* ax_combo_box =
      ToBrowserAccessibilityAuraLinux(ax_root->PlatformGetChild(0));
  ASSERT_NE(nullptr, ax_combo_box);

  AtkText* combo_box_text =
      ATK_TEXT(ax_combo_box->GetNode()->GetNativeViewAccessible());
  int start_offset, end_offset;

  auto contains_spelling_attribute = [](AtkAttributeSet* attributes) {
    const char* invalid_str =
        atk_text_attribute_get_name(ATK_TEXT_ATTR_INVALID);
    while (attributes) {
      AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data);
      if (!g_strcmp0(attribute->name, invalid_str) &&
          !g_strcmp0(attribute->value, "spelling"))
        return true;
      attributes = g_slist_next(attributes);
    }

    return false;
  };

  // Ensure that the first part of the value is not marked misspelled.
  for (int offset = 0; offset < value1_length; ++offset) {
    AtkAttributeSet* attributes = atk_text_get_run_attributes(
        combo_box_text, offset, &start_offset, &end_offset);
    EXPECT_FALSE(contains_spelling_attribute(attributes));
    EXPECT_EQ(0, start_offset);
    EXPECT_EQ(value1_length, end_offset);
    atk_attribute_set_free(attributes);
  }

  // Ensure that "helo" is marked misspelled.
  for (int offset = value1_length; offset < value1_length + 4; ++offset) {
    AtkAttributeSet* attributes = atk_text_get_run_attributes(
        combo_box_text, offset, &start_offset, &end_offset);
    EXPECT_EQ(value1_length, start_offset);
    EXPECT_EQ(value1_length + 4, end_offset);
    EXPECT_TRUE(contains_spelling_attribute(attributes));
    atk_attribute_set_free(attributes);
  }

  // Ensure that the last part of the value is not marked misspelled.
  for (int offset = value1_length + 4; offset < combo_box_value_length;
       ++offset) {
    AtkAttributeSet* attributes = atk_text_get_run_attributes(
        combo_box_text, offset, &start_offset, &end_offset);
    EXPECT_FALSE(contains_spelling_attribute(attributes));
    EXPECT_EQ(value1_length + 4, start_offset);
    EXPECT_EQ(combo_box_value_length, end_offset);
    atk_attribute_set_free(attributes);
  }

  manager.reset();
}

TEST_F(BrowserAccessibilityAuraLinuxTest, TextAtkStaticTextChange) {
  ui::AXNodeData root;
  root.id = 1;
  root.role = ax::mojom::Role::kRootWebArea;
  root.AddState(ax::mojom::State::kFocusable);

  ui::AXNodeData div_editable;
  div_editable.id = 2;
  div_editable.role = ax::mojom::Role::kGenericContainer;

  ui::AXNodeData text;
  text.id = 3;
  text.role = ax::mojom::Role::kStaticText;
  text.SetName("Text1 ");

  root.child_ids.push_back(div_editable.id);
  div_editable.child_ids.push_back(text.id);

  std::unique_ptr<BrowserAccessibilityManager> manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdate(root, div_editable, text),
          test_browser_accessibility_delegate_.get()));

  text.SetName("Text2");
  ui::AXTree* tree = const_cast<ui::AXTree*>(manager->ax_tree());
  ASSERT_TRUE(tree->Unserialize(MakeAXTreeUpdate(text)));

  // The change to the static text node should have triggered an update of the
  // containing div's hypertext.
  ui::AXPlatformNodeAuraLinux* div_node =
      ToBrowserAccessibilityAuraLinux(manager->GetFromID(div_editable.id))
          ->GetNode();
  EXPECT_STREQ(base::UTF16ToUTF8(div_node->GetHypertext()).c_str(), "Text2");
}

TEST_F(BrowserAccessibilityAuraLinuxTest, TestAtkTextGetOffesetAtPoint) {
  ui::AXNodeData static_text1;
  static_text1.id = 1;
  static_text1.role = ax::mojom::Role::kStaticText;
  static_text1.SetName("Hello");
  static_text1.child_ids = {2};

  ui::AXNodeData inline_box1;
  inline_box1.id = 2;
  inline_box1.role = ax::mojom::Role::kInlineTextBox;
  inline_box1.SetName("Hello");
  inline_box1.relative_bounds.bounds = gfx::RectF(0, 50, 25, 30);
  std::vector<int32_t> character_offsets1;
  // The width of each character is 5px.
  character_offsets1.push_back(5);
  character_offsets1.push_back(10);
  character_offsets1.push_back(15);
  character_offsets1.push_back(20);
  character_offsets1.push_back(25);
  inline_box1.AddIntListAttribute(
      ax::mojom::IntListAttribute::kCharacterOffsets, character_offsets1);
  inline_box1.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
                                  std::vector<int32_t>{0});
  inline_box1.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
                                  std::vector<int32_t>{5});

  std::unique_ptr<BrowserAccessibilityManager> manager(
      BrowserAccessibilityManager::Create(
          MakeAXTreeUpdate(static_text1, inline_box1),
          test_browser_accessibility_delegate_.get()));

  ASSERT_NE(nullptr, manager->GetRoot());
  BrowserAccessibilityAuraLinux* ax_root =
      ToBrowserAccessibilityAuraLinux(manager->GetRoot());
  ASSERT_NE(nullptr, ax_root);

  AtkObject* root_atk_object = ax_root->GetNode()->GetNativeViewAccessible();
  g_object_ref(root_atk_object);
  AtkText* atk_text = ATK_TEXT(root_atk_object);
  ASSERT_TRUE(ATK_IS_TEXT(atk_text));

  int x, y, width, height;
  char* text = atk_text_get_text(atk_text, 0, -1);
  int root_text_length = g_utf8_strlen(text, -1);
  g_free(text);
  for (int offset = 0; offset < root_text_length; offset++) {
    atk_text_get_character_extents(atk_text, offset, &x, &y, &width, &height,
                                   ATK_XY_SCREEN);
    int result = atk_text_get_offset_at_point(atk_text, x, y, ATK_XY_SCREEN);
    ASSERT_EQ(offset, result);
  }
  g_object_unref(root_atk_object);
  manager.reset();
}

}  // namespace content
