Add ICU message format support
[chromium-blink-merge.git] / chrome / browser / chromeos / fileapi / external_file_url_request_job_unittest.cc
blob9c161ce1e34edd2a9232ae6c391a1f30fa331787
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.
5 #include "chrome/browser/chromeos/fileapi/external_file_url_request_job.h"
7 #include "base/bind.h"
8 #include "base/files/file_util.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h"
12 #include "base/threading/thread.h"
13 #include "chrome/browser/chromeos/drive/drive_file_stream_reader.h"
14 #include "chrome/browser/chromeos/drive/drive_integration_service.h"
15 #include "chrome/browser/chromeos/drive/drive_test_util.h"
16 #include "chrome/browser/chromeos/drive/fake_file_system.h"
17 #include "chrome/browser/chromeos/drive/file_system_util.h"
18 #include "chrome/browser/prefs/browser_prefs.h"
19 #include "chrome/browser/prefs/pref_service_syncable.h"
20 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/test/base/testing_browser_process.h"
22 #include "chrome/test/base/testing_profile.h"
23 #include "chrome/test/base/testing_profile_manager.h"
24 #include "components/drive/service/fake_drive_service.h"
25 #include "components/drive/service/test_util.h"
26 #include "components/pref_registry/pref_registry_syncable.h"
27 #include "components/pref_registry/testing_pref_service_syncable.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/common/url_constants.h"
30 #include "content/public/test/test_browser_thread_bundle.h"
31 #include "content/public/test/test_file_system_options.h"
32 #include "google_apis/drive/test_util.h"
33 #include "net/base/request_priority.h"
34 #include "net/base/test_completion_callback.h"
35 #include "net/http/http_byte_range.h"
36 #include "net/url_request/redirect_info.h"
37 #include "net/url_request/url_request.h"
38 #include "net/url_request/url_request_context.h"
39 #include "net/url_request/url_request_test_util.h"
40 #include "storage/browser/fileapi/external_mount_points.h"
41 #include "storage/browser/fileapi/file_system_context.h"
42 #include "testing/gtest/include/gtest/gtest.h"
43 #include "url/gurl.h"
45 namespace chromeos {
46 namespace {
48 // A simple URLRequestJobFactory implementation to create
49 // ExternalFileURLRequestJob.
50 class TestURLRequestJobFactory : public net::URLRequestJobFactory {
51 public:
52 explicit TestURLRequestJobFactory(void* profile_id)
53 : profile_id_(profile_id) {}
55 ~TestURLRequestJobFactory() override {}
57 // net::URLRequestJobFactory override:
58 net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
59 const std::string& scheme,
60 net::URLRequest* request,
61 net::NetworkDelegate* network_delegate) const override {
62 return new ExternalFileURLRequestJob(
63 profile_id_, request, network_delegate);
66 net::URLRequestJob* MaybeInterceptRedirect(
67 net::URLRequest* request,
68 net::NetworkDelegate* network_delegate,
69 const GURL& location) const override {
70 return nullptr;
73 net::URLRequestJob* MaybeInterceptResponse(
74 net::URLRequest* request,
75 net::NetworkDelegate* network_delegate) const override {
76 return nullptr;
79 bool IsHandledProtocol(const std::string& scheme) const override {
80 return scheme == content::kExternalFileScheme;
83 bool IsHandledURL(const GURL& url) const override {
84 return url.is_valid() && IsHandledProtocol(url.scheme());
87 bool IsSafeRedirectTarget(const GURL& location) const override {
88 return true;
91 private:
92 void* const profile_id_;
93 DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory);
96 class TestDelegate : public net::TestDelegate {
97 public:
98 TestDelegate() {}
100 const GURL& redirect_url() const { return redirect_url_; }
102 // net::TestDelegate override.
103 void OnReceivedRedirect(net::URLRequest* request,
104 const net::RedirectInfo& redirect_info,
105 bool* defer_redirect) override {
106 redirect_url_ = redirect_info.new_url;
107 net::TestDelegate::OnReceivedRedirect(
108 request, redirect_info, defer_redirect);
111 private:
112 GURL redirect_url_;
114 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
117 } // namespace
119 class ExternalFileURLRequestJobTest : public testing::Test {
120 protected:
121 ExternalFileURLRequestJobTest()
122 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
123 integration_service_factory_callback_(base::Bind(
124 &ExternalFileURLRequestJobTest::CreateDriveIntegrationService,
125 base::Unretained(this))),
126 fake_file_system_(NULL) {}
128 ~ExternalFileURLRequestJobTest() override {}
130 void SetUp() override {
131 // Create a testing profile.
132 profile_manager_.reset(
133 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
134 ASSERT_TRUE(profile_manager_->SetUp());
135 Profile* const profile =
136 profile_manager_->CreateTestingProfile("test-user");
138 // Create the drive integration service for the profile.
139 integration_service_factory_scope_.reset(
140 new drive::DriveIntegrationServiceFactory::ScopedFactoryForTest(
141 &integration_service_factory_callback_));
142 drive::DriveIntegrationServiceFactory::GetForProfile(profile);
144 // Create the URL request job factory.
145 test_network_delegate_.reset(new net::TestNetworkDelegate);
146 test_url_request_job_factory_.reset(new TestURLRequestJobFactory(profile));
147 url_request_context_.reset(new net::URLRequestContext());
148 url_request_context_->set_job_factory(test_url_request_job_factory_.get());
149 url_request_context_->set_network_delegate(test_network_delegate_.get());
150 test_delegate_.reset(new TestDelegate);
153 void TearDown() override { profile_manager_.reset(); }
155 bool ReadDriveFileSync(const base::FilePath& file_path,
156 std::string* out_content) {
157 scoped_ptr<base::Thread> worker_thread(
158 new base::Thread("ReadDriveFileSync"));
159 if (!worker_thread->Start())
160 return false;
162 scoped_ptr<drive::DriveFileStreamReader> reader(
163 new drive::DriveFileStreamReader(
164 base::Bind(&ExternalFileURLRequestJobTest::GetFileSystem,
165 base::Unretained(this)),
166 worker_thread->task_runner().get()));
167 int error = net::ERR_FAILED;
168 scoped_ptr<drive::ResourceEntry> entry;
170 base::RunLoop run_loop;
171 reader->Initialize(file_path,
172 net::HttpByteRange(),
173 google_apis::test_util::CreateQuitCallback(
174 &run_loop,
175 google_apis::test_util::CreateCopyResultCallback(
176 &error, &entry)));
177 run_loop.Run();
179 if (error != net::OK || !entry)
180 return false;
182 // Read data from the reader.
183 std::string content;
184 if (drive::test_util::ReadAllData(reader.get(), &content) != net::OK)
185 return false;
187 if (static_cast<size_t>(entry->file_info().size()) != content.size())
188 return false;
190 *out_content = content;
191 return true;
194 scoped_ptr<net::URLRequestContext> url_request_context_;
195 scoped_ptr<TestDelegate> test_delegate_;
197 private:
198 // Create the drive integration service for the |profile|
199 drive::DriveIntegrationService* CreateDriveIntegrationService(
200 Profile* profile) {
201 drive::FakeDriveService* const drive_service = new drive::FakeDriveService;
202 if (!drive::test_util::SetUpTestEntries(drive_service))
203 return NULL;
205 const std::string& drive_mount_name =
206 drive::util::GetDriveMountPointPath(profile).BaseName().AsUTF8Unsafe();
207 storage::ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
208 drive_mount_name,
209 storage::kFileSystemTypeDrive,
210 storage::FileSystemMountOption(),
211 drive::util::GetDriveMountPointPath(profile));
212 DCHECK(!fake_file_system_);
213 fake_file_system_ = new drive::test_util::FakeFileSystem(drive_service);
214 if (!drive_cache_dir_.CreateUniqueTempDir())
215 return NULL;
216 return new drive::DriveIntegrationService(profile,
217 NULL,
218 drive_service,
219 drive_mount_name,
220 drive_cache_dir_.path(),
221 fake_file_system_);
224 drive::FileSystemInterface* GetFileSystem() { return fake_file_system_; }
226 content::TestBrowserThreadBundle thread_bundle_;
227 drive::DriveIntegrationServiceFactory::FactoryCallback
228 integration_service_factory_callback_;
229 scoped_ptr<drive::DriveIntegrationServiceFactory::ScopedFactoryForTest>
230 integration_service_factory_scope_;
231 scoped_ptr<drive::DriveIntegrationService> integration_service_;
232 drive::test_util::FakeFileSystem* fake_file_system_;
234 scoped_ptr<net::TestNetworkDelegate> test_network_delegate_;
235 scoped_ptr<TestURLRequestJobFactory> test_url_request_job_factory_;
237 scoped_ptr<TestingProfileManager> profile_manager_;
238 base::ScopedTempDir drive_cache_dir_;
239 scoped_refptr<storage::FileSystemContext> file_system_context_;
242 TEST_F(ExternalFileURLRequestJobTest, NonGetMethod) {
243 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
244 GURL("externalfile:drive-test-user-hash/root/File 1.txt"),
245 net::DEFAULT_PRIORITY, test_delegate_.get()));
246 request->set_method("POST"); // Set non "GET" method.
247 request->Start();
249 base::RunLoop().Run();
251 EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
252 EXPECT_EQ(net::ERR_METHOD_NOT_SUPPORTED, request->status().error());
255 TEST_F(ExternalFileURLRequestJobTest, RegularFile) {
256 const GURL kTestUrl("externalfile:drive-test-user-hash/root/File 1.txt");
257 const base::FilePath kTestFilePath("drive/root/File 1.txt");
259 // For the first time, the file should be fetched from the server.
261 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
262 kTestUrl, net::DEFAULT_PRIORITY, test_delegate_.get()));
263 request->Start();
265 base::RunLoop().Run();
267 EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
268 // It looks weird, but the mime type for the "File 1.txt" is "audio/mpeg"
269 // on the server.
270 std::string mime_type;
271 request->GetMimeType(&mime_type);
272 EXPECT_EQ("audio/mpeg", mime_type);
274 // Reading file must be done after |request| runs, otherwise
275 // it'll create a local cache file, and we cannot test correctly.
276 std::string expected_data;
277 ASSERT_TRUE(ReadDriveFileSync(kTestFilePath, &expected_data));
278 EXPECT_EQ(expected_data, test_delegate_->data_received());
281 // For the second time, the locally cached file should be used.
282 // The caching emulation is done by FakeFileSystem.
284 test_delegate_.reset(new TestDelegate);
285 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
286 GURL("externalfile:drive-test-user-hash/root/File 1.txt"),
287 net::DEFAULT_PRIORITY, test_delegate_.get()));
288 request->Start();
290 base::RunLoop().Run();
292 EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
293 std::string mime_type;
294 request->GetMimeType(&mime_type);
295 EXPECT_EQ("audio/mpeg", mime_type);
297 std::string expected_data;
298 ASSERT_TRUE(ReadDriveFileSync(kTestFilePath, &expected_data));
299 EXPECT_EQ(expected_data, test_delegate_->data_received());
303 TEST_F(ExternalFileURLRequestJobTest, HostedDocument) {
304 // Open a gdoc file.
305 test_delegate_->set_quit_on_redirect(true);
306 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
307 GURL(
308 "externalfile:drive-test-user-hash/root/Document 1 "
309 "excludeDir-test.gdoc"),
310 net::DEFAULT_PRIORITY, test_delegate_.get()));
311 request->Start();
313 base::RunLoop().Run();
315 EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
316 // Make sure that a hosted document triggers redirection.
317 EXPECT_TRUE(request->is_redirecting());
318 EXPECT_TRUE(test_delegate_->redirect_url().is_valid());
321 TEST_F(ExternalFileURLRequestJobTest, RootDirectory) {
322 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
323 GURL("externalfile:drive-test-user-hash/root"), net::DEFAULT_PRIORITY,
324 test_delegate_.get()));
325 request->Start();
327 base::RunLoop().Run();
329 EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
330 EXPECT_EQ(net::ERR_FAILED, request->status().error());
333 TEST_F(ExternalFileURLRequestJobTest, Directory) {
334 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
335 GURL("externalfile:drive-test-user-hash/root/Directory 1"),
336 net::DEFAULT_PRIORITY, test_delegate_.get()));
337 request->Start();
339 base::RunLoop().Run();
341 EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
342 EXPECT_EQ(net::ERR_FAILED, request->status().error());
345 TEST_F(ExternalFileURLRequestJobTest, NonExistingFile) {
346 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
347 GURL("externalfile:drive-test-user-hash/root/non-existing-file.txt"),
348 net::DEFAULT_PRIORITY, test_delegate_.get()));
349 request->Start();
351 base::RunLoop().Run();
353 EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
354 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request->status().error());
357 TEST_F(ExternalFileURLRequestJobTest, WrongFormat) {
358 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
359 GURL("externalfile:"), net::DEFAULT_PRIORITY, test_delegate_.get()));
360 request->Start();
362 base::RunLoop().Run();
364 EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
365 EXPECT_EQ(net::ERR_INVALID_URL, request->status().error());
368 TEST_F(ExternalFileURLRequestJobTest, Cancel) {
369 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
370 GURL("externalfile:drive-test-user-hash/root/File 1.txt"),
371 net::DEFAULT_PRIORITY, test_delegate_.get()));
373 // Start the request, and cancel it immediately after it.
374 request->Start();
375 request->Cancel();
377 base::RunLoop().Run();
379 EXPECT_EQ(net::URLRequestStatus::CANCELED, request->status().status());
382 TEST_F(ExternalFileURLRequestJobTest, RangeHeader) {
383 const GURL kTestUrl("externalfile:drive-test-user-hash/root/File 1.txt");
384 const base::FilePath kTestFilePath("drive/root/File 1.txt");
386 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
387 kTestUrl, net::DEFAULT_PRIORITY, test_delegate_.get()));
389 // Set range header.
390 request->SetExtraRequestHeaderByName(
391 "Range", "bytes=3-5", false /* overwrite */);
392 request->Start();
394 base::RunLoop().Run();
396 EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
398 // Reading file must be done after |request| runs, otherwise
399 // it'll create a local cache file, and we cannot test correctly.
400 std::string expected_data;
401 ASSERT_TRUE(ReadDriveFileSync(kTestFilePath, &expected_data));
402 EXPECT_EQ(expected_data.substr(3, 3), test_delegate_->data_received());
405 TEST_F(ExternalFileURLRequestJobTest, WrongRangeHeader) {
406 const GURL kTestUrl("externalfile:drive-test-user-hash/root/File 1.txt");
408 scoped_ptr<net::URLRequest> request(url_request_context_->CreateRequest(
409 kTestUrl, net::DEFAULT_PRIORITY, test_delegate_.get()));
411 // Set range header.
412 request->SetExtraRequestHeaderByName(
413 "Range", "Wrong Range Header Value", false /* overwrite */);
414 request->Start();
416 base::RunLoop().Run();
418 EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
419 EXPECT_EQ(net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, request->status().error());
422 } // namespace chromeos