- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / identity / gaia_web_auth_flow_unittest.cc
1 // Copyright (c) 2013 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 "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h"
6
7 #include <vector>
8
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "content/public/test/test_browser_thread.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace extensions {
16
17 class FakeWebAuthFlow : public WebAuthFlow {
18  public:
19   explicit FakeWebAuthFlow(WebAuthFlow::Delegate* delegate)
20       : WebAuthFlow(delegate,
21                     NULL,
22                     GURL(),
23                     WebAuthFlow::INTERACTIVE) {}
24
25   virtual void Start() OVERRIDE {}
26 };
27
28 class TestGaiaWebAuthFlow : public GaiaWebAuthFlow {
29  public:
30   TestGaiaWebAuthFlow(GaiaWebAuthFlow::Delegate* delegate,
31                       const std::string& extension_id,
32                       const OAuth2Info& oauth2_info,
33                       GoogleServiceAuthError::State ubertoken_error_state)
34       : GaiaWebAuthFlow(delegate,
35                         NULL,
36                         "extension_id",
37                         oauth2_info,
38                         "en-us"),
39         ubertoken_error_(ubertoken_error_state) {}
40
41   virtual void Start() OVERRIDE {
42     if (ubertoken_error_.state() == GoogleServiceAuthError::NONE)
43       OnUbertokenSuccess("fake_ubertoken");
44     else
45       OnUbertokenFailure(ubertoken_error_);
46   }
47
48  private:
49   virtual scoped_ptr<WebAuthFlow> CreateWebAuthFlow(GURL url) OVERRIDE {
50     return scoped_ptr<WebAuthFlow>(new FakeWebAuthFlow(this));
51   }
52
53   GoogleServiceAuthError ubertoken_error_;
54 };
55
56 class MockGaiaWebAuthFlowDelegate : public GaiaWebAuthFlow::Delegate {
57  public:
58   MOCK_METHOD3(OnGaiaFlowFailure,
59                void(GaiaWebAuthFlow::Failure failure,
60                     GoogleServiceAuthError service_error,
61                     const std::string& oauth_error));
62   MOCK_METHOD2(OnGaiaFlowCompleted,
63                void(const std::string& access_token,
64                     const std::string& expiration));
65 };
66
67 class IdentityGaiaWebAuthFlowTest : public testing::Test {
68  public:
69   IdentityGaiaWebAuthFlowTest()
70       : ubertoken_error_state_(GoogleServiceAuthError::NONE),
71         fake_ui_thread_(content::BrowserThread::UI, &message_loop_) {}
72
73   virtual void TearDown() {
74     testing::Test::TearDown();
75     base::RunLoop loop;
76     loop.RunUntilIdle();  // Run tasks so FakeWebAuthFlows get deleted.
77   }
78
79   scoped_ptr<TestGaiaWebAuthFlow> CreateTestFlow() {
80     OAuth2Info oauth2_info;
81     oauth2_info.client_id = "fake.client.id";
82     return scoped_ptr<TestGaiaWebAuthFlow>(new TestGaiaWebAuthFlow(
83         &delegate_, "extension_id", oauth2_info, ubertoken_error_state_));
84   }
85
86   std::string GetFinalTitle(const std::string& fragment) {
87     return std::string("Loading id.client.fake:/extension_id#") + fragment;
88   }
89
90   GoogleServiceAuthError GetNoneServiceError() {
91     return GoogleServiceAuthError(GoogleServiceAuthError::NONE);
92   }
93
94   void set_ubertoken_error(
95       GoogleServiceAuthError::State ubertoken_error_state) {
96     ubertoken_error_state_ = ubertoken_error_state;
97   }
98
99  protected:
100   testing::StrictMock<MockGaiaWebAuthFlowDelegate> delegate_;
101   GoogleServiceAuthError::State ubertoken_error_state_;
102   base::MessageLoop message_loop_;
103   content::TestBrowserThread fake_ui_thread_;
104 };
105
106 TEST_F(IdentityGaiaWebAuthFlowTest, OAuthError) {
107   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
108   flow->Start();
109   EXPECT_CALL(delegate_, OnGaiaFlowFailure(
110           GaiaWebAuthFlow::OAUTH_ERROR,
111           GoogleServiceAuthError(GoogleServiceAuthError::NONE),
112           "access_denied"));
113   flow->OnAuthFlowTitleChange(GetFinalTitle("error=access_denied"));
114 }
115
116 TEST_F(IdentityGaiaWebAuthFlowTest, Token) {
117   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
118   flow->Start();
119   EXPECT_CALL(delegate_, OnGaiaFlowCompleted("fake_access_token", ""));
120   flow->OnAuthFlowTitleChange(GetFinalTitle("access_token=fake_access_token"));
121 }
122
123 TEST_F(IdentityGaiaWebAuthFlowTest, TokenAndExpiration) {
124   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
125   flow->Start();
126   EXPECT_CALL(delegate_, OnGaiaFlowCompleted("fake_access_token", "3600"));
127   flow->OnAuthFlowTitleChange(
128       GetFinalTitle("access_token=fake_access_token&expires_in=3600"));
129 }
130
131 TEST_F(IdentityGaiaWebAuthFlowTest, ExtraFragmentParametersSuccess) {
132   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
133   flow->Start();
134   EXPECT_CALL(delegate_,
135               OnGaiaFlowCompleted("fake_access_token", "3600"));
136   flow->OnAuthFlowTitleChange(GetFinalTitle("chaff1=stuff&"
137                                             "expires_in=3600&"
138                                             "chaff2=and&"
139                                             "nonerror=fake_error&"
140                                             "chaff3=nonsense&"
141                                             "access_token=fake_access_token&"
142                                             "chaff4="));
143 }
144
145 TEST_F(IdentityGaiaWebAuthFlowTest, ExtraFragmentParametersError) {
146   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
147   flow->Start();
148   EXPECT_CALL(delegate_, OnGaiaFlowFailure(
149           GaiaWebAuthFlow::OAUTH_ERROR,
150           GoogleServiceAuthError(GoogleServiceAuthError::NONE),
151           "fake_error"));
152   flow->OnAuthFlowTitleChange(GetFinalTitle("chaff1=stuff&"
153                                             "expires_in=3600&"
154                                             "chaff2=and&"
155                                             "error=fake_error&"
156                                             "chaff3=nonsense&"
157                                             "access_token=fake_access_token&"
158                                             "chaff4="));
159 }
160
161 TEST_F(IdentityGaiaWebAuthFlowTest, TitleSpam) {
162   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
163   flow->Start();
164   flow->OnAuthFlowTitleChange(
165       "Loading https://extension_id.chromiumapp.org/#error=non_final_title");
166   flow->OnAuthFlowTitleChange("I'm feeling entitled.");
167   flow->OnAuthFlowTitleChange("");
168   flow->OnAuthFlowTitleChange(
169       "Loading id.client.fake:/bad_extension_id#error=non_final_title");
170   flow->OnAuthFlowTitleChange(
171       "Loading bad.id.client.fake:/extension_id#error=non_final_title");
172   EXPECT_CALL(delegate_, OnGaiaFlowCompleted("fake_access_token", ""));
173   flow->OnAuthFlowTitleChange(GetFinalTitle("access_token=fake_access_token"));
174 }
175
176 TEST_F(IdentityGaiaWebAuthFlowTest, EmptyFragment) {
177   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
178   flow->Start();
179   EXPECT_CALL(
180       delegate_,
181       OnGaiaFlowFailure(
182           GaiaWebAuthFlow::INVALID_REDIRECT,
183           GoogleServiceAuthError(GoogleServiceAuthError::NONE),
184           ""));
185   flow->OnAuthFlowTitleChange(GetFinalTitle(""));
186 }
187
188 TEST_F(IdentityGaiaWebAuthFlowTest, JunkFragment) {
189   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
190   flow->Start();
191   EXPECT_CALL(
192       delegate_,
193       OnGaiaFlowFailure(
194           GaiaWebAuthFlow::INVALID_REDIRECT,
195           GoogleServiceAuthError(GoogleServiceAuthError::NONE),
196           ""));
197   flow->OnAuthFlowTitleChange(GetFinalTitle("thisisjustabunchofjunk"));
198 }
199
200 TEST_F(IdentityGaiaWebAuthFlowTest, NoFragment) {
201   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
202   flow->Start();
203   // This won't be recognized as an interesting title.
204   flow->OnAuthFlowTitleChange("Loading id.client.fake:/extension_id");
205 }
206
207 TEST_F(IdentityGaiaWebAuthFlowTest, Host) {
208   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
209   flow->Start();
210   // These won't be recognized as interesting titles.
211   flow->OnAuthFlowTitleChange(
212       "Loading id.client.fake://extension_id#access_token=fake_access_token");
213   flow->OnAuthFlowTitleChange(
214       "Loading id.client.fake://extension_id/#access_token=fake_access_token");
215   flow->OnAuthFlowTitleChange(
216       "Loading "
217       "id.client.fake://host/extension_id/#access_token=fake_access_token");
218 }
219
220 TEST_F(IdentityGaiaWebAuthFlowTest, UbertokenFailure) {
221   set_ubertoken_error(GoogleServiceAuthError::CONNECTION_FAILED);
222   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
223   EXPECT_CALL(
224       delegate_,
225       OnGaiaFlowFailure(
226           GaiaWebAuthFlow::SERVICE_AUTH_ERROR,
227           GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED),
228           ""));
229   flow->Start();
230 }
231
232 TEST_F(IdentityGaiaWebAuthFlowTest, AuthFlowFailure) {
233   scoped_ptr<TestGaiaWebAuthFlow> flow = CreateTestFlow();
234   flow->Start();
235   EXPECT_CALL(
236       delegate_,
237       OnGaiaFlowFailure(
238           GaiaWebAuthFlow::WINDOW_CLOSED,
239           GoogleServiceAuthError(GoogleServiceAuthError::NONE),
240           ""));
241   flow->OnAuthFlowFailure(WebAuthFlow::WINDOW_CLOSED);
242 }
243
244 }  // namespace extensions