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"
22 using testing::Return
;
23 using testing::SaveArg
;
24 using testing::StrictMock
;
26 namespace proximity_auth
{
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
45 class FakeCryptAuthAccessTokenFetcher
: public CryptAuthAccessTokenFetcher
{
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
;
58 std::string access_token_
;
61 // Mock CryptAuthApiCallFlow, which handles the HTTP requests to CryptAuth.
62 class MockCryptAuthApiCallFlow
: public CryptAuthApiCallFlow
{
64 MockCryptAuthApiCallFlow() : CryptAuthApiCallFlow(GURL(std::string())) {}
65 virtual ~MockCryptAuthApiCallFlow() {}
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
));
75 DISALLOW_COPY_AND_ASSIGN(MockCryptAuthApiCallFlow
);
78 // Subclass of CryptAuthClient to use as test harness.
79 class MockCryptAuthClient
: public CryptAuthClient
{
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
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
),
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
));
101 DISALLOW_COPY_AND_ASSIGN(MockCryptAuthClient
);
104 // Callback that should never be invoked.
106 void NotCalled(const T
& type
) {
110 // Callback that saves the result returned by CryptAuthClient.
112 void SaveResult(T
* out
, const T
& result
) {
118 class ProximityAuthCryptAuthClientTest
: public testing::Test
{
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
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
);
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
) {
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(
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
) {
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
) {
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(
246 base::Bind(&SaveResult
<cryptauth::FindEligibleUnlockDevicesResponse
>,
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)
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
) {
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(
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
) {
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
>,
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
) {
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(
328 base::Bind(&SaveResult
<cryptauth::ToggleEasyUnlockResponse
>,
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
) {
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
>,
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
) {
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(
403 base::Bind(&SaveResult
<cryptauth::FinishEnrollmentResponse
>,
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
) {
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
) {
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.",
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
) {
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.",
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.
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.",
544 TEST_F(ProximityAuthCryptAuthClientTest
, DeviceClassifierIsSet
) {
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(
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