Flutter Windows Embedder
accessibility_plugin_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <memory>
8 
13 #include "flutter/shell/platform/windows/testing/engine_modifier.h"
14 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
15 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
16 #include "flutter/shell/platform/windows/testing/test_binary_messenger.h"
17 #include "flutter/shell/platform/windows/testing/windows_test.h"
18 #include "gmock/gmock.h"
19 #include "gtest/gtest.h"
20 
21 namespace flutter {
22 namespace testing {
23 
24 namespace {
25 
26 using ::testing::_;
27 using ::testing::NiceMock;
28 
29 static constexpr char kAccessibilityChannelName[] = "flutter/accessibility";
30 
31 class MockFlutterWindowsView : public FlutterWindowsView {
32  public:
33  MockFlutterWindowsView(FlutterWindowsEngine* engine,
34  std::unique_ptr<WindowBindingHandler> window)
35  : FlutterWindowsView(kImplicitViewId, engine, std::move(window)) {}
36 
37  MOCK_METHOD(void, AnnounceAlert, (const std::wstring& text), ());
38 };
39 
40 } // namespace
41 
42 class AccessibilityPluginTest : public WindowsTest {
43  public:
45  virtual ~AccessibilityPluginTest() = default;
46 
47  protected:
48  FlutterWindowsEngine* engine() { return engine_.get(); }
49  TestBinaryMessenger* messenger() { return &messenger_; }
50 
51  void SetUp() override {
52  WindowsTest::SetUp();
53 
54  FlutterWindowsEngineBuilder builder{GetContext()};
55  engine_ = builder.Build();
56 
57  auto window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
58  view_ = std::make_unique<NiceMock<MockFlutterWindowsView>>(
59  engine_.get(), std::move(window));
60 
61  EngineModifier modifier{engine_.get()};
62  modifier.SetSemanticsEnabled(true);
63  modifier.SetImplicitView(view_.get());
64 
65  plugin_ = std::make_unique<AccessibilityPlugin>(engine_.get());
66  AccessibilityPlugin::SetUp(&messenger_, plugin_.get());
67  }
68 
69  void SendAnnounceMessage(const std::string& message, EncodableValue view_id) {
70  EncodableMap data;
71  data[EncodableValue{"message"}] = EncodableValue{message};
72  data[EncodableValue{"viewId"}] = view_id;
73 
74  EncodableMap msg;
75  msg[EncodableValue{"type"}] = EncodableValue{"announce"};
76  msg[EncodableValue{"data"}] = EncodableValue{data};
77 
78  auto encoded =
80 
81  bool handled = messenger_.SimulateEngineMessage(
82  kAccessibilityChannelName, encoded->data(), encoded->size(),
83  [](const uint8_t* reply, size_t reply_size) {});
84 
85  EXPECT_TRUE(handled)
86  << "Message was not handled by the accessibility channel";
87  }
88 
89  MockFlutterWindowsView* view() { return view_.get(); }
90 
91  private:
92  std::unique_ptr<FlutterWindowsEngine> engine_;
93  std::unique_ptr<MockFlutterWindowsView> view_;
94  std::unique_ptr<AccessibilityPlugin> plugin_;
95  TestBinaryMessenger messenger_;
96 };
97 
98 TEST_F(AccessibilityPluginTest, DirectAnnounceCall) {
99  // Test calling Announce directly, bypassing the message channel
100  EXPECT_CALL(*view(), AnnounceAlert(::testing::Eq(L"Direct"))).Times(1);
101 
102  AccessibilityPlugin plugin(engine());
103  plugin.Announce(0, "Direct");
104 
105  ::testing::Mock::VerifyAndClearExpectations(view());
106 }
107 
108 TEST_F(AccessibilityPluginTest, AnnounceWithInt32ViewId) {
109  EXPECT_CALL(*view(), AnnounceAlert(::testing::Eq(L"Hello"))).Times(1);
110 
111  SendAnnounceMessage("Hello", EncodableValue{static_cast<int32_t>(0)});
112 
113  // Verify expectations are met
114  ::testing::Mock::VerifyAndClearExpectations(view());
115 }
116 
117 TEST_F(AccessibilityPluginTest, AnnounceWithInt64ViewId) {
118  EXPECT_CALL(*view(), AnnounceAlert(::testing::Eq(L"Hello World"))).Times(1);
119 
120  SendAnnounceMessage("Hello World", EncodableValue{static_cast<int64_t>(0)});
121 
122  // Verify expectations are met
123  ::testing::Mock::VerifyAndClearExpectations(view());
124 }
125 
126 TEST_F(AccessibilityPluginTest, AnnounceWithInvalidViewIdType) {
127  // Should not be called with invalid viewId type
128  EXPECT_CALL(*view(), AnnounceAlert(_)).Times(0);
129 
130  SendAnnounceMessage("Hello", EncodableValue{"invalid"});
131 }
132 TEST_F(AccessibilityPluginTest, AnnounceWithMissingMessage) {
133  // Should not be called when message is missing
134  EXPECT_CALL(*view(), AnnounceAlert(_)).Times(0);
135 
136  EncodableMap data;
137  data[EncodableValue{"viewId"}] = EncodableValue{static_cast<int32_t>(0)};
138 
139  EncodableMap msg;
140  msg[EncodableValue{"type"}] = EncodableValue{"announce"};
141  msg[EncodableValue{"data"}] = EncodableValue{data};
142 
143  auto encoded =
145 
146  messenger()->SimulateEngineMessage(
147  kAccessibilityChannelName, encoded->data(), encoded->size(),
148  [](const uint8_t* reply, size_t reply_size) {});
149 }
150 
151 } // namespace testing
152 } // namespace flutter
static void SetUp(BinaryMessenger *binary_messenger, AccessibilityPlugin *plugin)
virtual void Announce(const FlutterViewId view_id, const std::string_view message)
FlutterWindowsView(FlutterViewId view_id, FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > window_binding, std::shared_ptr< WindowsProcTable > windows_proc_table=nullptr)
std::unique_ptr< std::vector< uint8_t > > EncodeMessage(const T &message) const
Definition: message_codec.h:45
static const StandardMessageCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
void SendAnnounceMessage(const std::string &message, EncodableValue view_id)
MOCK_METHOD(void, NotifyWinEventWrapper,(ui::AXPlatformNodeWin *, ax::mojom::Event),(override))
MockFlutterWindowsView(FlutterWindowsEngine *engine, std::unique_ptr< WindowBindingHandler > wbh)
static constexpr char kAccessibilityChannelName[]
std::u16string text
Win32Message message
TEST_F(AccessibilityPluginTest, DirectAnnounceCall)
std::map< EncodableValue, EncodableValue > EncodableMap
constexpr FlutterViewId kImplicitViewId