Roll src/third_party/WebKit f36d5e0:68b67cd (svn 193299:193303)
[chromium-blink-merge.git] / components / proximity_auth / cryptauth / cryptauth_client_unittest.cc
blob61d4d46c900c3026daee7a0175d94c980190bb3a
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.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/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"
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(GURL(std::string())) {}
65 virtual ~MockCryptAuthApiCallFlow() {}
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));
74 private:
75 DISALLOW_COPY_AND_ASSIGN(MockCryptAuthApiCallFlow);
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() {}
93 MOCK_METHOD1(CreateFlowProxy, CryptAuthApiCallFlow*(const GURL& request_url));
95 scoped_ptr<CryptAuthApiCallFlow> CreateFlow(
96 const GURL& request_url) override {
97 return make_scoped_ptr(CreateFlowProxy(request_url));
100 private:
101 DISALLOW_COPY_AND_ASSIGN(MockCryptAuthClient);
104 // Callback that should never be invoked.
105 template <class T>
106 void NotCalled(const T& type) {
107 EXPECT_TRUE(false);
110 // Callback that saves the result returned by CryptAuthClient.
111 template <class T>
112 void SaveResult(T* out, const T& result) {
113 *out = result;
116 } // namespace
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()) {}
126 void SetUp() override {
127 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
128 switches::kCryptAuthHTTPHost, kTestGoogleApisUrl);
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);
137 client_.reset(new StrictMock<MockCryptAuthClient>(
138 access_token_fetcher_, url_request_context_, device_classifier));
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>();
147 EXPECT_CALL(*client_, CreateFlowProxy(GURL(request_url)))
148 .WillOnce(Return(api_call_flow));
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_)));
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());
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);
169 protected:
170 // Owned by |client_|.
171 FakeCryptAuthAccessTokenFetcher* access_token_fetcher_;
173 scoped_refptr<net::URLRequestContextGetter> url_request_context_;
174 scoped_ptr<StrictMock<MockCryptAuthClient>> client_;
176 std::string serialized_request_;
177 CryptAuthApiCallFlow::ResultCallback flow_result_callback_;
178 CryptAuthApiCallFlow::ErrorCallback flow_error_callback_;
181 TEST_F(ProximityAuthCryptAuthClientTest, GetMyDevicesSuccess) {
182 ExpectRequest(
183 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
184 "getmydevices?alt=proto");
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>));
194 cryptauth::GetMyDevicesRequest expected_request;
195 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
196 EXPECT_TRUE(expected_request.allow_stale_read());
198 // Return two devices, one unlock key and one unlockable device.
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);
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());
221 TEST_F(ProximityAuthCryptAuthClientTest, GetMyDevicesFailure) {
222 ExpectRequest(
223 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
224 "getmydevices?alt=proto");
226 std::string error_message;
227 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(),
228 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>),
229 base::Bind(&SaveResult<std::string>, &error_message));
231 std::string kStatus500Error("HTTP status: 500");
232 FailApiCallFlow(kStatus500Error);
233 EXPECT_EQ(kStatus500Error, error_message);
236 TEST_F(ProximityAuthCryptAuthClientTest, FindEligibleUnlockDevicesSuccess) {
237 ExpectRequest(
238 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
239 "findeligibleunlockdevices?alt=proto");
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>));
250 cryptauth::FindEligibleUnlockDevicesRequest expected_request;
251 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
252 EXPECT_EQ(kBluetoothAddress2, expected_request.callback_bluetooth_address());
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);
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);
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));
279 TEST_F(ProximityAuthCryptAuthClientTest, FindEligibleUnlockDevicesFailure) {
280 ExpectRequest(
281 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
282 "findeligibleunlockdevices?alt=proto");
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));
292 std::string kStatus403Error("HTTP status: 403");
293 FailApiCallFlow(kStatus403Error);
294 EXPECT_EQ(kStatus403Error, error_message);
297 TEST_F(ProximityAuthCryptAuthClientTest, SendDeviceSyncTickleSuccess) {
298 ExpectRequest(
299 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
300 "senddevicesynctickle?alt=proto");
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>));
309 cryptauth::SendDeviceSyncTickleRequest expected_request;
310 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
312 cryptauth::SendDeviceSyncTickleResponse response_proto;
313 FinishApiCallFlow(&response_proto);
316 TEST_F(ProximityAuthCryptAuthClientTest, ToggleEasyUnlockSuccess) {
317 ExpectRequest(
318 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
319 "toggleeasyunlock?alt=proto");
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>));
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());
338 cryptauth::ToggleEasyUnlockResponse response_proto;
339 FinishApiCallFlow(&response_proto);
342 TEST_F(ProximityAuthCryptAuthClientTest, SetupEnrollmentSuccess) {
343 ExpectRequest(
344 "https://www.testgoogleapis.com/cryptauth/v1/enrollment/"
345 "setupenrollment?alt=proto");
347 std::string kApplicationId = "mkaes";
348 std::vector<std::string> supported_protocols;
349 supported_protocols.push_back("gcmV1");
350 supported_protocols.push_back("testProtocol");
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>));
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));
369 // Return a fake enrollment session.
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);
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());
388 TEST_F(ProximityAuthCryptAuthClientTest, FinishEnrollmentSuccess) {
389 ExpectRequest(
390 "https://www.testgoogleapis.com/cryptauth/v1/enrollment/"
391 "finishenrollment?alt=proto");
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&>));
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());
414 cryptauth::FinishEnrollmentResponse response_proto;
415 response_proto.set_status("OK");
416 FinishApiCallFlow(&response_proto);
418 EXPECT_EQ("OK", result_proto.status());
421 TEST_F(ProximityAuthCryptAuthClientTest, FetchAccessTokenFailure) {
422 access_token_fetcher_->set_access_token("");
424 std::string error_message;
425 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(),
426 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>),
427 base::Bind(&SaveResult<std::string>, &error_message));
429 EXPECT_EQ("Failed to get a valid access token.", error_message);
432 TEST_F(ProximityAuthCryptAuthClientTest, ParseResponseProtoFailure) {
433 ExpectRequest(
434 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
435 "getmydevices?alt=proto");
437 std::string error_message;
438 client_->GetMyDevices(cryptauth::GetMyDevicesRequest(),
439 base::Bind(&NotCalled<cryptauth::GetMyDevicesResponse>),
440 base::Bind(&SaveResult<std::string>, &error_message));
442 flow_result_callback_.Run("Not a valid serialized response message.");
443 EXPECT_EQ("Failed to parse response proto.", error_message);
446 TEST_F(ProximityAuthCryptAuthClientTest,
447 MakeSecondRequestBeforeFirstRequestSucceeds) {
448 ExpectRequest(
449 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
450 "getmydevices?alt=proto");
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>));
459 // With request pending, make second request.
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);
470 // Complete first request.
472 cryptauth::GetMyDevicesResponse response_proto;
473 response_proto.add_devices();
474 response_proto.mutable_devices(0)->set_public_key(kPublicKey1);
475 FinishApiCallFlow(&response_proto);
478 ASSERT_EQ(1, result_proto.devices_size());
479 EXPECT_EQ(kPublicKey1, result_proto.devices(0).public_key());
482 TEST_F(ProximityAuthCryptAuthClientTest,
483 MakeSecondRequestBeforeFirstRequestFails) {
484 ExpectRequest(
485 "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
486 "getmydevices?alt=proto");
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));
494 // With request pending, make second request.
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);
505 // Fail first request.
506 std::string kStatus429Error = "HTTP status: 429";
507 FailApiCallFlow(kStatus429Error);
508 EXPECT_EQ(kStatus429Error, error_message);
511 TEST_F(ProximityAuthCryptAuthClientTest,
512 MakeSecondRequestAfterFirstRequestSucceeds) {
513 // Make first request successfully.
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>));
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());
532 // Second request fails.
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);
544 TEST_F(ProximityAuthCryptAuthClientTest, DeviceClassifierIsSet) {
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 cryptauth::GetMyDevicesRequest expected_request;
557 EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
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());
569 } // namespace proximity_auth