9 #include "flutter/fml/macros.h"
12 #include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
13 #include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
14 #include "flutter/shell/platform/windows/testing/test_binary_messenger.h"
15 #include "flutter/shell/platform/windows/testing/windows_test.h"
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18 #include "rapidjson/document.h"
25 using ::testing::NiceMock;
26 using ::testing::Return;
28 static constexpr
char kChannelName[] =
"flutter/platform";
30 static constexpr
char kClipboardGetDataMessage[] =
31 "{\"method\":\"Clipboard.getData\",\"args\":\"text/plain\"}";
32 static constexpr
char kClipboardGetDataFakeContentTypeMessage[] =
33 "{\"method\":\"Clipboard.getData\",\"args\":\"text/madeupcontenttype\"}";
34 static constexpr
char kClipboardHasStringsMessage[] =
35 "{\"method\":\"Clipboard.hasStrings\",\"args\":\"text/plain\"}";
36 static constexpr
char kClipboardHasStringsFakeContentTypeMessage[] =
37 "{\"method\":\"Clipboard.hasStrings\",\"args\":\"text/madeupcontenttype\"}";
38 static constexpr
char kClipboardSetDataMessage[] =
39 "{\"method\":\"Clipboard.setData\",\"args\":{\"text\":\"hello\"}}";
40 static constexpr
char kClipboardSetDataNullTextMessage[] =
41 "{\"method\":\"Clipboard.setData\",\"args\":{\"text\":null}}";
42 static constexpr
char kClipboardSetDataUnknownTypeMessage[] =
43 "{\"method\":\"Clipboard.setData\",\"args\":{\"madeuptype\":\"hello\"}}";
44 static constexpr
char kSystemSoundTypeAlertMessage[] =
45 "{\"method\":\"SystemSound.play\",\"args\":\"SystemSoundType.alert\"}";
46 static constexpr
char kSystemExitApplicationRequiredMessage[] =
47 "{\"method\":\"System.exitApplication\",\"args\":{\"type\":\"required\","
49 static constexpr
char kSystemExitApplicationCancelableMessage[] =
50 "{\"method\":\"System.exitApplication\",\"args\":{\"type\":\"cancelable\","
52 static constexpr
char kExitResponseCancelMessage[] =
53 "[{\"response\":\"cancel\"}]";
54 static constexpr
char kExitResponseExitMessage[] =
"[{\"response\":\"exit\"}]";
58 static constexpr
int kArbitraryErrorCode = 1;
62 class MockPlatformHandler :
public PlatformHandler {
64 explicit MockPlatformHandler(
65 BinaryMessenger* messenger,
66 FlutterWindowsEngine* engine,
67 std::optional<std::function<std::unique_ptr<ScopedClipboardInterface>()>>
68 scoped_clipboard_provider = std::nullopt)
69 : PlatformHandler(messenger, engine, scoped_clipboard_provider) {}
71 virtual ~MockPlatformHandler() =
default;
75 (std::unique_ptr<MethodResult<rapidjson::Document>>,
76 std::string_view
key),
80 (std::unique_ptr<MethodResult<rapidjson::Document>>),
85 std::unique_ptr<MethodResult<rapidjson::Document>>),
90 std::unique_ptr<MethodResult<rapidjson::Document>>),
95 (std::optional<HWND> hwnd,
96 std::optional<WPARAM> wparam,
97 std::optional<LPARAM> lparam,
102 FML_DISALLOW_COPY_AND_ASSIGN(MockPlatformHandler);
106 class MockScopedClipboard :
public ScopedClipboardInterface {
108 MockScopedClipboard() =
default;
109 virtual ~MockScopedClipboard() =
default;
111 MOCK_METHOD(
int, Open, (HWND window), (
override));
112 MOCK_METHOD(
bool, HasString, (), (
override));
113 MOCK_METHOD((std::variant<std::wstring, int>), GetString, (), (
override));
114 MOCK_METHOD(
int, SetString, (
const std::wstring
string), (
override));
117 FML_DISALLOW_COPY_AND_ASSIGN(MockScopedClipboard);
120 std::string SimulatePlatformMessage(TestBinaryMessenger* messenger,
123 EXPECT_TRUE(messenger->SimulateEngineMessage(
126 [result = &result](
const uint8_t* reply,
size_t reply_size) {
127 std::string response(reinterpret_cast<const char*>(reply), reply_size);
146 FlutterWindowsEngineBuilder builder{GetContext()};
148 engine_ = builder.Build();
152 FlutterWindowsEngineBuilder builder{GetContext()};
154 auto window = std::make_unique<NiceMock<MockWindowBindingHandler>>();
155 view_ = std::make_unique<FlutterWindowsView>(std::move(window));
156 engine_ = builder.Build();
158 engine_->SetView(view_.get());
162 std::unique_ptr<FlutterWindowsEngine> engine_;
163 std::unique_ptr<FlutterWindowsView> view_;
171 TestBinaryMessenger messenger;
173 auto clipboard = std::make_unique<MockScopedClipboard>();
175 EXPECT_CALL(*clipboard.get(), Open)
178 EXPECT_CALL(*clipboard.get(), HasString).Times(1).WillOnce(Return(
true));
179 EXPECT_CALL(*clipboard.get(), GetString)
181 .WillOnce(Return(std::wstring(L
"Hello world")));
187 SimulatePlatformMessage(&messenger, kClipboardGetDataMessage);
189 EXPECT_EQ(result,
"[{\"text\":\"Hello world\"}]");
195 TestBinaryMessenger messenger;
199 std::string result = SimulatePlatformMessage(
200 &messenger, kClipboardGetDataFakeContentTypeMessage);
202 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unknown clipboard format\",null]");
208 TestBinaryMessenger messenger;
212 SimulatePlatformMessage(&messenger, kClipboardGetDataMessage);
215 "[\"Clipboard error\",\"Clipboard is not available in "
216 "Windows headless mode\",null]");
222 TestBinaryMessenger messenger;
224 auto clipboard = std::make_unique<MockScopedClipboard>();
226 EXPECT_CALL(*clipboard.get(), Open)
228 .WillOnce(Return(kArbitraryErrorCode));
234 SimulatePlatformMessage(&messenger, kClipboardGetDataMessage);
236 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unable to open clipboard\",1]");
242 TestBinaryMessenger messenger;
244 auto clipboard = std::make_unique<MockScopedClipboard>();
246 EXPECT_CALL(*clipboard.get(), Open)
249 EXPECT_CALL(*clipboard.get(), HasString).Times(1).WillOnce(Return(
true));
250 EXPECT_CALL(*clipboard.get(), GetString)
252 .WillOnce(Return(kArbitraryErrorCode));
258 SimulatePlatformMessage(&messenger, kClipboardGetDataMessage);
260 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unable to get clipboard data\",1]");
266 TestBinaryMessenger messenger;
268 auto clipboard = std::make_unique<MockScopedClipboard>();
270 EXPECT_CALL(*clipboard.get(), Open)
273 EXPECT_CALL(*clipboard.get(), HasString).Times(1).WillOnce(Return(
true));
279 SimulatePlatformMessage(&messenger, kClipboardHasStringsMessage);
281 EXPECT_EQ(result,
"[{\"value\":true}]");
287 TestBinaryMessenger messenger;
289 auto clipboard = std::make_unique<MockScopedClipboard>();
291 EXPECT_CALL(*clipboard.get(), Open)
294 EXPECT_CALL(*clipboard.get(), HasString).Times(1).WillOnce(Return(
false));
300 SimulatePlatformMessage(&messenger, kClipboardHasStringsMessage);
302 EXPECT_EQ(result,
"[{\"value\":false}]");
308 TestBinaryMessenger messenger;
311 std::string result = SimulatePlatformMessage(
312 &messenger, kClipboardHasStringsFakeContentTypeMessage);
314 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unknown clipboard format\",null]");
320 TestBinaryMessenger messenger;
324 SimulatePlatformMessage(&messenger, kClipboardHasStringsMessage);
327 "[\"Clipboard error\",\"Clipboard is not available in Windows "
328 "headless mode\",null]");
335 TestBinaryMessenger messenger;
337 auto clipboard = std::make_unique<MockScopedClipboard>();
339 EXPECT_CALL(*clipboard.get(), Open)
347 SimulatePlatformMessage(&messenger, kClipboardHasStringsMessage);
349 EXPECT_EQ(result,
"[{\"value\":false}]");
355 TestBinaryMessenger messenger;
357 auto clipboard = std::make_unique<MockScopedClipboard>();
359 EXPECT_CALL(*clipboard.get(), Open)
361 .WillOnce(Return(kArbitraryErrorCode));
367 SimulatePlatformMessage(&messenger, kClipboardHasStringsMessage);
369 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unable to open clipboard\",1]");
375 TestBinaryMessenger messenger;
377 auto clipboard = std::make_unique<MockScopedClipboard>();
379 EXPECT_CALL(*clipboard.get(), Open)
382 EXPECT_CALL(*clipboard.get(), SetString)
384 .WillOnce([](std::wstring
string) {
385 EXPECT_EQ(
string, L
"hello");
393 SimulatePlatformMessage(&messenger, kClipboardSetDataMessage);
395 EXPECT_EQ(result,
"[null]");
402 TestBinaryMessenger messenger;
406 SimulatePlatformMessage(&messenger, kClipboardSetDataNullTextMessage);
408 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unknown clipboard format\",null]");
414 TestBinaryMessenger messenger;
418 SimulatePlatformMessage(&messenger, kClipboardSetDataUnknownTypeMessage);
420 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unknown clipboard format\",null]");
426 TestBinaryMessenger messenger;
430 SimulatePlatformMessage(&messenger, kClipboardSetDataMessage);
433 "[\"Clipboard error\",\"Clipboard is not available in Windows "
434 "headless mode\",null]");
440 TestBinaryMessenger messenger;
442 auto clipboard = std::make_unique<MockScopedClipboard>();
444 EXPECT_CALL(*clipboard.get(), Open)
446 .WillOnce(Return(kArbitraryErrorCode));
452 SimulatePlatformMessage(&messenger, kClipboardSetDataMessage);
454 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unable to open clipboard\",1]");
460 TestBinaryMessenger messenger;
462 auto clipboard = std::make_unique<MockScopedClipboard>();
464 EXPECT_CALL(*clipboard.get(), Open)
467 EXPECT_CALL(*clipboard.get(), SetString)
469 .WillOnce(Return(kArbitraryErrorCode));
475 SimulatePlatformMessage(&messenger, kClipboardSetDataMessage);
477 EXPECT_EQ(result,
"[\"Clipboard error\",\"Unable to set clipboard data\",1]");
483 TestBinaryMessenger messenger;
484 MockPlatformHandler platform_handler(&messenger, engine());
486 EXPECT_CALL(platform_handler, SystemSoundPlay(
"SystemSoundType.alert", _))
487 .WillOnce([](
const std::string& sound,
493 SimulatePlatformMessage(&messenger, kSystemSoundTypeAlertMessage);
495 EXPECT_EQ(result,
"[null]");
502 TestBinaryMessenger messenger([](
const std::string& channel,
503 const uint8_t*
message,
size_t size,
505 MockPlatformHandler platform_handler(&messenger, engine());
507 ON_CALL(platform_handler, QuitApplication)
508 .WillByDefault([&exit_code](std::optional<HWND> hwnd,
509 std::optional<WPARAM> wparam,
510 std::optional<LPARAM> lparam,
511 UINT ec) { exit_code = ec; });
512 EXPECT_CALL(platform_handler, QuitApplication).Times(1);
514 std::string result = SimulatePlatformMessage(
515 &messenger, kSystemExitApplicationRequiredMessage);
516 EXPECT_EQ(result,
"[{\"response\":\"exit\"}]");
517 EXPECT_EQ(exit_code, 1);
522 bool called_cancel =
false;
524 TestBinaryMessenger messenger(
525 [&called_cancel](
const std::string& channel,
const uint8_t*
message,
527 reply(
reinterpret_cast<const uint8_t*
>(kExitResponseCancelMessage),
528 sizeof(kExitResponseCancelMessage));
529 called_cancel =
true;
531 MockPlatformHandler platform_handler(&messenger, engine());
533 EXPECT_CALL(platform_handler, QuitApplication).Times(0);
535 std::string result = SimulatePlatformMessage(
536 &messenger, kSystemExitApplicationCancelableMessage);
537 EXPECT_EQ(result,
"[{\"response\":\"cancel\"}]");
538 EXPECT_TRUE(called_cancel);
543 bool called_cancel =
false;
546 TestBinaryMessenger messenger(
547 [&called_cancel](
const std::string& channel,
const uint8_t*
message,
549 reply(
reinterpret_cast<const uint8_t*
>(kExitResponseExitMessage),
550 sizeof(kExitResponseExitMessage));
551 called_cancel =
true;
553 MockPlatformHandler platform_handler(&messenger, engine());
555 ON_CALL(platform_handler, QuitApplication)
556 .WillByDefault([&exit_code](std::optional<HWND> hwnd,
557 std::optional<WPARAM> wparam,
558 std::optional<LPARAM> lparam,
559 UINT ec) { exit_code = ec; });
560 EXPECT_CALL(platform_handler, QuitApplication).Times(1);
562 std::string result = SimulatePlatformMessage(
563 &messenger, kSystemExitApplicationCancelableMessage);
564 EXPECT_EQ(result,
"[{\"response\":\"cancel\"}]");
565 EXPECT_TRUE(called_cancel);
566 EXPECT_EQ(exit_code, 2);