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/message_loop/message_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/web_test_util.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"
19 #import "testing/gtest_mac.h"
20 #include "testing/platform_test.h"
21 #import "third_party/ocmock/OCMock/OCMock.h"
22 #include "third_party/ocmock/gtest_support.h"
24 class MockGaiaConsumer : public GaiaAuthConsumer {
27 ~MockGaiaConsumer() {}
29 MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data));
30 MOCK_METHOD1(OnClientLoginFailure, void(const GoogleServiceAuthError& error));
31 MOCK_METHOD1(OnLogOutFailure, void(const GoogleServiceAuthError& error));
32 MOCK_METHOD1(OnGetCheckConnectionInfoSuccess, void(const std::string& data));
35 // Tests fixture for GaiaAuthFetcherIOS
36 class GaiaAuthFetcherIOSTest : public PlatformTest {
38 void SetUp() override {
39 CR_TEST_REQUIRES_WK_WEB_VIEW();
41 [[OCMockObject niceMockForClass:[WKWebView class]] retain]);
44 GaiaAuthFetcherIOSBridge* GetBridge(GaiaAuthFetcherIOS* gaia_auth_fetcher) {
45 return gaia_auth_fetcher->bridge_.get();
48 GaiaAuthFetcherIOS* GetGaiaAuthFetcher(GaiaAuthConsumer* consumer,
50 GaiaAuthFetcherIOS* gaia_auth_fetcher = new GaiaAuthFetcherIOS(
51 consumer, std::string(), GetRequestContext(), &browser_state_);
53 gaia_auth_fetcher->bridge_.reset(
54 new GaiaAuthFetcherIOSBridge(gaia_auth_fetcher, &browser_state_));
55 gaia_auth_fetcher->bridge_->web_view_.reset([mock_web_view_ retain]);
56 [gaia_auth_fetcher->bridge_->web_view_
57 setNavigationDelegate:gaia_auth_fetcher->bridge_
58 ->navigation_delegate_];
60 return gaia_auth_fetcher;
63 net::TestURLRequestContextGetter* GetRequestContext() {
64 if (!request_context_getter_.get()) {
65 request_context_getter_ =
66 new net::TestURLRequestContextGetter(message_loop_.task_runner());
68 return request_context_getter_.get();
71 // BrowserState, required for WKWebView creation.
72 web::TestBrowserState browser_state_;
73 base::MessageLoop message_loop_;
74 base::scoped_nsobject<id> mock_web_view_;
75 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
78 // Tests that the cancel mechanism works properly by cancelling an OAuthLogin
79 // request and controlling that the consumer is properly called.
80 TEST_F(GaiaAuthFetcherIOSTest, StartOAuthLoginCancelled) {
81 if (!experimental_flags::IsWKWebViewEnabled()) {
85 GoogleServiceAuthError expected_error =
86 GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
87 MockGaiaConsumer consumer;
88 EXPECT_CALL(consumer, OnClientLoginFailure(expected_error)).Times(1);
90 scoped_ptr<GaiaAuthFetcherIOS> gaia_auth_fetcher(
91 GetGaiaAuthFetcher(&consumer, true));
92 [static_cast<WKWebView*>([mock_web_view_ expect]) loadRequest:[OCMArg any]];
94 gaia_auth_fetcher->StartOAuthLogin("fake_token", "gaia");
95 gaia_auth_fetcher->CancelRequest();
96 EXPECT_OCMOCK_VERIFY(mock_web_view_);
99 // Tests that the successful case works properly by starting a MergeSession
100 // request, making it succeed and controlling that the consumer is properly
102 TEST_F(GaiaAuthFetcherIOSTest, StartMergeSession) {
103 if (!experimental_flags::IsWKWebViewEnabled()) {
107 MockGaiaConsumer consumer;
108 EXPECT_CALL(consumer, OnMergeSessionSuccess("data")).Times(1);
110 scoped_ptr<GaiaAuthFetcherIOS> gaia_auth_fetcher(
111 GetGaiaAuthFetcher(&consumer, true));
112 GaiaAuthFetcherIOSBridge* bridge = GetBridge(gaia_auth_fetcher.get());
113 [static_cast<WKWebView*>([[mock_web_view_ expect] andDo:^(NSInvocation*) {
114 bridge->URLFetchSuccess("data");
115 }]) loadRequest:[OCMArg any]];
117 gaia_auth_fetcher->StartMergeSession("uber_token", "");
118 EXPECT_OCMOCK_VERIFY(mock_web_view_);
121 // Tests that the failure case works properly by starting a LogOut request,
122 // making it fail, and controlling that the consumer is properly called.
123 TEST_F(GaiaAuthFetcherIOSTest, StartLogOutError) {
124 if (!experimental_flags::IsWKWebViewEnabled()) {
128 GoogleServiceAuthError expected_error =
129 GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED);
130 MockGaiaConsumer consumer;
131 EXPECT_CALL(consumer, OnLogOutFailure(expected_error)).Times(1);
133 scoped_ptr<GaiaAuthFetcherIOS> gaia_auth_fetcher(
134 GetGaiaAuthFetcher(&consumer, true));
135 GaiaAuthFetcherIOSBridge* bridge = GetBridge(gaia_auth_fetcher.get());
136 [static_cast<WKWebView*>([[mock_web_view_ expect] andDo:^(NSInvocation*) {
137 bridge->URLFetchFailure(false);
138 }]) loadRequest:[OCMArg any]];
140 gaia_auth_fetcher->StartLogOut();
141 EXPECT_OCMOCK_VERIFY(mock_web_view_);
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 MockGaiaConsumer consumer;
150 EXPECT_CALL(consumer, OnGetCheckConnectionInfoSuccess(data)).Times(1);
152 // Set up the fake URL Fetcher.
153 scoped_ptr<net::FakeURLFetcherFactory> fake_url_fetcher_factory(
154 new net::FakeURLFetcherFactory(new net::URLFetcherImplFactory()));
155 fake_url_fetcher_factory->SetFakeResponse(
156 GaiaUrls::GetInstance()->GetCheckConnectionInfoURLWithSource(
158 data, net::HTTP_OK, net::URLRequestStatus::SUCCESS);
160 scoped_ptr<GaiaAuthFetcherIOS> gaia_auth_fetcher(
161 GetGaiaAuthFetcher(&consumer, false));
162 gaia_auth_fetcher->StartGetCheckConnectionInfo();
163 message_loop_.RunUntilIdle();