OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium 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 | |
5 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
6 #error "This file requires ARC support." | |
7 #endif | |
8 | |
9 #import "remoting/ios/bridge/client_proxy.h" | |
10 | |
11 #import "base/compiler_specific.h" | |
12 #import "testing/gtest_mac.h" | |
13 | |
14 #import "remoting/ios/data_store.h" | |
15 #import "remoting/ios/bridge/client_proxy_delegate_wrapper.h" | |
16 | |
17 @interface ClientProxyDelegateTester : NSObject<ClientProxyDelegate> | |
18 @property(nonatomic, assign) BOOL isConnected; | |
19 @property(nonatomic, copy) NSString* statusMessage; | |
20 @property(nonatomic, copy) NSString* errorMessage; | |
21 @property(nonatomic, assign) BOOL isPairingSupported; | |
22 @property(nonatomic, assign) webrtc::DesktopSize size; | |
23 @property(nonatomic, assign) NSInteger stride; | |
24 @property(nonatomic, assign) uint8_t* data; | |
25 @property(nonatomic, assign) std::vector<webrtc::DesktopRect> regions; | |
26 @property(nonatomic, assign) webrtc::DesktopVector hotspot; | |
27 @end | |
28 | |
29 @implementation ClientProxyDelegateTester | |
30 | |
31 @synthesize isConnected = _isConnected; | |
32 @synthesize statusMessage = _statusMessage; | |
33 @synthesize errorMessage = _errorMessage; | |
34 @synthesize isPairingSupported = _isPairingSupported; | |
35 @synthesize size = _size; | |
36 @synthesize stride = _stride; | |
37 @synthesize data = _data; | |
38 @synthesize regions = _regions; | |
39 @synthesize hotspot = _hotspot; | |
40 | |
41 - (void)connected { | |
42 _isConnected = true; | |
43 } | |
44 | |
45 - (void)connectionStatus:(NSString*)statusMessage { | |
46 _statusMessage = statusMessage; | |
47 } | |
48 | |
49 - (void)connectionFailed:(NSString*)errorMessage { | |
50 _errorMessage = errorMessage; | |
51 } | |
52 | |
53 - (void)requestHostPin:(BOOL)pairingSupported { | |
54 _isPairingSupported = pairingSupported; | |
55 } | |
56 | |
57 - (void)applyFrame:(const webrtc::DesktopSize&)size | |
58 stride:(NSInteger)stride | |
59 data:(uint8_t*)data | |
60 regions:(const std::vector<webrtc::DesktopRect>&)regions { | |
61 _size = size; | |
62 _stride = stride; | |
63 _data = data; | |
64 _regions.assign(regions.begin(), regions.end()); | |
65 } | |
66 | |
67 - (void)applyCursor:(const webrtc::DesktopSize&)size | |
68 hotspot:(const webrtc::DesktopVector&)hotspot | |
69 cursorData:(uint8_t*)data { | |
70 _size = size; | |
71 _hotspot = hotspot; | |
72 _data = data; | |
73 } | |
74 | |
75 @end | |
76 | |
77 namespace remoting { | |
78 | |
79 namespace { | |
80 | |
81 NSString* kStatusINITIALIZING = @"Initializing connection"; | |
82 NSString* kStatusCONNECTING = @"Connecting"; | |
83 NSString* kStatusAUTHENTICATED = @"Authenticated"; | |
84 NSString* kStatusCONNECTED = @"Connected"; | |
85 NSString* kStatusFAILED = @"Connection Failed"; | |
86 NSString* kStatusCLOSED = @"Connection closed"; | |
87 NSString* kStatusDEFAULT = @"Unknown connection state"; | |
88 | |
89 NSString* kErrorPEER_IS_OFFLINE = @"Requested host is offline."; | |
90 NSString* kErrorSESSION_REJECTED = @"Session was rejected by the host."; | |
91 NSString* kErrorINCOMPATIBLE_PROTOCOL = @"Incompatible Protocol."; | |
92 NSString* kErrorAUTHENTICATION_FAILED = @"Authentication Failed."; | |
93 NSString* kErrorCHANNEL_CONNECTION_ERROR = @"Channel Connection Error"; | |
94 NSString* kErrorSIGNALING_ERROR = @"Signaling Error"; | |
95 NSString* kErrorSIGNALING_TIMEOUT = @"Signaling Timeout"; | |
96 NSString* kErrorHOST_OVERLOAD = @"Host Overload"; | |
97 NSString* kErrorUNKNOWN_ERROR = | |
98 @"An unknown error has occurred, preventing the session from opening."; | |
99 NSString* kErrorDEFAULT = @"An unknown error code has occurred."; | |
100 | |
101 const webrtc::DesktopSize kFrameSize(100, 100); | |
102 | |
103 // Note these are disjoint regions. Testing intersecting regions is beyond the | |
104 // scope of this test class. | |
105 const webrtc::DesktopRect kFrameSubRect1 = | |
106 webrtc::DesktopRect::MakeXYWH(0, 0, 10, 10); | |
107 const webrtc::DesktopRect kFrameSubRect2 = | |
108 webrtc::DesktopRect::MakeXYWH(11, 11, 10, 10); | |
109 const webrtc::DesktopRect kFrameSubRect3 = | |
110 webrtc::DesktopRect::MakeXYWH(22, 22, 10, 10); | |
111 | |
112 const int kCursorHeight = 10; | |
113 const int kCursorWidth = 20; | |
114 const int kCursorHotSpotX = 4; | |
115 const int kCursorHotSpotY = 8; | |
116 // |kCursorDataLength| is assumed to be evenly divisible by 4 | |
117 const int kCursorDataLength = kCursorHeight * kCursorWidth; | |
118 const uint32_t kCursorDataPattern = 0xF0E1D2C3; | |
119 | |
120 const std::string kHostName = "ClientProxyHostNameTest"; | |
121 const std::string kPairingId = "ClientProxyPairingIdTest"; | |
122 const std::string kPairingSecret = "ClientProxyPairingSecretTest"; | |
123 | |
124 } // namespace | |
125 | |
126 class ClientProxyTest : public ::testing::Test { | |
127 protected: | |
128 virtual void SetUp() OVERRIDE { | |
129 delegateTester_ = [[ClientProxyDelegateTester alloc] init]; | |
130 clientProxy_.reset(new ClientProxy( | |
131 [ClientProxyDelegateWrapper wrapDelegate:delegateTester_])); | |
132 } | |
133 | |
134 void ResetIsConnected() { delegateTester_.isConnected = false; } | |
135 | |
136 void TestConnnectionStatus(protocol::ConnectionToHost::State state, | |
137 NSString* expectedStatusMsg) { | |
138 ResetIsConnected(); | |
139 clientProxy_->ReportConnectionStatus(state, protocol::ErrorCode::OK); | |
140 EXPECT_NSEQ(expectedStatusMsg, delegateTester_.statusMessage); | |
141 | |
142 if (state == protocol::ConnectionToHost::State::CONNECTED) { | |
143 EXPECT_TRUE(delegateTester_.isConnected); | |
144 } else { | |
145 EXPECT_FALSE(delegateTester_.isConnected); | |
146 } | |
147 | |
148 TestErrorMessages(state, expectedStatusMsg); | |
149 } | |
150 | |
151 void TestForError(protocol::ConnectionToHost::State state, | |
152 protocol::ErrorCode errorCode, | |
153 NSString* expectedStatusMsg, | |
154 NSString* expectedErrorMsg) { | |
155 ResetIsConnected(); | |
156 clientProxy_->ReportConnectionStatus(state, errorCode); | |
157 EXPECT_FALSE(delegateTester_.isConnected); | |
158 EXPECT_NSEQ(expectedStatusMsg, delegateTester_.statusMessage); | |
159 EXPECT_NSEQ(expectedErrorMsg, delegateTester_.errorMessage); | |
160 } | |
161 | |
162 void TestErrorMessages(protocol::ConnectionToHost::State state, | |
163 NSString* expectedStatusMsg) { | |
164 TestForError(state, | |
165 protocol::ErrorCode::AUTHENTICATION_FAILED, | |
166 expectedStatusMsg, | |
167 kErrorAUTHENTICATION_FAILED); | |
168 TestForError(state, | |
169 protocol::ErrorCode::CHANNEL_CONNECTION_ERROR, | |
170 expectedStatusMsg, | |
171 kErrorCHANNEL_CONNECTION_ERROR); | |
172 TestForError(state, | |
173 protocol::ErrorCode::HOST_OVERLOAD, | |
174 expectedStatusMsg, | |
175 kErrorHOST_OVERLOAD); | |
176 TestForError(state, | |
177 protocol::ErrorCode::INCOMPATIBLE_PROTOCOL, | |
178 expectedStatusMsg, | |
179 kErrorINCOMPATIBLE_PROTOCOL); | |
180 TestForError(state, | |
181 protocol::ErrorCode::PEER_IS_OFFLINE, | |
182 expectedStatusMsg, | |
183 kErrorPEER_IS_OFFLINE); | |
184 TestForError(state, | |
185 protocol::ErrorCode::SESSION_REJECTED, | |
186 expectedStatusMsg, | |
187 kErrorSESSION_REJECTED); | |
188 TestForError(state, | |
189 protocol::ErrorCode::SIGNALING_ERROR, | |
190 expectedStatusMsg, | |
191 kErrorSIGNALING_ERROR); | |
192 TestForError(state, | |
193 protocol::ErrorCode::SIGNALING_TIMEOUT, | |
194 expectedStatusMsg, | |
195 kErrorSIGNALING_TIMEOUT); | |
196 TestForError(state, | |
197 protocol::ErrorCode::UNKNOWN_ERROR, | |
198 expectedStatusMsg, | |
199 kErrorUNKNOWN_ERROR); | |
200 TestForError(state, | |
201 static_cast<protocol::ErrorCode>(999), | |
202 expectedStatusMsg, | |
203 kErrorDEFAULT); | |
204 } | |
205 | |
206 void ValidateHost(const std::string& hostName, | |
207 const std::string& pairingId, | |
208 const std::string& pairingSecret) { | |
209 DataStore* store = [DataStore sharedStore]; | |
210 NSString* hostNameAsNSString = | |
211 [NSString stringWithUTF8String:hostName.c_str()]; | |
212 const HostPreferences* host = [store getHostForId:hostNameAsNSString]; | |
213 if (host != nil) { | |
214 [store removeHost:host]; | |
215 } | |
216 | |
217 clientProxy_->CommitPairingCredentials(hostName, pairingId, pairingSecret); | |
218 | |
219 host = [store getHostForId:hostNameAsNSString]; | |
220 | |
221 ASSERT_TRUE(host != nil); | |
222 ASSERT_STREQ(hostName.c_str(), [host.hostId UTF8String]); | |
223 ASSERT_STREQ(pairingId.c_str(), [host.pairId UTF8String]); | |
224 ASSERT_STREQ(pairingSecret.c_str(), [host.pairSecret UTF8String]); | |
225 } | |
226 | |
227 scoped_ptr<ClientProxy> clientProxy_; | |
228 ClientProxyDelegateTester* delegateTester_; | |
229 ClientProxyDelegateWrapper* delegateWrapper_; | |
230 }; | |
231 | |
232 TEST_F(ClientProxyTest, ReportConnectionStatusINITIALIZING) { | |
233 TestConnnectionStatus(protocol::ConnectionToHost::State::INITIALIZING, | |
234 kStatusINITIALIZING); | |
235 } | |
236 | |
237 TEST_F(ClientProxyTest, ReportConnectionStatusCONNECTING) { | |
238 TestConnnectionStatus(protocol::ConnectionToHost::State::CONNECTING, | |
239 kStatusCONNECTING); | |
240 } | |
241 | |
242 TEST_F(ClientProxyTest, ReportConnectionStatusAUTHENTICATED) { | |
243 TestConnnectionStatus(protocol::ConnectionToHost::State::AUTHENTICATED, | |
244 kStatusAUTHENTICATED); | |
245 } | |
246 | |
247 TEST_F(ClientProxyTest, ReportConnectionStatusCONNECTED) { | |
248 TestConnnectionStatus(protocol::ConnectionToHost::State::CONNECTED, | |
249 kStatusCONNECTED); | |
250 } | |
251 | |
252 TEST_F(ClientProxyTest, ReportConnectionStatusFAILED) { | |
253 TestConnnectionStatus(protocol::ConnectionToHost::State::FAILED, | |
254 kStatusFAILED); | |
255 } | |
256 | |
257 TEST_F(ClientProxyTest, ReportConnectionStatusCLOSED) { | |
258 TestConnnectionStatus(protocol::ConnectionToHost::State::CLOSED, | |
259 kStatusCLOSED); | |
260 } | |
261 | |
262 TEST_F(ClientProxyTest, ReportConnectionStatusDEFAULT) { | |
263 TestConnnectionStatus(static_cast<protocol::ConnectionToHost::State>(999), | |
264 kStatusDEFAULT); | |
265 } | |
266 | |
267 TEST_F(ClientProxyTest, DisplayAuthenticationPrompt) { | |
268 clientProxy_->DisplayAuthenticationPrompt(true); | |
269 ASSERT_TRUE(delegateTester_.isPairingSupported); | |
270 clientProxy_->DisplayAuthenticationPrompt(false); | |
271 ASSERT_FALSE(delegateTester_.isPairingSupported); | |
272 } | |
273 | |
274 TEST_F(ClientProxyTest, CommitPairingCredentialsBasic) { | |
275 ValidateHost("", "", ""); | |
276 } | |
277 | |
278 TEST_F(ClientProxyTest, CommitPairingCredentialsExtended) { | |
279 ValidateHost(kHostName, kPairingId, kPairingSecret); | |
280 } | |
281 | |
282 TEST_F(ClientProxyTest, RedrawCanvasBasic) { | |
283 | |
284 webrtc::BasicDesktopFrame frame(webrtc::DesktopSize(1, 1)); | |
285 webrtc::DesktopRegion regions; | |
286 regions.AddRect(webrtc::DesktopRect::MakeLTRB(0, 0, 1, 1)); | |
287 | |
288 clientProxy_->RedrawCanvas(webrtc::DesktopSize(1, 1), &frame, regions); | |
289 | |
290 ASSERT_TRUE(webrtc::DesktopSize(1, 1).equals(delegateTester_.size)); | |
291 ASSERT_EQ(4, delegateTester_.stride); | |
292 ASSERT_TRUE(delegateTester_.data != NULL); | |
293 ASSERT_EQ(1, delegateTester_.regions.size()); | |
294 ASSERT_TRUE(delegateTester_.regions[0].equals( | |
295 webrtc::DesktopRect::MakeLTRB(0, 0, 1, 1))); | |
296 } | |
297 TEST_F(ClientProxyTest, RedrawCanvasExtended) { | |
298 | |
299 webrtc::BasicDesktopFrame frame(kFrameSize); | |
300 webrtc::DesktopRegion regions; | |
301 regions.AddRect(kFrameSubRect1); | |
302 regions.AddRect(kFrameSubRect2); | |
303 regions.AddRect(kFrameSubRect3); | |
304 | |
305 clientProxy_->RedrawCanvas(kFrameSize, &frame, regions); | |
306 | |
307 ASSERT_TRUE(kFrameSize.equals(delegateTester_.size)); | |
308 ASSERT_EQ(kFrameSize.width() * webrtc::DesktopFrame::kBytesPerPixel, | |
309 delegateTester_.stride); | |
310 ASSERT_TRUE(delegateTester_.data != NULL); | |
311 ASSERT_EQ(3, delegateTester_.regions.size()); | |
312 ASSERT_TRUE(delegateTester_.regions[0].equals(kFrameSubRect1)); | |
313 ASSERT_TRUE(delegateTester_.regions[1].equals(kFrameSubRect2)); | |
314 ASSERT_TRUE(delegateTester_.regions[2].equals(kFrameSubRect3)); | |
315 } | |
316 | |
317 TEST_F(ClientProxyTest, UpdateCursorBasic) { | |
318 protocol::CursorShapeInfo cursor_proto; | |
319 cursor_proto.set_width(1); | |
320 cursor_proto.set_height(1); | |
321 cursor_proto.set_hotspot_x(0); | |
322 cursor_proto.set_hotspot_y(0); | |
323 | |
324 char data[4]; | |
325 memset(data, 0xFF, 4); | |
326 | |
327 cursor_proto.set_data(data); | |
328 | |
329 clientProxy_->UpdateCursorShape(cursor_proto); | |
330 | |
331 ASSERT_EQ(1, delegateTester_.size.width()); | |
332 ASSERT_EQ(1, delegateTester_.size.height()); | |
333 ASSERT_EQ(0, delegateTester_.hotspot.x()); | |
334 ASSERT_EQ(0, delegateTester_.hotspot.y()); | |
335 ASSERT_TRUE(delegateTester_.data != NULL); | |
336 for (int i = 0; i < 4; i++) { | |
337 ASSERT_EQ(0xFF, delegateTester_.data[i]); | |
338 } | |
339 } | |
340 | |
341 TEST_F(ClientProxyTest, UpdateCursorExtended) { | |
342 protocol::CursorShapeInfo cursor_proto; | |
343 cursor_proto.set_width(kCursorWidth); | |
344 cursor_proto.set_height(kCursorHeight); | |
345 cursor_proto.set_hotspot_x(kCursorHotSpotX); | |
346 cursor_proto.set_hotspot_y(kCursorHotSpotY); | |
347 | |
348 char data[kCursorDataLength]; | |
349 memset_pattern4(data, &kCursorDataPattern, kCursorDataLength); | |
350 | |
351 cursor_proto.set_data(data); | |
352 | |
353 clientProxy_->UpdateCursorShape(cursor_proto); | |
354 | |
355 ASSERT_EQ(kCursorWidth, delegateTester_.size.width()); | |
356 ASSERT_EQ(kCursorHeight, delegateTester_.size.height()); | |
357 ASSERT_EQ(kCursorHotSpotX, delegateTester_.hotspot.x()); | |
358 ASSERT_EQ(kCursorHotSpotY, delegateTester_.hotspot.y()); | |
359 ASSERT_TRUE(delegateTester_.data != NULL); | |
360 for (int i = 0; i < kCursorDataLength / 4; i++) { | |
361 ASSERT_TRUE(memcmp(&delegateTester_.data[i * 4], &kCursorDataPattern, 4) == | |
362 0); | |
363 } | |
364 } | |
365 | |
366 } // namespace remoting | |
OLD | NEW |