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 #include "components/proximity_auth/cryptauth/cryptauth_client.h" | |
6 | |
7 #include "base/command_line.h" | |
8 #include "base/test/null_task_runner.h" | |
9 #include "components/proximity_auth/cryptauth/cryptauth_access_token_fetcher.h" | |
10 #include "components/proximity_auth/cryptauth/cryptauth_api_call_flow.h" | |
11 #include "components/proximity_auth/cryptauth/cryptauth_client_factory.h" | |
12 #include "components/proximity_auth/cryptauth/proto/cryptauth_api.pb.h" | |
13 #include "components/proximity_auth/switches.h" | |
14 #include "google_apis/gaia/fake_oauth2_token_service.h" | |
15 #include "net/url_request/test_url_fetcher_factory.h" | |
16 #include "net/url_request/url_request_test_util.h" | |
17 #include "testing/gmock/include/gmock/gmock.h" | |
18 #include "testing/gtest/include/gtest/gtest.h" | |
19 | |
20 using testing::_; | |
21 using testing::DoAll; | |
22 using testing::Return; | |
23 using testing::SaveArg; | |
24 using testing::StrictMock; | |
25 | |
26 namespace proximity_auth { | |
27 | |
28 namespace { | |
29 | |
30 const char kTestGoogleApisUrl[] = "https://www.testgoogleapis.com"; | |
31 const char kAccessToken[] = "access_token"; | |
32 const char kPublicKey1[] = "public_key1"; | |
33 const char kPublicKey2[] = "public_key2"; | |
34 const char kBluetoothAddress1[] = "AA:AA:AA:AA:AA:AA"; | |
35 const char kBluetoothAddress2[] = "BB:BB:BB:BB:BB:BB"; | |
36 | |
37 // Values for the DeviceClassifier field. | |
38 const int kDeviceOsVersionCode = 100; | |
39 const int kDeviceSoftwareVersionCode = 200; | |
40 const char kDeviceSoftwarePackage[] = "cryptauth_client_unittest"; | |
41 const cryptauth::DeviceType kDeviceType = cryptauth::CHROME; | |
42 | |
43 // CryptAuthAccessTokenFetcher implementation simply returning a predetermined | |
44 // access token. | |
45 class FakeCryptAuthAccessTokenFetcher : public CryptAuthAccessTokenFetcher { | |
46 public: | |
47 FakeCryptAuthAccessTokenFetcher() : access_token_(kAccessToken) {} | |
48 | |
49 void FetchAccessToken(const AccessTokenCallback& callback) override { | |
50 callback.Run(access_token_); | |
51 } | |
52 | |
53 void set_access_token(const std::string& access_token) { | |
54 access_token_ = access_token; | |
55 }; | |
56 | |
57 private: | |
58 std::string access_token_; | |
59 }; | |
60 | |
61 // Mock CryptAuthApiCallFlow, which handles the HTTP requests to CryptAuth. | |
62 class MockCryptAuthApiCallFlow : public CryptAuthApiCallFlow { | |
63 public: | |
64 MockCryptAuthApiCallFlow() : CryptAuthApiCallFlow(GURL(std::string())) {} | |
65 virtual ~MockCryptAuthApiCallFlow() {} | |
66 | |
67 MOCK_METHOD5(Start, | |
68 void(net::URLRequestContextGetter* context, | |
69 const std::string& access_token, | |
70 const std::string& serialized_request, | |
71 const ResultCallback& result_callback, | |
72 const ErrorCallback& error_callback)); | |
73 | |
74 private: | |
75 DISALLOW_COPY_AND_ASSIGN(MockCryptAuthApiCallFlow); | |
76 }; | |
77 | |
78 // Subclass of CryptAuthClient to use as test harness. | |
79 class MockCryptAuthClient : public CryptAuthClient { | |
80 public: | |
81 // Ownership of |access_token_fetcher| is passed to the superclass. Due to the | |
82 // limitations of gmock, we need to use a raw pointer argument rather than a | |
83 // scoped_ptr. | |
84 MockCryptAuthClient( | |
85 CryptAuthAccessTokenFetcher* access_token_fetcher, | |
86 scoped_refptr<net::URLRequestContextGetter> url_request_context, | |
87 const cryptauth::DeviceClassifier& device_classifier) | |
88 : CryptAuthClient(make_scoped_ptr(access_token_fetcher), | |
89 url_request_context, | |
90 device_classifier) {} | |
91 virtual ~MockCryptAuthClient() {} | |
92 | |
93 MOCK_METHOD1(CreateFlowProxy, CryptAuthApiCallFlow*(const GURL& request_url)); | |
94 | |
95 scoped_ptr<CryptAuthApiCallFlow> CreateFlow( | |
96 const GURL& request_url) override { | |
97 return make_scoped_ptr(CreateFlowProxy(request_url)); | |
98 }; | |
99 | |
100 private: | |
101 DISALLOW_COPY_AND_ASSIGN(MockCryptAuthClient); | |
102 }; | |
103 | |
104 // Callback that should never be invoked. | |
105 template <class T> | |
106 void NotCalled(const T& type) { | |
107 EXPECT_TRUE(false); | |
108 } | |
109 | |
110 // Callback that saves the result returned by CryptAuthClient. | |
111 template <class T> | |
112 void SaveResult(T* out, const T& result) { | |
113 *out = result; | |
114 } | |
115 | |
116 } // namespace | |
117 | |
118 class ProximityAuthCryptAuthClientTest : public testing::Test { | |
119 protected: | |
120 ProximityAuthCryptAuthClientTest() | |
121 : access_token_fetcher_(new FakeCryptAuthAccessTokenFetcher()), | |
122 url_request_context_( | |
123 new net::TestURLRequestContextGetter(new base::NullTaskRunner())), | |
124 serialized_request_(std::string()) {} | |
125 | |
126 void SetUp() override { | |
127 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( | |
128 switches::kCryptAuthHTTPHost, kTestGoogleApisUrl); | |
129 | |
130 cryptauth::DeviceClassifier device_classifier; | |
131 device_classifier.set_device_os_version_code(kDeviceOsVersionCode); | |
132 device_classifier.set_device_software_version_code( | |
133 kDeviceSoftwareVersionCode); | |
134 device_classifier.set_device_software_package(kDeviceSoftwarePackage); | |
135 device_classifier.set_device_type(kDeviceType); | |
136 | |
137 client_.reset(new StrictMock<MockCryptAuthClient>( | |
138 access_token_fetcher_, url_request_context_, device_classifier)); | |
139 } | |
140 | |
141 // Sets up an expectation and captures a CryptAuth API request to | |
142 // |request_url|. | |
143 void ExpectRequest(const std::string& request_url) { | |
144 StrictMock<MockCryptAuthApiCallFlow>* api_call_flow = | |
145 new StrictMock<MockCryptAuthApiCallFlow>(); | |
146 | |
147 EXPECT_CALL(*client_, CreateFlowProxy(GURL(request_url))) | |
148 .WillOnce(Return(api_call_flow)); | |
149 | |
150 EXPECT_CALL(*api_call_flow, | |
151 Start(url_request_context_.get(), kAccessToken, _, _, _)) | |
152 .WillOnce(DoAll(SaveArg<2>(&serialized_request_), | |
153 SaveArg<3>(&flow_result_callback_), | |
154 SaveArg<4>(&flow_error_callback_))); | |
155 } | |
156 | |
157 // Returns |response_proto| as the result to the current API request. | |
158 // ExpectResult() must have been called first. | |
159 void FinishApiCallFlow(const google::protobuf::MessageLite* response_proto) { | |
160 flow_result_callback_.Run(response_proto->SerializeAsString()); | |
161 } | |
162 | |
163 // Ends the current API request with |error_message|. ExpectResult() must have | |
164 // been called first. | |
165 void FailApiCallFlow(const std::string& error_message) { | |
166 flow_error_callback_.Run(error_message); | |
167 } | |
168 | |
169 protected: | |
170 // Owned by |client_|. | |
171 FakeCryptAuthAccessTokenFetcher* access_token_fetcher_; | |
172 | |
173 scoped_refptr<net::URLRequestContextGetter> url_request_context_; | |
174 scoped_ptr<StrictMock<MockCryptAuthClient>> client_; | |
175 | |
176 std::string serialized_request_; | |
177 CryptAuthApiCallFlow::ResultCallback flow_result_callback_; | |
178 CryptAuthApiCallFlow::ErrorCallback flow_error_callback_; | |
179 }; | |
180 | |
181 TEST_F(ProximityAuthCryptAuthClientTest, GetMyDevicesSuccess) { | |
182 ExpectRequest( | |
183 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
184 "getmydevices?alt=proto"); | |
185 | |
186 cryptauth::GetMyDevicesResponse result_proto; | |
187 cryptauth::GetMyDevicesRequest request_proto; | |
188 request_proto.set_allow_stale_read(true); | |
189 client_->GetMyDevices( | |
190 request_proto, | |
191 base::Bind(&SaveResult<cryptauth::GetMyDevicesResponse>, &result_proto), | |
192 base::Bind(&NotCalled<std::string>)); | |
193 | |
194 cryptauth::GetMyDevicesRequest expected_request; | |
195 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_)); | |
196 EXPECT_TRUE(expected_request.allow_stale_read()); | |
197 | |
198 // Return two devices, one unlock key and one unlockable device. | |
199 { | |
200 cryptauth::GetMyDevicesResponse response_proto; | |
201 response_proto.add_devices(); | |
202 response_proto.mutable_devices(0)->set_public_key(kPublicKey1); | |
203 response_proto.mutable_devices(0)->set_unlock_key(true); | |
204 response_proto.mutable_devices(0) | |
205 ->set_bluetooth_address(kBluetoothAddress1); | |
206 response_proto.add_devices(); | |
207 response_proto.mutable_devices(1)->set_public_key(kPublicKey2); | |
208 response_proto.mutable_devices(1)->set_unlockable(true); | |
209 FinishApiCallFlow(&response_proto); | |
210 } | |
211 | |
212 // Check that the result received in callback is the same as the response. | |
213 ASSERT_EQ(2, result_proto.devices_size()); | |
214 EXPECT_EQ(kPublicKey1, result_proto.devices(0).public_key()); | |
215 EXPECT_TRUE(result_proto.devices(0).unlock_key()); | |
216 EXPECT_EQ(kBluetoothAddress1, result_proto.devices(0).bluetooth_address()); | |
217 EXPECT_EQ(kPublicKey2, result_proto.devices(1).public_key()); | |
218 EXPECT_TRUE(result_proto.devices(1).unlockable()); | |
219 } | |
220 | |
221 TEST_F(ProximityAuthCryptAuthClientTest, GetMyDevicesFailure) { | |
222 ExpectRequest( | |
223 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
224 "getmydevices?alt=proto"); | |
225 | |
226 std::string error_message; | |
227 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(), | |
228 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>), | |
229 base::Bind(&SaveResult<std::string>, &error_message)); | |
230 | |
231 std::string kStatus500Error("HTTP status: 500"); | |
232 FailApiCallFlow(kStatus500Error); | |
233 EXPECT_EQ(kStatus500Error, error_message); | |
234 } | |
235 | |
236 TEST_F(ProximityAuthCryptAuthClientTest, FindEligibleUnlockDevicesSuccess) { | |
237 ExpectRequest( | |
238 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
239 "findeligibleunlockdevices?alt=proto"); | |
240 | |
241 cryptauth::FindEligibleUnlockDevicesResponse result_proto; | |
242 cryptauth::FindEligibleUnlockDevicesRequest request_proto; | |
243 request_proto.set_callback_bluetooth_address(kBluetoothAddress2); | |
244 client_->FindEligibleUnlockDevices( | |
245 request_proto, | |
246 base::Bind(&SaveResult<cryptauth::FindEligibleUnlockDevicesResponse>, | |
247 &result_proto), | |
248 base::Bind(&NotCalled<std::string>)); | |
249 | |
250 cryptauth::FindEligibleUnlockDevicesRequest expected_request; | |
251 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_)); | |
252 EXPECT_EQ(kBluetoothAddress2, expected_request.callback_bluetooth_address()); | |
253 | |
254 // Return a response proto with one eligible and one ineligible device. | |
255 cryptauth::FindEligibleUnlockDevicesResponse response_proto; | |
256 response_proto.add_eligible_devices(); | |
257 response_proto.mutable_eligible_devices(0)->set_public_key(kPublicKey1); | |
258 | |
259 const std::string kIneligibilityReason = "You require more vespine gas."; | |
260 response_proto.add_ineligible_devices(); | |
261 response_proto.mutable_ineligible_devices(0) | |
262 ->mutable_device() | |
263 ->set_public_key(kPublicKey2); | |
264 response_proto.mutable_ineligible_devices(0) | |
265 ->add_reasons(kIneligibilityReason); | |
266 FinishApiCallFlow(&response_proto); | |
267 | |
268 // Check that the result received in callback is the same as the response. | |
269 ASSERT_EQ(1, result_proto.eligible_devices_size()); | |
270 EXPECT_EQ(kPublicKey1, result_proto.eligible_devices(0).public_key()); | |
271 ASSERT_EQ(1, result_proto.ineligible_devices_size()); | |
272 EXPECT_EQ(kPublicKey2, | |
273 result_proto.ineligible_devices(0).device().public_key()); | |
274 ASSERT_EQ(1, result_proto.ineligible_devices(0).reasons_size()); | |
275 EXPECT_EQ(kIneligibilityReason, | |
276 result_proto.ineligible_devices(0).reasons(0)); | |
277 } | |
278 | |
279 TEST_F(ProximityAuthCryptAuthClientTest, FindEligibleUnlockDevicesFailure) { | |
280 ExpectRequest( | |
281 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
282 "findeligibleunlockdevices?alt=proto"); | |
283 | |
284 std::string error_message; | |
285 cryptauth::FindEligibleUnlockDevicesRequest request_proto; | |
286 request_proto.set_callback_bluetooth_address(kBluetoothAddress1); | |
287 client_->FindEligibleUnlockDevices( | |
288 request_proto, | |
289 base::Bind(&NotCalled<cryptauth::FindEligibleUnlockDevicesResponse>), | |
290 base::Bind(&SaveResult<std::string>, &error_message)); | |
291 | |
292 std::string kStatus403Error("HTTP status: 403"); | |
293 FailApiCallFlow(kStatus403Error); | |
294 EXPECT_EQ(kStatus403Error, error_message); | |
295 } | |
296 | |
297 TEST_F(ProximityAuthCryptAuthClientTest, SendDeviceSyncTickleSuccess) { | |
298 ExpectRequest( | |
299 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
300 "senddevicesynctickle?alt=proto"); | |
301 | |
302 cryptauth::SendDeviceSyncTickleResponse result_proto; | |
303 client_->SendDeviceSyncTickle( | |
304 cryptauth::SendDeviceSyncTickleRequest(), | |
305 base::Bind(&SaveResult<cryptauth::SendDeviceSyncTickleResponse>, | |
306 &result_proto), | |
307 base::Bind(&NotCalled<std::string>)); | |
308 | |
309 cryptauth::SendDeviceSyncTickleRequest expected_request; | |
310 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_)); | |
311 | |
312 cryptauth::SendDeviceSyncTickleResponse response_proto; | |
313 FinishApiCallFlow(&response_proto); | |
314 } | |
315 | |
316 TEST_F(ProximityAuthCryptAuthClientTest, ToggleEasyUnlockSuccess) { | |
317 ExpectRequest( | |
318 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
319 "toggleeasyunlock?alt=proto"); | |
320 | |
321 cryptauth::ToggleEasyUnlockResponse result_proto; | |
322 cryptauth::ToggleEasyUnlockRequest request_proto; | |
323 request_proto.set_enable(true); | |
324 request_proto.set_apply_to_all(false); | |
325 request_proto.set_public_key(kPublicKey1); | |
326 client_->ToggleEasyUnlock( | |
327 request_proto, | |
328 base::Bind(&SaveResult<cryptauth::ToggleEasyUnlockResponse>, | |
329 &result_proto), | |
330 base::Bind(&NotCalled<std::string>)); | |
331 | |
332 cryptauth::ToggleEasyUnlockRequest expected_request; | |
333 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_)); | |
334 EXPECT_TRUE(expected_request.enable()); | |
335 EXPECT_EQ(kPublicKey1, expected_request.public_key()); | |
336 EXPECT_FALSE(expected_request.apply_to_all()); | |
337 | |
338 cryptauth::ToggleEasyUnlockResponse response_proto; | |
339 FinishApiCallFlow(&response_proto); | |
340 } | |
341 | |
342 TEST_F(ProximityAuthCryptAuthClientTest, SetupEnrollmentSuccess) { | |
343 ExpectRequest( | |
344 "https://www.testgoogleapis.com/cryptauth/v1/enrollment/" | |
345 "setupenrollment?alt=proto"); | |
346 | |
347 std::string kApplicationId = "mkaes"; | |
348 std::vector<std::string> supported_protocols; | |
349 supported_protocols.push_back("gcmV1"); | |
350 supported_protocols.push_back("testProtocol"); | |
351 | |
352 cryptauth::SetupEnrollmentResponse result_proto; | |
353 cryptauth::SetupEnrollmentRequest request_proto; | |
354 request_proto.set_application_id(kApplicationId); | |
355 request_proto.add_types("gcmV1"); | |
356 request_proto.add_types("testProtocol"); | |
357 client_->SetupEnrollment( | |
358 request_proto, base::Bind(&SaveResult<cryptauth::SetupEnrollmentResponse>, | |
359 &result_proto), | |
360 base::Bind(&NotCalled<std::string>)); | |
361 | |
362 cryptauth::SetupEnrollmentRequest expected_request; | |
363 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_)); | |
364 EXPECT_EQ(kApplicationId, expected_request.application_id()); | |
365 ASSERT_EQ(2, expected_request.types_size()); | |
366 EXPECT_EQ("gcmV1", expected_request.types(0)); | |
367 EXPECT_EQ("testProtocol", expected_request.types(1)); | |
368 | |
369 // Return a fake enrollment session. | |
370 { | |
371 cryptauth::SetupEnrollmentResponse response_proto; | |
372 response_proto.set_status("OK"); | |
373 response_proto.add_infos(); | |
374 response_proto.mutable_infos(0)->set_type("gcmV1"); | |
375 response_proto.mutable_infos(0)->set_enrollment_session_id("session_id"); | |
376 response_proto.mutable_infos(0)->set_server_ephemeral_key("ephemeral_key"); | |
377 FinishApiCallFlow(&response_proto); | |
378 } | |
379 | |
380 // Check that the returned proto is the same as the one just created. | |
381 EXPECT_EQ("OK", result_proto.status()); | |
382 ASSERT_EQ(1, result_proto.infos_size()); | |
383 EXPECT_EQ("gcmV1", result_proto.infos(0).type()); | |
384 EXPECT_EQ("session_id", result_proto.infos(0).enrollment_session_id()); | |
385 EXPECT_EQ("ephemeral_key", result_proto.infos(0).server_ephemeral_key()); | |
386 } | |
387 | |
388 TEST_F(ProximityAuthCryptAuthClientTest, FinishEnrollmentSuccess) { | |
389 ExpectRequest( | |
390 "https://www.testgoogleapis.com/cryptauth/v1/enrollment/" | |
391 "finishenrollment?alt=proto"); | |
392 | |
393 const char kEnrollmentSessionId[] = "enrollment_session_id"; | |
394 const char kEnrollmentMessage[] = "enrollment_message"; | |
395 const char kDeviceEphemeralKey[] = "device_ephermal_key"; | |
396 cryptauth::FinishEnrollmentResponse result_proto; | |
397 cryptauth::FinishEnrollmentRequest request_proto; | |
398 request_proto.set_enrollment_session_id(kEnrollmentSessionId); | |
399 request_proto.set_enrollment_message(kEnrollmentMessage); | |
400 request_proto.set_device_ephemeral_key(kDeviceEphemeralKey); | |
401 client_->FinishEnrollment( | |
402 request_proto, | |
403 base::Bind(&SaveResult<cryptauth::FinishEnrollmentResponse>, | |
404 &result_proto), | |
405 base::Bind(&NotCalled<const std::string&>)); | |
406 | |
407 cryptauth::FinishEnrollmentRequest expected_request; | |
408 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_)); | |
409 EXPECT_EQ(kEnrollmentSessionId, expected_request.enrollment_session_id()); | |
410 EXPECT_EQ(kEnrollmentMessage, expected_request.enrollment_message()); | |
411 EXPECT_EQ(kDeviceEphemeralKey, expected_request.device_ephemeral_key()); | |
412 | |
413 { | |
414 cryptauth::FinishEnrollmentResponse response_proto; | |
415 response_proto.set_status("OK"); | |
416 FinishApiCallFlow(&response_proto); | |
417 } | |
418 EXPECT_EQ("OK", result_proto.status()); | |
419 } | |
420 | |
421 TEST_F(ProximityAuthCryptAuthClientTest, FetchAccessTokenFailure) { | |
422 access_token_fetcher_->set_access_token(""); | |
423 | |
424 std::string error_message; | |
425 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(), | |
426 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>), | |
427 base::Bind(&SaveResult<std::string>, &error_message)); | |
428 | |
429 EXPECT_EQ("Failed to get a valid access token.", error_message); | |
430 } | |
431 | |
432 TEST_F(ProximityAuthCryptAuthClientTest, ParseResponseProtoFailure) { | |
433 ExpectRequest( | |
434 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
435 "getmydevices?alt=proto"); | |
436 | |
437 std::string error_message; | |
438 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(), | |
439 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>), | |
440 base::Bind(&SaveResult<std::string>, &error_message)); | |
441 | |
442 flow_result_callback_.Run("Not a valid serialized response message."); | |
443 EXPECT_EQ("Failed to parse response proto.", error_message); | |
444 } | |
445 | |
446 TEST_F(ProximityAuthCryptAuthClientTest, | |
447 MakeSecondRequestBeforeFirstRequestSucceeds) { | |
448 ExpectRequest( | |
449 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
450 "getmydevices?alt=proto"); | |
451 | |
452 // Make first request. | |
453 cryptauth::GetMyDevicesResponse result_proto; | |
454 client_->GetMyDevices( | |
455 cryptauth::GetMyDevicesRequest(), | |
456 base::Bind(&SaveResult<cryptauth::GetMyDevicesResponse>, &result_proto), | |
457 base::Bind(&NotCalled<std::string>)); | |
458 | |
459 // With request pending, make second request. | |
460 { | |
461 std::string error_message; | |
462 client_->FindEligibleUnlockDevices( | |
463 cryptauth::FindEligibleUnlockDevicesRequest(), | |
464 base::Bind(&NotCalled<cryptauth::FindEligibleUnlockDevicesResponse>), | |
465 base::Bind(&SaveResult<std::string>, &error_message)); | |
466 EXPECT_EQ("Client has been used for another request. Do not reuse.", | |
467 error_message); | |
468 } | |
469 | |
470 // Complete first request. | |
471 { | |
472 cryptauth::GetMyDevicesResponse response_proto; | |
473 response_proto.add_devices(); | |
474 response_proto.mutable_devices(0)->set_public_key(kPublicKey1); | |
475 FinishApiCallFlow(&response_proto); | |
476 } | |
477 | |
478 ASSERT_EQ(1, result_proto.devices_size()); | |
479 EXPECT_EQ(kPublicKey1, result_proto.devices(0).public_key()); | |
480 } | |
481 | |
482 TEST_F(ProximityAuthCryptAuthClientTest, | |
483 MakeSecondRequestBeforeFirstRequestFails) { | |
484 ExpectRequest( | |
485 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
486 "getmydevices?alt=proto"); | |
487 | |
488 // Make first request. | |
489 std::string error_message; | |
490 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(), | |
491 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>), | |
492 base::Bind(&SaveResult<std::string>, &error_message)); | |
493 | |
494 // With request pending, make second request. | |
495 { | |
496 std::string error_message; | |
497 client_->FindEligibleUnlockDevices( | |
498 cryptauth::FindEligibleUnlockDevicesRequest(), | |
499 base::Bind(&NotCalled<cryptauth::FindEligibleUnlockDevicesResponse>), | |
500 base::Bind(&SaveResult<std::string>, &error_message)); | |
501 EXPECT_EQ("Client has been used for another request. Do not reuse.", | |
502 error_message); | |
503 } | |
504 | |
505 // Fail first request. | |
506 std::string kStatus429Error = "HTTP status: 429"; | |
507 FailApiCallFlow(kStatus429Error); | |
508 EXPECT_EQ(kStatus429Error, error_message); | |
509 } | |
510 | |
511 TEST_F(ProximityAuthCryptAuthClientTest, | |
512 MakeSecondRequestAfterFirstRequestSucceeds) { | |
513 // Make first request successfully. | |
514 { | |
515 ExpectRequest( | |
516 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
517 "getmydevices?alt=proto"); | |
518 cryptauth::GetMyDevicesResponse result_proto; | |
519 client_->GetMyDevices( | |
520 cryptauth::GetMyDevicesRequest(), | |
521 base::Bind(&SaveResult<cryptauth::GetMyDevicesResponse>, &result_proto), | |
522 base::Bind(&NotCalled<std::string>)); | |
523 | |
524 cryptauth::GetMyDevicesResponse response_proto; | |
525 response_proto.add_devices(); | |
526 response_proto.mutable_devices(0)->set_public_key(kPublicKey1); | |
527 FinishApiCallFlow(&response_proto); | |
528 ASSERT_EQ(1, result_proto.devices_size()); | |
529 EXPECT_EQ(kPublicKey1, result_proto.devices(0).public_key()); | |
530 } | |
531 | |
532 // Second request fails. | |
533 { | |
534 std::string error_message; | |
535 client_->FindEligibleUnlockDevices( | |
536 cryptauth::FindEligibleUnlockDevicesRequest(), | |
537 base::Bind(&NotCalled<cryptauth::FindEligibleUnlockDevicesResponse>), | |
538 base::Bind(&SaveResult<std::string>, &error_message)); | |
539 EXPECT_EQ("Client has been used for another request. Do not reuse.", | |
540 error_message); | |
541 } | |
542 } | |
543 | |
544 TEST_F(ProximityAuthCryptAuthClientTest, DeviceClassifierIsSet) { | |
545 ExpectRequest( | |
546 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/" | |
547 "getmydevices?alt=proto"); | |
548 | |
549 cryptauth::GetMyDevicesResponse result_proto; | |
550 cryptauth::GetMyDevicesRequest request_proto; | |
551 request_proto.set_allow_stale_read(true); | |
552 client_->GetMyDevices( | |
553 request_proto, | |
554 base::Bind(&SaveResult<cryptauth::GetMyDevicesResponse>, &result_proto), | |
555 base::Bind(&NotCalled<std::string>)); | |
556 cryptauth::GetMyDevicesRequest expected_request; | |
557 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_)); | |
558 | |
559 const cryptauth::DeviceClassifier& device_classifier = | |
560 expected_request.device_classifier(); | |
561 EXPECT_EQ(kDeviceOsVersionCode, device_classifier.device_os_version_code()); | |
562 EXPECT_EQ(kDeviceSoftwareVersionCode, | |
563 device_classifier.device_software_version_code()); | |
564 EXPECT_EQ(kDeviceSoftwarePackage, | |
565 device_classifier.device_software_package()); | |
566 EXPECT_EQ(kDeviceType, device_classifier.device_type()); | |
567 } | |
568 | |
569 } // namespace proximity_auth | |
OLD | NEW |