blob: 5ddb17f308f539fc585e0be1790626a2ad58391b [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/search/background/ntp_background_service.h"
#include <utility>
#include <vector>
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/search/background/ntp_background_data.h"
#include "components/version_info/version_info.h"
#include "content/public/test/browser_task_environment.h"
#include "services/network/public/cpp/data_element.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using testing::Eq;
using testing::StartsWith;
class NtpBackgroundServiceTest : public testing::Test {
public:
NtpBackgroundServiceTest()
: task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP),
test_shared_loader_factory_(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_)) {}
~NtpBackgroundServiceTest() override {}
void SetUp() override {
testing::Test::SetUp();
service_ =
std::make_unique<NtpBackgroundService>(test_shared_loader_factory_);
}
void SetUpResponseWithData(const GURL& load_url,
const std::string& response) {
test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
[&](const network::ResourceRequest& request) {}));
test_url_loader_factory_.AddResponse(load_url.spec(), response);
}
void SetUpResponseWithNetworkError(const GURL& load_url) {
test_url_loader_factory_.AddResponse(
load_url, network::mojom::URLResponseHead::New(), std::string(),
network::URLLoaderCompletionStatus(net::HTTP_NOT_FOUND));
}
NtpBackgroundService* service() { return service_.get(); }
network::TestURLLoaderFactory* test_url_loader_factory() {
return &test_url_loader_factory_;
}
private:
// Required to run tests from UI and threads.
content::BrowserTaskEnvironment task_environment_;
network::TestURLLoaderFactory test_url_loader_factory_;
scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
std::unique_ptr<NtpBackgroundService> service_;
};
TEST_F(NtpBackgroundServiceTest, CorrectCollectionRequest) {
g_browser_process->SetApplicationLocale("foo");
service()->FetchCollectionInfo();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1u, test_url_loader_factory()->pending_requests()->size());
std::string request_body = test_url_loader_factory()
->pending_requests()
->at(0)
.request.request_body->elements()
->at(0)
.As<network::DataElementBytes>()
.AsStringPiece()
.as_string();
ntp::background::GetCollectionsRequest collection_request;
EXPECT_TRUE(collection_request.ParseFromString(request_body));
EXPECT_EQ("foo", collection_request.language());
EXPECT_EQ(2, collection_request.filtering_label_size());
EXPECT_EQ("chrome_desktop_ntp", collection_request.filtering_label(0));
EXPECT_EQ("chrome_desktop_ntp.M" + version_info::GetMajorVersionNumber(),
collection_request.filtering_label(1));
}
TEST_F(NtpBackgroundServiceTest, CollectionInfoNetworkError) {
SetUpResponseWithNetworkError(service()->GetCollectionsLoadURLForTesting());
ASSERT_TRUE(service()->collection_info().empty());
service()->FetchCollectionInfo();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(service()->collection_info().empty());
EXPECT_EQ(service()->collection_error_info().error_type,
ErrorType::NET_ERROR);
}
TEST_F(NtpBackgroundServiceTest, BadCollectionsResponse) {
SetUpResponseWithData(service()->GetCollectionsLoadURLForTesting(),
"bad serialized GetCollectionsResponse");
ASSERT_TRUE(service()->collection_info().empty());
service()->FetchCollectionInfo();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(service()->collection_info().empty());
EXPECT_EQ(service()->collection_error_info().error_type,
ErrorType::SERVICE_ERROR);
}
TEST_F(NtpBackgroundServiceTest, GoodCollectionsResponse) {
ntp::background::Collection collection;
collection.set_collection_id("shapes");
collection.set_collection_name("Shapes");
collection.add_preview()->set_image_url("https://wallpapers.co/some_image");
ntp::background::GetCollectionsResponse response;
*response.add_collections() = collection;
std::string response_string;
response.SerializeToString(&response_string);
SetUpResponseWithData(service()->GetCollectionsLoadURLForTesting(),
response_string);
ASSERT_TRUE(service()->collection_info().empty());
service()->FetchCollectionInfo();
base::RunLoop().RunUntilIdle();
CollectionInfo collection_info;
collection_info.collection_id = collection.collection_id();
collection_info.collection_name = collection.collection_name();
collection_info.preview_image_url = GURL(
collection.preview(0).image_url() + GetThumbnailImageOptionsForTesting());
EXPECT_FALSE(service()->collection_info().empty());
EXPECT_THAT(service()->collection_info().at(0), Eq(collection_info));
EXPECT_EQ(service()->collection_error_info().error_type, ErrorType::NONE);
}
TEST_F(NtpBackgroundServiceTest, CollectionImagesNetworkError) {
SetUpResponseWithNetworkError(service()->GetImagesURLForTesting());
ASSERT_TRUE(service()->collection_images().empty());
service()->FetchCollectionImageInfo("shapes");
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(service()->collection_images().empty());
EXPECT_EQ(service()->collection_images_error_info().error_type,
ErrorType::NET_ERROR);
}
TEST_F(NtpBackgroundServiceTest, BadCollectionImagesResponse) {
SetUpResponseWithData(service()->GetImagesURLForTesting(),
"bad serialized GetImagesInCollectionResponse");
ASSERT_TRUE(service()->collection_images().empty());
service()->FetchCollectionImageInfo("shapes");
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(service()->collection_images().empty());
EXPECT_EQ(service()->collection_images_error_info().error_type,
ErrorType::SERVICE_ERROR);
}
TEST_F(NtpBackgroundServiceTest, GoodCollectionImagesResponse) {
ntp::background::Image image;
image.set_asset_id(12345);
image.set_image_url("https://wallpapers.co/some_image");
image.add_attribution()->set_text("attribution text");
image.set_action_url("https://wallpapers.co/some_image/learn_more");
ntp::background::GetImagesInCollectionResponse response;
*response.add_images() = image;
std::string response_string;
response.SerializeToString(&response_string);
SetUpResponseWithData(service()->GetImagesURLForTesting(), response_string);
ASSERT_TRUE(service()->collection_images().empty());
service()->FetchCollectionImageInfo("shapes");
base::RunLoop().RunUntilIdle();
CollectionImage collection_image;
collection_image.collection_id = "shapes";
collection_image.asset_id = image.asset_id();
collection_image.thumbnail_image_url =
GURL(image.image_url() + GetThumbnailImageOptionsForTesting());
collection_image.image_url =
GURL(image.image_url() + service()->GetImageOptionsForTesting());
collection_image.attribution.push_back(image.attribution(0).text());
collection_image.attribution_action_url = GURL(image.action_url());
EXPECT_FALSE(service()->collection_images().empty());
EXPECT_THAT(service()->collection_images().at(0), Eq(collection_image));
EXPECT_EQ(service()->collection_images_error_info().error_type,
ErrorType::NONE);
}
TEST_F(NtpBackgroundServiceTest, MultipleRequests) {
ntp::background::Collection collection;
collection.set_collection_id("shapes");
collection.set_collection_name("Shapes");
collection.add_preview()->set_image_url("https://wallpapers.co/some_image");
ntp::background::GetCollectionsResponse collection_response;
*collection_response.add_collections() = collection;
std::string collection_response_string;
collection_response.SerializeToString(&collection_response_string);
ntp::background::Image image;
image.set_asset_id(12345);
image.set_image_url("https://wallpapers.co/some_image");
image.add_attribution()->set_text("attribution text");
ntp::background::GetImagesInCollectionResponse image_response;
*image_response.add_images() = image;
std::string image_response_string;
image_response.SerializeToString(&image_response_string);
SetUpResponseWithData(service()->GetCollectionsLoadURLForTesting(),
collection_response_string);
SetUpResponseWithData(service()->GetImagesURLForTesting(),
image_response_string);
ASSERT_TRUE(service()->collection_info().empty());
ASSERT_TRUE(service()->collection_images().empty());
service()->FetchCollectionInfo();
service()->FetchCollectionImageInfo("shapes");
// Subsequent requests are ignored while the loader is in use.
service()->FetchCollectionImageInfo("colors");
base::RunLoop().RunUntilIdle();
CollectionInfo collection_info;
collection_info.collection_id = collection.collection_id();
collection_info.collection_name = collection.collection_name();
collection_info.preview_image_url = GURL(
collection.preview(0).image_url() + GetThumbnailImageOptionsForTesting());
CollectionImage collection_image;
collection_image.collection_id = "shapes";
collection_image.asset_id = image.asset_id();
collection_image.thumbnail_image_url =
GURL(image.image_url() + GetThumbnailImageOptionsForTesting());
collection_image.image_url =
GURL(image.image_url() + service()->GetImageOptionsForTesting());
collection_image.attribution.push_back(image.attribution(0).text());
EXPECT_FALSE(service()->collection_info().empty());
EXPECT_THAT(service()->collection_info().at(0), Eq(collection_info));
EXPECT_FALSE(service()->collection_images().empty());
EXPECT_THAT(service()->collection_images().at(0), Eq(collection_image));
}
TEST_F(NtpBackgroundServiceTest, NextImageNetworkError) {
SetUpResponseWithNetworkError(service()->GetNextImageURLForTesting());
service()->FetchNextCollectionImage("shapes", base::nullopt);
base::RunLoop().RunUntilIdle();
EXPECT_THAT(service()->next_image_error_info().error_type,
Eq(ErrorType::NET_ERROR));
}
TEST_F(NtpBackgroundServiceTest, BadNextImageResponse) {
SetUpResponseWithData(service()->GetNextImageURLForTesting(),
"bad serialized GetImageFromCollectionResponse");
service()->FetchNextCollectionImage("shapes", base::nullopt);
base::RunLoop().RunUntilIdle();
EXPECT_THAT(service()->next_image_error_info().error_type,
Eq(ErrorType::SERVICE_ERROR));
}
TEST_F(NtpBackgroundServiceTest, GoodNextImageResponse) {
ntp::background::Image image;
image.set_asset_id(12345);
image.set_image_url("https://wallpapers.co/some_image");
image.add_attribution()->set_text("attribution text");
image.set_action_url("https://wallpapers.co/some_image/learn_more");
ntp::background::GetImageFromCollectionResponse response;
*response.mutable_image() = image;
response.set_resume_token("resume1");
std::string response_string;
response.SerializeToString(&response_string);
SetUpResponseWithData(service()->GetNextImageURLForTesting(),
response_string);
// NOTE: the effect of the resume token in the request (i.e. prevent images
// from being repeated) cannot be verified in a unit test.
service()->FetchNextCollectionImage("shapes", "resume0");
base::RunLoop().RunUntilIdle();
CollectionImage collection_image;
collection_image.collection_id = "shapes";
collection_image.asset_id = image.asset_id();
collection_image.thumbnail_image_url =
GURL(image.image_url() + GetThumbnailImageOptionsForTesting());
collection_image.image_url =
GURL(image.image_url() + service()->GetImageOptionsForTesting());
collection_image.attribution.push_back(image.attribution(0).text());
collection_image.attribution_action_url = GURL(image.action_url());
EXPECT_THAT(service()->next_image(), Eq(collection_image));
EXPECT_THAT(service()->next_image_resume_token(), Eq("resume1"));
EXPECT_THAT(service()->collection_images_error_info().error_type,
Eq(ErrorType::NONE));
}
TEST_F(NtpBackgroundServiceTest, MultipleRequestsNextImage) {
ntp::background::Image image;
image.set_asset_id(12345);
image.set_image_url("https://wallpapers.co/some_image");
image.add_attribution()->set_text("attribution text");
image.set_action_url("https://wallpapers.co/some_image/learn_more");
ntp::background::GetImageFromCollectionResponse response;
*response.mutable_image() = image;
response.set_resume_token("resume1");
std::string response_string;
response.SerializeToString(&response_string);
SetUpResponseWithData(service()->GetNextImageURLForTesting(),
response_string);
// NOTE: the effect of the resume token in the request (i.e. prevent images
// from being repeated) cannot be verified in a unit test.
service()->FetchNextCollectionImage("shapes", base::nullopt);
// Subsequent requests are ignored while the loader is in use.
service()->FetchNextCollectionImage("shapes", "resume0");
base::RunLoop().RunUntilIdle();
CollectionImage collection_image;
collection_image.collection_id = "shapes";
collection_image.asset_id = image.asset_id();
collection_image.thumbnail_image_url =
GURL(image.image_url() + GetThumbnailImageOptionsForTesting());
collection_image.image_url =
GURL(image.image_url() + service()->GetImageOptionsForTesting());
collection_image.attribution.push_back(image.attribution(0).text());
collection_image.attribution_action_url = GURL(image.action_url());
EXPECT_THAT(service()->next_image(), Eq(collection_image));
EXPECT_THAT(service()->next_image_resume_token(), Eq("resume1"));
EXPECT_THAT(service()->collection_images_error_info().error_type,
Eq(ErrorType::NONE));
}
TEST_F(NtpBackgroundServiceTest, CheckValidAndInvalidBackdropUrls) {
ntp::background::Image image;
image.set_asset_id(12345);
image.set_image_url("https://wallpapers.co/some_image");
image.add_attribution()->set_text("attribution text");
image.set_action_url("https://wallpapers.co/some_image/learn_more");
ntp::background::GetImagesInCollectionResponse response;
*response.add_images() = image;
std::string response_string;
response.SerializeToString(&response_string);
SetUpResponseWithData(service()->GetImagesURLForTesting(), response_string);
ASSERT_TRUE(service()->collection_images().empty());
service()->FetchCollectionImageInfo("shapes");
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(service()->IsValidBackdropUrl(
GURL(image.image_url() + service()->GetImageOptionsForTesting())));
EXPECT_FALSE(service()->IsValidBackdropUrl(
GURL("http://wallpapers.co/some_image=imageOptions")));
EXPECT_FALSE(service()->IsValidBackdropUrl(
GURL("https://wallpapers.co/another_image")));
}
TEST_F(NtpBackgroundServiceTest, GetThumbnailUrl) {
const GURL kInvalidUrl("foo");
const GURL kValidUrl("https://www.foo.com");
const GURL kValidThumbnailUrl("https://www.foo.com/thumbnail");
service()->AddValidBackdropUrlWithThumbnailForTesting(kValidUrl,
kValidThumbnailUrl);
EXPECT_EQ(kValidThumbnailUrl, service()->GetThumbnailUrl(kValidUrl));
EXPECT_EQ(GURL::EmptyGURL(), service()->GetThumbnailUrl(kInvalidUrl));
}