blob: 2fa55b77ade7b9aa0626375f9c8b722fc15988cc [file] [log] [blame]
// Copyright 2021 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 "google_apis/drive/drive_base_requests.h"
#include <stdint.h>
#include <memory>
#include <utility>
#include "base/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/values.h"
#include "google_apis/common/dummy_auth_service.h"
#include "google_apis/common/request_sender.h"
#include "google_apis/common/test_util.h"
#include "google_apis/drive/drive_api_parser.h"
#include "google_apis/drive/drive_api_requests.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "services/network/test/fake_test_cert_verifier_params_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace google_apis {
namespace {
class FakeMultipartUploadRequest : public MultipartUploadRequestBase {
public:
FakeMultipartUploadRequest(base::SequencedTaskRunner* blocking_task_runner,
const std::string& metadata_json,
const std::string& content_type,
int64_t content_length,
const base::FilePath& local_file_path,
FileResourceCallback callback,
google_apis::ProgressCallback progress_callback,
const GURL& url,
std::string* upload_content_type,
std::string* upload_content_data)
: MultipartUploadRequestBase(blocking_task_runner,
metadata_json,
content_type,
content_length,
local_file_path,
std::move(callback),
progress_callback),
url_(url),
upload_content_type_(upload_content_type),
upload_content_data_(upload_content_data) {}
~FakeMultipartUploadRequest() override = default;
std::string GetRequestType() const override { return "POST"; }
bool GetContentData(std::string* content_type,
std::string* content_data) override {
const bool result =
MultipartUploadRequestBase::GetContentData(content_type, content_data);
*upload_content_type_ = *content_type;
*upload_content_data_ = *content_data;
return result;
}
protected:
GURL GetURL() const override { return url_; }
private:
const GURL url_;
const raw_ptr<std::string> upload_content_type_;
const raw_ptr<std::string> upload_content_data_;
};
} // namespace
class DriveBaseRequestsTest : public testing::Test {
public:
DriveBaseRequestsTest() {
mojo::Remote<network::mojom::NetworkService> network_service_remote;
network_service_ = network::NetworkService::Create(
network_service_remote.BindNewPipeAndPassReceiver());
network::mojom::NetworkContextParamsPtr context_params =
network::mojom::NetworkContextParams::New();
// Use a dummy CertVerifier that always passes cert verification, since
// these unittests don't need to test CertVerifier behavior.
context_params->cert_verifier_params =
network::FakeTestCertVerifierParamsFactory::GetCertVerifierParams();
network_service_remote->CreateNetworkContext(
network_context_.BindNewPipeAndPassReceiver(),
std::move(context_params));
mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver>
default_observer_receiver;
network::mojom::NetworkServiceParamsPtr network_service_params =
network::mojom::NetworkServiceParams::New();
network_service_params->default_observer =
default_observer_receiver.InitWithNewPipeAndPassRemote();
network_service_remote->SetParams(std::move(network_service_params));
network::mojom::URLLoaderFactoryParamsPtr params =
network::mojom::URLLoaderFactoryParams::New();
params->process_id = network::mojom::kBrowserProcessId;
params->is_corb_enabled = false;
network_context_->CreateURLLoaderFactory(
url_loader_factory_.BindNewPipeAndPassReceiver(), std::move(params));
test_shared_loader_factory_ =
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
url_loader_factory_.get());
}
void SetUp() override {
sender_ = std::make_unique<RequestSender>(
std::make_unique<DummyAuthService>(), test_shared_loader_factory_,
task_environment_.GetMainThreadTaskRunner(),
std::string(), /* custom user agent */
TRAFFIC_ANNOTATION_FOR_TESTS);
test_server_.RegisterRequestHandler(base::BindRepeating(
&DriveBaseRequestsTest::HandleRequest, base::Unretained(this)));
ASSERT_TRUE(test_server_.Start());
}
void TearDown() override {
// Deleting the sender here will delete all request objects.
sender_.reset();
// Wait for any DeleteSoon tasks to run.
task_environment_.RunUntilIdle();
}
std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
const net::test_server::HttpRequest& request) {
std::unique_ptr<net::test_server::BasicHttpResponse> response(
new net::test_server::BasicHttpResponse);
response->set_code(response_code_);
response->set_content(response_body_);
response->set_content_type("application/json");
return std::move(response);
}
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::MainThreadType::IO};
std::unique_ptr<network::mojom::NetworkService> network_service_;
mojo::Remote<network::mojom::NetworkContext> network_context_;
mojo::Remote<network::mojom::URLLoaderFactory> url_loader_factory_;
scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
test_shared_loader_factory_;
std::unique_ptr<RequestSender> sender_;
net::EmbeddedTestServer test_server_;
net::HttpStatusCode response_code_ = net::HTTP_OK;
std::string response_body_;
};
typedef DriveBaseRequestsTest MultipartUploadRequestBaseTest;
TEST_F(MultipartUploadRequestBaseTest, Basic) {
response_code_ = net::HTTP_OK;
response_body_ = "{\"kind\": \"drive#file\", \"id\": \"file_id\"}";
std::unique_ptr<google_apis::FileResource> file;
ApiErrorCode error = OTHER_ERROR;
base::RunLoop run_loop;
const base::FilePath source_path =
google_apis::test_util::GetTestFilePath("drive/text.txt");
std::string upload_content_type;
std::string upload_content_data;
std::unique_ptr<FakeMultipartUploadRequest> multipart_request =
std::make_unique<FakeMultipartUploadRequest>(
sender_->blocking_task_runner(), "{json:\"test\"}", "text/plain", 10,
source_path,
test_util::CreateQuitCallback(
&run_loop, test_util::CreateCopyResultCallback(&error, &file)),
ProgressCallback(), test_server_.base_url(), &upload_content_type,
&upload_content_data);
multipart_request->SetBoundaryForTesting("TESTBOUNDARY");
sender_->StartRequestWithAuthRetry(
std::make_unique<drive::SingleBatchableDelegateRequest>(
sender_.get(), std::move(multipart_request)));
run_loop.Run();
EXPECT_EQ("multipart/related; boundary=TESTBOUNDARY", upload_content_type);
EXPECT_EQ(
"--TESTBOUNDARY\n"
"Content-Type: application/json\n"
"\n"
"{json:\"test\"}\n"
"--TESTBOUNDARY\n"
"Content-Type: text/plain\n"
"\n"
"This is a sample file. I like chocolate and chips.\n"
"\n"
"--TESTBOUNDARY--",
upload_content_data);
ASSERT_EQ(HTTP_SUCCESS, error);
EXPECT_EQ("file_id", file->file_id());
}
} // namespace google_apis