Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / components / proximity_auth / cryptauth / cryptauth_client_impl_unittest.cc
blob801291289de1f3dc1fc61401a72937d58367824a
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 #include "components/proximity_auth/cryptauth/cryptauth_client_impl.h"
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 "google_apis/gaia/fake_oauth2_token_service.h"
14 #include "net/url_request/test_url_fetcher_factory.h"
15 #include "net/url_request/url_request_test_util.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "url/gurl.h"
20 using testing::_;
21 using testing::DoAll;
22 using testing::Return;
23 using testing::SaveArg;
24 using testing::StrictMock;
26 namespace proximity_auth {
28 namespace {
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";
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;
43 // CryptAuthAccessTokenFetcher implementation simply returning a predetermined
44 // access token.
45 class FakeCryptAuthAccessTokenFetcher : public CryptAuthAccessTokenFetcher {
46 public:
47 FakeCryptAuthAccessTokenFetcher() : access_token_(kAccessToken) {}
49 void FetchAccessToken(const AccessTokenCallback& callback) override {
50 callback.Run(access_token_);
53 void set_access_token(const std::string& access_token) {
54 access_token_ = access_token;
57 private:
58 std::string access_token_;
61 // Mock CryptAuthApiCallFlow, which handles the HTTP requests to CryptAuth.
62 class MockCryptAuthApiCallFlow : public CryptAuthApiCallFlow {
63 public:
64 MockCryptAuthApiCallFlow() : CryptAuthApiCallFlow() {}
65 virtual ~MockCryptAuthApiCallFlow() {}
67 MOCK_METHOD6(Start,
68 void(const GURL&,
69 net::URLRequestContextGetter* context,
70 const std::string& access_token,
71 const std::string& serialized_request,
72 const ResultCallback& result_callback,
73 const ErrorCallback& error_callback));
75 private:
76 DISALLOW_COPY_AND_ASSIGN(MockCryptAuthApiCallFlow);
79 // Callback that should never be invoked.
80 template <class T>
81 void NotCalled(const T& type) {
82 EXPECT_TRUE(false);
85 // Callback that saves the result returned by CryptAuthClient.
86 template <class T>
87 void SaveResult(T* out, const T& result) {
88 *out = result;
91 } // namespace
93 class ProximityAuthCryptAuthClientTest : public testing::Test {
94 protected:
95 ProximityAuthCryptAuthClientTest()
96 : access_token_fetcher_(new FakeCryptAuthAccessTokenFetcher()),
97 api_call_flow_(new StrictMock<MockCryptAuthApiCallFlow>()),
98 url_request_context_(
99 new net::TestURLRequestContextGetter(new base::NullTaskRunner())),
100 serialized_request_(std::string()) {}
102 void SetUp() override {
103 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
104 switches::kCryptAuthHTTPHost, kTestGoogleApisUrl);
106 cryptauth::DeviceClassifier device_classifier;
107 device_classifier.set_device_os_version_code(kDeviceOsVersionCode);
108 device_classifier.set_device_software_version_code(
109 kDeviceSoftwareVersionCode);
110 device_classifier.set_device_software_package(kDeviceSoftwarePackage);
111 device_classifier.set_device_type(kDeviceType);
113 client_.reset(new CryptAuthClientImpl(
114 make_scoped_ptr(api_call_flow_), make_scoped_ptr(access_token_fetcher_),
115 url_request_context_, device_classifier));
118 // Sets up an expectation and captures a CryptAuth API request to
119 // |request_url|.
120 void ExpectRequest(const std::string& request_url) {
121 GURL url(request_url);
122 EXPECT_CALL(*api_call_flow_,
123 Start(url, url_request_context_.get(), kAccessToken, _, _, _))
124 .WillOnce(DoAll(SaveArg<3>(&serialized_request_),
125 SaveArg<4>(&flow_result_callback_),
126 SaveArg<5>(&flow_error_callback_)));
129 // Returns |response_proto| as the result to the current API request.
130 // ExpectResult() must have been called first.
131 void FinishApiCallFlow(const google::protobuf::MessageLite* response_proto) {
132 flow_result_callback_.Run(response_proto->SerializeAsString());
135 // Ends the current API request with |error_message|. ExpectResult() must have
136 // been called first.
137 void FailApiCallFlow(const std::string& error_message) {
138 flow_error_callback_.Run(error_message);
141 protected:
142 // Owned by |client_|.
143 FakeCryptAuthAccessTokenFetcher* access_token_fetcher_;
144 // Owned by |client_|.
145 StrictMock<MockCryptAuthApiCallFlow>* api_call_flow_;
147 scoped_refptr<net::URLRequestContextGetter> url_request_context_;
148 scoped_ptr<CryptAuthClient> client_;
150 std::string serialized_request_;
151 CryptAuthApiCallFlow::ResultCallback flow_result_callback_;
152 CryptAuthApiCallFlow::ErrorCallback flow_error_callback_;
155 TEST_F(ProximityAuthCryptAuthClientTest, GetMyDevicesSuccess) {
156 ExpectRequest(
157 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
158 "getmydevices?alt=proto");
160 cryptauth::GetMyDevicesResponse result_proto;
161 cryptauth::GetMyDevicesRequest request_proto;
162 request_proto.set_allow_stale_read(true);
163 client_->GetMyDevices(
164 request_proto,
165 base::Bind(&SaveResult<cryptauth::GetMyDevicesResponse>, &result_proto),
166 base::Bind(&NotCalled<std::string>));
168 cryptauth::GetMyDevicesRequest expected_request;
169 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
170 EXPECT_TRUE(expected_request.allow_stale_read());
172 // Return two devices, one unlock key and one unlockable device.
174 cryptauth::GetMyDevicesResponse response_proto;
175 response_proto.add_devices();
176 response_proto.mutable_devices(0)->set_public_key(kPublicKey1);
177 response_proto.mutable_devices(0)->set_unlock_key(true);
178 response_proto.mutable_devices(0)
179 ->set_bluetooth_address(kBluetoothAddress1);
180 response_proto.add_devices();
181 response_proto.mutable_devices(1)->set_public_key(kPublicKey2);
182 response_proto.mutable_devices(1)->set_unlockable(true);
183 FinishApiCallFlow(&response_proto);
186 // Check that the result received in callback is the same as the response.
187 ASSERT_EQ(2, result_proto.devices_size());
188 EXPECT_EQ(kPublicKey1, result_proto.devices(0).public_key());
189 EXPECT_TRUE(result_proto.devices(0).unlock_key());
190 EXPECT_EQ(kBluetoothAddress1, result_proto.devices(0).bluetooth_address());
191 EXPECT_EQ(kPublicKey2, result_proto.devices(1).public_key());
192 EXPECT_TRUE(result_proto.devices(1).unlockable());
195 TEST_F(ProximityAuthCryptAuthClientTest, GetMyDevicesFailure) {
196 ExpectRequest(
197 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
198 "getmydevices?alt=proto");
200 std::string error_message;
201 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(),
202 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>),
203 base::Bind(&SaveResult<std::string>, &error_message));
205 std::string kStatus500Error("HTTP status: 500");
206 FailApiCallFlow(kStatus500Error);
207 EXPECT_EQ(kStatus500Error, error_message);
210 TEST_F(ProximityAuthCryptAuthClientTest, FindEligibleUnlockDevicesSuccess) {
211 ExpectRequest(
212 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
213 "findeligibleunlockdevices?alt=proto");
215 cryptauth::FindEligibleUnlockDevicesResponse result_proto;
216 cryptauth::FindEligibleUnlockDevicesRequest request_proto;
217 request_proto.set_callback_bluetooth_address(kBluetoothAddress2);
218 client_->FindEligibleUnlockDevices(
219 request_proto,
220 base::Bind(&SaveResult<cryptauth::FindEligibleUnlockDevicesResponse>,
221 &result_proto),
222 base::Bind(&NotCalled<std::string>));
224 cryptauth::FindEligibleUnlockDevicesRequest expected_request;
225 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
226 EXPECT_EQ(kBluetoothAddress2, expected_request.callback_bluetooth_address());
228 // Return a response proto with one eligible and one ineligible device.
229 cryptauth::FindEligibleUnlockDevicesResponse response_proto;
230 response_proto.add_eligible_devices();
231 response_proto.mutable_eligible_devices(0)->set_public_key(kPublicKey1);
233 const std::string kIneligibilityReason = "You require more vespine gas.";
234 response_proto.add_ineligible_devices();
235 response_proto.mutable_ineligible_devices(0)
236 ->mutable_device()
237 ->set_public_key(kPublicKey2);
238 response_proto.mutable_ineligible_devices(0)
239 ->add_reasons(kIneligibilityReason);
240 FinishApiCallFlow(&response_proto);
242 // Check that the result received in callback is the same as the response.
243 ASSERT_EQ(1, result_proto.eligible_devices_size());
244 EXPECT_EQ(kPublicKey1, result_proto.eligible_devices(0).public_key());
245 ASSERT_EQ(1, result_proto.ineligible_devices_size());
246 EXPECT_EQ(kPublicKey2,
247 result_proto.ineligible_devices(0).device().public_key());
248 ASSERT_EQ(1, result_proto.ineligible_devices(0).reasons_size());
249 EXPECT_EQ(kIneligibilityReason,
250 result_proto.ineligible_devices(0).reasons(0));
253 TEST_F(ProximityAuthCryptAuthClientTest, FindEligibleUnlockDevicesFailure) {
254 ExpectRequest(
255 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
256 "findeligibleunlockdevices?alt=proto");
258 std::string error_message;
259 cryptauth::FindEligibleUnlockDevicesRequest request_proto;
260 request_proto.set_callback_bluetooth_address(kBluetoothAddress1);
261 client_->FindEligibleUnlockDevices(
262 request_proto,
263 base::Bind(&NotCalled<cryptauth::FindEligibleUnlockDevicesResponse>),
264 base::Bind(&SaveResult<std::string>, &error_message));
266 std::string kStatus403Error("HTTP status: 403");
267 FailApiCallFlow(kStatus403Error);
268 EXPECT_EQ(kStatus403Error, error_message);
271 TEST_F(ProximityAuthCryptAuthClientTest, SendDeviceSyncTickleSuccess) {
272 ExpectRequest(
273 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
274 "senddevicesynctickle?alt=proto");
276 cryptauth::SendDeviceSyncTickleResponse result_proto;
277 client_->SendDeviceSyncTickle(
278 cryptauth::SendDeviceSyncTickleRequest(),
279 base::Bind(&SaveResult<cryptauth::SendDeviceSyncTickleResponse>,
280 &result_proto),
281 base::Bind(&NotCalled<std::string>));
283 cryptauth::SendDeviceSyncTickleRequest expected_request;
284 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
286 cryptauth::SendDeviceSyncTickleResponse response_proto;
287 FinishApiCallFlow(&response_proto);
290 TEST_F(ProximityAuthCryptAuthClientTest, ToggleEasyUnlockSuccess) {
291 ExpectRequest(
292 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
293 "toggleeasyunlock?alt=proto");
295 cryptauth::ToggleEasyUnlockResponse result_proto;
296 cryptauth::ToggleEasyUnlockRequest request_proto;
297 request_proto.set_enable(true);
298 request_proto.set_apply_to_all(false);
299 request_proto.set_public_key(kPublicKey1);
300 client_->ToggleEasyUnlock(
301 request_proto,
302 base::Bind(&SaveResult<cryptauth::ToggleEasyUnlockResponse>,
303 &result_proto),
304 base::Bind(&NotCalled<std::string>));
306 cryptauth::ToggleEasyUnlockRequest expected_request;
307 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
308 EXPECT_TRUE(expected_request.enable());
309 EXPECT_EQ(kPublicKey1, expected_request.public_key());
310 EXPECT_FALSE(expected_request.apply_to_all());
312 cryptauth::ToggleEasyUnlockResponse response_proto;
313 FinishApiCallFlow(&response_proto);
316 TEST_F(ProximityAuthCryptAuthClientTest, SetupEnrollmentSuccess) {
317 ExpectRequest(
318 "https://www.testgoogleapis.com/cryptauth/v1/enrollment/"
319 "setup?alt=proto");
321 std::string kApplicationId = "mkaes";
322 std::vector<std::string> supported_protocols;
323 supported_protocols.push_back("gcmV1");
324 supported_protocols.push_back("testProtocol");
326 cryptauth::SetupEnrollmentResponse result_proto;
327 cryptauth::SetupEnrollmentRequest request_proto;
328 request_proto.set_application_id(kApplicationId);
329 request_proto.add_types("gcmV1");
330 request_proto.add_types("testProtocol");
331 client_->SetupEnrollment(
332 request_proto, base::Bind(&SaveResult<cryptauth::SetupEnrollmentResponse>,
333 &result_proto),
334 base::Bind(&NotCalled<std::string>));
336 cryptauth::SetupEnrollmentRequest expected_request;
337 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
338 EXPECT_EQ(kApplicationId, expected_request.application_id());
339 ASSERT_EQ(2, expected_request.types_size());
340 EXPECT_EQ("gcmV1", expected_request.types(0));
341 EXPECT_EQ("testProtocol", expected_request.types(1));
343 // Return a fake enrollment session.
345 cryptauth::SetupEnrollmentResponse response_proto;
346 response_proto.set_status("OK");
347 response_proto.add_infos();
348 response_proto.mutable_infos(0)->set_type("gcmV1");
349 response_proto.mutable_infos(0)->set_enrollment_session_id("session_id");
350 response_proto.mutable_infos(0)->set_server_ephemeral_key("ephemeral_key");
351 FinishApiCallFlow(&response_proto);
354 // Check that the returned proto is the same as the one just created.
355 EXPECT_EQ("OK", result_proto.status());
356 ASSERT_EQ(1, result_proto.infos_size());
357 EXPECT_EQ("gcmV1", result_proto.infos(0).type());
358 EXPECT_EQ("session_id", result_proto.infos(0).enrollment_session_id());
359 EXPECT_EQ("ephemeral_key", result_proto.infos(0).server_ephemeral_key());
362 TEST_F(ProximityAuthCryptAuthClientTest, FinishEnrollmentSuccess) {
363 ExpectRequest(
364 "https://www.testgoogleapis.com/cryptauth/v1/enrollment/"
365 "finish?alt=proto");
367 const char kEnrollmentSessionId[] = "enrollment_session_id";
368 const char kEnrollmentMessage[] = "enrollment_message";
369 const char kDeviceEphemeralKey[] = "device_ephermal_key";
370 cryptauth::FinishEnrollmentResponse result_proto;
371 cryptauth::FinishEnrollmentRequest request_proto;
372 request_proto.set_enrollment_session_id(kEnrollmentSessionId);
373 request_proto.set_enrollment_message(kEnrollmentMessage);
374 request_proto.set_device_ephemeral_key(kDeviceEphemeralKey);
375 client_->FinishEnrollment(
376 request_proto,
377 base::Bind(&SaveResult<cryptauth::FinishEnrollmentResponse>,
378 &result_proto),
379 base::Bind(&NotCalled<const std::string&>));
381 cryptauth::FinishEnrollmentRequest expected_request;
382 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
383 EXPECT_EQ(kEnrollmentSessionId, expected_request.enrollment_session_id());
384 EXPECT_EQ(kEnrollmentMessage, expected_request.enrollment_message());
385 EXPECT_EQ(kDeviceEphemeralKey, expected_request.device_ephemeral_key());
388 cryptauth::FinishEnrollmentResponse response_proto;
389 response_proto.set_status("OK");
390 FinishApiCallFlow(&response_proto);
392 EXPECT_EQ("OK", result_proto.status());
395 TEST_F(ProximityAuthCryptAuthClientTest, FetchAccessTokenFailure) {
396 access_token_fetcher_->set_access_token("");
398 std::string error_message;
399 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(),
400 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>),
401 base::Bind(&SaveResult<std::string>, &error_message));
403 EXPECT_EQ("Failed to get a valid access token.", error_message);
406 TEST_F(ProximityAuthCryptAuthClientTest, ParseResponseProtoFailure) {
407 ExpectRequest(
408 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
409 "getmydevices?alt=proto");
411 std::string error_message;
412 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(),
413 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>),
414 base::Bind(&SaveResult<std::string>, &error_message));
416 flow_result_callback_.Run("Not a valid serialized response message.");
417 EXPECT_EQ("Failed to parse response proto.", error_message);
420 TEST_F(ProximityAuthCryptAuthClientTest,
421 MakeSecondRequestBeforeFirstRequestSucceeds) {
422 ExpectRequest(
423 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
424 "getmydevices?alt=proto");
426 // Make first request.
427 cryptauth::GetMyDevicesResponse result_proto;
428 client_->GetMyDevices(
429 cryptauth::GetMyDevicesRequest(),
430 base::Bind(&SaveResult<cryptauth::GetMyDevicesResponse>, &result_proto),
431 base::Bind(&NotCalled<std::string>));
433 // With request pending, make second request.
435 std::string error_message;
436 client_->FindEligibleUnlockDevices(
437 cryptauth::FindEligibleUnlockDevicesRequest(),
438 base::Bind(&NotCalled<cryptauth::FindEligibleUnlockDevicesResponse>),
439 base::Bind(&SaveResult<std::string>, &error_message));
440 EXPECT_EQ("Client has been used for another request. Do not reuse.",
441 error_message);
444 // Complete first request.
446 cryptauth::GetMyDevicesResponse response_proto;
447 response_proto.add_devices();
448 response_proto.mutable_devices(0)->set_public_key(kPublicKey1);
449 FinishApiCallFlow(&response_proto);
452 ASSERT_EQ(1, result_proto.devices_size());
453 EXPECT_EQ(kPublicKey1, result_proto.devices(0).public_key());
456 TEST_F(ProximityAuthCryptAuthClientTest,
457 MakeSecondRequestBeforeFirstRequestFails) {
458 ExpectRequest(
459 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
460 "getmydevices?alt=proto");
462 // Make first request.
463 std::string error_message;
464 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(),
465 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>),
466 base::Bind(&SaveResult<std::string>, &error_message));
468 // With request pending, make second request.
470 std::string error_message;
471 client_->FindEligibleUnlockDevices(
472 cryptauth::FindEligibleUnlockDevicesRequest(),
473 base::Bind(&NotCalled<cryptauth::FindEligibleUnlockDevicesResponse>),
474 base::Bind(&SaveResult<std::string>, &error_message));
475 EXPECT_EQ("Client has been used for another request. Do not reuse.",
476 error_message);
479 // Fail first request.
480 std::string kStatus429Error = "HTTP status: 429";
481 FailApiCallFlow(kStatus429Error);
482 EXPECT_EQ(kStatus429Error, error_message);
485 TEST_F(ProximityAuthCryptAuthClientTest,
486 MakeSecondRequestAfterFirstRequestSucceeds) {
487 // Make first request successfully.
489 ExpectRequest(
490 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
491 "getmydevices?alt=proto");
492 cryptauth::GetMyDevicesResponse result_proto;
493 client_->GetMyDevices(
494 cryptauth::GetMyDevicesRequest(),
495 base::Bind(&SaveResult<cryptauth::GetMyDevicesResponse>, &result_proto),
496 base::Bind(&NotCalled<std::string>));
498 cryptauth::GetMyDevicesResponse response_proto;
499 response_proto.add_devices();
500 response_proto.mutable_devices(0)->set_public_key(kPublicKey1);
501 FinishApiCallFlow(&response_proto);
502 ASSERT_EQ(1, result_proto.devices_size());
503 EXPECT_EQ(kPublicKey1, result_proto.devices(0).public_key());
506 // Second request fails.
508 std::string error_message;
509 client_->FindEligibleUnlockDevices(
510 cryptauth::FindEligibleUnlockDevicesRequest(),
511 base::Bind(&NotCalled<cryptauth::FindEligibleUnlockDevicesResponse>),
512 base::Bind(&SaveResult<std::string>, &error_message));
513 EXPECT_EQ("Client has been used for another request. Do not reuse.",
514 error_message);
518 TEST_F(ProximityAuthCryptAuthClientTest, DeviceClassifierIsSet) {
519 ExpectRequest(
520 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
521 "getmydevices?alt=proto");
523 cryptauth::GetMyDevicesResponse result_proto;
524 cryptauth::GetMyDevicesRequest request_proto;
525 request_proto.set_allow_stale_read(true);
526 client_->GetMyDevices(
527 request_proto,
528 base::Bind(&SaveResult<cryptauth::GetMyDevicesResponse>, &result_proto),
529 base::Bind(&NotCalled<std::string>));
530 cryptauth::GetMyDevicesRequest expected_request;
531 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
533 const cryptauth::DeviceClassifier& device_classifier =
534 expected_request.device_classifier();
535 EXPECT_EQ(kDeviceOsVersionCode, device_classifier.device_os_version_code());
536 EXPECT_EQ(kDeviceSoftwareVersionCode,
537 device_classifier.device_software_version_code());
538 EXPECT_EQ(kDeviceSoftwarePackage,
539 device_classifier.device_software_package());
540 EXPECT_EQ(kDeviceType, device_classifier.device_type());
543 TEST_F(ProximityAuthCryptAuthClientTest, GetAccessTokenUsed) {
544 EXPECT_TRUE(client_->GetAccessTokenUsed().empty());
545 ExpectRequest(
546 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
547 "getmydevices?alt=proto");
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 EXPECT_EQ(kAccessToken, client_->GetAccessTokenUsed());
559 } // namespace proximity_auth