Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: sync/internal_api/attachments/attachment_uploader_impl_unittest.cc

Issue 304253010: Add authentication support to AttachmentUploaderImpl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Apply CR feedback from pavely Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "sync/internal_api/public/attachments/attachment_uploader_impl.h" 5 #include "sync/internal_api/public/attachments/attachment_uploader_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/memory/ref_counted.h" 9 #include "base/memory/ref_counted.h"
10 #include "base/memory/ref_counted_memory.h" 10 #include "base/memory/ref_counted_memory.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/synchronization/lock.h"
15 #include "base/thread_task_runner_handle.h"
14 #include "base/threading/non_thread_safe.h" 16 #include "base/threading/non_thread_safe.h"
15 #include "base/threading/thread.h" 17 #include "base/threading/thread.h"
18 #include "google_apis/gaia/fake_oauth2_token_service.h"
19 #include "google_apis/gaia/gaia_constants.h"
20 #include "google_apis/gaia/oauth2_token_service_request.h"
16 #include "net/test/embedded_test_server/embedded_test_server.h" 21 #include "net/test/embedded_test_server/embedded_test_server.h"
17 #include "net/test/embedded_test_server/http_request.h" 22 #include "net/test/embedded_test_server/http_request.h"
18 #include "net/test/embedded_test_server/http_response.h" 23 #include "net/test/embedded_test_server/http_response.h"
19 #include "net/url_request/url_request_test_util.h" 24 #include "net/url_request/url_request_test_util.h"
20 #include "sync/api/attachments/attachment.h" 25 #include "sync/api/attachments/attachment.h"
21 #include "sync/protocol/sync.pb.h" 26 #include "sync/protocol/sync.pb.h"
27 #include "testing/gmock/include/gmock/gmock-matchers.h"
22 #include "testing/gtest/include/gtest/gtest.h" 28 #include "testing/gtest/include/gtest/gtest.h"
23 29
24 namespace { 30 namespace {
25 31
26 const char kAttachmentData[] = "some data"; 32 const char kAttachmentData[] = "some data";
33 const char kAccountId[] = "some-account-id";
34 const char kAccessToken[] = "some-access-token";
35 const char kAuthorization[] = "Authorization";
27 36
28 } // namespace 37 } // namespace
29 38
30 namespace syncer { 39 namespace syncer {
31 40
32 using net::test_server::BasicHttpResponse; 41 using net::test_server::BasicHttpResponse;
33 using net::test_server::HttpRequest; 42 using net::test_server::HttpRequest;
34 using net::test_server::HttpResponse; 43 using net::test_server::HttpResponse;
35 44
36 class RequestHandler; 45 class RequestHandler;
37 46
47 // A mock implementation of an OAuth2TokenService.
48 //
49 // Use |SetResponse| to vary the response to token requests.
50 //
51 // Use |num_invalidate_token| and |last_token_invalidated| to check the number
52 // of invalidate token operations performed and the last token invalidated.
53 class MockOAuth2TokenService : public FakeOAuth2TokenService {
54 public:
55 MockOAuth2TokenService();
56 virtual ~MockOAuth2TokenService();
57
58 void SetResponse(const GoogleServiceAuthError& error,
59 const std::string& access_token,
60 const base::Time& expiration);
61
62 int num_invalidate_token() const { return num_invalidate_token_; }
63
64 const std::string& last_token_invalidated() const {
65 return last_token_invalidated_;
66 }
67
68 protected:
69 virtual void FetchOAuth2Token(RequestImpl* request,
70 const std::string& account_id,
71 net::URLRequestContextGetter* getter,
72 const std::string& client_id,
73 const std::string& client_secret,
74 const ScopeSet& scopes) OVERRIDE;
75
76 virtual void InvalidateOAuth2Token(const std::string& account_id,
77 const std::string& client_id,
78 const ScopeSet& scopes,
79 const std::string& access_token) OVERRIDE;
80
81 private:
82 GoogleServiceAuthError response_error_;
83 std::string response_access_token_;
84 base::Time response_expiration_;
85 int num_invalidate_token_;
86 std::string last_token_invalidated_;
87 };
88
89 MockOAuth2TokenService::MockOAuth2TokenService()
90 : response_error_(GoogleServiceAuthError::AuthErrorNone()),
91 response_access_token_(kAccessToken),
92 response_expiration_(base::Time::Max()),
93 num_invalidate_token_(0) {
94 }
95
96 MockOAuth2TokenService::~MockOAuth2TokenService() {
97 }
98
99 void MockOAuth2TokenService::SetResponse(const GoogleServiceAuthError& error,
100 const std::string& access_token,
101 const base::Time& expiration) {
102 response_error_ = error;
103 response_access_token_ = access_token;
104 response_expiration_ = expiration;
105 }
106
107 void MockOAuth2TokenService::FetchOAuth2Token(
108 RequestImpl* request,
109 const std::string& account_id,
110 net::URLRequestContextGetter* getter,
111 const std::string& client_id,
112 const std::string& client_secret,
113 const ScopeSet& scopes) {
114 base::MessageLoop::current()->PostTask(
115 FROM_HERE,
116 base::Bind(&OAuth2TokenService::RequestImpl::InformConsumer,
117 request->AsWeakPtr(),
118 response_error_,
119 response_access_token_,
120 response_expiration_));
121 }
122
123 void MockOAuth2TokenService::InvalidateOAuth2Token(
124 const std::string& account_id,
125 const std::string& client_id,
126 const ScopeSet& scopes,
127 const std::string& access_token) {
128 ++num_invalidate_token_;
129 last_token_invalidated_ = access_token;
130 }
131
132 class TokenServiceProvider
133 : public OAuth2TokenServiceRequest::TokenServiceProvider,
134 base::NonThreadSafe {
135 public:
136 TokenServiceProvider(OAuth2TokenService* token_service);
137 virtual ~TokenServiceProvider();
138
139 // OAuth2TokenService::TokenServiceProvider implementation.
140 virtual scoped_refptr<base::SingleThreadTaskRunner>
141 GetTokenServiceTaskRunner() OVERRIDE;
142 virtual OAuth2TokenService* GetTokenService() OVERRIDE;
143
144 private:
145 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
146 OAuth2TokenService* token_service_;
147 };
148
149 TokenServiceProvider::TokenServiceProvider(OAuth2TokenService* token_service)
150 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
151 token_service_(token_service) {
152 DCHECK(token_service_);
153 }
154
155 TokenServiceProvider::~TokenServiceProvider() {
156 }
157
158 scoped_refptr<base::SingleThreadTaskRunner>
159 TokenServiceProvider::GetTokenServiceTaskRunner() {
160 return task_runner_;
161 }
162
163 OAuth2TokenService* TokenServiceProvider::GetTokenService() {
164 DCHECK(task_runner_->BelongsToCurrentThread());
165 return token_service_;
166 }
167
38 // Text fixture for AttachmentUploaderImpl test. 168 // Text fixture for AttachmentUploaderImpl test.
39 // 169 //
40 // This fixture provides an embedded HTTP server for interacting with 170 // This fixture provides an embedded HTTP server and a mock OAuth2 token service
41 // AttachmentUploaderImpl. 171 // for interacting with AttachmentUploaderImpl
42 class AttachmentUploaderImplTest : public testing::Test, 172 class AttachmentUploaderImplTest : public testing::Test,
43 public base::NonThreadSafe { 173 public base::NonThreadSafe {
44 public: 174 public:
45 void OnRequestReceived(const HttpRequest& request); 175 void OnRequestReceived(const HttpRequest& request);
46 176
47 protected: 177 protected:
48 AttachmentUploaderImplTest(); 178 AttachmentUploaderImplTest();
49 virtual void SetUp(); 179 virtual void SetUp();
50 180
51 // Run the message loop until UploadDone has been invoked |num_uploads| times. 181 // Run the message loop until UploadDone has been invoked |num_uploads| times.
52 void RunAndWaitFor(int num_uploads); 182 void RunAndWaitFor(int num_uploads);
53 183
54 scoped_ptr<AttachmentUploader>& uploader(); 184 scoped_ptr<AttachmentUploader>& uploader();
55 const AttachmentUploader::UploadCallback& upload_callback() const; 185 const AttachmentUploader::UploadCallback& upload_callback() const;
56 std::vector<HttpRequest>& http_requests_received(); 186 std::vector<HttpRequest>& http_requests_received();
57 std::vector<AttachmentUploader::UploadResult>& upload_results(); 187 std::vector<AttachmentUploader::UploadResult>& upload_results();
58 std::vector<AttachmentId>& updated_attachment_ids(); 188 std::vector<AttachmentId>& updated_attachment_ids();
189 MockOAuth2TokenService& token_service();
190 base::MessageLoopForIO& message_loop();
191 RequestHandler& request_handler();
59 192
60 private: 193 private:
61 // An UploadCallback invoked by AttachmentUploaderImpl. 194 // An UploadCallback invoked by AttachmentUploaderImpl.
62 void UploadDone(const AttachmentUploader::UploadResult& result, 195 void UploadDone(const AttachmentUploader::UploadResult& result,
63 const AttachmentId& updated_attachment_id); 196 const AttachmentId& updated_attachment_id);
64 197
65 base::MessageLoopForIO message_loop_; 198 base::MessageLoopForIO message_loop_;
66 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; 199 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
67 scoped_ptr<RequestHandler> request_handler_; 200 scoped_ptr<RequestHandler> request_handler_;
68 scoped_ptr<AttachmentUploader> uploader_; 201 scoped_ptr<AttachmentUploader> uploader_;
69 AttachmentUploader::UploadCallback upload_callback_; 202 AttachmentUploader::UploadCallback upload_callback_;
70 net::test_server::EmbeddedTestServer server_; 203 net::test_server::EmbeddedTestServer server_;
71
72 // A closure that signals an upload has finished. 204 // A closure that signals an upload has finished.
73 base::Closure signal_upload_done_; 205 base::Closure signal_upload_done_;
74 std::vector<HttpRequest> http_requests_received_; 206 std::vector<HttpRequest> http_requests_received_;
75 std::vector<AttachmentUploader::UploadResult> upload_results_; 207 std::vector<AttachmentUploader::UploadResult> upload_results_;
76 std::vector<AttachmentId> updated_attachment_ids_; 208 std::vector<AttachmentId> updated_attachment_ids_;
209 scoped_ptr<MockOAuth2TokenService> token_service_;
77 210
78 // Must be last data member. 211 // Must be last data member.
79 base::WeakPtrFactory<AttachmentUploaderImplTest> weak_ptr_factory_; 212 base::WeakPtrFactory<AttachmentUploaderImplTest> weak_ptr_factory_;
80 }; 213 };
81 214
82 // Handles HTTP requests received by the EmbeddedTestServer. 215 // Handles HTTP requests received by the EmbeddedTestServer.
216 //
217 // Responds with HTTP_OK by default. See |SetStatusCode|.
83 class RequestHandler : public base::NonThreadSafe { 218 class RequestHandler : public base::NonThreadSafe {
84 public: 219 public:
85 // Construct a RequestHandler that will PostTask to |test| using 220 // Construct a RequestHandler that will PostTask to |test| using
86 // |test_task_runner|. 221 // |test_task_runner|.
87 RequestHandler( 222 RequestHandler(
88 const scoped_refptr<base::SingleThreadTaskRunner>& test_task_runner, 223 const scoped_refptr<base::SingleThreadTaskRunner>& test_task_runner,
89 const base::WeakPtr<AttachmentUploaderImplTest>& test); 224 const base::WeakPtr<AttachmentUploaderImplTest>& test);
90 225
91 ~RequestHandler(); 226 ~RequestHandler();
92 227
93 scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request); 228 scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request);
94 229
230 // Set the HTTP status code to respond with.
231 void SetStatusCode(const net::HttpStatusCode& status_code);
232
233 // Returns the HTTP status code that will be used in responses.
234 net::HttpStatusCode GetStatusCode() const;
235
95 private: 236 private:
237 // Protects status_code_.
238 mutable base::Lock mutex_;
239 net::HttpStatusCode status_code_;
240
96 scoped_refptr<base::SingleThreadTaskRunner> test_task_runner_; 241 scoped_refptr<base::SingleThreadTaskRunner> test_task_runner_;
97 base::WeakPtr<AttachmentUploaderImplTest> test_; 242 base::WeakPtr<AttachmentUploaderImplTest> test_;
98 }; 243 };
99 244
100 AttachmentUploaderImplTest::AttachmentUploaderImplTest() 245 AttachmentUploaderImplTest::AttachmentUploaderImplTest()
101 : weak_ptr_factory_(this) { 246 : weak_ptr_factory_(this) {
102 } 247 }
103 248
104 void AttachmentUploaderImplTest::OnRequestReceived(const HttpRequest& request) { 249 void AttachmentUploaderImplTest::OnRequestReceived(const HttpRequest& request) {
105 DCHECK(CalledOnValidThread()); 250 DCHECK(CalledOnValidThread());
106 http_requests_received_.push_back(request); 251 http_requests_received_.push_back(request);
107 } 252 }
108 253
109 void AttachmentUploaderImplTest::SetUp() { 254 void AttachmentUploaderImplTest::SetUp() {
110 DCHECK(CalledOnValidThread()); 255 DCHECK(CalledOnValidThread());
111 request_handler_.reset(new RequestHandler(message_loop_.message_loop_proxy(), 256 request_handler_.reset(new RequestHandler(message_loop_.message_loop_proxy(),
112 weak_ptr_factory_.GetWeakPtr())); 257 weak_ptr_factory_.GetWeakPtr()));
113 url_request_context_getter_ = 258 url_request_context_getter_ =
114 new net::TestURLRequestContextGetter(message_loop_.message_loop_proxy()); 259 new net::TestURLRequestContextGetter(message_loop_.message_loop_proxy());
115 260
116 ASSERT_TRUE(server_.InitializeAndWaitUntilReady()); 261 ASSERT_TRUE(server_.InitializeAndWaitUntilReady());
117 server_.RegisterRequestHandler( 262 server_.RegisterRequestHandler(
118 base::Bind(&RequestHandler::HandleRequest, 263 base::Bind(&RequestHandler::HandleRequest,
119 base::Unretained(request_handler_.get()))); 264 base::Unretained(request_handler_.get())));
120 265
121 std::string url_prefix( 266 std::string url_prefix(
122 base::StringPrintf("http://localhost:%d/uploads/", server_.port())); 267 base::StringPrintf("http://localhost:%d/uploads/", server_.port()));
123 268
124 uploader().reset( 269 token_service_.reset(new MockOAuth2TokenService);
125 new AttachmentUploaderImpl(url_prefix, url_request_context_getter_)); 270 scoped_ptr<OAuth2TokenServiceRequest::TokenServiceProvider>
271 token_service_provider(new TokenServiceProvider(token_service_.get()));
272
273 OAuth2TokenService::ScopeSet scopes;
274 scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope);
275 uploader().reset(new AttachmentUploaderImpl(url_prefix,
276 url_request_context_getter_,
277 kAccountId,
278 scopes,
279 token_service_provider.Pass()));
280
126 upload_callback_ = base::Bind(&AttachmentUploaderImplTest::UploadDone, 281 upload_callback_ = base::Bind(&AttachmentUploaderImplTest::UploadDone,
127 base::Unretained(this)); 282 base::Unretained(this));
128 } 283 }
129 284
130 void AttachmentUploaderImplTest::RunAndWaitFor(int num_uploads) { 285 void AttachmentUploaderImplTest::RunAndWaitFor(int num_uploads) {
131 for (int i = 0; i < num_uploads; ++i) { 286 for (int i = 0; i < num_uploads; ++i) {
132 // Run the loop until one upload completes. 287 // Run the loop until one upload completes.
133 base::RunLoop run_loop; 288 base::RunLoop run_loop;
134 signal_upload_done_ = run_loop.QuitClosure(); 289 signal_upload_done_ = run_loop.QuitClosure();
135 run_loop.Run(); 290 run_loop.Run();
(...skipping 16 matching lines...) Expand all
152 std::vector<AttachmentUploader::UploadResult>& 307 std::vector<AttachmentUploader::UploadResult>&
153 AttachmentUploaderImplTest::upload_results() { 308 AttachmentUploaderImplTest::upload_results() {
154 return upload_results_; 309 return upload_results_;
155 } 310 }
156 311
157 std::vector<AttachmentId>& 312 std::vector<AttachmentId>&
158 AttachmentUploaderImplTest::updated_attachment_ids() { 313 AttachmentUploaderImplTest::updated_attachment_ids() {
159 return updated_attachment_ids_; 314 return updated_attachment_ids_;
160 } 315 }
161 316
317 MockOAuth2TokenService& AttachmentUploaderImplTest::token_service() {
318 return *token_service_;
319 }
320
321 base::MessageLoopForIO& AttachmentUploaderImplTest::message_loop() {
322 return message_loop_;
323 }
324
325 RequestHandler& AttachmentUploaderImplTest::request_handler() {
326 return *request_handler_;
327 }
328
162 void AttachmentUploaderImplTest::UploadDone( 329 void AttachmentUploaderImplTest::UploadDone(
163 const AttachmentUploader::UploadResult& result, 330 const AttachmentUploader::UploadResult& result,
164 const AttachmentId& updated_attachment_id) { 331 const AttachmentId& updated_attachment_id) {
165 DCHECK(CalledOnValidThread()); 332 DCHECK(CalledOnValidThread());
166 upload_results_.push_back(result); 333 upload_results_.push_back(result);
167 updated_attachment_ids_.push_back(updated_attachment_id); 334 updated_attachment_ids_.push_back(updated_attachment_id);
168 signal_upload_done_.Run(); 335 signal_upload_done_.Run();
169 } 336 }
170 337
171 RequestHandler::RequestHandler( 338 RequestHandler::RequestHandler(
172 const scoped_refptr<base::SingleThreadTaskRunner>& test_task_runner, 339 const scoped_refptr<base::SingleThreadTaskRunner>& test_task_runner,
173 const base::WeakPtr<AttachmentUploaderImplTest>& test) 340 const base::WeakPtr<AttachmentUploaderImplTest>& test)
174 : test_task_runner_(test_task_runner), test_(test) { 341 : status_code_(net::HTTP_OK),
342 test_task_runner_(test_task_runner),
343 test_(test) {
175 DetachFromThread(); 344 DetachFromThread();
176 } 345 }
177 346
178 RequestHandler::~RequestHandler() { 347 RequestHandler::~RequestHandler() {
179 DetachFromThread(); 348 DetachFromThread();
180 } 349 }
181 350
182 scoped_ptr<HttpResponse> RequestHandler::HandleRequest( 351 scoped_ptr<HttpResponse> RequestHandler::HandleRequest(
183 const HttpRequest& request) { 352 const HttpRequest& request) {
184 DCHECK(CalledOnValidThread()); 353 DCHECK(CalledOnValidThread());
185 test_task_runner_->PostTask( 354 test_task_runner_->PostTask(
186 FROM_HERE, 355 FROM_HERE,
187 base::Bind( 356 base::Bind(
188 &AttachmentUploaderImplTest::OnRequestReceived, test_, request)); 357 &AttachmentUploaderImplTest::OnRequestReceived, test_, request));
189 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); 358 scoped_ptr<BasicHttpResponse> response(new BasicHttpResponse);
190 http_response->set_code(net::HTTP_OK); 359 response->set_code(GetStatusCode());
191 http_response->set_content("hello"); 360 response->set_content_type("text/plain");
192 http_response->set_content_type("text/plain"); 361 return response.PassAs<HttpResponse>();
193 return http_response.PassAs<HttpResponse>(); 362 }
363
364 void RequestHandler::SetStatusCode(const net::HttpStatusCode& status_code) {
365 base::AutoLock lock(mutex_);
366 status_code_ = status_code;
367 }
368
369 net::HttpStatusCode RequestHandler::GetStatusCode() const {
370 base::AutoLock lock(mutex_);
371 return status_code_;
194 } 372 }
195 373
196 // Verify the "happy case" of uploading an attachment. 374 // Verify the "happy case" of uploading an attachment.
375 //
376 // Token is requested, token is returned, HTTP request is made, attachment is
377 // received by server.
197 TEST_F(AttachmentUploaderImplTest, UploadAttachment_HappyCase) { 378 TEST_F(AttachmentUploaderImplTest, UploadAttachment_HappyCase) {
379 token_service().AddAccount(kAccountId);
380 request_handler().SetStatusCode(net::HTTP_OK);
381
198 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString); 382 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
199 some_data->data() = kAttachmentData; 383 some_data->data() = kAttachmentData;
200 Attachment attachment = Attachment::Create(some_data); 384 Attachment attachment = Attachment::Create(some_data);
201 uploader()->UploadAttachment(attachment, upload_callback()); 385 uploader()->UploadAttachment(attachment, upload_callback());
386
387 // Run until the done callback is invoked.
202 RunAndWaitFor(1); 388 RunAndWaitFor(1);
203 389
390 // See that the done callback was invoked with the right arguments.
391 ASSERT_EQ(1U, upload_results().size());
392 EXPECT_EQ(AttachmentUploader::UPLOAD_SUCCESS, upload_results()[0]);
393 ASSERT_EQ(1U, updated_attachment_ids().size());
394 EXPECT_EQ(attachment.GetId(), updated_attachment_ids()[0]);
395
204 // See that the HTTP server received one request. 396 // See that the HTTP server received one request.
205 EXPECT_EQ(1U, http_requests_received().size()); 397 ASSERT_EQ(1U, http_requests_received().size());
206 const HttpRequest& http_request = http_requests_received().front(); 398 const HttpRequest& http_request = http_requests_received().front();
207 EXPECT_EQ(net::test_server::METHOD_POST, http_request.method); 399 EXPECT_EQ(net::test_server::METHOD_POST, http_request.method);
208 std::string expected_relative_url("/uploads/" + 400 std::string expected_relative_url("/uploads/" +
209 attachment.GetId().GetProto().unique_id()); 401 attachment.GetId().GetProto().unique_id());
210 EXPECT_EQ(expected_relative_url, http_request.relative_url); 402 EXPECT_EQ(expected_relative_url, http_request.relative_url);
211 EXPECT_TRUE(http_request.has_content); 403 EXPECT_TRUE(http_request.has_content);
212 EXPECT_EQ(kAttachmentData, http_request.content); 404 EXPECT_EQ(kAttachmentData, http_request.content);
405 std::string expected_header(kAuthorization);
pavely 2014/06/04 23:34:39 expected_header is not used.
maniscalco 2014/06/05 00:12:12 Removed! On 2014/06/04 23:34:39, pavely wrote:
406 const std::string header_name(kAuthorization);
407 const std::string header_value(std::string("Bearer ") + kAccessToken);
408 EXPECT_THAT(http_request.headers,
409 testing::Contains(testing::Pair(header_name, header_value)));
213 410
214 // See that the UploadCallback received a result and updated AttachmentId.
215 EXPECT_EQ(1U, upload_results().size());
216 EXPECT_EQ(1U, updated_attachment_ids().size());
217 EXPECT_EQ(AttachmentUploader::UPLOAD_SUCCESS, upload_results().front());
218 EXPECT_EQ(attachment.GetId(), updated_attachment_ids().front());
219 // TODO(maniscalco): Once AttachmentUploaderImpl is capable of updating the 411 // TODO(maniscalco): Once AttachmentUploaderImpl is capable of updating the
220 // AttachmentId with server address information about the attachment, add some 412 // AttachmentId with server address information about the attachment, add some
221 // checks here to verify it works properly (bug 371522). 413 // checks here to verify it works properly (bug 371522).
222 } 414 }
223 415
224 // Verify two overlapping calls to upload the same attachment result in only one 416 // Verify two overlapping calls to upload the same attachment result in only one
225 // HTTP request. 417 // HTTP request.
226 TEST_F(AttachmentUploaderImplTest, UploadAttachment_Collapse) { 418 TEST_F(AttachmentUploaderImplTest, UploadAttachment_Collapse) {
419 token_service().AddAccount(kAccountId);
420 request_handler().SetStatusCode(net::HTTP_OK);
421
227 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString); 422 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
228 some_data->data() = kAttachmentData; 423 some_data->data() = kAttachmentData;
229 Attachment attachment1 = Attachment::Create(some_data); 424 Attachment attachment1 = Attachment::Create(some_data);
230 Attachment attachment2 = attachment1; 425 Attachment attachment2 = attachment1;
231 uploader()->UploadAttachment(attachment1, upload_callback()); 426 uploader()->UploadAttachment(attachment1, upload_callback());
232 uploader()->UploadAttachment(attachment2, upload_callback()); 427 uploader()->UploadAttachment(attachment2, upload_callback());
428 base::RunLoop().RunUntilIdle();
429
233 // Wait for upload_callback() to be invoked twice. 430 // Wait for upload_callback() to be invoked twice.
234 RunAndWaitFor(2); 431 RunAndWaitFor(2);
235 // See there was only one request. 432 // See there was only one request.
236 EXPECT_EQ(1U, http_requests_received().size()); 433 EXPECT_EQ(1U, http_requests_received().size());
237 } 434 }
238 435
239 // Verify that the internal state associated with an upload is removed when the 436 // Verify that the internal state associated with an upload is removed when the
240 // uplaod finishes. We do this by issuing two non-overlapping uploads for the 437 // uplaod finishes. We do this by issuing two non-overlapping uploads for the
241 // same attachment and see that it results in two HTTP requests. 438 // same attachment and see that it results in two HTTP requests.
242 TEST_F(AttachmentUploaderImplTest, UploadAttachment_CleanUpAfterUpload) { 439 TEST_F(AttachmentUploaderImplTest, UploadAttachment_CleanUpAfterUpload) {
440 token_service().AddAccount(kAccountId);
441 request_handler().SetStatusCode(net::HTTP_OK);
442
243 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString); 443 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
244 some_data->data() = kAttachmentData; 444 some_data->data() = kAttachmentData;
245 Attachment attachment1 = Attachment::Create(some_data); 445 Attachment attachment1 = Attachment::Create(some_data);
246 Attachment attachment2 = attachment1; 446 Attachment attachment2 = attachment1;
247 uploader()->UploadAttachment(attachment1, upload_callback()); 447 uploader()->UploadAttachment(attachment1, upload_callback());
448 base::RunLoop().RunUntilIdle();
449
248 // Wait for upload_callback() to be invoked before starting the second upload. 450 // Wait for upload_callback() to be invoked before starting the second upload.
249 RunAndWaitFor(1); 451 RunAndWaitFor(1);
250 uploader()->UploadAttachment(attachment2, upload_callback()); 452 uploader()->UploadAttachment(attachment2, upload_callback());
453 base::RunLoop().RunUntilIdle();
454
251 // Wait for upload_callback() to be invoked a second time. 455 // Wait for upload_callback() to be invoked a second time.
252 RunAndWaitFor(1); 456 RunAndWaitFor(1);
253 // See there were two requests. 457 // See there were two requests.
254 EXPECT_EQ(2U, http_requests_received().size()); 458 ASSERT_EQ(2U, http_requests_received().size());
255 } 459 }
256 460
461 // Verify that we do not issue an HTTP request when we fail to receive an access
462 // token.
463 //
464 // Token is requested, no token is returned, no HTTP request is made
465 TEST_F(AttachmentUploaderImplTest, UploadAttachment_FailToGetToken) {
466 // Note, we won't receive a token because we did not add kAccountId to the
467 // token service.
468 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
469 some_data->data() = kAttachmentData;
470 Attachment attachment = Attachment::Create(some_data);
471 uploader()->UploadAttachment(attachment, upload_callback());
472
473 RunAndWaitFor(1);
474
475 // See that the done callback was invoked.
476 ASSERT_EQ(1U, upload_results().size());
477 EXPECT_EQ(AttachmentUploader::UPLOAD_UNSPECIFIED_ERROR, upload_results()[0]);
478 ASSERT_EQ(1U, updated_attachment_ids().size());
479 EXPECT_EQ(attachment.GetId(), updated_attachment_ids()[0]);
480
481 // See that no HTTP request was received.
482 ASSERT_EQ(0U, http_requests_received().size());
483 }
484
485 // Verify behavior when the server returns "503 Service Unavailable".
486 TEST_F(AttachmentUploaderImplTest, UploadAttachment_ServiceUnavilable) {
487 token_service().AddAccount(kAccountId);
488 request_handler().SetStatusCode(net::HTTP_SERVICE_UNAVAILABLE);
489
490 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
491 some_data->data() = kAttachmentData;
492 Attachment attachment = Attachment::Create(some_data);
493 uploader()->UploadAttachment(attachment, upload_callback());
494
495 RunAndWaitFor(1);
496
497 // See that the done callback was invoked.
498 ASSERT_EQ(1U, upload_results().size());
499 EXPECT_EQ(AttachmentUploader::UPLOAD_UNSPECIFIED_ERROR, upload_results()[0]);
500 ASSERT_EQ(1U, updated_attachment_ids().size());
501 EXPECT_EQ(attachment.GetId(), updated_attachment_ids()[0]);
502
503 // See that the HTTP server received one request.
504 ASSERT_EQ(1U, http_requests_received().size());
505 const HttpRequest& http_request = http_requests_received().front();
506 EXPECT_EQ(net::test_server::METHOD_POST, http_request.method);
507 std::string expected_relative_url("/uploads/" +
508 attachment.GetId().GetProto().unique_id());
509 EXPECT_EQ(expected_relative_url, http_request.relative_url);
510 EXPECT_TRUE(http_request.has_content);
511 EXPECT_EQ(kAttachmentData, http_request.content);
512 std::string expected_header(kAuthorization);
513 const std::string header_name(kAuthorization);
514 const std::string header_value(std::string("Bearer ") + kAccessToken);
515 EXPECT_THAT(http_request.headers,
516 testing::Contains(testing::Pair(header_name, header_value)));
517
518 // See that we did not invalidate the token.
519 ASSERT_EQ(0, token_service().num_invalidate_token());
520 }
521
522 // Verify that when we receive an "401 Unauthorized" we invalidate the access
523 // token.
524 TEST_F(AttachmentUploaderImplTest, UploadAttachment_BadToken) {
525 token_service().AddAccount(kAccountId);
526 request_handler().SetStatusCode(net::HTTP_UNAUTHORIZED);
527
528 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
529 some_data->data() = kAttachmentData;
530 Attachment attachment = Attachment::Create(some_data);
531 uploader()->UploadAttachment(attachment, upload_callback());
532
533 RunAndWaitFor(1);
534
535 // See that the done callback was invoked.
536 ASSERT_EQ(1U, upload_results().size());
537 EXPECT_EQ(AttachmentUploader::UPLOAD_UNSPECIFIED_ERROR, upload_results()[0]);
538 ASSERT_EQ(1U, updated_attachment_ids().size());
539 EXPECT_EQ(attachment.GetId(), updated_attachment_ids()[0]);
540
541 // See that the HTTP server received one request.
542 ASSERT_EQ(1U, http_requests_received().size());
543 const HttpRequest& http_request = http_requests_received().front();
544 EXPECT_EQ(net::test_server::METHOD_POST, http_request.method);
545 std::string expected_relative_url("/uploads/" +
546 attachment.GetId().GetProto().unique_id());
547 EXPECT_EQ(expected_relative_url, http_request.relative_url);
548 EXPECT_TRUE(http_request.has_content);
549 EXPECT_EQ(kAttachmentData, http_request.content);
550 std::string expected_header(kAuthorization);
551 const std::string header_name(kAuthorization);
552 const std::string header_value(std::string("Bearer ") + kAccessToken);
553 EXPECT_THAT(http_request.headers,
554 testing::Contains(testing::Pair(header_name, header_value)));
555
556 // See that we invalidated the token.
557 ASSERT_EQ(1, token_service().num_invalidate_token());
558 }
559
560 // TODO(maniscalco): Add test case for when we are uploading an attachment that
561 // already exists. 409 Conflict? (bug 379825)
562
257 } // namespace syncer 563 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698