| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/signin/ios/browser/account_consistency_service.h" | 5 #include "components/signin/ios/browser/account_consistency_service.h" |
| 6 | 6 |
| 7 #import <WebKit/WebKit.h> | 7 #import <WebKit/WebKit.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #import "base/mac/scoped_nsobject.h" | |
| 12 #include "components/signin/core/browser/account_reconcilor.h" | 11 #include "components/signin/core/browser/account_reconcilor.h" |
| 13 #include "components/signin/core/browser/account_tracker_service.h" | 12 #include "components/signin/core/browser/account_tracker_service.h" |
| 14 #include "components/signin/core/browser/fake_signin_manager.h" | 13 #include "components/signin/core/browser/fake_signin_manager.h" |
| 15 #include "components/signin/core/browser/gaia_cookie_manager_service.h" | 14 #include "components/signin/core/browser/gaia_cookie_manager_service.h" |
| 16 #include "components/signin/core/browser/test_signin_client.h" | 15 #include "components/signin/core/browser/test_signin_client.h" |
| 17 #include "components/signin/core/common/signin_pref_names.h" | 16 #include "components/signin/core/common/signin_pref_names.h" |
| 18 #include "components/sync_preferences/testing_pref_service_syncable.h" | 17 #include "components/sync_preferences/testing_pref_service_syncable.h" |
| 19 #include "google_apis/gaia/gaia_constants.h" | 18 #include "google_apis/gaia/gaia_constants.h" |
| 20 #include "ios/web/public/test/fakes/test_browser_state.h" | 19 #include "ios/web/public/test/fakes/test_browser_state.h" |
| 21 #import "ios/web/public/test/fakes/test_web_state.h" | 20 #import "ios/web/public/test/fakes/test_web_state.h" |
| 22 #include "ios/web/public/test/test_web_thread_bundle.h" | 21 #include "ios/web/public/test/test_web_thread_bundle.h" |
| 23 #include "ios/web/public/web_state/web_state_policy_decider.h" | 22 #include "ios/web/public/web_state/web_state_policy_decider.h" |
| 24 #include "testing/gmock/include/gmock/gmock.h" | 23 #include "testing/gmock/include/gmock/gmock.h" |
| 25 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
| 26 #include "testing/platform_test.h" | 25 #include "testing/platform_test.h" |
| 27 #include "third_party/ocmock/OCMock/OCMock.h" | 26 #include "third_party/ocmock/OCMock/OCMock.h" |
| 28 #include "third_party/ocmock/gtest_support.h" | 27 #include "third_party/ocmock/gtest_support.h" |
| 29 | 28 |
| 29 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 30 #error "This file requires ARC support." |
| 31 #endif |
| 32 |
| 30 namespace { | 33 namespace { |
| 31 // URL of the Google domain where the CHROME_CONNECTED cookie is set/removed. | 34 // URL of the Google domain where the CHROME_CONNECTED cookie is set/removed. |
| 32 NSURL* const kGoogleUrl = [NSURL URLWithString:@"https://google.com/"]; | 35 NSURL* const kGoogleUrl = [NSURL URLWithString:@"https://google.com/"]; |
| 33 // URL of the Youtube domain where the CHROME_CONNECTED cookie is set/removed. | 36 // URL of the Youtube domain where the CHROME_CONNECTED cookie is set/removed. |
| 34 NSURL* const kYoutubeUrl = [NSURL URLWithString:@"https://youtube.com/"]; | 37 NSURL* const kYoutubeUrl = [NSURL URLWithString:@"https://youtube.com/"]; |
| 35 // URL of a country Google domain where the CHROME_CONNECTED cookie is | 38 // URL of a country Google domain where the CHROME_CONNECTED cookie is |
| 36 // set/removed. | 39 // set/removed. |
| 37 NSURL* const kCountryGoogleUrl = [NSURL URLWithString:@"https://google.de/"]; | 40 NSURL* const kCountryGoogleUrl = [NSURL URLWithString:@"https://google.de/"]; |
| 38 | 41 |
| 39 // Google domain. | 42 // Google domain. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 56 : AccountConsistencyService(browser_state, | 59 : AccountConsistencyService(browser_state, |
| 57 account_reconcilor, | 60 account_reconcilor, |
| 58 cookie_settings, | 61 cookie_settings, |
| 59 gaia_cookie_manager_service, | 62 gaia_cookie_manager_service, |
| 60 signin_client, | 63 signin_client, |
| 61 signin_manager) {} | 64 signin_manager) {} |
| 62 | 65 |
| 63 private: | 66 private: |
| 64 WKWebView* BuildWKWebView() override { | 67 WKWebView* BuildWKWebView() override { |
| 65 if (!mock_web_view_) { | 68 if (!mock_web_view_) { |
| 66 mock_web_view_.reset( | 69 mock_web_view_ = [OCMockObject niceMockForClass:[WKWebView class]]; |
| 67 [[OCMockObject niceMockForClass:[WKWebView class]] retain]); | |
| 68 } | 70 } |
| 69 return mock_web_view_; | 71 return mock_web_view_; |
| 70 } | 72 } |
| 71 base::scoped_nsobject<id> mock_web_view_; | 73 id mock_web_view_; |
| 72 }; | 74 }; |
| 73 | 75 |
| 74 // Mock AccountReconcilor to catch call to OnReceivedManageAccountsResponse. | 76 // Mock AccountReconcilor to catch call to OnReceivedManageAccountsResponse. |
| 75 class MockAccountReconcilor : public AccountReconcilor { | 77 class MockAccountReconcilor : public AccountReconcilor { |
| 76 public: | 78 public: |
| 77 MockAccountReconcilor() | 79 MockAccountReconcilor() |
| 78 : AccountReconcilor(nullptr, nullptr, nullptr, nullptr) {} | 80 : AccountReconcilor(nullptr, nullptr, nullptr, nullptr) {} |
| 79 MOCK_METHOD1(OnReceivedManageAccountsResponse, void(signin::GAIAServiceType)); | 81 MOCK_METHOD1(OnReceivedManageAccountsResponse, void(signin::GAIAServiceType)); |
| 80 }; | 82 }; |
| 81 | 83 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 } | 150 } |
| 149 | 151 |
| 150 // Adds an expectation for |url| to be loaded in the web view of | 152 // Adds an expectation for |url| to be loaded in the web view of |
| 151 // |account_consistency_service_|. | 153 // |account_consistency_service_|. |
| 152 // |continue_navigation| controls whether navigation will continue or be | 154 // |continue_navigation| controls whether navigation will continue or be |
| 153 // stopped on page load. | 155 // stopped on page load. |
| 154 void AddPageLoadedExpectation(NSURL* url, bool continue_navigation) { | 156 void AddPageLoadedExpectation(NSURL* url, bool continue_navigation) { |
| 155 void (^continueBlock)(NSInvocation*) = ^(NSInvocation* invocation) { | 157 void (^continueBlock)(NSInvocation*) = ^(NSInvocation* invocation) { |
| 156 if (!continue_navigation) | 158 if (!continue_navigation) |
| 157 return; | 159 return; |
| 158 WKWebView* web_view = nil; | 160 __unsafe_unretained WKWebView* web_view = nil; |
| 159 [invocation getArgument:&web_view atIndex:0]; | 161 [invocation getArgument:&web_view atIndex:0]; |
| 160 [GetNavigationDelegate() webView:web_view didFinishNavigation:nil]; | 162 [GetNavigationDelegate() webView:web_view didFinishNavigation:nil]; |
| 161 }; | 163 }; |
| 162 [static_cast<WKWebView*>([[GetMockWKWebView() expect] andDo:continueBlock]) | 164 [static_cast<WKWebView*>([[GetMockWKWebView() expect] andDo:continueBlock]) |
| 163 loadHTMLString:[OCMArg any] | 165 loadHTMLString:[OCMArg any] |
| 164 baseURL:url]; | 166 baseURL:url]; |
| 165 } | 167 } |
| 166 | 168 |
| 167 void ResetAccountConsistencyService() { | 169 void ResetAccountConsistencyService() { |
| 168 if (account_consistency_service_) { | 170 if (account_consistency_service_) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 // Check that main Google domains are added. | 231 // Check that main Google domains are added. |
| 230 AddPageLoadedExpectation(kGoogleUrl, true /* continue_navigation */); | 232 AddPageLoadedExpectation(kGoogleUrl, true /* continue_navigation */); |
| 231 AddPageLoadedExpectation(kYoutubeUrl, true /* continue_navigation */); | 233 AddPageLoadedExpectation(kYoutubeUrl, true /* continue_navigation */); |
| 232 SignIn(); | 234 SignIn(); |
| 233 // Check that other Google domains are added on navigation. | 235 // Check that other Google domains are added on navigation. |
| 234 AddPageLoadedExpectation(kCountryGoogleUrl, true /* continue_navigation */); | 236 AddPageLoadedExpectation(kCountryGoogleUrl, true /* continue_navigation */); |
| 235 | 237 |
| 236 id delegate = | 238 id delegate = |
| 237 [OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)]; | 239 [OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)]; |
| 238 NSDictionary* headers = [NSDictionary dictionary]; | 240 NSDictionary* headers = [NSDictionary dictionary]; |
| 239 base::scoped_nsobject<NSHTTPURLResponse> response([[NSHTTPURLResponse alloc] | 241 NSHTTPURLResponse* response = |
| 240 initWithURL:kCountryGoogleUrl | 242 [[NSHTTPURLResponse alloc] initWithURL:kCountryGoogleUrl |
| 241 statusCode:200 | 243 statusCode:200 |
| 242 HTTPVersion:@"HTTP/1.1" | 244 HTTPVersion:@"HTTP/1.1" |
| 243 headerFields:headers]); | 245 headerFields:headers]; |
| 244 account_consistency_service_->SetWebStateHandler(&web_state_, delegate); | 246 account_consistency_service_->SetWebStateHandler(&web_state_, delegate); |
| 245 EXPECT_TRUE(web_state_.ShouldAllowResponse(response)); | 247 EXPECT_TRUE(web_state_.ShouldAllowResponse(response)); |
| 246 web_state_.WebStateDestroyed(); | 248 web_state_.WebStateDestroyed(); |
| 247 | 249 |
| 248 // Check that all domains are removed. | 250 // Check that all domains are removed. |
| 249 AddPageLoadedExpectation(kGoogleUrl, true /* continue_navigation */); | 251 AddPageLoadedExpectation(kGoogleUrl, true /* continue_navigation */); |
| 250 AddPageLoadedExpectation(kYoutubeUrl, true /* continue_navigation */); | 252 AddPageLoadedExpectation(kYoutubeUrl, true /* continue_navigation */); |
| 251 AddPageLoadedExpectation(kCountryGoogleUrl, true /* continue_navigation */); | 253 AddPageLoadedExpectation(kCountryGoogleUrl, true /* continue_navigation */); |
| 252 SignOut(); | 254 SignOut(); |
| 253 EXPECT_OCMOCK_VERIFY(GetMockWKWebView()); | 255 EXPECT_OCMOCK_VERIFY(GetMockWKWebView()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 | 287 |
| 286 // Tests that the X-Chrome-Manage-Accounts header is ignored unless it comes | 288 // Tests that the X-Chrome-Manage-Accounts header is ignored unless it comes |
| 287 // from Gaia signon realm. | 289 // from Gaia signon realm. |
| 288 TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsNotOnGaia) { | 290 TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsNotOnGaia) { |
| 289 id delegate = | 291 id delegate = |
| 290 [OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)]; | 292 [OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)]; |
| 291 | 293 |
| 292 NSDictionary* headers = | 294 NSDictionary* headers = |
| 293 [NSDictionary dictionaryWithObject:@"action=DEFAULT" | 295 [NSDictionary dictionaryWithObject:@"action=DEFAULT" |
| 294 forKey:@"X-Chrome-Manage-Accounts"]; | 296 forKey:@"X-Chrome-Manage-Accounts"]; |
| 295 base::scoped_nsobject<NSHTTPURLResponse> response([[NSHTTPURLResponse alloc] | 297 NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc] |
| 296 initWithURL:[NSURL URLWithString:@"https://google.com"] | 298 initWithURL:[NSURL URLWithString:@"https://google.com"] |
| 297 statusCode:200 | 299 statusCode:200 |
| 298 HTTPVersion:@"HTTP/1.1" | 300 HTTPVersion:@"HTTP/1.1" |
| 299 headerFields:headers]); | 301 headerFields:headers]; |
| 300 account_consistency_service_->SetWebStateHandler(&web_state_, delegate); | 302 account_consistency_service_->SetWebStateHandler(&web_state_, delegate); |
| 301 EXPECT_TRUE(web_state_.ShouldAllowResponse(response)); | 303 EXPECT_TRUE(web_state_.ShouldAllowResponse(response)); |
| 302 web_state_.WebStateDestroyed(); | 304 web_state_.WebStateDestroyed(); |
| 303 | 305 |
| 304 EXPECT_OCMOCK_VERIFY(delegate); | 306 EXPECT_OCMOCK_VERIFY(delegate); |
| 305 } | 307 } |
| 306 | 308 |
| 307 // Tests that navigation to Gaia signon realm with no X-Chrome-Manage-Accounts | 309 // Tests that navigation to Gaia signon realm with no X-Chrome-Manage-Accounts |
| 308 // header in the response are simply untouched. | 310 // header in the response are simply untouched. |
| 309 TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsNoHeader) { | 311 TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsNoHeader) { |
| 310 id delegate = | 312 id delegate = |
| 311 [OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)]; | 313 [OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)]; |
| 312 | 314 |
| 313 NSDictionary* headers = [NSDictionary dictionary]; | 315 NSDictionary* headers = [NSDictionary dictionary]; |
| 314 base::scoped_nsobject<NSHTTPURLResponse> response([[NSHTTPURLResponse alloc] | 316 NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc] |
| 315 initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"] | 317 initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"] |
| 316 statusCode:200 | 318 statusCode:200 |
| 317 HTTPVersion:@"HTTP/1.1" | 319 HTTPVersion:@"HTTP/1.1" |
| 318 headerFields:headers]); | 320 headerFields:headers]; |
| 319 account_consistency_service_->SetWebStateHandler(&web_state_, delegate); | 321 account_consistency_service_->SetWebStateHandler(&web_state_, delegate); |
| 320 EXPECT_TRUE(web_state_.ShouldAllowResponse(response)); | 322 EXPECT_TRUE(web_state_.ShouldAllowResponse(response)); |
| 321 web_state_.WebStateDestroyed(); | 323 web_state_.WebStateDestroyed(); |
| 322 | 324 |
| 323 EXPECT_OCMOCK_VERIFY(delegate); | 325 EXPECT_OCMOCK_VERIFY(delegate); |
| 324 } | 326 } |
| 325 | 327 |
| 326 // Tests that the ManageAccountsDelegate is notified when a navigation on Gaia | 328 // Tests that the ManageAccountsDelegate is notified when a navigation on Gaia |
| 327 // signon realm returns with a X-Chrome-Manage-Accounts header with action | 329 // signon realm returns with a X-Chrome-Manage-Accounts header with action |
| 328 // DEFAULT. | 330 // DEFAULT. |
| 329 TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsDefault) { | 331 TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsDefault) { |
| 330 id delegate = | 332 id delegate = |
| 331 [OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)]; | 333 [OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)]; |
| 332 // Default action is |onManageAccounts|. | 334 // Default action is |onManageAccounts|. |
| 333 [[delegate expect] onManageAccounts]; | 335 [[delegate expect] onManageAccounts]; |
| 334 | 336 |
| 335 NSDictionary* headers = | 337 NSDictionary* headers = |
| 336 [NSDictionary dictionaryWithObject:@"action=DEFAULT" | 338 [NSDictionary dictionaryWithObject:@"action=DEFAULT" |
| 337 forKey:@"X-Chrome-Manage-Accounts"]; | 339 forKey:@"X-Chrome-Manage-Accounts"]; |
| 338 base::scoped_nsobject<NSHTTPURLResponse> response([[NSHTTPURLResponse alloc] | 340 NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc] |
| 339 initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"] | 341 initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"] |
| 340 statusCode:200 | 342 statusCode:200 |
| 341 HTTPVersion:@"HTTP/1.1" | 343 HTTPVersion:@"HTTP/1.1" |
| 342 headerFields:headers]); | 344 headerFields:headers]; |
| 343 account_consistency_service_->SetWebStateHandler(&web_state_, delegate); | 345 account_consistency_service_->SetWebStateHandler(&web_state_, delegate); |
| 344 EXPECT_CALL(account_reconcilor_, OnReceivedManageAccountsResponse( | 346 EXPECT_CALL(account_reconcilor_, OnReceivedManageAccountsResponse( |
| 345 signin::GAIA_SERVICE_TYPE_DEFAULT)) | 347 signin::GAIA_SERVICE_TYPE_DEFAULT)) |
| 346 .Times(1); | 348 .Times(1); |
| 347 EXPECT_FALSE(web_state_.ShouldAllowResponse(response)); | 349 EXPECT_FALSE(web_state_.ShouldAllowResponse(response)); |
| 348 web_state_.WebStateDestroyed(); | 350 web_state_.WebStateDestroyed(); |
| 349 | 351 |
| 350 EXPECT_OCMOCK_VERIFY(delegate); | 352 EXPECT_OCMOCK_VERIFY(delegate); |
| 351 } | 353 } |
| 352 | 354 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 // Tests that main domains are added to the internal map when cookies are set in | 442 // Tests that main domains are added to the internal map when cookies are set in |
| 441 // reaction to signin. | 443 // reaction to signin. |
| 442 TEST_F(AccountConsistencyServiceTest, SigninAddCookieOnMainDomains) { | 444 TEST_F(AccountConsistencyServiceTest, SigninAddCookieOnMainDomains) { |
| 443 AddPageLoadedExpectation(kGoogleUrl, true /* continue_navigation */); | 445 AddPageLoadedExpectation(kGoogleUrl, true /* continue_navigation */); |
| 444 AddPageLoadedExpectation(kYoutubeUrl, true /* continue_navigation */); | 446 AddPageLoadedExpectation(kYoutubeUrl, true /* continue_navigation */); |
| 445 SignIn(); | 447 SignIn(); |
| 446 | 448 |
| 447 CheckDomainHasCookie(kGoogleDomain); | 449 CheckDomainHasCookie(kGoogleDomain); |
| 448 CheckDomainHasCookie(kYoutubeDomain); | 450 CheckDomainHasCookie(kYoutubeDomain); |
| 449 } | 451 } |
| OLD | NEW |