blob: 4d81513d1688c08b57fbb9d688f60cc0fb7c613d [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// NOTE: These tests are run as part of "unit_tests" (in chrome/test/unit)
// rather than as part of test_shell_tests because they rely on being able
// to instantiate a MessageLoop of type TYPE_IO. test_shell_tests uses
// TYPE_UI, which URLRequest doesn't allow.
//
#include "webkit/fileapi/file_system_dir_url_request_job.h"
#include "build/build_config.h"
#include <string>
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/format_macros.h"
#include "base/message_loop.h"
#include "base/platform_file.h"
#include "base/scoped_temp_dir.h"
#include "base/string_piece.h"
#include "base/threading/thread.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/http/http_request_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/fileapi/file_system_path_manager.h"
namespace fileapi {
namespace {
// We always use the TEMPORARY FileSystem in this test.
static const char kFileSystemURLPrefix[] = "filesystem:http://remote/temporary/";
class FileSystemDirURLRequestJobTest : public testing::Test {
protected:
FileSystemDirURLRequestJobTest()
: message_loop_(MessageLoop::TYPE_IO), // simulate an IO thread
ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) {
}
virtual void SetUp() {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
// We use the main thread so that we can get the root path synchronously.
// TODO(adamk): Run this on the FILE thread we've created as well.
path_manager_.reset(new FileSystemPathManager(
base::MessageLoopProxy::CreateForCurrentThread(),
temp_dir_.path(), false, false));
path_manager_->GetFileSystemRootPath(
GURL("http://remote/"), kFileSystemTypeTemporary, true, // create
callback_factory_.NewCallback(
&FileSystemDirURLRequestJobTest::OnGetRootPath));
MessageLoop::current()->RunAllPending();
file_thread_.reset(
new base::Thread("FileSystemDirURLRequestJobTest FILE Thread"));
base::Thread::Options options(MessageLoop::TYPE_IO, 0);
file_thread_->StartWithOptions(options);
net::URLRequest::RegisterProtocolFactory(
"filesystem", &FileSystemDirURLRequestJobFactory);
}
virtual void TearDown() {
// NOTE: order matters, request must die before delegate
request_.reset(NULL);
delegate_.reset(NULL);
file_thread_.reset(NULL);
net::URLRequest::RegisterProtocolFactory("filesystem", NULL);
}
void OnGetRootPath(bool success, const FilePath& root_path,
const std::string& name) {
ASSERT_TRUE(success);
root_path_ = root_path;
}
void TestRequest(const GURL& url) {
delegate_.reset(new TestDelegate());
delegate_->set_quit_on_redirect(true);
request_.reset(new net::URLRequest(url, delegate_.get()));
job_ = new FileSystemDirURLRequestJob(request_.get(), path_manager_.get(),
file_thread_->message_loop_proxy());
request_->Start();
ASSERT_TRUE(request_->is_pending()); // verify that we're starting async
MessageLoop::current()->Run();
}
void CreateDirectory(const base::StringPiece dir_name) {
FilePath path = root_path_.AppendASCII(dir_name);
ASSERT_TRUE(file_util::CreateDirectory(path));
}
GURL CreateFileSystemURL(const std::string path) {
return GURL(kFileSystemURLPrefix + path);
}
static net::URLRequestJob* FileSystemDirURLRequestJobFactory(
net::URLRequest* request,
const std::string& scheme) {
DCHECK(job_);
net::URLRequestJob* temp = job_;
job_ = NULL;
return temp;
}
ScopedTempDir temp_dir_;
FilePath root_path_;
scoped_ptr<net::URLRequest> request_;
scoped_ptr<TestDelegate> delegate_;
scoped_ptr<FileSystemPathManager> path_manager_;
scoped_ptr<base::Thread> file_thread_;
MessageLoop message_loop_;
base::ScopedCallbackFactory<FileSystemDirURLRequestJobTest> callback_factory_;
static net::URLRequestJob* job_;
};
// static
net::URLRequestJob* FileSystemDirURLRequestJobTest::job_ = NULL;
// TODO(adamk): Write tighter tests once we've decided on a format for directory
// listing responses.
TEST_F(FileSystemDirURLRequestJobTest, DirectoryListing) {
CreateDirectory("foo");
CreateDirectory("foo/bar");
CreateDirectory("foo/bar/baz");
TestRequest(CreateFileSystemURL("foo/bar/"));
ASSERT_FALSE(request_->is_pending());
EXPECT_EQ(1, delegate_->response_started_count());
EXPECT_FALSE(delegate_->received_data_before_response());
EXPECT_GT(delegate_->bytes_received(), 0);
}
TEST_F(FileSystemDirURLRequestJobTest, InvalidURL) {
TestRequest(GURL("filesystem:/foo/bar/baz"));
ASSERT_FALSE(request_->is_pending());
EXPECT_TRUE(delegate_->request_failed());
ASSERT_FALSE(request_->status().is_success());
EXPECT_EQ(net::ERR_INVALID_URL, request_->status().os_error());
}
TEST_F(FileSystemDirURLRequestJobTest, NoSuchRoot) {
TestRequest(GURL("filesystem:http://remote/persistent/somedir/"));
ASSERT_FALSE(request_->is_pending());
ASSERT_FALSE(request_->status().is_success());
EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request_->status().os_error());
}
TEST_F(FileSystemDirURLRequestJobTest, NoSuchDirectory) {
TestRequest(CreateFileSystemURL("somedir/"));
ASSERT_FALSE(request_->is_pending());
ASSERT_FALSE(request_->status().is_success());
EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, request_->status().os_error());
}
} // namespace (anonymous)
} // namespace fileapi