OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include <algorithm> |
| 6 #include <string> |
| 7 #include <vector> |
| 8 |
5 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/strings/string_util.h" |
6 #include "base/test/test_simple_task_runner.h" | 11 #include "base/test/test_simple_task_runner.h" |
7 #include "remoting/base/auto_thread_task_runner.h" | 12 #include "remoting/base/auto_thread_task_runner.h" |
8 #include "remoting/base/constants.h" | 13 #include "remoting/base/constants.h" |
9 #include "remoting/host/audio_capturer.h" | 14 #include "remoting/host/audio_capturer.h" |
10 #include "remoting/host/client_session.h" | 15 #include "remoting/host/client_session.h" |
11 #include "remoting/host/desktop_environment.h" | 16 #include "remoting/host/desktop_environment.h" |
| 17 #include "remoting/host/host_extension.h" |
12 #include "remoting/host/host_mock_objects.h" | 18 #include "remoting/host/host_mock_objects.h" |
13 #include "remoting/host/screen_capturer_fake.h" | 19 #include "remoting/host/screen_capturer_fake.h" |
14 #include "remoting/protocol/protocol_mock_objects.h" | 20 #include "remoting/protocol/protocol_mock_objects.h" |
15 #include "testing/gmock/include/gmock/gmock-matchers.h" | 21 #include "testing/gmock/include/gmock/gmock-matchers.h" |
| 22 #include "testing/gmock_mutant.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
17 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" | 24 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" |
18 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" | 25 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" |
19 #include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_object
s.h" | 26 #include "third_party/webrtc/modules/desktop_capture/screen_capturer_mock_object
s.h" |
20 | 27 |
21 namespace remoting { | 28 namespace remoting { |
22 | 29 |
23 using protocol::MockConnectionToClient; | 30 using protocol::MockConnectionToClient; |
24 using protocol::MockClientStub; | 31 using protocol::MockClientStub; |
25 using protocol::MockHostStub; | 32 using protocol::MockHostStub; |
26 using protocol::MockInputStub; | 33 using protocol::MockInputStub; |
27 using protocol::MockSession; | 34 using protocol::MockSession; |
28 using protocol::MockVideoStub; | 35 using protocol::MockVideoStub; |
29 using protocol::SessionConfig; | 36 using protocol::SessionConfig; |
30 | 37 |
31 using testing::_; | 38 using testing::_; |
32 using testing::AnyNumber; | 39 using testing::AnyNumber; |
33 using testing::AtMost; | 40 using testing::AtMost; |
| 41 using testing::CreateFunctor; |
34 using testing::DeleteArg; | 42 using testing::DeleteArg; |
35 using testing::DoAll; | 43 using testing::DoAll; |
36 using testing::Expectation; | 44 using testing::Expectation; |
| 45 using testing::Invoke; |
37 using testing::Return; | 46 using testing::Return; |
38 using testing::ReturnRef; | 47 using testing::ReturnRef; |
39 using testing::Sequence; | 48 using testing::Sequence; |
40 using testing::StrEq; | 49 using testing::StrEq; |
41 using testing::StrictMock; | 50 using testing::StrictMock; |
42 | 51 |
43 namespace { | 52 namespace { |
44 | 53 |
| 54 const char kDefaultTestCapability[] = "default"; |
| 55 |
45 ACTION_P2(InjectClipboardEvent, connection, event) { | 56 ACTION_P2(InjectClipboardEvent, connection, event) { |
46 connection->clipboard_stub()->InjectClipboardEvent(event); | 57 connection->clipboard_stub()->InjectClipboardEvent(event); |
47 } | 58 } |
48 | 59 |
49 ACTION_P2(InjectKeyEvent, connection, event) { | 60 ACTION_P2(InjectKeyEvent, connection, event) { |
50 connection->input_stub()->InjectKeyEvent(event); | 61 connection->input_stub()->InjectKeyEvent(event); |
51 } | 62 } |
52 | 63 |
53 ACTION_P2(InjectMouseEvent, connection, event) { | 64 ACTION_P2(InjectMouseEvent, connection, event) { |
54 connection->input_stub()->InjectMouseEvent(event); | 65 connection->input_stub()->InjectMouseEvent(event); |
55 } | 66 } |
56 | 67 |
57 ACTION_P2(LocalMouseMoved, client_session, event) { | 68 ACTION_P2(LocalMouseMoved, client_session, event) { |
58 client_session->OnLocalMouseMoved( | 69 client_session->OnLocalMouseMoved( |
59 webrtc::DesktopVector(event.x(), event.y())); | 70 webrtc::DesktopVector(event.x(), event.y())); |
60 } | 71 } |
61 | 72 |
62 ACTION_P2(SetGnubbyAuthHandlerForTesting, client_session, gnubby_auth_handler) { | 73 ACTION_P2(SetGnubbyAuthHandlerForTesting, client_session, gnubby_auth_handler) { |
63 client_session->SetGnubbyAuthHandlerForTesting(gnubby_auth_handler); | 74 client_session->SetGnubbyAuthHandlerForTesting(gnubby_auth_handler); |
64 } | 75 } |
65 | 76 |
66 ACTION_P2(DeliverClientMessage, client_session, message) { | 77 ACTION_P2(DeliverClientMessage, client_session, message) { |
67 client_session->DeliverClientMessage(message); | 78 client_session->DeliverClientMessage(message); |
68 } | 79 } |
69 | 80 |
| 81 ACTION_P2(AddHostCapabilities, client_session, capability) { |
| 82 client_session->AddHostCapabilities(capability); |
70 } | 83 } |
71 | 84 |
| 85 // Matches a |protocol::Capabilities| argument against a list of capabilities |
| 86 // formatted as a space-separated string. |
| 87 MATCHER_P(EqCapabilities, expected_capabilities, "") { |
| 88 if (!arg.has_capabilities()) |
| 89 return false; |
| 90 |
| 91 std::vector<std::string> words_args; |
| 92 std::vector<std::string> words_expected; |
| 93 Tokenize(arg.capabilities(), " ", &words_args); |
| 94 Tokenize(expected_capabilities, " ", &words_expected); |
| 95 std::sort(words_args.begin(), words_args.end()); |
| 96 std::sort(words_expected.begin(), words_expected.end()); |
| 97 return words_args == words_expected; |
| 98 } |
| 99 |
| 100 // |HostExtension| implementation that can handle an extension message type and |
| 101 // provide capabilities. |
| 102 class FakeExtension : public HostExtension { |
| 103 public: |
| 104 FakeExtension(const std::string& message_type, |
| 105 const std::string& capabilities); |
| 106 virtual ~FakeExtension(); |
| 107 |
| 108 virtual std::string GetCapabilities() OVERRIDE; |
| 109 virtual scoped_ptr<HostExtensionSession> CreateExtensionSession( |
| 110 ClientSession* client_session) OVERRIDE; |
| 111 |
| 112 bool message_handled() { |
| 113 return message_handled_; |
| 114 } |
| 115 |
| 116 private: |
| 117 class FakeExtensionSession : public HostExtensionSession { |
| 118 public: |
| 119 FakeExtensionSession(FakeExtension* extension); |
| 120 virtual ~FakeExtensionSession(); |
| 121 |
| 122 virtual bool OnExtensionMessage( |
| 123 ClientSession* client_session, |
| 124 const protocol::ExtensionMessage& message) OVERRIDE; |
| 125 |
| 126 private: |
| 127 FakeExtension* extension_; |
| 128 }; |
| 129 |
| 130 std::string message_type_; |
| 131 std::string capabilities_; |
| 132 bool message_handled_; |
| 133 }; |
| 134 |
| 135 typedef std::vector<HostExtension*> HostExtensionList; |
| 136 |
| 137 void CreateExtensionSessions(const HostExtensionList& extensions, |
| 138 ClientSession* client_session) { |
| 139 for (HostExtensionList::const_iterator extension = extensions.begin(); |
| 140 extension != extensions.end(); ++extension) { |
| 141 scoped_ptr<HostExtensionSession> extension_session = |
| 142 (*extension)->CreateExtensionSession(client_session); |
| 143 if (extension_session) |
| 144 client_session->AddExtensionSession(extension_session.Pass()); |
| 145 } |
| 146 } |
| 147 |
| 148 } // namespace |
| 149 |
72 class ClientSessionTest : public testing::Test { | 150 class ClientSessionTest : public testing::Test { |
73 public: | 151 public: |
74 ClientSessionTest() : client_jid_("user@domain/rest-of-jid") {} | 152 ClientSessionTest() : client_jid_("user@domain/rest-of-jid") {} |
75 | 153 |
76 virtual void SetUp() OVERRIDE; | 154 virtual void SetUp() OVERRIDE; |
77 virtual void TearDown() OVERRIDE; | 155 virtual void TearDown() OVERRIDE; |
78 | 156 |
79 // Disconnects the client session. | 157 // Disconnects the client session. |
80 void DisconnectClientSession(); | 158 void DisconnectClientSession(); |
81 | 159 |
(...skipping 11 matching lines...) Expand all Loading... |
93 | 171 |
94 // Creates a fake webrtc::ScreenCapturer, to mock | 172 // Creates a fake webrtc::ScreenCapturer, to mock |
95 // DesktopEnvironment::CreateVideoCapturer(). | 173 // DesktopEnvironment::CreateVideoCapturer(). |
96 webrtc::ScreenCapturer* CreateVideoCapturer(); | 174 webrtc::ScreenCapturer* CreateVideoCapturer(); |
97 | 175 |
98 // Notifies the client session that the client connection has been | 176 // Notifies the client session that the client connection has been |
99 // authenticated and channels have been connected. This effectively enables | 177 // authenticated and channels have been connected. This effectively enables |
100 // the input pipe line and starts video capturing. | 178 // the input pipe line and starts video capturing. |
101 void ConnectClientSession(); | 179 void ConnectClientSession(); |
102 | 180 |
| 181 // Creates expectations to send an extension message and to disconnect |
| 182 // afterwards. |
| 183 void SetSendMessageAndDisconnectExpectation(const std::string& message_type); |
| 184 |
103 // Invoked when the last reference to the AutoThreadTaskRunner has been | 185 // Invoked when the last reference to the AutoThreadTaskRunner has been |
104 // released and quits the message loop to finish the test. | 186 // released and quits the message loop to finish the test. |
105 void QuitMainMessageLoop(); | 187 void QuitMainMessageLoop(); |
106 | 188 |
107 // Message loop passed to |client_session_| to perform all functions on. | 189 // Message loop passed to |client_session_| to perform all functions on. |
108 base::MessageLoop message_loop_; | 190 base::MessageLoop message_loop_; |
109 | 191 |
110 // ClientSession instance under test. | 192 // ClientSession instance under test. |
111 scoped_ptr<ClientSession> client_session_; | 193 scoped_ptr<ClientSession> client_session_; |
112 | 194 |
(...skipping 11 matching lines...) Expand all Loading... |
124 // DesktopEnvironment owns |input_injector_|, but input injection tests need | 206 // DesktopEnvironment owns |input_injector_|, but input injection tests need |
125 // to express expectations on it. | 207 // to express expectations on it. |
126 scoped_ptr<MockInputInjector> input_injector_; | 208 scoped_ptr<MockInputInjector> input_injector_; |
127 | 209 |
128 // ClientSession owns |connection_| but tests need it to inject fake events. | 210 // ClientSession owns |connection_| but tests need it to inject fake events. |
129 MockConnectionToClient* connection_; | 211 MockConnectionToClient* connection_; |
130 | 212 |
131 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory_; | 213 scoped_ptr<MockDesktopEnvironmentFactory> desktop_environment_factory_; |
132 }; | 214 }; |
133 | 215 |
| 216 FakeExtension::FakeExtension(const std::string& message_type, |
| 217 const std::string& capabilities) |
| 218 : message_type_(message_type), |
| 219 capabilities_(capabilities), |
| 220 message_handled_(false) { |
| 221 } |
| 222 |
| 223 FakeExtension::~FakeExtension() {} |
| 224 |
| 225 std::string FakeExtension::GetCapabilities() { |
| 226 return capabilities_; |
| 227 } |
| 228 |
| 229 scoped_ptr<HostExtensionSession> FakeExtension::CreateExtensionSession( |
| 230 ClientSession* client_session) { |
| 231 return scoped_ptr<HostExtensionSession>(new FakeExtensionSession(this)); |
| 232 } |
| 233 |
| 234 FakeExtension::FakeExtensionSession::FakeExtensionSession( |
| 235 FakeExtension* extension) |
| 236 : extension_(extension) { |
| 237 } |
| 238 |
| 239 FakeExtension::FakeExtensionSession::~FakeExtensionSession() {} |
| 240 |
| 241 bool FakeExtension::FakeExtensionSession::OnExtensionMessage( |
| 242 ClientSession* client_session, |
| 243 const protocol::ExtensionMessage& message) { |
| 244 if (message.type() == extension_->message_type_) { |
| 245 extension_->message_handled_ = true; |
| 246 return true; |
| 247 } |
| 248 return false; |
| 249 } |
| 250 |
134 void ClientSessionTest::SetUp() { | 251 void ClientSessionTest::SetUp() { |
135 // Arrange to run |message_loop_| until no components depend on it. | 252 // Arrange to run |message_loop_| until no components depend on it. |
136 scoped_refptr<AutoThreadTaskRunner> ui_task_runner = new AutoThreadTaskRunner( | 253 scoped_refptr<AutoThreadTaskRunner> ui_task_runner = new AutoThreadTaskRunner( |
137 message_loop_.message_loop_proxy(), | 254 message_loop_.message_loop_proxy(), |
138 base::Bind(&ClientSessionTest::QuitMainMessageLoop, | 255 base::Bind(&ClientSessionTest::QuitMainMessageLoop, |
139 base::Unretained(this))); | 256 base::Unretained(this))); |
140 | 257 |
141 desktop_environment_factory_.reset(new MockDesktopEnvironmentFactory()); | 258 desktop_environment_factory_.reset(new MockDesktopEnvironmentFactory()); |
142 EXPECT_CALL(*desktop_environment_factory_, CreatePtr()) | 259 EXPECT_CALL(*desktop_environment_factory_, CreatePtr()) |
143 .Times(AnyNumber()) | 260 .Times(AnyNumber()) |
(...skipping 29 matching lines...) Expand all Loading... |
173 ui_task_runner, // Audio thread. | 290 ui_task_runner, // Audio thread. |
174 ui_task_runner, // Input thread. | 291 ui_task_runner, // Input thread. |
175 ui_task_runner, // Capture thread. | 292 ui_task_runner, // Capture thread. |
176 ui_task_runner, // Encode thread. | 293 ui_task_runner, // Encode thread. |
177 ui_task_runner, // Network thread. | 294 ui_task_runner, // Network thread. |
178 ui_task_runner, // UI thread. | 295 ui_task_runner, // UI thread. |
179 connection.PassAs<protocol::ConnectionToClient>(), | 296 connection.PassAs<protocol::ConnectionToClient>(), |
180 desktop_environment_factory_.get(), | 297 desktop_environment_factory_.get(), |
181 base::TimeDelta(), | 298 base::TimeDelta(), |
182 NULL)); | 299 NULL)); |
| 300 |
| 301 // By default, client will report the same capabilities as the host. |
| 302 EXPECT_CALL(client_stub_, SetCapabilities(_)) |
| 303 .Times(AtMost(1)) |
| 304 .WillOnce(Invoke(client_session_.get(), &ClientSession::SetCapabilities)); |
183 } | 305 } |
184 | 306 |
185 void ClientSessionTest::TearDown() { | 307 void ClientSessionTest::TearDown() { |
186 // Verify that the client session has been stopped. | 308 // Verify that the client session has been stopped. |
187 EXPECT_TRUE(!client_session_); | 309 EXPECT_TRUE(!client_session_); |
188 } | 310 } |
189 | 311 |
190 void ClientSessionTest::DisconnectClientSession() { | 312 void ClientSessionTest::DisconnectClientSession() { |
191 client_session_->DisconnectSession(); | 313 client_session_->DisconnectSession(); |
192 // MockSession won't trigger OnConnectionClosed, so fake it. | 314 // MockSession won't trigger OnConnectionClosed, so fake it. |
(...skipping 11 matching lines...) Expand all Loading... |
204 MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment(); | 326 MockDesktopEnvironment* desktop_environment = new MockDesktopEnvironment(); |
205 EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr()) | 327 EXPECT_CALL(*desktop_environment, CreateAudioCapturerPtr()) |
206 .Times(0); | 328 .Times(0); |
207 EXPECT_CALL(*desktop_environment, CreateInputInjectorPtr()) | 329 EXPECT_CALL(*desktop_environment, CreateInputInjectorPtr()) |
208 .WillOnce(Invoke(this, &ClientSessionTest::CreateInputInjector)); | 330 .WillOnce(Invoke(this, &ClientSessionTest::CreateInputInjector)); |
209 EXPECT_CALL(*desktop_environment, CreateScreenControlsPtr()) | 331 EXPECT_CALL(*desktop_environment, CreateScreenControlsPtr()) |
210 .Times(AtMost(1)); | 332 .Times(AtMost(1)); |
211 EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr()) | 333 EXPECT_CALL(*desktop_environment, CreateVideoCapturerPtr()) |
212 .WillOnce(Invoke(this, &ClientSessionTest::CreateVideoCapturer)); | 334 .WillOnce(Invoke(this, &ClientSessionTest::CreateVideoCapturer)); |
213 EXPECT_CALL(*desktop_environment, GetCapabilities()) | 335 EXPECT_CALL(*desktop_environment, GetCapabilities()) |
214 .Times(AtMost(1)); | 336 .Times(AtMost(1)) |
| 337 .WillOnce(Return(kDefaultTestCapability)); |
215 EXPECT_CALL(*desktop_environment, SetCapabilities(_)) | 338 EXPECT_CALL(*desktop_environment, SetCapabilities(_)) |
216 .Times(AtMost(1)); | 339 .Times(AtMost(1)); |
217 | 340 |
218 return desktop_environment; | 341 return desktop_environment; |
219 } | 342 } |
220 | 343 |
221 InputInjector* ClientSessionTest::CreateInputInjector() { | 344 InputInjector* ClientSessionTest::CreateInputInjector() { |
222 EXPECT_TRUE(input_injector_); | 345 EXPECT_TRUE(input_injector_); |
223 return input_injector_.release(); | 346 return input_injector_.release(); |
224 } | 347 } |
225 | 348 |
226 webrtc::ScreenCapturer* ClientSessionTest::CreateVideoCapturer() { | 349 webrtc::ScreenCapturer* ClientSessionTest::CreateVideoCapturer() { |
227 return new ScreenCapturerFake(); | 350 return new ScreenCapturerFake(); |
228 } | 351 } |
229 | 352 |
230 void ClientSessionTest::ConnectClientSession() { | 353 void ClientSessionTest::ConnectClientSession() { |
231 client_session_->OnConnectionAuthenticated(client_session_->connection()); | 354 client_session_->OnConnectionAuthenticated(client_session_->connection()); |
232 client_session_->OnConnectionChannelsConnected(client_session_->connection()); | 355 client_session_->OnConnectionChannelsConnected(client_session_->connection()); |
233 } | 356 } |
234 | 357 |
| 358 void ClientSessionTest::SetSendMessageAndDisconnectExpectation( |
| 359 const std::string& message_type) { |
| 360 protocol::ExtensionMessage message; |
| 361 message.set_type(message_type); |
| 362 message.set_data("data"); |
| 363 |
| 364 Expectation authenticated = |
| 365 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)) |
| 366 .WillOnce(Return(true)); |
| 367 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)) |
| 368 .After(authenticated) |
| 369 .WillOnce(DoAll( |
| 370 DeliverClientMessage(client_session_.get(), message), |
| 371 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), |
| 372 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); |
| 373 } |
| 374 |
235 void ClientSessionTest::QuitMainMessageLoop() { | 375 void ClientSessionTest::QuitMainMessageLoop() { |
236 message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); | 376 message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); |
237 } | 377 } |
238 | 378 |
239 MATCHER_P2(EqualsClipboardEvent, m, d, "") { | 379 MATCHER_P2(EqualsClipboardEvent, m, d, "") { |
240 return (strcmp(arg.mime_type().c_str(), m) == 0 && | 380 return (strcmp(arg.mime_type().c_str(), m) == 0 && |
241 memcmp(arg.data().data(), d, arg.data().size()) == 0); | 381 memcmp(arg.data().data(), d, arg.data().size()) == 0); |
242 } | 382 } |
243 | 383 |
244 TEST_F(ClientSessionTest, ClipboardStubFilter) { | 384 TEST_F(ClientSessionTest, ClipboardStubFilter) { |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 DeliverClientMessage(client_session_.get(), message), | 732 DeliverClientMessage(client_session_.get(), message), |
593 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), | 733 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), |
594 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); | 734 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); |
595 EXPECT_CALL(*gnubby_auth_handler, DeliverClientMessage(_)); | 735 EXPECT_CALL(*gnubby_auth_handler, DeliverClientMessage(_)); |
596 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); | 736 EXPECT_CALL(session_event_handler_, OnSessionClosed(_)); |
597 | 737 |
598 ConnectClientSession(); | 738 ConnectClientSession(); |
599 message_loop_.Run(); | 739 message_loop_.Run(); |
600 } | 740 } |
601 | 741 |
| 742 // Verifies that messages can be handled by extensions. |
| 743 TEST_F(ClientSessionTest, ExtensionMessages_MessageHandled) { |
| 744 FakeExtension extension1("ext1", "cap1"); |
| 745 FakeExtension extension2("ext2", "cap2"); |
| 746 FakeExtension extension3("ext3", "cap3"); |
| 747 HostExtensionList extensions; |
| 748 extensions.push_back(&extension1); |
| 749 extensions.push_back(&extension2); |
| 750 extensions.push_back(&extension3); |
| 751 |
| 752 EXPECT_CALL(session_event_handler_, OnSessionClientCapabilities(_)) |
| 753 .WillOnce(Invoke(CreateFunctor(&CreateExtensionSessions, extensions))); |
| 754 |
| 755 SetSendMessageAndDisconnectExpectation("ext2"); |
| 756 ConnectClientSession(); |
| 757 message_loop_.Run(); |
| 758 |
| 759 EXPECT_FALSE(extension1.message_handled()); |
| 760 EXPECT_TRUE(extension2.message_handled()); |
| 761 EXPECT_FALSE(extension3.message_handled()); |
| 762 } |
| 763 |
| 764 // Verifies that extension messages not handled by extensions don't result in a |
| 765 // crash. |
| 766 TEST_F(ClientSessionTest, ExtensionMessages_MessageNotHandled) { |
| 767 FakeExtension extension1("ext1", "cap1"); |
| 768 HostExtensionList extensions; |
| 769 extensions.push_back(&extension1); |
| 770 |
| 771 EXPECT_CALL(session_event_handler_, OnSessionClientCapabilities(_)) |
| 772 .WillOnce(Invoke(CreateFunctor(&CreateExtensionSessions, extensions))); |
| 773 |
| 774 SetSendMessageAndDisconnectExpectation("extX"); |
| 775 ConnectClientSession(); |
| 776 message_loop_.Run(); |
| 777 |
| 778 EXPECT_FALSE(extension1.message_handled()); |
| 779 } |
| 780 |
| 781 TEST_F(ClientSessionTest, ReportCapabilities) { |
| 782 Expectation authenticated = |
| 783 EXPECT_CALL(session_event_handler_, OnSessionAuthenticated(_)) |
| 784 .WillOnce(DoAll( |
| 785 AddHostCapabilities(client_session_.get(), "capX capZ"), |
| 786 AddHostCapabilities(client_session_.get(), ""), |
| 787 AddHostCapabilities(client_session_.get(), "capY"), |
| 788 Return(true))); |
| 789 EXPECT_CALL(client_stub_, |
| 790 SetCapabilities(EqCapabilities("capX capY capZ default"))); |
| 791 EXPECT_CALL(session_event_handler_, OnSessionChannelsConnected(_)) |
| 792 .After(authenticated) |
| 793 .WillOnce(DoAll( |
| 794 InvokeWithoutArgs(this, &ClientSessionTest::DisconnectClientSession), |
| 795 InvokeWithoutArgs(this, &ClientSessionTest::StopClientSession))); |
| 796 |
| 797 ConnectClientSession(); |
| 798 message_loop_.Run(); |
| 799 } |
| 800 |
602 } // namespace remoting | 801 } // namespace remoting |
OLD | NEW |