Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / google_apis / drive / request_sender_unittest.cc
1 // Copyright 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 "google_apis/drive/request_sender.h"
6
7 #include "base/sequenced_task_runner.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "google_apis/drive/base_requests.h"
10 #include "google_apis/drive/dummy_auth_service.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace google_apis {
14
15 namespace {
16
17 const char kTestRefreshToken[] = "valid-refresh-token";
18 const char kTestAccessToken[] = "valid-access-token";
19
20 // Enum for indicating the reason why a request is finished.
21 enum FinishReason {
22   NONE,
23   SUCCESS,
24   CANCEL,
25   AUTH_FAILURE,
26 };
27
28 // AuthService for testing purpose. It accepts kTestRefreshToken and returns
29 // kTestAccessToken + {"1", "2", "3", ...}.
30 class TestAuthService : public DummyAuthService {
31  public:
32   TestAuthService() : auth_try_count_(0) {}
33
34   virtual void StartAuthentication(
35       const AuthStatusCallback& callback) OVERRIDE {
36     // RequestSender should clear the rejected access token before starting
37     // to request another one.
38     EXPECT_FALSE(HasAccessToken());
39
40     ++auth_try_count_;
41
42     if (refresh_token() == kTestRefreshToken) {
43       const std::string token =
44           kTestAccessToken + base::IntToString(auth_try_count_);
45       set_access_token(token);
46       callback.Run(HTTP_SUCCESS, token);
47     } else {
48       set_access_token("");
49       callback.Run(HTTP_UNAUTHORIZED, "");
50     }
51   }
52
53  private:
54   int auth_try_count_;
55 };
56
57 // The main test fixture class.
58 class RequestSenderTest : public testing::Test {
59  protected:
60   RequestSenderTest()
61      : auth_service_(new TestAuthService),
62        request_sender_(auth_service_, NULL, NULL, "dummy-user-agent") {
63     auth_service_->set_refresh_token(kTestRefreshToken);
64     auth_service_->set_access_token(kTestAccessToken);
65   }
66
67   TestAuthService* auth_service_;  // Owned by |request_sender_|.
68   RequestSender request_sender_;
69 };
70
71 // Minimal implementation for AuthenticatedRequestInterface that can interact
72 // with RequestSender correctly.
73 class TestRequest : public AuthenticatedRequestInterface {
74  public:
75   TestRequest(RequestSender* sender,
76               bool* start_called,
77               FinishReason* finish_reason)
78       : sender_(sender),
79         start_called_(start_called),
80         finish_reason_(finish_reason),
81         weak_ptr_factory_(this) {
82   }
83
84   // Test the situation that the request has finished.
85   void FinishRequestWithSuccess() {
86     *finish_reason_ = SUCCESS;
87     sender_->RequestFinished(this);
88   }
89
90   const std::string& passed_access_token() const {
91     return passed_access_token_;
92   }
93
94   const ReAuthenticateCallback& passed_reauth_callback() const {
95     return passed_reauth_callback_;
96   }
97
98   virtual void Start(const std::string& access_token,
99                      const std::string& custom_user_agent,
100                      const ReAuthenticateCallback& callback) OVERRIDE {
101     *start_called_ = true;
102     passed_access_token_ = access_token;
103     passed_reauth_callback_ = callback;
104
105     // This request class itself does not return any response at this point.
106     // Each test case should respond properly by using the above methods.
107   }
108
109   virtual void Cancel() OVERRIDE {
110     EXPECT_TRUE(*start_called_);
111     *finish_reason_ = CANCEL;
112     sender_->RequestFinished(this);
113   }
114
115   virtual void OnAuthFailed(GDataErrorCode code) OVERRIDE {
116     *finish_reason_ = AUTH_FAILURE;
117     sender_->RequestFinished(this);
118   }
119
120   virtual base::WeakPtr<AuthenticatedRequestInterface> GetWeakPtr() OVERRIDE {
121     return weak_ptr_factory_.GetWeakPtr();
122   }
123
124  private:
125   RequestSender* sender_;
126   bool* start_called_;
127   FinishReason* finish_reason_;
128   std::string passed_access_token_;
129   ReAuthenticateCallback passed_reauth_callback_;
130   base::WeakPtrFactory<TestRequest> weak_ptr_factory_;
131 };
132
133 }  // namespace
134
135 TEST_F(RequestSenderTest, StartAndFinishRequest) {
136   bool start_called  = false;
137   FinishReason finish_reason = NONE;
138   TestRequest* request = new TestRequest(&request_sender_,
139                                          &start_called,
140                                          &finish_reason);
141   base::WeakPtr<AuthenticatedRequestInterface> weak_ptr = request->GetWeakPtr();
142
143   base::Closure cancel_closure = request_sender_.StartRequestWithRetry(request);
144   EXPECT_TRUE(!cancel_closure.is_null());
145
146   // Start is called with the specified access token. Let it succeed.
147   EXPECT_TRUE(start_called);
148   EXPECT_EQ(kTestAccessToken, request->passed_access_token());
149   request->FinishRequestWithSuccess();
150   EXPECT_FALSE(weak_ptr);  // The request object is deleted.
151
152   // It is safe to run the cancel closure even after the request is finished.
153   // It is just no-op. The TestRequest::Cancel method is not called.
154   cancel_closure.Run();
155   EXPECT_EQ(SUCCESS, finish_reason);
156 }
157
158 TEST_F(RequestSenderTest, StartAndCancelRequest) {
159   bool start_called  = false;
160   FinishReason finish_reason = NONE;
161   TestRequest* request = new TestRequest(&request_sender_,
162                                          &start_called,
163                                          &finish_reason);
164   base::WeakPtr<AuthenticatedRequestInterface> weak_ptr = request->GetWeakPtr();
165
166   base::Closure cancel_closure = request_sender_.StartRequestWithRetry(request);
167   EXPECT_TRUE(!cancel_closure.is_null());
168   EXPECT_TRUE(start_called);
169
170   cancel_closure.Run();
171   EXPECT_EQ(CANCEL, finish_reason);
172   EXPECT_FALSE(weak_ptr);  // The request object is deleted.
173 }
174
175 TEST_F(RequestSenderTest, NoRefreshToken) {
176   auth_service_->ClearRefreshToken();
177   auth_service_->ClearAccessToken();
178
179   bool start_called  = false;
180   FinishReason finish_reason = NONE;
181   TestRequest* request = new TestRequest(&request_sender_,
182                                          &start_called,
183                                          &finish_reason);
184   base::WeakPtr<AuthenticatedRequestInterface> weak_ptr = request->GetWeakPtr();
185
186   base::Closure cancel_closure = request_sender_.StartRequestWithRetry(request);
187   EXPECT_TRUE(!cancel_closure.is_null());
188
189   // The request is not started at all because no access token is obtained.
190   EXPECT_FALSE(start_called);
191   EXPECT_EQ(AUTH_FAILURE, finish_reason);
192   EXPECT_FALSE(weak_ptr);  // The request object is deleted.
193 }
194
195 TEST_F(RequestSenderTest, ValidRefreshTokenAndNoAccessToken) {
196   auth_service_->ClearAccessToken();
197
198   bool start_called  = false;
199   FinishReason finish_reason = NONE;
200   TestRequest* request = new TestRequest(&request_sender_,
201                                          &start_called,
202                                          &finish_reason);
203   base::WeakPtr<AuthenticatedRequestInterface> weak_ptr = request->GetWeakPtr();
204
205   base::Closure cancel_closure = request_sender_.StartRequestWithRetry(request);
206   EXPECT_TRUE(!cancel_closure.is_null());
207
208   // Access token should indicate that this is the first retry.
209   EXPECT_TRUE(start_called);
210   EXPECT_EQ(kTestAccessToken + std::string("1"),
211             request->passed_access_token());
212   request->FinishRequestWithSuccess();
213   EXPECT_EQ(SUCCESS, finish_reason);
214   EXPECT_FALSE(weak_ptr);  // The request object is deleted.
215 }
216
217 TEST_F(RequestSenderTest, AccessTokenRejectedSeveralTimes) {
218   bool start_called  = false;
219   FinishReason finish_reason = NONE;
220   TestRequest* request = new TestRequest(&request_sender_,
221                                          &start_called,
222                                          &finish_reason);
223   base::WeakPtr<AuthenticatedRequestInterface> weak_ptr = request->GetWeakPtr();
224
225   base::Closure cancel_closure = request_sender_.StartRequestWithRetry(request);
226   EXPECT_TRUE(!cancel_closure.is_null());
227
228   EXPECT_TRUE(start_called);
229   EXPECT_EQ(kTestAccessToken, request->passed_access_token());
230   // Emulate the case that the access token was rejected by the remote service.
231   request->passed_reauth_callback().Run(request);
232   // New access token is fetched. Let it fail once again.
233   EXPECT_EQ(kTestAccessToken + std::string("1"),
234             request->passed_access_token());
235   request->passed_reauth_callback().Run(request);
236   // Once more.
237   EXPECT_EQ(kTestAccessToken + std::string("2"),
238             request->passed_access_token());
239   request->passed_reauth_callback().Run(request);
240
241   // Currently, limit for the retry is controlled in each request object, not
242   // by the RequestSender. So with this TestRequest, RequestSender retries
243   // infinitely. Let it succeed/
244   EXPECT_EQ(kTestAccessToken + std::string("3"),
245             request->passed_access_token());
246   request->FinishRequestWithSuccess();
247   EXPECT_EQ(SUCCESS, finish_reason);
248   EXPECT_FALSE(weak_ptr);
249 }
250
251 }  // namespace google_apis