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