Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Unified Diff: headless/public/util/generic_url_request_job_test.cc

Issue 2815003003: Headless (breaking change): A better GenericURLRequestJob::Delegate API (Closed)
Patch Set: Changes for Sami Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « headless/public/util/generic_url_request_job.cc ('k') | headless/public/util/http_url_fetcher.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: headless/public/util/generic_url_request_job_test.cc
diff --git a/headless/public/util/generic_url_request_job_test.cc b/headless/public/util/generic_url_request_job_test.cc
index 02e52cc082187e1b5f8bb08d8e04df252b3c4f61..b4aec67f81b1ea7b60cea063ac6b40ed7e8e46be 100644
--- a/headless/public/util/generic_url_request_job_test.cc
+++ b/headless/public/util/generic_url_request_job_test.cc
@@ -18,11 +18,15 @@
#include "headless/public/util/expedited_dispatcher.h"
#include "headless/public/util/testing/generic_url_request_mocks.h"
#include "headless/public/util/url_fetcher.h"
+#include "net/base/elements_upload_data_stream.h"
+#include "net/base/upload_bytes_element_reader.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using testing::_;
+
std::ostream& operator<<(std::ostream& os, const base::Value& value) {
std::string json;
base::JSONWriter::WriteWithOptions(
@@ -41,21 +45,25 @@ namespace headless {
namespace {
+class MockDelegate : public MockGenericURLRequestJobDelegate {
+ public:
+ MOCK_METHOD2(OnResourceLoadFailed,
+ void(const Request* request, net::Error error));
+};
+
class MockFetcher : public URLFetcher {
public:
MockFetcher(base::DictionaryValue* fetch_request,
- const std::string& json_reply)
- : fetch_reply_(base::JSONReader::Read(json_reply, base::JSON_PARSE_RFC)),
- fetch_request_(fetch_request) {
- CHECK(fetch_reply_) << "Invalid json: " << json_reply;
- }
+ std::map<std::string, std::string>* json_fetch_reply_map)
+ : json_fetch_reply_map_(json_fetch_reply_map),
+ fetch_request_(fetch_request) {}
~MockFetcher() override {}
void StartFetch(const GURL& url,
const std::string& method,
+ const std::string& post_data,
const net::HttpRequestHeaders& request_headers,
- const std::string& devtools_request_id,
ResultListener* result_listener) override {
// Record the request.
fetch_request_->SetString("url", url.spec());
@@ -65,10 +73,22 @@ class MockFetcher : public URLFetcher {
headers->SetString(it.name(), it.value());
}
fetch_request_->Set("headers", std::move(headers));
+ if (!post_data.empty())
+ fetch_request_->SetString("post_data", post_data);
+
+ const auto find_it = json_fetch_reply_map_->find(url.spec());
+ if (find_it == json_fetch_reply_map_->end()) {
+ result_listener->OnFetchStartError(net::ERR_ADDRESS_UNREACHABLE);
+ return;
+ }
// Return the canned response.
+ std::unique_ptr<base::Value> fetch_reply(
+ base::JSONReader::Read(find_it->second, base::JSON_PARSE_RFC));
+ CHECK(fetch_reply) << "Invalid json: " << find_it->second;
+
base::DictionaryValue* reply_dictionary;
- ASSERT_TRUE(fetch_reply_->GetAsDictionary(&reply_dictionary));
+ ASSERT_TRUE(fetch_reply->GetAsDictionary(&reply_dictionary));
std::string final_url;
ASSERT_TRUE(reply_dictionary->GetString("url", &final_url));
int http_response_code;
@@ -94,7 +114,7 @@ class MockFetcher : public URLFetcher {
}
private:
- std::unique_ptr<base::Value> fetch_reply_;
+ std::map<std::string, std::string>* json_fetch_reply_map_; // NOT OWNED
base::DictionaryValue* fetch_request_; // NOT OWNED
std::string response_data_; // Here to ensure the required lifetime.
};
@@ -102,13 +122,13 @@ class MockFetcher : public URLFetcher {
class MockProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
public:
// Details of the fetch will be stored in |fetch_request|.
- // The fetch response will be created from parsing |json_fetch_reply_|.
+ // The fetch response will be created from parsing |json_fetch_reply_map|.
MockProtocolHandler(base::DictionaryValue* fetch_request,
- std::string* json_fetch_reply,
+ std::map<std::string, std::string>* json_fetch_reply_map,
URLRequestDispatcher* dispatcher,
GenericURLRequestJob::Delegate* job_delegate)
: fetch_request_(fetch_request),
- json_fetch_reply_(json_fetch_reply),
+ json_fetch_reply_map_(json_fetch_reply_map),
job_delegate_(job_delegate),
dispatcher_(dispatcher) {}
@@ -118,13 +138,13 @@ class MockProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
net::NetworkDelegate* network_delegate) const override {
return new GenericURLRequestJob(
request, network_delegate, dispatcher_,
- base::MakeUnique<MockFetcher>(fetch_request_, *json_fetch_reply_),
+ base::MakeUnique<MockFetcher>(fetch_request_, json_fetch_reply_map_),
job_delegate_);
}
private:
base::DictionaryValue* fetch_request_; // NOT OWNED
- std::string* json_fetch_reply_; // NOT OWNED
+ std::map<std::string, std::string>* json_fetch_reply_map_; // NOT OWNED
GenericURLRequestJob::Delegate* job_delegate_; // NOT OWNED
URLRequestDispatcher* dispatcher_; // NOT OWNED
};
@@ -136,16 +156,16 @@ class GenericURLRequestJobTest : public testing::Test {
GenericURLRequestJobTest() : dispatcher_(message_loop_.task_runner()) {
url_request_job_factory_.SetProtocolHandler(
"https", base::WrapUnique(new MockProtocolHandler(
- &fetch_request_, &json_fetch_reply_, &dispatcher_,
+ &fetch_request_, &json_fetch_reply_map_, &dispatcher_,
&job_delegate_)));
url_request_context_.set_job_factory(&url_request_job_factory_);
url_request_context_.set_cookie_store(&cookie_store_);
}
- std::unique_ptr<net::URLRequest> CreateAndCompleteJob(
+ std::unique_ptr<net::URLRequest> CreateAndCompleteGetJob(
const GURL& url,
const std::string& json_reply) {
- json_fetch_reply_ = json_reply;
+ json_fetch_reply_map_[url.spec()] = json_reply;
std::unique_ptr<net::URLRequest> request(url_request_context_.CreateRequest(
url, net::DEFAULT_PRIORITY, &request_delegate_));
@@ -164,17 +184,57 @@ class GenericURLRequestJobTest : public testing::Test {
MockURLRequestDelegate request_delegate_;
base::DictionaryValue fetch_request_; // The request sent to MockFetcher.
- std::string json_fetch_reply_; // The reply to be sent by MockFetcher.
- MockGenericURLRequestJobDelegate job_delegate_;
+ std::map<std::string, std::string>
+ json_fetch_reply_map_; // Replies to be sent by MockFetcher.
+ MockDelegate job_delegate_;
};
-TEST_F(GenericURLRequestJobTest, BasicRequestParams) {
- // TODO(alexclarke): Lobby for raw string literals and use them here!
- json_fetch_reply_ =
- "{\"url\":\"https://example.com\","
- " \"http_response_code\":200,"
- " \"data\":\"Reply\","
- " \"headers\":{\"Content-Type\":\"text/plain\"}}";
+TEST_F(GenericURLRequestJobTest, BasicGetRequestParams) {
+ json_fetch_reply_map_["https://example.com/"] = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Reply",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
+
+ std::unique_ptr<net::URLRequest> request(url_request_context_.CreateRequest(
+ GURL("https://example.com"), net::DEFAULT_PRIORITY, &request_delegate_));
+ request->SetReferrer("https://referrer.example.com");
+ request->SetExtraRequestHeaderByName("Extra-Header", "Value", true);
+ request->SetExtraRequestHeaderByName("User-Agent", "TestBrowser", true);
+ request->SetExtraRequestHeaderByName("Accept", "text/plain", true);
+ request->Start();
+ base::RunLoop().RunUntilIdle();
+
+ std::string expected_request_json = R"(
+ {
+ "url": "https://example.com/",
+ "method": "GET",
+ "headers": {
+ "Accept": "text/plain",
+ "Cookie": "",
+ "Extra-Header": "Value",
+ "Referer": "https://referrer.example.com/",
+ "User-Agent": "TestBrowser"
+ }
+ })";
+
+ EXPECT_THAT(fetch_request_, MatchesJson(expected_request_json));
+}
+
+TEST_F(GenericURLRequestJobTest, BasicPostRequestParams) {
+ json_fetch_reply_map_["https://example.com/"] = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Reply",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
std::unique_ptr<net::URLRequest> request(url_request_context_.CreateRequest(
GURL("https://example.com"), net::DEFAULT_PRIORITY, &request_delegate_));
@@ -182,33 +242,46 @@ TEST_F(GenericURLRequestJobTest, BasicRequestParams) {
request->SetExtraRequestHeaderByName("Extra-Header", "Value", true);
request->SetExtraRequestHeaderByName("User-Agent", "TestBrowser", true);
request->SetExtraRequestHeaderByName("Accept", "text/plain", true);
+ request->set_method("POST");
+
+ std::string post_data = "lorem ipsom";
+ request->set_upload(net::ElementsUploadDataStream::CreateWithReader(
+ base::MakeUnique<net::UploadBytesElementReader>(post_data.data(),
+ post_data.size()),
+ 0));
request->Start();
base::RunLoop().RunUntilIdle();
- std::string expected_request_json =
- "{\"url\": \"https://example.com/\","
- " \"method\": \"GET\","
- " \"headers\": {"
- " \"Accept\": \"text/plain\","
- " \"Cookie\": \"\","
- " \"Extra-Header\": \"Value\","
- " \"Referer\": \"https://referrer.example.com/\","
- " \"User-Agent\": \"TestBrowser\""
- " }"
- "}";
+ std::string expected_request_json = R"(
+ {
+ "url": "https://example.com/",
+ "method": "POST",
+ "post_data": "lorem ipsom",
+ "headers": {
+ "Accept": "text/plain",
+ "Cookie": "",
+ "Extra-Header": "Value",
+ "Referer": "https://referrer.example.com/",
+ "User-Agent": "TestBrowser"
+ }
+ })";
EXPECT_THAT(fetch_request_, MatchesJson(expected_request_json));
}
TEST_F(GenericURLRequestJobTest, BasicRequestProperties) {
- std::string reply =
- "{\"url\":\"https://example.com\","
- " \"http_response_code\":200,"
- " \"data\":\"Reply\","
- " \"headers\":{\"Content-Type\":\"text/html; charset=UTF-8\"}}";
+ std::string reply = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Reply",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
std::unique_ptr<net::URLRequest> request(
- CreateAndCompleteJob(GURL("https://example.com"), reply));
+ CreateAndCompleteGetJob(GURL("https://example.com"), reply));
EXPECT_EQ(200, request->GetResponseCode());
@@ -227,14 +300,18 @@ TEST_F(GenericURLRequestJobTest, BasicRequestProperties) {
}
TEST_F(GenericURLRequestJobTest, BasicRequestContents) {
- std::string reply =
- "{\"url\":\"https://example.com\","
- " \"http_response_code\":200,"
- " \"data\":\"Reply\","
- " \"headers\":{\"Content-Type\":\"text/html; charset=UTF-8\"}}";
+ std::string reply = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Reply",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
std::unique_ptr<net::URLRequest> request(
- CreateAndCompleteJob(GURL("https://example.com"), reply));
+ CreateAndCompleteGetJob(GURL("https://example.com"), reply));
const int kBufferSize = 256;
scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
@@ -249,14 +326,18 @@ TEST_F(GenericURLRequestJobTest, BasicRequestContents) {
}
TEST_F(GenericURLRequestJobTest, ReadInParts) {
- std::string reply =
- "{\"url\":\"https://example.com\","
- " \"http_response_code\":200,"
- " \"data\":\"Reply\","
- " \"headers\":{\"Content-Type\":\"text/html; charset=UTF-8\"}}";
+ std::string reply = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Reply",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
std::unique_ptr<net::URLRequest> request(
- CreateAndCompleteJob(GURL("https://example.com"), reply));
+ CreateAndCompleteGetJob(GURL("https://example.com"), reply));
const int kBufferSize = 3;
scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
@@ -332,41 +413,200 @@ TEST_F(GenericURLRequestJobTest, RequestWithCookies) {
/* http_only */ false, net::CookieSameSite::NO_RESTRICTION,
net::COOKIE_PRIORITY_DEFAULT));
- std::string reply =
- "{\"url\":\"https://example.com\","
- " \"http_response_code\":200,"
- " \"data\":\"Reply\","
- " \"headers\":{\"Content-Type\":\"text/html; charset=UTF-8\"}}";
+ std::string reply = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Reply",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
std::unique_ptr<net::URLRequest> request(
- CreateAndCompleteJob(GURL("https://example.com"), reply));
-
- std::string expected_request_json =
- "{\"url\": \"https://example.com/\","
- " \"method\": \"GET\","
- " \"headers\": {"
- " \"Cookie\": \"basic_cookie=1; secure_cookie=2; http_only_cookie=3\","
- " \"Referer\": \"\""
- " }"
- "}";
+ CreateAndCompleteGetJob(GURL("https://example.com"), reply));
+
+ std::string expected_request_json = R"(
+ {
+ "url": "https://example.com/",
+ "method": "GET",
+ "headers": {
+ "Cookie": "basic_cookie=1; secure_cookie=2; http_only_cookie=3",
+ "Referer": ""
+ }
+ })";
EXPECT_THAT(fetch_request_, MatchesJson(expected_request_json));
}
TEST_F(GenericURLRequestJobTest, DelegateBlocksLoading) {
- std::string reply =
- "{\"url\":\"https://example.com\","
- " \"http_response_code\":200,"
- " \"data\":\"Reply\","
- " \"headers\":{\"Content-Type\":\"text/html; charset=UTF-8\"}}";
-
- job_delegate_.SetShouldBlock(true);
+ std::string reply = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Reply",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
+
+ job_delegate_.SetPolicy(base::Bind([](PendingRequest* pending_request) {
+ pending_request->BlockRequest(net::ERR_FILE_NOT_FOUND);
+ }));
std::unique_ptr<net::URLRequest> request(
- CreateAndCompleteJob(GURL("https://example.com"), reply));
+ CreateAndCompleteGetJob(GURL("https://example.com"), reply));
EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
EXPECT_EQ(net::ERR_FILE_NOT_FOUND, request->status().error());
}
+TEST_F(GenericURLRequestJobTest, DelegateModifiesRequest) {
+ json_fetch_reply_map_["https://example.com/"] = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Welcome to example.com",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
+
+ json_fetch_reply_map_["https://othersite.com/"] = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Welcome to othersite.com",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
+
+ // Turn the GET into a POST to a different site.
+ job_delegate_.SetPolicy(base::Bind([](PendingRequest* pending_request) {
+ net::HttpRequestHeaders headers;
+ headers.SetHeader("TestHeader", "Hello");
+ pending_request->ModifyRequest(GURL("https://othersite.com"), "POST",
+ "Some post data!", headers);
+ }));
+
+ std::unique_ptr<net::URLRequest> request(url_request_context_.CreateRequest(
+ GURL("https://example.com"), net::DEFAULT_PRIORITY, &request_delegate_));
+ request->Start();
+ base::RunLoop().RunUntilIdle();
+
+ std::string expected_request_json = R"(
+ {
+ "url": "https://othersite.com/",
+ "method": "POST",
+ "post_data": "Some post data!",
+ "headers": {
+ "TestHeader": "Hello"
+ }
+ })";
+
+ EXPECT_THAT(fetch_request_, MatchesJson(expected_request_json));
+
+ EXPECT_EQ(200, request->GetResponseCode());
+ // The modification should not be visible to the URlRequest.
+ EXPECT_EQ("https://example.com/", request->url().spec());
+ EXPECT_EQ("GET", request->method());
+
+ const int kBufferSize = 256;
+ scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
+ int bytes_read;
+ EXPECT_TRUE(request->Read(buffer.get(), kBufferSize, &bytes_read));
+ EXPECT_EQ(24, bytes_read);
+ EXPECT_EQ("Welcome to othersite.com",
+ std::string(buffer->data(), bytes_read));
+}
+
+TEST_F(GenericURLRequestJobTest, DelegateMocks404Response) {
+ std::string reply = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Reply",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
+
+ job_delegate_.SetPolicy(base::Bind([](PendingRequest* pending_request) {
+ std::unique_ptr<GenericURLRequestJob::MockResponseData> mock_response_data(
+ new GenericURLRequestJob::MockResponseData());
+ mock_response_data->http_response_code = 404;
+ mock_response_data->response_data = "HTTP/1.1 404 Not Found\r\n\r\n";
+ pending_request->MockResponse(std::move(mock_response_data));
+ }));
+
+ std::unique_ptr<net::URLRequest> request(
+ CreateAndCompleteGetJob(GURL("https://example.com"), reply));
+
+ EXPECT_EQ(404, request->GetResponseCode());
+}
+
+TEST_F(GenericURLRequestJobTest, DelegateMocks302Response) {
+ job_delegate_.SetPolicy(base::Bind([](PendingRequest* pending_request) {
+ if (pending_request->GetRequest()->GetURLRequest()->url().spec() ==
+ "https://example.com/") {
+ std::unique_ptr<GenericURLRequestJob::MockResponseData>
+ mock_response_data(new GenericURLRequestJob::MockResponseData());
+ mock_response_data->http_response_code = 302;
+ mock_response_data->response_data =
+ "HTTP/1.1 302 Found\r\n"
+ "Location: https://foo.com/\r\n\r\n";
+ pending_request->MockResponse(std::move(mock_response_data));
+ } else {
+ pending_request->AllowRequest();
+ }
+ }));
+
+ json_fetch_reply_map_["https://example.com/"] = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Welcome to example.com",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
+
+ json_fetch_reply_map_["https://foo.com/"] = R"(
+ {
+ "url": "https://example.com",
+ "http_response_code": 200,
+ "data": "Welcome to foo.com",
+ "headers": {
+ "Content-Type": "text/html; charset=UTF-8"
+ }
+ })";
+
+ std::unique_ptr<net::URLRequest> request(url_request_context_.CreateRequest(
+ GURL("https://example.com"), net::DEFAULT_PRIORITY, &request_delegate_));
+ request->Start();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(200, request->GetResponseCode());
+ EXPECT_EQ("https://foo.com/", request->url().spec());
+
+ const int kBufferSize = 256;
+ scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize));
+ int bytes_read;
+ EXPECT_TRUE(request->Read(buffer.get(), kBufferSize, &bytes_read));
+ EXPECT_EQ(18, bytes_read);
+ EXPECT_EQ("Welcome to foo.com", std::string(buffer->data(), bytes_read));
+}
+
+TEST_F(GenericURLRequestJobTest, OnResourceLoadFailed) {
+ EXPECT_CALL(job_delegate_,
+ OnResourceLoadFailed(_, net::ERR_ADDRESS_UNREACHABLE));
+
+ std::unique_ptr<net::URLRequest> request(url_request_context_.CreateRequest(
+ GURL("https://i-dont-exist.com"), net::DEFAULT_PRIORITY,
+ &request_delegate_));
+ request->Start();
+ base::RunLoop().RunUntilIdle();
+}
+
} // namespace headless
« no previous file with comments | « headless/public/util/generic_url_request_job.cc ('k') | headless/public/util/http_url_fetcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698