Sends NetworkChangeNotifier connection type changes to Blink, to support NetInfo v3.
[chromium-blink-merge.git] / remoting / ios / bridge / client_proxy_unittest.mm
blob16242983f1f76bc470b83d25e1eddf3a6ff75dff
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.
5 #if !defined(__has_feature) || !__has_feature(objc_arc)
6 #error "This file requires ARC support."
7 #endif
9 #import "remoting/ios/bridge/client_proxy.h"
11 #import "base/compiler_specific.h"
12 #import "testing/gtest_mac.h"
14 #import "remoting/ios/data_store.h"
15 #import "remoting/ios/bridge/client_proxy_delegate_wrapper.h"
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
29 @implementation ClientProxyDelegateTester
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;
41 - (void)connected {
42   _isConnected = true;
45 - (void)connectionStatus:(NSString*)statusMessage {
46   _statusMessage = statusMessage;
49 - (void)connectionFailed:(NSString*)errorMessage {
50   _errorMessage = errorMessage;
53 - (void)requestHostPin:(BOOL)pairingSupported {
54   _isPairingSupported = pairingSupported;
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());
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;
75 @end
77 namespace remoting {
79 namespace {
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";
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.";
101 const webrtc::DesktopSize kFrameSize(100, 100);
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);
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;
120 const std::string kHostName = "ClientProxyHostNameTest";
121 const std::string kPairingId = "ClientProxyPairingIdTest";
122 const std::string kPairingSecret = "ClientProxyPairingSecretTest";
124 }  // namespace
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   }
134   void ResetIsConnected() { delegateTester_.isConnected = false; }
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);
142     if (state == protocol::ConnectionToHost::State::CONNECTED) {
143       EXPECT_TRUE(delegateTester_.isConnected);
144     } else {
145       EXPECT_FALSE(delegateTester_.isConnected);
146     }
148     TestErrorMessages(state, expectedStatusMsg);
149   }
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   }
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   }
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     }
217     clientProxy_->CommitPairingCredentials(hostName, pairingId, pairingSecret);
219     host = [store getHostForId:hostNameAsNSString];
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   }
227   scoped_ptr<ClientProxy> clientProxy_;
228   ClientProxyDelegateTester* delegateTester_;
229   ClientProxyDelegateWrapper* delegateWrapper_;
232 TEST_F(ClientProxyTest, ReportConnectionStatusINITIALIZING) {
233   TestConnnectionStatus(protocol::ConnectionToHost::State::INITIALIZING,
234                         kStatusINITIALIZING);
237 TEST_F(ClientProxyTest, ReportConnectionStatusCONNECTING) {
238   TestConnnectionStatus(protocol::ConnectionToHost::State::CONNECTING,
239                         kStatusCONNECTING);
242 TEST_F(ClientProxyTest, ReportConnectionStatusAUTHENTICATED) {
243   TestConnnectionStatus(protocol::ConnectionToHost::State::AUTHENTICATED,
244                         kStatusAUTHENTICATED);
247 TEST_F(ClientProxyTest, ReportConnectionStatusCONNECTED) {
248   TestConnnectionStatus(protocol::ConnectionToHost::State::CONNECTED,
249                         kStatusCONNECTED);
252 TEST_F(ClientProxyTest, ReportConnectionStatusFAILED) {
253   TestConnnectionStatus(protocol::ConnectionToHost::State::FAILED,
254                         kStatusFAILED);
257 TEST_F(ClientProxyTest, ReportConnectionStatusCLOSED) {
258   TestConnnectionStatus(protocol::ConnectionToHost::State::CLOSED,
259                         kStatusCLOSED);
262 TEST_F(ClientProxyTest, ReportConnectionStatusDEFAULT) {
263   TestConnnectionStatus(static_cast<protocol::ConnectionToHost::State>(999),
264                         kStatusDEFAULT);
267 TEST_F(ClientProxyTest, DisplayAuthenticationPrompt) {
268   clientProxy_->DisplayAuthenticationPrompt(true);
269   ASSERT_TRUE(delegateTester_.isPairingSupported);
270   clientProxy_->DisplayAuthenticationPrompt(false);
271   ASSERT_FALSE(delegateTester_.isPairingSupported);
274 TEST_F(ClientProxyTest, CommitPairingCredentialsBasic) {
275   ValidateHost("", "", "");
278 TEST_F(ClientProxyTest, CommitPairingCredentialsExtended) {
279   ValidateHost(kHostName, kPairingId, kPairingSecret);
282 TEST_F(ClientProxyTest, RedrawCanvasBasic) {
284   webrtc::BasicDesktopFrame frame(webrtc::DesktopSize(1, 1));
285   webrtc::DesktopRegion regions;
286   regions.AddRect(webrtc::DesktopRect::MakeLTRB(0, 0, 1, 1));
288   clientProxy_->RedrawCanvas(webrtc::DesktopSize(1, 1), &frame, regions);
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)));
297 TEST_F(ClientProxyTest, RedrawCanvasExtended) {
299   webrtc::BasicDesktopFrame frame(kFrameSize);
300   webrtc::DesktopRegion regions;
301   regions.AddRect(kFrameSubRect1);
302   regions.AddRect(kFrameSubRect2);
303   regions.AddRect(kFrameSubRect3);
305   clientProxy_->RedrawCanvas(kFrameSize, &frame, regions);
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));
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);
324   char data[4];
325   memset(data, 0xFF, 4);
327   cursor_proto.set_data(data);
329   clientProxy_->UpdateCursorShape(cursor_proto);
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   }
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);
348   char data[kCursorDataLength];
349   memset_pattern4(data, &kCursorDataPattern, kCursorDataLength);
351   cursor_proto.set_data(data);
353   clientProxy_->UpdateCursorShape(cursor_proto);
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   }
366 }  // namespace remoting