blob: a799c93707d8bf77559bc6196a451638e7bdc3ff [file] [log] [blame]
// Copyright 2018 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 "chrome/browser/android/explore_sites/explore_sites_fetcher.h"
#include "base/message_loop/message_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/mock_callback.h"
#include "base/test/test_mock_time_task_runner.h"
#include "chrome/browser/android/explore_sites/catalog.pb.h"
#include "chrome/browser/android/explore_sites/explore_sites_types.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_request_status.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "services/network/test/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "url/gurl.h"
using testing::_;
using testing::DoAll;
using testing::Eq;
using testing::SaveArg;
namespace explore_sites {
// TODO(freedjm): Add tests for the headers.
class ExploreSitesFetcherTest : public testing::Test {
public:
ExploreSitesFetcherTest();
void SetUp() override;
ExploreSitesRequestStatus RunFetcherWithNetError(net::Error net_error);
ExploreSitesRequestStatus RunFetcherWithHttpError(
net::HttpStatusCode http_error);
ExploreSitesRequestStatus RunFetcherWithData(const std::string& response_data,
std::string* data_received);
private:
ExploreSitesFetcher::Callback StoreResult();
network::TestURLLoaderFactory::PendingRequest* GetPendingRequest(
size_t index);
ExploreSitesRequestStatus RunFetcher(
base::OnceCallback<void(void)> respond_callback,
std::string* data_received);
void RespondWithData(const std::string& data);
void RespondWithNetError(int net_error);
void RespondWithHttpError(net::HttpStatusCode http_error);
network::TestURLLoaderFactory test_url_loader_factory_;
scoped_refptr<network::SharedURLLoaderFactory>
test_shared_url_loader_factory_;
network::ResourceRequest last_resource_request_;
ExploreSitesRequestStatus last_status_;
std::unique_ptr<std::string> last_data_;
base::MessageLoopForIO message_loop_;
scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
};
ExploreSitesFetcher::Callback ExploreSitesFetcherTest::StoreResult() {
return base::BindLambdaForTesting(
[&](ExploreSitesRequestStatus status, std::unique_ptr<std::string> data) {
last_status_ = status;
last_data_ = std::move(data);
});
}
ExploreSitesFetcherTest::ExploreSitesFetcherTest()
: test_shared_url_loader_factory_(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_)),
task_runner_(new base::TestMockTimeTaskRunner) {
message_loop_.SetTaskRunner(task_runner_);
}
void ExploreSitesFetcherTest::SetUp() {
test_url_loader_factory_.SetInterceptor(
base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
last_resource_request_ = request;
}));
}
ExploreSitesRequestStatus ExploreSitesFetcherTest::RunFetcherWithNetError(
net::Error net_error) {
std::string data_received;
ExploreSitesRequestStatus status =
RunFetcher(base::BindOnce(&ExploreSitesFetcherTest::RespondWithNetError,
base::Unretained(this), net_error),
&data_received);
EXPECT_TRUE(data_received.empty());
return status;
}
ExploreSitesRequestStatus ExploreSitesFetcherTest::RunFetcherWithHttpError(
net::HttpStatusCode http_error) {
std::string data_received;
ExploreSitesRequestStatus status =
RunFetcher(base::BindOnce(&ExploreSitesFetcherTest::RespondWithHttpError,
base::Unretained(this), http_error),
&data_received);
EXPECT_TRUE(data_received.empty());
return status;
}
ExploreSitesRequestStatus ExploreSitesFetcherTest::RunFetcherWithData(
const std::string& response_data,
std::string* data_received) {
return RunFetcher(base::BindOnce(&ExploreSitesFetcherTest::RespondWithData,
base::Unretained(this), response_data),
data_received);
}
void ExploreSitesFetcherTest::RespondWithNetError(int net_error) {
int pending_requests_count = test_url_loader_factory_.NumPending();
DCHECK(pending_requests_count > 0);
network::URLLoaderCompletionStatus completion_status(net_error);
test_url_loader_factory_.SimulateResponseForPendingRequest(
GetPendingRequest(0)->request.url, completion_status,
network::ResourceResponseHead(), std::string());
}
void ExploreSitesFetcherTest::RespondWithHttpError(
net::HttpStatusCode http_error) {
int pending_requests_count = test_url_loader_factory_.NumPending();
auto resource_response_head = network::CreateResourceResponseHead(http_error);
DCHECK(pending_requests_count > 0);
test_url_loader_factory_.SimulateResponseForPendingRequest(
GetPendingRequest(0)->request.url,
network::URLLoaderCompletionStatus(net::OK), resource_response_head,
std::string());
}
void ExploreSitesFetcherTest::RespondWithData(const std::string& data) {
DCHECK(test_url_loader_factory_.pending_requests()->size() > 0);
test_url_loader_factory_.SimulateResponseForPendingRequest(
GetPendingRequest(0)->request.url.spec(), data);
}
network::TestURLLoaderFactory::PendingRequest*
ExploreSitesFetcherTest::GetPendingRequest(size_t index) {
if (index >= test_url_loader_factory_.pending_requests()->size())
return nullptr;
network::TestURLLoaderFactory::PendingRequest* request =
&(*test_url_loader_factory_.pending_requests())[index];
DCHECK(request);
return request;
}
ExploreSitesRequestStatus ExploreSitesFetcherTest::RunFetcher(
base::OnceCallback<void(void)> respond_callback,
std::string* data_received) {
std::unique_ptr<ExploreSitesFetcher> fetcher =
ExploreSitesFetcher::CreateForGetCatalog(StoreResult(), "", "KE",
test_shared_url_loader_factory_);
std::move(respond_callback).Run();
task_runner_->RunUntilIdle();
if (last_data_)
*data_received = *last_data_;
return last_status_;
}
TEST_F(ExploreSitesFetcherTest, NetErrors) {
EXPECT_EQ(ExploreSitesRequestStatus::kShouldSuspendBlockedByAdministrator,
RunFetcherWithNetError(net::ERR_BLOCKED_BY_ADMINISTRATOR));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithNetError(net::ERR_INTERNET_DISCONNECTED));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithNetError(net::ERR_NETWORK_CHANGED));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithNetError(net::ERR_CONNECTION_RESET));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithNetError(net::ERR_CONNECTION_CLOSED));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithNetError(net::ERR_CONNECTION_REFUSED));
}
TEST_F(ExploreSitesFetcherTest, HttpErrors) {
EXPECT_EQ(ExploreSitesRequestStatus::kShouldSuspendBadRequest,
RunFetcherWithHttpError(net::HTTP_BAD_REQUEST));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithHttpError(net::HTTP_NOT_IMPLEMENTED));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithHttpError(net::HTTP_UNAUTHORIZED));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithHttpError(net::HTTP_NOT_FOUND));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithHttpError(net::HTTP_CONFLICT));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithHttpError(net::HTTP_INTERNAL_SERVER_ERROR));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithHttpError(net::HTTP_BAD_GATEWAY));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithHttpError(net::HTTP_SERVICE_UNAVAILABLE));
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithHttpError(net::HTTP_GATEWAY_TIMEOUT));
}
TEST_F(ExploreSitesFetcherTest, EmptyResponse) {
std::string data;
EXPECT_EQ(ExploreSitesRequestStatus::kShouldRetry,
RunFetcherWithData("", &data));
EXPECT_TRUE(data.empty());
}
TEST_F(ExploreSitesFetcherTest, Success) {
std::string data;
EXPECT_EQ(ExploreSitesRequestStatus::kSuccess,
RunFetcherWithData("Any data.", &data));
EXPECT_FALSE(data.empty());
EXPECT_EQ(data, "Any data.");
}
} // namespace explore_sites