Chromium Code Reviews| 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 |