blob: 2adf76c6c9d5201d0c523d8ad2baf8b0eb7fa883 [file] [log] [blame]
// Copyright 2020 The Fuchsia 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 "src/ui/a11y/lib/screen_reader/recover_a11y_focus_action.h"
#include <fuchsia/accessibility/cpp/fidl.h>
#include <lib/gtest/test_loop_fixture.h>
#include <lib/sys/cpp/testing/component_context_provider.h>
#include <zircon/types.h>
#include <memory>
#include <gmock/gmock.h>
#include "src/ui/a11y/bin/a11y_manager/tests/util/util.h"
#include "src/ui/a11y/lib/annotation/tests/mocks/mock_annotation_view.h"
#include "src/ui/a11y/lib/focus_chain/tests/mocks/mock_focus_chain_registry.h"
#include "src/ui/a11y/lib/focus_chain/tests/mocks/mock_focus_chain_requester.h"
#include "src/ui/a11y/lib/screen_reader/focus/tests/mocks/mock_a11y_focus_manager.h"
#include "src/ui/a11y/lib/screen_reader/screen_reader_context.h"
#include "src/ui/a11y/lib/screen_reader/tests/mocks/mock_screen_reader_context.h"
#include "src/ui/a11y/lib/semantics/tests/mocks/mock_semantic_provider.h"
#include "src/ui/a11y/lib/semantics/tests/mocks/mock_semantics_event_manager.h"
#include "src/ui/a11y/lib/view/tests/mocks/mock_view_semantics.h"
namespace accessibility_test {
namespace {
using a11y::ScreenReaderContext;
class RecoverA11YFocusActionTest : public gtest::TestLoopFixture {
public:
RecoverA11YFocusActionTest()
: view_manager_(std::make_unique<a11y::SemanticTreeServiceFactory>(),
std::make_unique<MockViewSemanticsFactory>(),
std::make_unique<MockAnnotationViewFactory>(),
std::make_unique<MockSemanticsEventManager>(), context_provider_.context(),
context_provider_.context()->outgoing()->debug_dir()),
semantic_provider_(&view_manager_) {
action_context_.semantics_source = &view_manager_;
screen_reader_context_ = std::make_unique<MockScreenReaderContext>();
a11y_focus_manager_ptr_ = screen_reader_context_->mock_a11y_focus_manager_ptr();
mock_speaker_ptr_ = screen_reader_context_->mock_speaker_ptr();
view_manager_.SetSemanticsEnabled(true);
fuchsia::accessibility::semantics::Node node;
node.set_node_id(0);
node.set_role(fuchsia::accessibility::semantics::Role::TEXT_FIELD);
node.mutable_child_ids()->push_back(1);
fuchsia::accessibility::semantics::Node node2;
node2.set_node_id(1);
node2.mutable_attributes()->set_label("node2");
std::vector<decltype(node)> update_nodes;
update_nodes.push_back(std::move(node));
update_nodes.push_back(std::move(node2));
semantic_provider_.UpdateSemanticNodes(std::move(update_nodes));
RunLoopUntilIdle();
semantic_provider_.CommitUpdates();
RunLoopUntilIdle();
a11y_focus_manager_ptr_->SetA11yFocus(semantic_provider_.koid(), 0,
[](bool result) { EXPECT_TRUE(result); });
}
vfs::PseudoDir* debug_dir() { return context_provider_.context()->outgoing()->debug_dir(); }
sys::testing::ComponentContextProvider context_provider_;
a11y::ViewManager view_manager_;
a11y::ScreenReaderAction::ActionContext action_context_;
std::unique_ptr<MockScreenReaderContext> screen_reader_context_;
MockA11yFocusManager* a11y_focus_manager_ptr_;
MockScreenReaderContext::MockSpeaker* mock_speaker_ptr_;
MockSemanticProvider semantic_provider_;
};
TEST_F(RecoverA11YFocusActionTest, FocusIsStillValid) {
a11y_focus_manager_ptr_->SetA11yFocus(semantic_provider_.koid(), 0,
[](bool result) { EXPECT_TRUE(result); });
a11y::RecoverA11YFocusAction action(&action_context_, screen_reader_context_.get());
action.Run({});
RunLoopUntilIdle();
auto focus = a11y_focus_manager_ptr_->GetA11yFocus();
ASSERT_TRUE(focus);
ASSERT_EQ(focus->view_ref_koid, semantic_provider_.koid());
ASSERT_EQ(focus->node_id, 0u);
EXPECT_TRUE(a11y_focus_manager_ptr_->IsUpdateHighlightsCalled());
}
TEST_F(RecoverA11YFocusActionTest, InvalidFocusRecoversToFirstDescribableNode) {
// Sets the focus to a node that does not exist, then run the action.
a11y_focus_manager_ptr_->SetA11yFocus(semantic_provider_.koid(), 100,
[](bool result) { EXPECT_TRUE(result); });
a11y::RecoverA11YFocusAction action(&action_context_, screen_reader_context_.get());
action.Run({});
RunLoopUntilIdle();
auto focus = a11y_focus_manager_ptr_->GetA11yFocus();
ASSERT_TRUE(focus);
EXPECT_EQ(semantic_provider_.koid(), focus->view_ref_koid);
EXPECT_EQ(focus->node_id, 1u);
EXPECT_TRUE(mock_speaker_ptr_->node_ids().empty());
}
} // namespace
} // namespace accessibility_test