| Index: content/browser/android/url_request_content_job_unittest.cc
|
| diff --git a/content/browser/android/url_request_content_job_unittest.cc b/content/browser/android/url_request_content_job_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e4b5f9e6a7e002352054405c1ccd0eabd2356e97
|
| --- /dev/null
|
| +++ b/content/browser/android/url_request_content_job_unittest.cc
|
| @@ -0,0 +1,198 @@
|
| +// Copyright 2014 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.
|
| +
|
| +#include "content/browser/android/url_request_content_job.h"
|
| +
|
| +#include <algorithm>
|
| +
|
| +#include "base/files/file_util.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/strings/stringprintf.h"
|
| +#include "base/test/test_file_util.h"
|
| +#include "net/url_request/url_request.h"
|
| +#include "net/url_request/url_request_test_util.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +
|
| +namespace content {
|
| +
|
| +namespace {
|
| +
|
| +// A URLRequestJobFactory that will return URLRequestContentJobWithCallbacks
|
| +// instances for content:// scheme URLs.
|
| +class CallbacksJobFactory : public net::URLRequestJobFactory {
|
| + public:
|
| + class JobObserver {
|
| + public:
|
| + virtual void OnJobCreated(URLRequestContentJob* job) = 0;
|
| + };
|
| +
|
| + CallbacksJobFactory(const base::FilePath& path, JobObserver* observer)
|
| + : path_(path), observer_(observer) {
|
| + }
|
| +
|
| + ~CallbacksJobFactory() override {}
|
| +
|
| + net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
|
| + const std::string& scheme,
|
| + net::URLRequest* request,
|
| + net::NetworkDelegate* network_delegate) const override {
|
| + URLRequestContentJob* job =
|
| + new URLRequestContentJob(
|
| + request,
|
| + network_delegate,
|
| + path_,
|
| + const_cast<base::MessageLoop*>(&message_loop_)->task_runner());
|
| + observer_->OnJobCreated(job);
|
| + return job;
|
| + }
|
| +
|
| + net::URLRequestJob* MaybeInterceptRedirect(
|
| + net::URLRequest* request,
|
| + net::NetworkDelegate* network_delegate,
|
| + const GURL& location) const override {
|
| + return nullptr;
|
| + }
|
| +
|
| + net::URLRequestJob* MaybeInterceptResponse(
|
| + net::URLRequest* request,
|
| + net::NetworkDelegate* network_delegate) const override {
|
| + return nullptr;
|
| + }
|
| +
|
| + bool IsHandledProtocol(const std::string& scheme) const override {
|
| + return scheme == "content";
|
| + }
|
| +
|
| + bool IsHandledURL(const GURL& url) const override {
|
| + return IsHandledProtocol(url.scheme());
|
| + }
|
| +
|
| + bool IsSafeRedirectTarget(const GURL& location) const override {
|
| + return false;
|
| + }
|
| +
|
| + private:
|
| + base::MessageLoop message_loop_;
|
| + base::FilePath path_;
|
| + JobObserver* observer_;
|
| +};
|
| +
|
| +class JobObserverImpl : public CallbacksJobFactory::JobObserver {
|
| + public:
|
| + void OnJobCreated(URLRequestContentJob* job) override {
|
| + jobs_.push_back(job);
|
| + }
|
| +
|
| + typedef std::vector<scoped_refptr<URLRequestContentJob> > JobList;
|
| +
|
| + const JobList& jobs() { return jobs_; }
|
| +
|
| + protected:
|
| + JobList jobs_;
|
| +};
|
| +
|
| +// A simple holder for start/end used in http range requests.
|
| +struct Range {
|
| + int start;
|
| + int end;
|
| +
|
| + explicit Range(int start, int end) {
|
| + this->start = start;
|
| + this->end = end;
|
| + }
|
| +};
|
| +
|
| +// A superclass for tests of the OnSeekComplete / OnReadComplete functions of
|
| +// URLRequestContentJob.
|
| +class URLRequestContentJobTest : public testing::Test {
|
| + public:
|
| + URLRequestContentJobTest();
|
| +
|
| + protected:
|
| + // This inserts an image file into the android MediaStore and retrieves the
|
| + // content URI. Then creates and runs a URLRequestContentJob to get the
|
| + // contents out of it. If a Range is provided, this function will add the
|
| + // appropriate Range http header to the request and verify the bytes
|
| + // retrieved.
|
| + void RunRequest(const Range* range);
|
| +
|
| + JobObserverImpl observer_;
|
| + net::TestURLRequestContext context_;
|
| + net::TestDelegate delegate_;
|
| +};
|
| +
|
| +URLRequestContentJobTest::URLRequestContentJobTest() {}
|
| +
|
| +void URLRequestContentJobTest::RunRequest(const Range* range) {
|
| + base::FilePath test_dir;
|
| + PathService::Get(base::DIR_SOURCE_ROOT, &test_dir);
|
| + test_dir = test_dir.AppendASCII("content");
|
| + test_dir = test_dir.AppendASCII("test");
|
| + test_dir = test_dir.AppendASCII("data");
|
| + test_dir = test_dir.AppendASCII("android");
|
| + ASSERT_TRUE(base::PathExists(test_dir));
|
| + base::FilePath image_file = test_dir.Append(FILE_PATH_LITERAL("red.png"));
|
| +
|
| + // Insert the image into MediaStore. MediaStore will do some conversions, and
|
| + // return the content URI.
|
| + base::FilePath path = base::InsertImageIntoMediaStore(image_file);
|
| + EXPECT_TRUE(path.IsContentUri());
|
| + EXPECT_TRUE(base::PathExists(path));
|
| + int64 file_size;
|
| + EXPECT_TRUE(base::GetFileSize(path, &file_size));
|
| + EXPECT_LT(0, file_size);
|
| + CallbacksJobFactory factory(path, &observer_);
|
| + context_.set_job_factory(&factory);
|
| +
|
| + scoped_ptr<net::URLRequest> request(context_.CreateRequest(
|
| + GURL(path.value()), net::DEFAULT_PRIORITY, &delegate_, NULL));
|
| + int expected_length = file_size;
|
| + if (range) {
|
| + ASSERT_GE(range->start, 0);
|
| + ASSERT_GE(range->end, 0);
|
| + ASSERT_LE(range->start, range->end);
|
| + std::string range_value =
|
| + base::StringPrintf("bytes=%d-%d", range->start, range->end);
|
| + request->SetExtraRequestHeaderByName(
|
| + net::HttpRequestHeaders::kRange, range_value, true /*overwrite*/);
|
| + if (range->start <= file_size)
|
| + expected_length =
|
| + std::min(range->end, (int) (file_size - 1)) - range->start + 1;
|
| + else
|
| + expected_length = 0;
|
| + }
|
| + request->Start();
|
| +
|
| + base::RunLoop loop;
|
| + loop.Run();
|
| +
|
| + EXPECT_FALSE(delegate_.request_failed());
|
| + ASSERT_EQ(observer_.jobs().size(), 1u);
|
| + EXPECT_EQ(delegate_.bytes_received(), expected_length);
|
| +}
|
| +
|
| +TEST_F(URLRequestContentJobTest, ContentURIWithoutRange) {
|
| + RunRequest(NULL);
|
| +}
|
| +
|
| +TEST_F(URLRequestContentJobTest, ContentURIWithSmallRange) {
|
| + Range range(1, 10);
|
| + RunRequest(&range);
|
| +}
|
| +
|
| +TEST_F(URLRequestContentJobTest, ContentURIWithLargeRange) {
|
| + Range range(1, 100000);
|
| + RunRequest(&range);
|
| +}
|
| +
|
| +TEST_F(URLRequestContentJobTest, ContentURIWithZeroRange) {
|
| + Range range(0, 0);
|
| + RunRequest(&range);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +} // namespace content
|
|
|