Commit 9f70641b authored by Ting Shao's avatar Ting Shao Committed by Commit Bot

ServiceWorker: Refactor FakeNetworkURLLoaderFactory for unit test

Extend FakeNetworkURLLoaderFactory by making response headers, body
and completion status configurable.

Bug: 648295

Change-Id: Ib033ab617fb8efba8d3d81c9ea5651801a60a3a6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1595656
Commit-Queue: Ting Shao <ting.shao@intel.com>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarMakoto Shimazu <shimazu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#666573}
parent 3845b3c8
...@@ -10,10 +10,80 @@ ...@@ -10,10 +10,80 @@
namespace content { namespace content {
namespace {
const char kDefaultHeader[] = "HTTP/1.1 200 OK\n\n";
const char kDefaultBody[] = "this body came from the network";
const char kDefaultHeaderForJS[] =
"HTTP/1.1 200 OK\n"
"Content-Type: application/javascript\n\n";
const char kDefaultBodyForJS[] = "/*this body came from the network*/";
} // namespace
FakeNetworkURLLoaderFactory::ResponseInfo::ResponseInfo(
const std::string& headers,
const std::string& body,
bool network_accessed,
net::Error error_code)
: headers(headers),
body(body),
network_accessed(network_accessed),
error_code(error_code) {}
FakeNetworkURLLoaderFactory::ResponseInfo::ResponseInfo() = default;
FakeNetworkURLLoaderFactory::ResponseInfo::ResponseInfo(
FakeNetworkURLLoaderFactory::ResponseInfo&& info) = default;
FakeNetworkURLLoaderFactory::ResponseInfo::~ResponseInfo() = default;
FakeNetworkURLLoaderFactory::ResponseInfo&
FakeNetworkURLLoaderFactory::ResponseInfo::operator=(
FakeNetworkURLLoaderFactory::ResponseInfo&& info) = default;
FakeNetworkURLLoaderFactory::FakeNetworkURLLoaderFactory() = default; FakeNetworkURLLoaderFactory::FakeNetworkURLLoaderFactory() = default;
FakeNetworkURLLoaderFactory::FakeNetworkURLLoaderFactory(
const std::string& headers,
const std::string& body,
bool network_accessed,
net::Error error_code)
: user_defined_default_response_info_(
std::make_unique<FakeNetworkURLLoaderFactory::ResponseInfo>(
headers,
body,
network_accessed,
error_code)) {}
FakeNetworkURLLoaderFactory::~FakeNetworkURLLoaderFactory() = default; FakeNetworkURLLoaderFactory::~FakeNetworkURLLoaderFactory() = default;
void FakeNetworkURLLoaderFactory::SetResponse(const GURL& url,
const std::string& headers,
const std::string& body,
bool network_accessed,
net::Error error_code) {
response_info_map_[url] =
ResponseInfo(headers, body, network_accessed, error_code);
}
const FakeNetworkURLLoaderFactory::ResponseInfo&
FakeNetworkURLLoaderFactory::FindResponseInfo(const GURL& url) const {
auto it = response_info_map_.find(url);
if (it != response_info_map_.end())
return it->second;
if (user_defined_default_response_info_)
return *user_defined_default_response_info_;
static const base::NoDestructor<ResponseInfo> kDefaultResponseInfo(
kDefaultHeader, kDefaultBody, /*network_accessed=*/true, net::OK);
static const base::NoDestructor<ResponseInfo> kDefaultJsResponseInfo(
kDefaultHeaderForJS, kDefaultBodyForJS, /*network_accessed=*/true,
net::OK);
bool is_js =
base::EndsWith(url.path(), ".js", base::CompareCase::INSENSITIVE_ASCII);
return is_js ? *kDefaultJsResponseInfo : *kDefaultResponseInfo;
}
void FakeNetworkURLLoaderFactory::CreateLoaderAndStart( void FakeNetworkURLLoaderFactory::CreateLoaderAndStart(
network::mojom::URLLoaderRequest request, network::mojom::URLLoaderRequest request,
int32_t routing_id, int32_t routing_id,
...@@ -22,34 +92,28 @@ void FakeNetworkURLLoaderFactory::CreateLoaderAndStart( ...@@ -22,34 +92,28 @@ void FakeNetworkURLLoaderFactory::CreateLoaderAndStart(
const network::ResourceRequest& url_request, const network::ResourceRequest& url_request,
network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
bool is_js = base::EndsWith(url_request.url.path(), ".js", const ResponseInfo& response_info = FindResponseInfo(url_request.url);
base::CompareCase::INSENSITIVE_ASCII);
std::string headers = "HTTP/1.1 200 OK\n";
if (is_js)
headers += "Content-Type: application/javascript\n";
headers += "\n";
net::HttpResponseInfo info; net::HttpResponseInfo info;
info.headers = base::MakeRefCounted<net::HttpResponseHeaders>( info.headers = base::MakeRefCounted<net::HttpResponseHeaders>(
net::HttpUtil::AssembleRawHeaders(headers)); net::HttpUtil::AssembleRawHeaders(response_info.headers));
network::ResourceResponseHead response; network::ResourceResponseHead response;
response.headers = info.headers; response.headers = info.headers;
response.headers->GetMimeType(&response.mime_type); response.headers->GetMimeType(&response.mime_type);
response.network_accessed = response_info.network_accessed;
client->OnReceiveResponse(response); client->OnReceiveResponse(response);
std::string body = "this body came from the network"; uint32_t bytes_written = response_info.body.size();
if (is_js)
body = "/*" + body + "*/";
uint32_t bytes_written = body.size();
mojo::ScopedDataPipeProducerHandle producer_handle; mojo::ScopedDataPipeProducerHandle producer_handle;
mojo::ScopedDataPipeConsumerHandle consumer_handle; mojo::ScopedDataPipeConsumerHandle consumer_handle;
CHECK_EQ(MOJO_RESULT_OK, CHECK_EQ(MOJO_RESULT_OK,
mojo::CreateDataPipe(nullptr, &producer_handle, &consumer_handle)); mojo::CreateDataPipe(nullptr, &producer_handle, &consumer_handle));
producer_handle->WriteData(body.data(), &bytes_written, producer_handle->WriteData(response_info.body.data(), &bytes_written,
MOJO_WRITE_DATA_FLAG_ALL_OR_NONE); MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
client->OnStartLoadingResponseBody(std::move(consumer_handle)); client->OnStartLoadingResponseBody(std::move(consumer_handle));
network::URLLoaderCompletionStatus status; network::URLLoaderCompletionStatus status;
status.error_code = net::OK; status.error_code = response_info.error_code;
client->OnComplete(status); client->OnComplete(status);
} }
......
...@@ -10,14 +10,29 @@ ...@@ -10,14 +10,29 @@
namespace content { namespace content {
// A URLLoaderFactory that returns 200 OK with a simple body to any request. // A configurable URLLoaderFactory:
// Any request path that ends in ".js" gets a body of // 1. By default, it returns 200 OK with a simple body to any request:
// "/*this body came from the network*/". Other requests get // If request path ends in ".js", body is:
// "/*this body came from the network*/". Otherwise, body is:
// "this body came from the network". // "this body came from the network".
// 2. The default response can be overridden through the non-default
// constructor.
// 3. Call SetResponse() to set specific response for a url.
class FakeNetworkURLLoaderFactory final class FakeNetworkURLLoaderFactory final
: public network::mojom::URLLoaderFactory { : public network::mojom::URLLoaderFactory {
public: public:
// If this constructor is used:
// A default response is used for any url request that is not configured
// through SetResponse().
FakeNetworkURLLoaderFactory(); FakeNetworkURLLoaderFactory();
// If this constructor is used:
// The provided response is used for any url request that is not configured
// through SetResponse().
FakeNetworkURLLoaderFactory(const std::string& headers,
const std::string& body,
bool network_accessed,
net::Error error_code);
~FakeNetworkURLLoaderFactory() override; ~FakeNetworkURLLoaderFactory() override;
// network::mojom::URLLoaderFactory implementation. // network::mojom::URLLoaderFactory implementation.
...@@ -32,7 +47,46 @@ class FakeNetworkURLLoaderFactory final ...@@ -32,7 +47,46 @@ class FakeNetworkURLLoaderFactory final
void Clone(network::mojom::URLLoaderFactoryRequest request) override; void Clone(network::mojom::URLLoaderFactoryRequest request) override;
// Sets the response for a specific url. CreateLoaderAndStart() uses this
// response instead of the default.
void SetResponse(const GURL& url,
const std::string& headers,
const std::string& body,
bool network_accessed,
net::Error error_code);
private: private:
class ResponseInfo {
public:
ResponseInfo();
ResponseInfo(ResponseInfo&& info);
ResponseInfo(const std::string& headers,
const std::string& body,
bool network_accessed,
net::Error error_code);
~ResponseInfo();
ResponseInfo& operator=(ResponseInfo&& info);
GURL url;
std::string headers;
std::string body;
bool network_accessed = true;
net::Error error_code = net::OK;
};
// Returns the ResponseInfo for the |url|, it follows the order:
// 1. Returns the matching entry in |response_info_map_| if exists.
// 2. Returns |user_defined_default_response_info_| if it's set.
// 3. Returns default response info (defined inside this method).
const ResponseInfo& FindResponseInfo(const GURL& url) const;
// This is user-defined default response info, it overrides the default
// response info.
std::unique_ptr<ResponseInfo> user_defined_default_response_info_;
// User-defined URL => ResponseInfo map.
base::flat_map<GURL, ResponseInfo> response_info_map_;
mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_; mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
DISALLOW_COPY_AND_ASSIGN(FakeNetworkURLLoaderFactory); DISALLOW_COPY_AND_ASSIGN(FakeNetworkURLLoaderFactory);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment