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
3 // found in the LICENSE file.
5 #include "ios/chrome/browser/signin/gaia_auth_fetcher_ios.h"
7 #import "base/mac/scoped_nsobject.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/run_loop.h"
10 #include "google_apis/gaia/gaia_urls.h"
11 #include "ios/chrome/browser/experimental_flags.h"
12 #include "ios/chrome/browser/signin/gaia_auth_fetcher_ios_private.h"
13 #include "ios/web/public/test/test_browser_state.h"
14 #include "ios/web/public/test/test_web_thread_bundle.h"
15 #include "ios/web/public/test/web_test_util.h"
16 #include "net/url_request/test_url_fetcher_factory.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #import "testing/gtest_mac.h"
20 #include "testing/platform_test.h"
21 #import "third_party/ocmock/OCMock/OCMock.h"
22 #import "third_party/ocmock/gtest_support.h"
26 class FakeGaiaAuthFetcherIOSBridge : public GaiaAuthFetcherIOSBridge {
28 FakeGaiaAuthFetcherIOSBridge(GaiaAuthFetcherIOS* fetcher,
29 web::BrowserState* browser_state)
30 : GaiaAuthFetcherIOSBridge(fetcher, browser_state), mock_web_view_(nil) {}
33 WKWebView* CreateWKWebView() override {
34 if (!mock_web_view_) {
35 mock_web_view_ = [OCMockObject niceMockForClass:[WKWebView class]];
37 return [mock_web_view_ retain];
42 class MockGaiaConsumer : public GaiaAuthConsumer {
45 ~MockGaiaConsumer() {}
47 MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data));
48 MOCK_METHOD1(OnClientLoginFailure, void(const GoogleServiceAuthError& error));
49 MOCK_METHOD1(OnLogOutFailure, void(const GoogleServiceAuthError& error));
50 MOCK_METHOD1(OnGetCheckConnectionInfoSuccess, void(const std::string& data));
54 // Tests fixture for GaiaAuthFetcherIOS
55 class GaiaAuthFetcherIOSTest : public PlatformTest {
57 void SetUp() override {
58 PlatformTest::SetUp();
59 web::BrowserState::GetActiveStateManager(&browser_state_)->SetActive(true);
60 gaia_auth_fetcher_.reset(new GaiaAuthFetcherIOS(&consumer_, std::string(),
61 nullptr, &browser_state_));
62 gaia_auth_fetcher_->bridge_.reset(new FakeGaiaAuthFetcherIOSBridge(
63 gaia_auth_fetcher_.get(), &browser_state_));
66 void TearDown() override {
67 gaia_auth_fetcher_.reset();
68 web::BrowserState::GetActiveStateManager(&browser_state_)->SetActive(false);
69 PlatformTest::TearDown();
72 GaiaAuthFetcherIOSBridge* GetBridge() {
73 return gaia_auth_fetcher_->bridge_.get();
76 id GetMockWKWebView() { return gaia_auth_fetcher_->bridge_->GetWKWebView(); }
78 web::TestWebThreadBundle thread_bundle_;
79 // BrowserState, required for WKWebView creation.
80 web::TestBrowserState browser_state_;
81 MockGaiaConsumer consumer_;
82 scoped_ptr<GaiaAuthFetcherIOS> gaia_auth_fetcher_;
85 // Tests that the cancel mechanism works properly by cancelling an OAuthLogin
86 // request and controlling that the consumer is properly called.
87 TEST_F(GaiaAuthFetcherIOSTest, StartOAuthLoginCancelled) {
88 if (!experimental_flags::IsWKWebViewEnabled()) {
92 GoogleServiceAuthError expected_error =
93 GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
94 EXPECT_CALL(consumer_, OnClientLoginFailure(expected_error)).Times(1);
96 [static_cast<WKWebView*>([GetMockWKWebView() expect])
97 loadHTMLString:[OCMArg any]
98 baseURL:[OCMArg any]];
99 [[GetMockWKWebView() expect] stopLoading];
101 gaia_auth_fetcher_->StartOAuthLogin("fake_token", "gaia");
102 gaia_auth_fetcher_->CancelRequest();
103 EXPECT_OCMOCK_VERIFY(GetMockWKWebView());
106 // Tests that the successful case works properly by starting a MergeSession
107 // request, making it succeed and controlling that the consumer is properly
109 TEST_F(GaiaAuthFetcherIOSTest, StartMergeSession) {
110 if (!experimental_flags::IsWKWebViewEnabled()) {
114 EXPECT_CALL(consumer_, OnMergeSessionSuccess("data")).Times(1);
116 [static_cast<WKWebView*>([[GetMockWKWebView() expect] andDo:^(NSInvocation*) {
117 GetBridge()->URLFetchSuccess("data");
118 }]) loadHTMLString:[OCMArg any]
119 baseURL:[OCMArg any]];
121 gaia_auth_fetcher_->StartMergeSession("uber_token", "");
122 EXPECT_OCMOCK_VERIFY(GetMockWKWebView());
125 // Tests that the failure case works properly by starting a LogOut request,
126 // making it fail, and controlling that the consumer is properly called.
127 TEST_F(GaiaAuthFetcherIOSTest, StartLogOutError) {
128 if (!experimental_flags::IsWKWebViewEnabled()) {
132 GoogleServiceAuthError expected_error =
133 GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED);
134 EXPECT_CALL(consumer_, OnLogOutFailure(expected_error)).Times(1);
136 [static_cast<WKWebView*>([[GetMockWKWebView() expect] andDo:^(NSInvocation*) {
137 GetBridge()->URLFetchFailure(false);
138 }]) loadRequest:[OCMArg any]];
140 gaia_auth_fetcher_->StartLogOut();
141 EXPECT_OCMOCK_VERIFY(GetMockWKWebView());
144 // Tests that requests that do not require cookies are using the original
145 // GaiaAuthFetcher and not the GaiaAuthFetcherIOS specialization.
146 TEST_F(GaiaAuthFetcherIOSTest, StartGetCheckConnectionInfo) {
148 "[{\"carryBackToken\": \"token1\", \"url\": \"http://www.google.com\"}]");
149 EXPECT_CALL(consumer_, OnGetCheckConnectionInfoSuccess(data)).Times(1);
151 // Set up the fake URL Fetcher.
152 scoped_ptr<net::FakeURLFetcherFactory> fake_url_fetcher_factory(
153 new net::FakeURLFetcherFactory(new net::URLFetcherImplFactory()));
154 fake_url_fetcher_factory->SetFakeResponse(
155 GaiaUrls::GetInstance()->GetCheckConnectionInfoURLWithSource(
157 data, net::HTTP_OK, net::URLRequestStatus::SUCCESS);
159 gaia_auth_fetcher_->StartGetCheckConnectionInfo();
160 base::RunLoop().RunUntilIdle();
163 // Tests whether the WKWebView is actually stopped when the browser state is
165 TEST_F(GaiaAuthFetcherIOSTest, OnInactive) {
166 CR_TEST_REQUIRES_WK_WEB_VIEW();
167 [[GetMockWKWebView() expect] stopLoading];
168 web::BrowserState::GetActiveStateManager(&browser_state_)->SetActive(false);
169 EXPECT_OCMOCK_VERIFY(GetMockWKWebView());
172 // Tests that the pending request is processed when the browser state becomes
174 TEST_F(GaiaAuthFetcherIOSTest, FetchOnActive) {
175 if (!experimental_flags::IsWKWebViewEnabled()) {
179 EXPECT_CALL(consumer_, OnMergeSessionSuccess("data")).Times(1);
181 // No action is made until the browser state is active, then a WKWebView and
182 // its navigation delegate are created, and the request is processed.
183 [[GetMockWKWebView() expect] setNavigationDelegate:[OCMArg isNotNil]];
184 [static_cast<WKWebView*>([[GetMockWKWebView() expect] andDo:^(NSInvocation*) {
185 GetBridge()->URLFetchSuccess("data");
186 }]) loadHTMLString:[OCMArg any]
187 baseURL:[OCMArg any]];
189 web::BrowserState::GetActiveStateManager(&browser_state_)->SetActive(false);
190 gaia_auth_fetcher_->StartMergeSession("uber_token", "");
191 web::BrowserState::GetActiveStateManager(&browser_state_)->SetActive(true);
192 EXPECT_OCMOCK_VERIFY(GetMockWKWebView());
195 // Tests that the pending request is stopped when the browser state becomes
196 // inactive and restarted when it becomes active again.
197 TEST_F(GaiaAuthFetcherIOSTest, StopOnInactiveReFetchOnActive) {
198 if (!experimental_flags::IsWKWebViewEnabled()) {
202 EXPECT_CALL(consumer_, OnMergeSessionSuccess("data")).Times(1);
204 [static_cast<WKWebView*>([GetMockWKWebView() expect])
205 loadHTMLString:[OCMArg any]
206 baseURL:[OCMArg any]];
207 [[GetMockWKWebView() expect] setNavigationDelegate:[OCMArg isNil]];
208 [[GetMockWKWebView() expect] setNavigationDelegate:[OCMArg isNotNil]];
209 [static_cast<WKWebView*>([[GetMockWKWebView() expect] andDo:^(NSInvocation*) {
210 GetBridge()->URLFetchSuccess("data");
211 }]) loadHTMLString:[OCMArg any]
212 baseURL:[OCMArg any]];
214 gaia_auth_fetcher_->StartMergeSession("uber_token", "");
215 web::BrowserState::GetActiveStateManager(&browser_state_)->SetActive(false);
216 web::BrowserState::GetActiveStateManager(&browser_state_)->SetActive(true);
217 EXPECT_OCMOCK_VERIFY(GetMockWKWebView());