// Copyright 2013 The Flutter 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 "accessibility_bridge.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "flutter/third_party/accessibility/ax/ax_tree_manager_map.h"
#include "test_accessibility_bridge.h"

namespace flutter {
namespace testing {

using ::testing::Contains;

FlutterSemanticsNode CreateSemanticsNode(
    int32_t id,
    const char* label,
    const std::vector<int32_t>* children = nullptr) {
  return {
      .id = id,
      .flags = static_cast<FlutterSemanticsFlag>(0),
      .actions = static_cast<FlutterSemanticsAction>(0),
      .text_selection_base = -1,
      .text_selection_extent = -1,
      .label = label,
      .hint = "",
      .value = "",
      .increased_value = "",
      .decreased_value = "",
      .child_count = children ? children->size() : 0,
      .children_in_traversal_order = children ? children->data() : nullptr,
      .custom_accessibility_actions_count = 0,
      .tooltip = "",
  };
}

TEST(AccessibilityBridgeTest, basicTest) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();

  std::vector<int32_t> children{1, 2};
  FlutterSemanticsNode root = CreateSemanticsNode(0, "root", &children);
  FlutterSemanticsNode child1 = CreateSemanticsNode(1, "child 1");
  FlutterSemanticsNode child2 = CreateSemanticsNode(2, "child 2");

  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->AddFlutterSemanticsNodeUpdate(&child1);
  bridge->AddFlutterSemanticsNodeUpdate(&child2);
  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
  auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
  auto child2_node = bridge->GetFlutterPlatformNodeDelegateFromID(2).lock();
  EXPECT_EQ(root_node->GetChildCount(), 2);
  EXPECT_EQ(root_node->GetData().child_ids[0], 1);
  EXPECT_EQ(root_node->GetData().child_ids[1], 2);
  EXPECT_EQ(root_node->GetName(), "root");

  EXPECT_EQ(child1_node->GetChildCount(), 0);
  EXPECT_EQ(child1_node->GetName(), "child 1");

  EXPECT_EQ(child2_node->GetChildCount(), 0);
  EXPECT_EQ(child2_node->GetName(), "child 2");
}

TEST(AccessibilityBridgeTest, canFireChildrenChangedCorrectly) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();

  std::vector<int32_t> children{1};
  FlutterSemanticsNode root = CreateSemanticsNode(0, "root", &children);
  FlutterSemanticsNode child1 = CreateSemanticsNode(1, "child 1");

  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->AddFlutterSemanticsNodeUpdate(&child1);

  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
  auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
  EXPECT_EQ(root_node->GetChildCount(), 1);
  EXPECT_EQ(root_node->GetData().child_ids[0], 1);
  EXPECT_EQ(root_node->GetName(), "root");

  EXPECT_EQ(child1_node->GetChildCount(), 0);
  EXPECT_EQ(child1_node->GetName(), "child 1");
  bridge->accessibility_events.clear();

  // Add a child to root.
  root.child_count = 2;
  int32_t new_children[] = {1, 2};
  root.children_in_traversal_order = new_children;

  FlutterSemanticsNode child2 = CreateSemanticsNode(2, "child 2");

  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->AddFlutterSemanticsNodeUpdate(&child2);
  bridge->CommitUpdates();

  root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();

  EXPECT_EQ(root_node->GetChildCount(), 2);
  EXPECT_EQ(root_node->GetData().child_ids[0], 1);
  EXPECT_EQ(root_node->GetData().child_ids[1], 2);
  EXPECT_EQ(bridge->accessibility_events.size(), size_t{2});
  std::set<ui::AXEventGenerator::Event> actual_event{
      bridge->accessibility_events.begin(), bridge->accessibility_events.end()};
  EXPECT_THAT(actual_event,
              Contains(ui::AXEventGenerator::Event::CHILDREN_CHANGED));
  EXPECT_THAT(actual_event,
              Contains(ui::AXEventGenerator::Event::SUBTREE_CREATED));
}

TEST(AccessibilityBridgeTest, canRecreateNodeDelegates) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();

  std::vector<int32_t> children{1};
  FlutterSemanticsNode root = CreateSemanticsNode(0, "root", &children);
  FlutterSemanticsNode child1 = CreateSemanticsNode(1, "child 1");

  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->AddFlutterSemanticsNodeUpdate(&child1);
  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0);
  auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1);
  EXPECT_FALSE(root_node.expired());
  EXPECT_FALSE(child1_node.expired());

  bridge->RecreateNodeDelegates();

  // Old tree is destroyed.
  EXPECT_TRUE(root_node.expired());
  EXPECT_TRUE(child1_node.expired());

  // New tree still has the data.
  auto new_root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
  auto new_child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
  EXPECT_EQ(new_root_node->GetChildCount(), 1);
  EXPECT_EQ(new_root_node->GetData().child_ids[0], 1);
  EXPECT_EQ(new_root_node->GetName(), "root");

  EXPECT_EQ(new_child1_node->GetChildCount(), 0);
  EXPECT_EQ(new_child1_node->GetName(), "child 1");
}

TEST(AccessibilityBridgeTest, canHandleSelectionChangeCorrectly) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();
  FlutterSemanticsNode root = CreateSemanticsNode(0, "root");
  root.flags = static_cast<FlutterSemanticsFlag>(
      FlutterSemanticsFlag::kFlutterSemanticsFlagIsTextField |
      FlutterSemanticsFlag::kFlutterSemanticsFlagIsFocused);
  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->CommitUpdates();

  const ui::AXTreeData& tree = bridge->GetAXTreeData();
  EXPECT_EQ(tree.sel_anchor_object_id, ui::AXNode::kInvalidAXID);
  bridge->accessibility_events.clear();

  // Update the selection.
  root.text_selection_base = 0;
  root.text_selection_extent = 5;
  bridge->AddFlutterSemanticsNodeUpdate(&root);

  bridge->CommitUpdates();

  EXPECT_EQ(tree.sel_anchor_object_id, 0);
  EXPECT_EQ(tree.sel_anchor_offset, 0);
  EXPECT_EQ(tree.sel_focus_object_id, 0);
  EXPECT_EQ(tree.sel_focus_offset, 5);
  ASSERT_EQ(bridge->accessibility_events.size(), size_t{2});
  EXPECT_EQ(bridge->accessibility_events[0],
            ui::AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED);
  EXPECT_EQ(bridge->accessibility_events[1],
            ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED);
}

TEST(AccessibilityBridgeTest, doesNotAssignEditableRootToSelectableText) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();
  FlutterSemanticsNode root = CreateSemanticsNode(0, "root");
  root.flags = static_cast<FlutterSemanticsFlag>(
      FlutterSemanticsFlag::kFlutterSemanticsFlagIsTextField |
      FlutterSemanticsFlag::kFlutterSemanticsFlagIsReadOnly);
  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();

  EXPECT_FALSE(root_node->GetData().GetBoolAttribute(
      ax::mojom::BoolAttribute::kEditableRoot));
}

TEST(AccessibilityBridgeTest, ToggleHasToggleButtonRole) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();
  FlutterSemanticsNode root = CreateSemanticsNode(0, "root");
  root.flags = static_cast<FlutterSemanticsFlag>(
      FlutterSemanticsFlag::kFlutterSemanticsFlagHasToggledState |
      FlutterSemanticsFlag::kFlutterSemanticsFlagHasEnabledState |
      FlutterSemanticsFlag::kFlutterSemanticsFlagIsEnabled);
  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
  EXPECT_EQ(root_node->GetData().role, ax::mojom::Role::kToggleButton);
}

TEST(AccessibilityBridgeTest, SliderHasSliderRole) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();
  FlutterSemanticsNode root = CreateSemanticsNode(0, "root");
  root.flags = static_cast<FlutterSemanticsFlag>(
      FlutterSemanticsFlag::kFlutterSemanticsFlagIsSlider |
      FlutterSemanticsFlag::kFlutterSemanticsFlagHasEnabledState |
      FlutterSemanticsFlag::kFlutterSemanticsFlagIsEnabled |
      FlutterSemanticsFlag::kFlutterSemanticsFlagIsFocusable);
  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
  EXPECT_EQ(root_node->GetData().role, ax::mojom::Role::kSlider);
}

// Ensure that checkboxes have their checked status set apropriately
// Previously, only Radios could have this flag updated
// Resulted in the issue seen at
// https://github.com/flutter/flutter/issues/96218
// As this fix involved code run on all platforms, it is included here.
TEST(AccessibilityBridgeTest, CanSetCheckboxChecked) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();
  FlutterSemanticsNode root = CreateSemanticsNode(0, "root");
  root.flags = static_cast<FlutterSemanticsFlag>(
      FlutterSemanticsFlag::kFlutterSemanticsFlagHasCheckedState |
      FlutterSemanticsFlag::kFlutterSemanticsFlagIsChecked);
  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
  EXPECT_EQ(root_node->GetData().role, ax::mojom::Role::kCheckBox);
  EXPECT_EQ(root_node->GetData().GetCheckedState(),
            ax::mojom::CheckedState::kTrue);
}

// Verify that a node can be moved from one parent to another.
TEST(AccessibilityBridgeTest, CanReparentNode) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();

  std::vector<int32_t> root_children{1};
  std::vector<int32_t> child1_children{2};
  FlutterSemanticsNode root = CreateSemanticsNode(0, "root", &root_children);
  FlutterSemanticsNode child1 =
      CreateSemanticsNode(1, "child 1", &child1_children);
  FlutterSemanticsNode child2 = CreateSemanticsNode(2, "child 2");

  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->AddFlutterSemanticsNodeUpdate(&child1);
  bridge->AddFlutterSemanticsNodeUpdate(&child2);
  bridge->CommitUpdates();
  bridge->accessibility_events.clear();

  // Reparent child2 from child1 to the root.
  child1.child_count = 0;
  child1.children_in_traversal_order = nullptr;

  int32_t new_root_children[] = {1, 2};
  root.child_count = 2;
  root.children_in_traversal_order = new_root_children;

  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->AddFlutterSemanticsNodeUpdate(&child1);
  bridge->AddFlutterSemanticsNodeUpdate(&child2);
  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
  auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
  auto child2_node = bridge->GetFlutterPlatformNodeDelegateFromID(2).lock();

  EXPECT_EQ(root_node->GetChildCount(), 2);
  EXPECT_EQ(root_node->GetData().child_ids[0], 1);
  EXPECT_EQ(root_node->GetData().child_ids[1], 2);
  EXPECT_EQ(root_node->GetName(), "root");

  EXPECT_EQ(child1_node->GetChildCount(), 0);
  EXPECT_EQ(child1_node->GetName(), "child 1");

  EXPECT_EQ(child2_node->GetChildCount(), 0);
  EXPECT_EQ(child2_node->GetName(), "child 2");

  ASSERT_EQ(bridge->accessibility_events.size(), size_t{5});

  // Child2 is moved from child1 to root.
  EXPECT_THAT(bridge->accessibility_events,
              Contains(ui::AXEventGenerator::Event::CHILDREN_CHANGED).Times(2));
  EXPECT_THAT(bridge->accessibility_events,
              Contains(ui::AXEventGenerator::Event::SUBTREE_CREATED).Times(1));

  // Child1 is no longer a parent. It loses its group role and disables its
  // 'clip children' attribute.
  EXPECT_THAT(
      bridge->accessibility_events,
      Contains(ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED).Times(1));
  EXPECT_THAT(bridge->accessibility_events,
              Contains(ui::AXEventGenerator::Event::ROLE_CHANGED).Times(1));
}

// Verify that multiple nodes can be moved to new parents.
TEST(AccessibilityBridgeTest, CanReparentMultipleNodes) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();

  int32_t root_id = 0;
  int32_t intermediary1_id = 1;
  int32_t intermediary2_id = 2;
  int32_t leaf1_id = 3;
  int32_t leaf2_id = 4;
  int32_t leaf3_id = 5;

  std::vector<int32_t> root_children{intermediary1_id, intermediary2_id};
  std::vector<int32_t> intermediary1_children{leaf1_id};
  std::vector<int32_t> intermediary2_children{leaf2_id, leaf3_id};
  FlutterSemanticsNode root =
      CreateSemanticsNode(root_id, "root", &root_children);
  FlutterSemanticsNode intermediary1 = CreateSemanticsNode(
      intermediary1_id, "intermediary 1", &intermediary1_children);
  FlutterSemanticsNode intermediary2 = CreateSemanticsNode(
      intermediary2_id, "intermediary 2", &intermediary2_children);
  FlutterSemanticsNode leaf1 = CreateSemanticsNode(leaf1_id, "leaf 1");
  FlutterSemanticsNode leaf2 = CreateSemanticsNode(leaf2_id, "leaf 2");
  FlutterSemanticsNode leaf3 = CreateSemanticsNode(leaf3_id, "leaf 3");

  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->AddFlutterSemanticsNodeUpdate(&intermediary1);
  bridge->AddFlutterSemanticsNodeUpdate(&intermediary2);
  bridge->AddFlutterSemanticsNodeUpdate(&leaf1);
  bridge->AddFlutterSemanticsNodeUpdate(&leaf2);
  bridge->AddFlutterSemanticsNodeUpdate(&leaf3);
  bridge->CommitUpdates();
  bridge->accessibility_events.clear();

  // Swap intermediary 1's and intermediary2's children.
  int32_t new_intermediary1_children[] = {leaf2_id, leaf3_id};
  intermediary1.child_count = 2;
  intermediary1.children_in_traversal_order = new_intermediary1_children;

  int32_t new_intermediary2_children[] = {leaf1_id};
  intermediary2.child_count = 1;
  intermediary2.children_in_traversal_order = new_intermediary2_children;

  bridge->AddFlutterSemanticsNodeUpdate(&intermediary1);
  bridge->AddFlutterSemanticsNodeUpdate(&intermediary2);
  bridge->AddFlutterSemanticsNodeUpdate(&leaf1);
  bridge->AddFlutterSemanticsNodeUpdate(&leaf2);
  bridge->AddFlutterSemanticsNodeUpdate(&leaf3);
  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(root_id).lock();
  auto intermediary1_node =
      bridge->GetFlutterPlatformNodeDelegateFromID(intermediary1_id).lock();
  auto intermediary2_node =
      bridge->GetFlutterPlatformNodeDelegateFromID(intermediary2_id).lock();
  auto leaf1_node =
      bridge->GetFlutterPlatformNodeDelegateFromID(leaf1_id).lock();
  auto leaf2_node =
      bridge->GetFlutterPlatformNodeDelegateFromID(leaf2_id).lock();
  auto leaf3_node =
      bridge->GetFlutterPlatformNodeDelegateFromID(leaf3_id).lock();

  EXPECT_EQ(root_node->GetChildCount(), 2);
  EXPECT_EQ(root_node->GetData().child_ids[0], intermediary1_id);
  EXPECT_EQ(root_node->GetData().child_ids[1], intermediary2_id);
  EXPECT_EQ(root_node->GetName(), "root");

  EXPECT_EQ(intermediary1_node->GetChildCount(), 2);
  EXPECT_EQ(intermediary1_node->GetData().child_ids[0], leaf2_id);
  EXPECT_EQ(intermediary1_node->GetData().child_ids[1], leaf3_id);
  EXPECT_EQ(intermediary1_node->GetName(), "intermediary 1");

  EXPECT_EQ(intermediary2_node->GetChildCount(), 1);
  EXPECT_EQ(intermediary2_node->GetData().child_ids[0], leaf1_id);
  EXPECT_EQ(intermediary2_node->GetName(), "intermediary 2");

  EXPECT_EQ(leaf1_node->GetChildCount(), 0);
  EXPECT_EQ(leaf1_node->GetName(), "leaf 1");

  EXPECT_EQ(leaf2_node->GetChildCount(), 0);
  EXPECT_EQ(leaf2_node->GetName(), "leaf 2");

  EXPECT_EQ(leaf3_node->GetChildCount(), 0);
  EXPECT_EQ(leaf3_node->GetName(), "leaf 3");

  // Intermediary 1 and intermediary 2 have new children.
  // Leaf 1, 2, and 3 are all moved.
  ASSERT_EQ(bridge->accessibility_events.size(), size_t{5});
  EXPECT_THAT(bridge->accessibility_events,
              Contains(ui::AXEventGenerator::Event::CHILDREN_CHANGED).Times(2));
  EXPECT_THAT(bridge->accessibility_events,
              Contains(ui::AXEventGenerator::Event::SUBTREE_CREATED).Times(3));
}

// Verify that a node with a child can be moved from one parent to another.
TEST(AccessibilityBridgeTest, CanReparentNodeWithChild) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();

  int32_t root_id = 0;
  int32_t intermediary1_id = 1;
  int32_t intermediary2_id = 2;
  int32_t leaf1_id = 3;

  std::vector<int32_t> root_children{intermediary1_id, intermediary2_id};
  std::vector<int32_t> intermediary1_children{leaf1_id};
  FlutterSemanticsNode root =
      CreateSemanticsNode(root_id, "root", &root_children);
  FlutterSemanticsNode intermediary1 = CreateSemanticsNode(
      intermediary1_id, "intermediary 1", &intermediary1_children);
  FlutterSemanticsNode intermediary2 =
      CreateSemanticsNode(intermediary2_id, "intermediary 2");
  FlutterSemanticsNode leaf1 = CreateSemanticsNode(leaf1_id, "leaf 1");

  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->AddFlutterSemanticsNodeUpdate(&intermediary1);
  bridge->AddFlutterSemanticsNodeUpdate(&intermediary2);
  bridge->AddFlutterSemanticsNodeUpdate(&leaf1);
  bridge->CommitUpdates();
  bridge->accessibility_events.clear();

  // Move intermediary1 from root to intermediary 2.
  int32_t new_root_children[] = {intermediary2_id};
  root.child_count = 1;
  root.children_in_traversal_order = new_root_children;

  int32_t new_intermediary2_children[] = {intermediary1_id};
  intermediary2.child_count = 1;
  intermediary2.children_in_traversal_order = new_intermediary2_children;

  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->AddFlutterSemanticsNodeUpdate(&intermediary1);
  bridge->AddFlutterSemanticsNodeUpdate(&intermediary2);
  bridge->AddFlutterSemanticsNodeUpdate(&leaf1);
  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(root_id).lock();
  auto intermediary1_node =
      bridge->GetFlutterPlatformNodeDelegateFromID(intermediary1_id).lock();
  auto intermediary2_node =
      bridge->GetFlutterPlatformNodeDelegateFromID(intermediary2_id).lock();
  auto leaf1_node =
      bridge->GetFlutterPlatformNodeDelegateFromID(leaf1_id).lock();

  EXPECT_EQ(root_node->GetChildCount(), 1);
  EXPECT_EQ(root_node->GetData().child_ids[0], intermediary2_id);
  EXPECT_EQ(root_node->GetName(), "root");

  EXPECT_EQ(intermediary2_node->GetChildCount(), 1);
  EXPECT_EQ(intermediary2_node->GetData().child_ids[0], intermediary1_id);
  EXPECT_EQ(intermediary2_node->GetName(), "intermediary 2");

  EXPECT_EQ(intermediary1_node->GetChildCount(), 1);
  EXPECT_EQ(intermediary1_node->GetData().child_ids[0], leaf1_id);
  EXPECT_EQ(intermediary1_node->GetName(), "intermediary 1");

  EXPECT_EQ(leaf1_node->GetChildCount(), 0);
  EXPECT_EQ(leaf1_node->GetName(), "leaf 1");

  ASSERT_EQ(bridge->accessibility_events.size(), size_t{5});

  EXPECT_THAT(bridge->accessibility_events,
              Contains(ui::AXEventGenerator::Event::CHILDREN_CHANGED).Times(2));
  EXPECT_THAT(bridge->accessibility_events,
              Contains(ui::AXEventGenerator::Event::SUBTREE_CREATED).Times(1));

  // Intermediary 2 becomes a parent node. It updates to group role and enables
  // its 'clip children' attribute.
  EXPECT_THAT(
      bridge->accessibility_events,
      Contains(ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED).Times(1));
  EXPECT_THAT(bridge->accessibility_events,
              Contains(ui::AXEventGenerator::Event::ROLE_CHANGED).Times(1));
}

TEST(AccessibilityBridgeTest, AXTreeManagerTest) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();

  ui::AXTreeID tree_id = bridge->GetTreeID();
  ui::AXTreeManager* manager =
      ui::AXTreeManagerMap::GetInstance().GetManager(tree_id);
  ASSERT_EQ(manager, static_cast<ui::AXTreeManager*>(bridge.get()));
}

TEST(AccessibilityBridgeTest, LineBreakingObjectTest) {
  std::shared_ptr<TestAccessibilityBridge> bridge =
      std::make_shared<TestAccessibilityBridge>();

  const int32_t root_id = 0;

  FlutterSemanticsNode root = CreateSemanticsNode(root_id, "root", {});

  bridge->AddFlutterSemanticsNodeUpdate(&root);
  bridge->CommitUpdates();

  auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(root_id).lock();
  auto root_data = root_node->GetData();
  EXPECT_TRUE(root_data.HasBoolAttribute(
      ax::mojom::BoolAttribute::kIsLineBreakingObject));
  EXPECT_TRUE(root_data.GetBoolAttribute(
      ax::mojom::BoolAttribute::kIsLineBreakingObject));
}

}  // namespace testing
}  // namespace flutter
