// Copyright 2019 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/bin/a11y_manager/app.h"

#include <fuchsia/accessibility/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/inspect/testing/cpp/inspect.h>
#include <lib/sys/cpp/testing/component_context_provider.h>
#include <lib/syslog/cpp/macros.h>
#include <lib/ui/scenic/cpp/view_identity.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>

#include <gtest/gtest.h>
#include <src/lib/fostr/fidl/fuchsia/accessibility/formatting.h>

#include "src/lib/testing/loop_fixture/real_loop_fixture.h"
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
#include "src/ui/a11y/bin/a11y_manager/tests/mocks/mock_color_transform_handler.h"
#include "src/ui/a11y/bin/a11y_manager/tests/mocks/mock_focus_chain.h"
#include "src/ui/a11y/bin/a11y_manager/tests/mocks/mock_property_provider.h"
#include "src/ui/a11y/bin/a11y_manager/tests/mocks/mock_setui_accessibility.h"
#include "src/ui/a11y/bin/a11y_manager/tests/util/util.h"
#include "src/ui/a11y/lib/gesture_manager/recognizers/one_finger_n_tap_recognizer.h"
#include "src/ui/a11y/lib/screen_reader/tests/mocks/mock_screen_reader_context.h"
#include "src/ui/a11y/lib/screen_reader/tests/mocks/mock_tts_engine.h"
#include "src/ui/a11y/lib/semantics/tests/mocks/mock_semantic_listener.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/testing/input.h"
#include "src/ui/a11y/lib/util/tests/mocks/mock_boot_info_manager.h"
#include "src/ui/a11y/lib/util/util.h"
#include "src/ui/a11y/lib/view/a11y_view_semantics.h"
#include "src/ui/a11y/lib/view/tests/mocks/mock_accessibility_view.h"
#include "src/ui/a11y/lib/view/tests/mocks/mock_view_injector_factory.h"
#include "src/ui/a11y/lib/view/tests/mocks/scenic_mocks.h"

namespace accessibility_test {
namespace {

using fuchsia::accessibility::semantics::Node;
using fuchsia::accessibility::semantics::NodePtr;
using fuchsia::ui::input::accessibility::EventHandling;
using fuchsia::ui::input::accessibility::PointerEventListener;
using fuchsia::ui::input::accessibility::PointerEventListenerPtr;

template <typename LoopFixture>
class UnitTest : public LoopFixture {
 public:
  UnitTest()
      : context_provider_(),
        context_(context_provider_.context()),
        mock_color_transform_handler_(&context_provider_),
        mock_setui_(&context_provider_),
        mock_focus_chain_(&context_provider_),
        mock_property_provider_(&context_provider_),
        mock_boot_info_manager_(context_, true),
        tts_manager_(context_),
        color_transform_manager_(context_),
        screen_reader_context_factory_() {
    auto mock_a11y_view = std::make_unique<MockAccessibilityView>();
    mock_a11y_view->SetTouchSource(mock_local_hit_.NewTouchSource());
    mock_a11y_view_ptr_ = mock_a11y_view.get();
    view_manager_ = std::make_unique<a11y::ViewManager>(
        std::make_unique<a11y::SemanticTreeServiceFactory>(),
        std::make_unique<a11y::A11yViewSemanticsFactory>(),
        std::make_unique<MockViewInjectorFactory>(), std::make_unique<MockSemanticsEventManager>(),
        std::move(mock_a11y_view), context_provider_.context());
    mock_semantic_provider_ = std::make_unique<MockSemanticProvider>(view_manager_.get());
    mock_local_hit_.SetViewRefKoidForTouchEvents(mock_semantic_provider_->koid());
  }

  void AddNodeToTree(uint32_t node_id, std::string label,
                     std::vector<uint32_t> child_ids = std::vector<uint32_t>()) {
    std::vector<fuchsia::accessibility::semantics::Node> updates;
    updates.emplace_back(CreateTestNode(node_id, label, child_ids));
    mock_semantic_provider_->UpdateSemanticNodes(std::move(updates));
    mock_semantic_provider_->CommitUpdates();
    LoopFixture::RunLoopUntilIdle();
  }

  void ConnectSpeakerAndEngineToTtsManager() {
    // The speaker and engine need to be connected to the tts manager before the
    // screen reader announces it's on. In order to verify that the screen reader
    // correctly vocalizes, we need to expicitly connect the speaker and engine.
    fuchsia::accessibility::tts::EnginePtr engine_ptr;
    tts_manager_.OpenEngine(
        engine_ptr.NewRequest(),
        [](fuchsia::accessibility::tts::TtsManager_OpenEngine_Result result) {});
    LoopFixture::RunLoopUntilIdle();

    MockTtsEngine mock_tts_engine;
    tts_manager_.RegisterEngine(
        mock_tts_engine.GetHandle(),
        [](fuchsia::accessibility::tts::EngineRegistry_RegisterEngine_Result result) {});
    LoopFixture::RunLoopUntilIdle();
  }

  std::unique_ptr<a11y_manager::App> GetApp(const bool a11y_view_initialized = true) {
    auto app = std::make_unique<a11y_manager::App>(
        context_, view_manager_.get(), &tts_manager_, &color_transform_manager_,
        &gesture_listener_registry_, &mock_boot_info_manager_, &screen_reader_context_factory_,
        inspector_.GetRoot().CreateChild("app"));

    auto identity = scenic::NewViewIdentityOnCreation();

    a11y_control_ref_ = std::move(identity.view_ref_control);
    mock_a11y_view_ptr_->set_view_ref(std::move(identity.view_ref));

    LoopFixture::RunLoopUntilIdle();
    // App is created, but is not fully-initialized.  Make sure the fetch of settings only happens
    // after it has been initialized.
    EXPECT_EQ(0, mock_setui_.num_watch_called());
    EXPECT_EQ(1, mock_property_provider_.get_profile_count());
    mock_property_provider_.SetLocale("en");
    mock_property_provider_.ReplyToGetProfile();
    LoopFixture::RunLoopUntilIdle();
    EXPECT_EQ(1,
              mock_property_provider_.get_profile_count());  // Still 1, no changes in profile yet.

    if (a11y_view_initialized) {
      mock_a11y_view_ptr_->invoke_scene_ready_callback();
      LoopFixture::RunLoopUntilIdle();
    }

    return app;
  }

  sys::testing::ComponentContextProvider context_provider_;
  sys::ComponentContext* context_;
  inspect::Inspector inspector_;

  MockLocalHit mock_local_hit_;
  MockColorTransformHandler mock_color_transform_handler_;
  MockSetUIAccessibility mock_setui_;
  MockFocusChain mock_focus_chain_;
  MockPropertyProvider mock_property_provider_;
  MockBootInfoManager mock_boot_info_manager_;
  std::unique_ptr<a11y::ViewManager> view_manager_;
  a11y::TtsManager tts_manager_;
  a11y::ColorTransformManager color_transform_manager_;
  a11y::GestureListenerRegistry gesture_listener_registry_;
  std::unique_ptr<MockSemanticProvider> mock_semantic_provider_;
  MockScreenReaderContextFactory screen_reader_context_factory_;
  MockAccessibilityView* mock_a11y_view_ptr_;

 private:
  // We don't actually use these times. If we did, we'd want to more closely correlate them with
  // fake time.
  // uint64_t input_event_time_ = 0;
  fuchsia::ui::views::ViewRefControl a11y_control_ref_;
};

using AppUnitTest = UnitTest<gtest::TestLoopFixture>;

// Test to make sure ViewManager Service is exposed by A11y.
// Test sends a node update to ViewManager and then compare the expected
// result using log file created by semantics manager.
TEST_F(AppUnitTest, UpdateNodeToSemanticsManager) {
  auto app = GetApp();
  // Turn on the screen reader.
  fuchsia::settings::AccessibilitySettings settings;
  settings.set_screen_reader(true);
  mock_setui_.Set(std::move(settings), [](auto) {});

  // Enable semantics and verify that they were enabled correctly.
  view_manager_->SetSemanticsEnabled(true);
  RunLoopUntilIdle();
  EXPECT_TRUE(mock_semantic_provider_->GetSemanticsEnabled());

  // Creating test node to update.
  AddNodeToTree(0, "Label A");

  // Check that the node is in the semantic tree
  auto created_node = view_manager_->GetSemanticNode(mock_semantic_provider_->koid(), 0u);
  EXPECT_TRUE(created_node);
  EXPECT_EQ(created_node->attributes().label(), "Label A");
}

// This test makes sure that services implemented by the Tts manager are
// available.
TEST_F(AppUnitTest, OffersTtsManagerServices) {
  auto app = GetApp();
  fuchsia::accessibility::tts::TtsManagerPtr tts_manager;
  context_provider_.ConnectToPublicService(tts_manager.NewRequest());
  RunLoopUntilIdle();
  EXPECT_TRUE(tts_manager.is_bound());
}

TEST_F(AppUnitTest, NoListenerInitially) {
  auto app = GetApp();
  mock_setui_.Set({}, [](auto) {});

  RunLoopUntilIdle();
}

TEST_F(AppUnitTest, ColorCorrectionApplied) {
  auto app = GetApp();
  fuchsia::settings::AccessibilitySettings accessibilitySettings;
  accessibilitySettings.set_screen_reader(false);
  accessibilitySettings.set_color_inversion(false);
  accessibilitySettings.set_enable_magnification(false);
  accessibilitySettings.set_color_correction(fuchsia::settings::ColorBlindnessType::NONE);
  mock_setui_.Set(std::move(accessibilitySettings), [](auto) {});

  RunLoopUntilIdle();

  EXPECT_EQ(fuchsia::accessibility::ColorCorrectionMode::DISABLED,
            mock_color_transform_handler_.GetColorCorrectionMode());

  // Turn on color correction.
  fuchsia::settings::AccessibilitySettings newAccessibilitySettings;
  newAccessibilitySettings.set_color_correction(
      fuchsia::settings::ColorBlindnessType::DEUTERANOMALY);
  mock_setui_.Set(std::move(newAccessibilitySettings), [](auto) {});
  RunLoopUntilIdle();

  // Verify that stuff changed
  EXPECT_EQ(fuchsia::accessibility::ColorCorrectionMode::CORRECT_DEUTERANOMALY,
            mock_color_transform_handler_.GetColorCorrectionMode());
}

TEST_F(AppUnitTest, ColorInversionApplied) {
  auto app = GetApp();
  fuchsia::settings::AccessibilitySettings accessibilitySettings;
  accessibilitySettings.set_screen_reader(false);
  accessibilitySettings.set_color_inversion(false);
  accessibilitySettings.set_enable_magnification(false);
  accessibilitySettings.set_color_correction(fuchsia::settings::ColorBlindnessType::NONE);
  mock_setui_.Set(std::move(accessibilitySettings), [](auto) {});
  RunLoopUntilIdle();

  EXPECT_FALSE(mock_color_transform_handler_.GetColorInversionEnabled());

  // Turn on color correction.
  fuchsia::settings::AccessibilitySettings newAccessibilitySettings;
  newAccessibilitySettings.set_color_inversion(true);
  mock_setui_.Set(std::move(newAccessibilitySettings), [](auto) {});
  RunLoopUntilIdle();

  // Verify that stuff changed
  EXPECT_TRUE(mock_color_transform_handler_.GetColorInversionEnabled());
}

TEST_F(AppUnitTest, ScreenReaderOnAtUserInitiatedReboot) {
  fuchsia::settings::AccessibilitySettings accessibilitySettings;
  accessibilitySettings.set_screen_reader(true);
  accessibilitySettings.set_color_inversion(false);
  accessibilitySettings.set_enable_magnification(false);
  accessibilitySettings.set_color_correction(fuchsia::settings::ColorBlindnessType::NONE);

  mock_setui_.Set(std::move(accessibilitySettings), [](auto) {});
  RunLoopUntilIdle();

  auto app = GetApp();

  // Verify that screen reader is on.
  EXPECT_TRUE(app->state().screen_reader_enabled());

  // Both a speaker and an engine need to be connected to the TTS manager in
  // order for the screen reader to announce that it's on.
  ConnectSpeakerAndEngineToTtsManager();

  auto mock_screen_reader_context = screen_reader_context_factory_.mock_screen_reader_context();
  ASSERT_TRUE(mock_screen_reader_context);

  auto mock_speaker = mock_screen_reader_context->mock_speaker_ptr();
  ASSERT_TRUE(mock_speaker);
  EXPECT_TRUE(mock_speaker->ReceivedSpeak());
  EXPECT_EQ(mock_speaker->message_ids().size(), 1u);
}

TEST_F(AppUnitTest, ScreenReaderOnAtSystemReboot) {
  fuchsia::settings::AccessibilitySettings accessibilitySettings;
  accessibilitySettings.set_screen_reader(true);
  accessibilitySettings.set_color_inversion(false);
  accessibilitySettings.set_enable_magnification(false);
  accessibilitySettings.set_color_correction(fuchsia::settings::ColorBlindnessType::NONE);

  mock_setui_.Set(std::move(accessibilitySettings), [](auto) {});
  RunLoopUntilIdle();

  mock_boot_info_manager_.SetLastRebootWasUserInitiated(false);
  auto app = GetApp();

  // Both a speaker and an engine need to be connected to the TTS manager in
  // order for the screen reader to announce that it's on.
  ConnectSpeakerAndEngineToTtsManager();

  auto mock_screen_reader_context = screen_reader_context_factory_.mock_screen_reader_context();
  ASSERT_TRUE(mock_screen_reader_context);

  auto mock_speaker = mock_screen_reader_context->mock_speaker_ptr();
  ASSERT_TRUE(mock_speaker);
  EXPECT_FALSE(mock_speaker->ReceivedSpeak());
}

TEST_F(AppUnitTest, ScreenReaderAnnouncesOnWhenUserExplicitlyEnables) {
  {
    fuchsia::settings::AccessibilitySettings accessibilitySettings;
    accessibilitySettings.set_screen_reader(false);
    accessibilitySettings.set_color_inversion(false);
    accessibilitySettings.set_enable_magnification(false);
    accessibilitySettings.set_color_correction(fuchsia::settings::ColorBlindnessType::NONE);

    mock_setui_.Set(std::move(accessibilitySettings), [](auto) {});
    RunLoopUntilIdle();
  }

  auto app = GetApp();

  auto mock_screen_reader_context = screen_reader_context_factory_.mock_screen_reader_context();
  // Screen reader should not yet be instantiated. Since the context is created
  // at the same time as the screen reader object, we can check whether the
  // context has been initialized.
  ASSERT_FALSE(mock_screen_reader_context);

  {
    fuchsia::settings::AccessibilitySettings accessibilitySettings;
    accessibilitySettings.set_screen_reader(true);
    accessibilitySettings.set_color_inversion(false);
    accessibilitySettings.set_enable_magnification(false);
    accessibilitySettings.set_color_correction(fuchsia::settings::ColorBlindnessType::NONE);

    mock_setui_.Set(std::move(accessibilitySettings), [](auto) {});
    RunLoopUntilIdle();
  }

  // Both a speaker and an engine need to be connected to the TTS manager in
  // order for the screen reader to announce that it's on.
  ConnectSpeakerAndEngineToTtsManager();

  mock_screen_reader_context = screen_reader_context_factory_.mock_screen_reader_context();
  ASSERT_TRUE(mock_screen_reader_context);

  auto mock_speaker = mock_screen_reader_context->mock_speaker_ptr();
  ASSERT_TRUE(mock_speaker);
  EXPECT_TRUE(mock_speaker->ReceivedSpeak());
  EXPECT_EQ(mock_speaker->message_ids().size(), 1u);
}

TEST_F(AppUnitTest, InitializesFocusChain) {
  auto app = GetApp();
  // Ensures that when App is initialized, it connects to the Focus Chain different services.
  RunLoopUntilIdle();

  ASSERT_TRUE(mock_focus_chain_.listener());
}

// Makes sure FocusChain is wired up with the screen reader, when screen reader is enabled.
// This test uses explore action to make sure when a node is tapped, then screen reader can call
// RequestFocus() on FocusChain. This confirms that FocusChain is connected to ScreenReader.
TEST_F(AppUnitTest, FocusChainIsWiredToScreenReader) {
  auto app = GetApp();
  // Enable Screen Reader.
  fuchsia::settings::AccessibilitySettings accessibilitySettings;
  accessibilitySettings.set_screen_reader(true);
  accessibilitySettings.set_color_inversion(false);
  accessibilitySettings.set_enable_magnification(false);
  accessibilitySettings.set_color_correction(fuchsia::settings::ColorBlindnessType::NONE);
  mock_setui_.Set(std::move(accessibilitySettings), [](auto) {});
  RunLoopUntilIdle();

  // Creating test node to update.
  AddNodeToTree(0, "Label A");

  auto created_node = view_manager_->GetSemanticNode(mock_semantic_provider_->koid(), 0u);
  EXPECT_TRUE(created_node);
  EXPECT_EQ(created_node->attributes().label(), "Label A");

  // Set HitTest result which is required to know which node is being tapped.
  mock_semantic_provider_->SetHitTestResult(0);

  // Send Tap event for view_ref_. This should trigger explore action, which should then call
  // FocusChain to set focus to the tapped view.
  mock_local_hit_.EnqueueTapToEvents();
  mock_local_hit_.SimulateEnqueuedEvents();

  RunLoopFor(a11y::kMaxTapDuration);

  auto mock_screen_reader_context = screen_reader_context_factory_.mock_screen_reader_context();
  ASSERT_TRUE(mock_screen_reader_context);

  auto mock_focus_manager = mock_screen_reader_context->mock_a11y_focus_manager_ptr();
  ASSERT_TRUE(mock_focus_manager);

  auto a11y_focus = mock_focus_manager->GetA11yFocus();
  ASSERT_TRUE(a11y_focus);

  EXPECT_EQ(mock_semantic_provider_->koid(), a11y_focus->view_ref_koid);
}

TEST_F(AppUnitTest, AfterStartupHasLocaleAndViewCoordinateConverterAvailable) {
  auto app = GetApp();

  // Note: 2 here because as soon as we get a settings, we call Watch() again.
  EXPECT_EQ(2, mock_setui_.num_watch_called());

  // App is initialized, so it should have requested once the locale.
  ASSERT_EQ(1, mock_property_provider_.get_profile_count());
  mock_property_provider_.SetLocale("en-US");
  mock_property_provider_.SendOnChangeEvent();
  RunLoopUntilIdle();
  // The event causes GetProfile() to be invoked again from the a11y manager side. Check if the call
  // happened through the mock.
  ASSERT_EQ(2, mock_property_provider_.get_profile_count());
  EXPECT_TRUE(view_manager_->GetViewCoordinateConverterForTest());
}

TEST_F(AppUnitTest, ScreenReaderReinitializesWhenLocaleChanges) {
  auto app = GetApp(/*a11y_view_initialized=*/false);
  fuchsia::settings::AccessibilitySettings accessibilitySettings;
  accessibilitySettings.set_screen_reader(true);
  accessibilitySettings.set_color_inversion(false);
  accessibilitySettings.set_enable_magnification(false);
  accessibilitySettings.set_color_correction(fuchsia::settings::ColorBlindnessType::NONE);
  mock_setui_.Set(std::move(accessibilitySettings), [](auto) {});
  RunLoopUntilIdle();

  // A11y manager is not initialized yet, because the a11y view is not ready.
  EXPECT_FALSE(app->state().screen_reader_enabled());

  mock_a11y_view_ptr_->invoke_scene_ready_callback();
  RunLoopUntilIdle();

  EXPECT_TRUE(app->state().screen_reader_enabled());
  auto old_screen_reader_ptr = app->screen_reader();
  ASSERT_TRUE(old_screen_reader_ptr);
  EXPECT_EQ(old_screen_reader_ptr->context()->locale_id(), "en");
  mock_property_provider_.SetLocale("en-US");
  mock_property_provider_.SendOnChangeEvent();
  RunLoopUntilIdle();
  // The event causes GetProfile() to be invoked again from the a11y manager side. Check if the call
  // happened through the mock.
  ASSERT_EQ(2, mock_property_provider_.get_profile_count());
  // Sends a reply.
  mock_property_provider_.ReplyToGetProfile();
  RunLoopUntilIdle();
  auto new_screen_reader_ptr = app->screen_reader();
  ASSERT_TRUE(new_screen_reader_ptr);
  EXPECT_EQ(new_screen_reader_ptr->context()->locale_id(), "en-US");
  EXPECT_NE(new_screen_reader_ptr, old_screen_reader_ptr);
}

TEST_F(AppUnitTest, ScreenReaderUsesDefaultLocaleIfPropertyProviderDisconnectsOrIsNotAvailable) {
  auto app = GetApp();
  EXPECT_FALSE(app->state().screen_reader_enabled());
  mock_property_provider_.CloseChannels();
  RunLoopUntilIdle();
  // Only one call to GetProfile happened, because the channel was closed.
  ASSERT_EQ(1, mock_property_provider_.get_profile_count());
  // Turns on the Screen Reader and checks that it picks up the default locale.
  fuchsia::settings::AccessibilitySettings accessibilitySettings;
  accessibilitySettings.set_screen_reader(true);
  accessibilitySettings.set_color_inversion(false);
  accessibilitySettings.set_enable_magnification(false);
  accessibilitySettings.set_color_correction(fuchsia::settings::ColorBlindnessType::NONE);
  mock_setui_.Set(std::move(accessibilitySettings), [](auto) {});
  RunLoopUntilIdle();
  EXPECT_EQ(app->screen_reader()->context()->locale_id(), "en-US");
}

TEST_F(AppUnitTest, OffersVirtualkeyboardServices) {
  auto app = GetApp();
  fuchsia::accessibility::virtualkeyboard::RegistryPtr registry;
  context_provider_.ConnectToPublicService(registry.NewRequest());
  RunLoopUntilIdle();
  EXPECT_TRUE(registry.is_bound());
}

// Inspect tests use `RealLoopFixture`, because `ReadFromInspector` requires `RunPromise()`.
using InspectTest = UnitTest<gtest::RealLoopFixture>;

TEST_F(InspectTest, TreeHasFeatureNodes) {
  // Create the a11y_manager.
  auto app = GetApp();

  // Read the inspect tree.
  fpromise::result<inspect::Hierarchy> tree = RunPromise(inspect::ReadFromInspector(inspector_));
  ASSERT_TRUE(tree.is_ok());

  // Get a11y manager's tree.
  const inspect::Hierarchy* app_root_tree = tree.value().GetByPath({"app"});
  ASSERT_TRUE(app_root_tree);

  // Get the node from the tree, and verify expected properties are present on the node.
  //
  // Access the properties with a literal string, rather than a `kOnstant`, to ensure
  // that changes to `app.h` don't accidentally break tools (e.g. triage plugins) that
  // depend on these names.
  const inspect::NodeValue& app_root_node = app_root_tree->node();
  EXPECT_TRUE(app_root_node.get_property<inspect::BoolPropertyValue>("screen_reader_enabled"));
  EXPECT_TRUE(app_root_node.get_property<inspect::BoolPropertyValue>("magnifier_enabled"));
  EXPECT_TRUE(app_root_node.get_property<inspect::BoolPropertyValue>("color_inversion_enabled"));
  EXPECT_TRUE(app_root_node.get_property<inspect::UintPropertyValue>("color_correction_mode"));
}

TEST_F(InspectTest, TreeGetsUpdates) {
  // Create the a11y_manager.
  auto app = GetApp();

  // Create the values we want to set.
  fuchsia::settings::AccessibilitySettings newAccessibilitySettings;
  newAccessibilitySettings.set_screen_reader(true)
      .set_enable_magnification(true)
      .set_color_inversion(true)
      .set_color_correction(fuchsia::settings::ColorBlindnessType::DEUTERANOMALY);

  // Verify that our test settings differ from the initial settings.
  //
  // This ensures that the Inspect values verified below were actually a consequence
  // of `SetState()`, and not just defaults.
  const a11y_manager::A11yManagerState initial_state = app->state();
  const a11y_manager::A11yManagerState new_state =
      a11y_manager::A11yManagerState().withSettings(newAccessibilitySettings);
  ASSERT_NE(initial_state.screen_reader_enabled(), new_state.screen_reader_enabled());
  ASSERT_NE(initial_state.magnifier_enabled(), new_state.magnifier_enabled());
  ASSERT_NE(initial_state.color_inversion_enabled(), new_state.color_inversion_enabled());
  ASSERT_NE(initial_state.color_correction_mode(), new_state.color_correction_mode());

  // Change settings.
  mock_setui_.Set(std::move(newAccessibilitySettings), [](auto) {});
  RunLoopUntilIdle();

  // Read the inspect tree.
  fpromise::result<inspect::Hierarchy> tree = RunPromise(inspect::ReadFromInspector(inspector_));
  ASSERT_TRUE(tree.is_ok());

  // Get a11y manager's tree.
  const inspect::Hierarchy* app_root_tree = tree.value().GetByPath({"app"});
  ASSERT_TRUE(app_root_tree);

  // Get the node from the tree, and verify expected properties are present on the node.
  //
  // Access the properties with a literal string, rather than a `kOnstant`, to ensure
  // that changes to `app.h` don't accidentally break tools (e.g. triage plugins) that
  // depend on these names.
  const inspect::NodeValue& app_root_node = app_root_tree->node();
  auto* screen_reader_prop =
      app_root_node.get_property<inspect::BoolPropertyValue>("screen_reader_enabled");
  auto* magnifier_prop =
      app_root_node.get_property<inspect::BoolPropertyValue>("magnifier_enabled");
  auto* color_inversion_prop =
      app_root_node.get_property<inspect::BoolPropertyValue>("color_inversion_enabled");
  auto* color_correction_prop =
      app_root_node.get_property<inspect::UintPropertyValue>("color_correction_mode");
  ASSERT_TRUE(screen_reader_prop);
  ASSERT_TRUE(magnifier_prop);
  ASSERT_TRUE(color_inversion_prop);
  ASSERT_TRUE(color_correction_prop);

  // Verify property values.
  std::stringstream expected_mode_string;
  std::stringstream actual_mode_string;
  expected_mode_string << new_state.color_correction_mode();
  actual_mode_string << fuchsia::accessibility::ColorCorrectionMode(color_correction_prop->value());
  EXPECT_EQ(new_state.screen_reader_enabled(), screen_reader_prop->value());
  EXPECT_EQ(new_state.magnifier_enabled(), magnifier_prop->value());
  EXPECT_EQ(new_state.color_inversion_enabled(), color_inversion_prop->value());
  EXPECT_EQ(expected_mode_string.str(), actual_mode_string.str());
}

// TODO(https://fxbug.dev/42126946): Improve tests to cover what happens if services aren't available at
// startup.

}  // namespace
}  // namespace accessibility_test
