blob: 61ad10cc020cc0f110eb14215336fcd787a5da2e [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 "components/image_fetcher/core/image_fetcher_impl.h"
#include <memory>
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/test/bind_test_util.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "components/image_fetcher/core/fake_image_decoder.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "net/http/http_util.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.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 "ui/gfx/image/image.h"
#include "ui/gfx/image/image_unittest_util.h"
using testing::_;
using testing::Eq;
using testing::Property;
namespace image_fetcher {
namespace {
constexpr char kImageData[] = "data";
constexpr char kImageURL[] = "http://image.test/test.png";
constexpr char kImageUmaName[] = "TestUma";
class ImageFetcherImplTest : public testing::Test {
public:
ImageFetcherImplTest()
: shared_factory_(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&test_url_loader_factory_)) {
auto decoder = std::make_unique<FakeImageDecoder>();
fake_image_decoder_ = decoder.get();
image_fetcher_ = std::make_unique<image_fetcher::ImageFetcherImpl>(
std::move(decoder), shared_factory_);
}
void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); }
FakeImageDecoder* image_decoder() { return fake_image_decoder_; }
network::TestURLLoaderFactory* test_url_loader_factory() {
return &test_url_loader_factory_;
}
ImageFetcherImpl* image_fetcher() { return image_fetcher_.get(); }
private:
std::unique_ptr<ImageFetcherImpl> image_fetcher_;
FakeImageDecoder* fake_image_decoder_;
network::TestURLLoaderFactory test_url_loader_factory_;
scoped_refptr<network::SharedURLLoaderFactory> shared_factory_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
DISALLOW_COPY_AND_ASSIGN(ImageFetcherImplTest);
};
MATCHER(ValidImage, "") {
return arg.Width() == 2 && arg.Height() == 3;
}
MATCHER(EmptyImage, "") {
return arg.Width() == 0;
}
TEST_F(ImageFetcherImplTest, FetchImageAndDataSuccess) {
test_url_loader_factory()->AddResponse(kImageURL, kImageData);
base::MockCallback<ImageDataFetcherCallback> data_callback;
base::MockCallback<ImageFetcherCallback> image_callback;
EXPECT_CALL(data_callback, Run(kImageData, _));
EXPECT_CALL(image_callback, Run(ValidImage(), _));
image_fetcher()->FetchImageAndData(
GURL(kImageURL), data_callback.Get(), image_callback.Get(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
RunUntilIdle();
}
TEST_F(ImageFetcherImplTest, FetchImageAndData3xSuccess) {
// Fetch an image three times.
test_url_loader_factory()->AddResponse(kImageURL, kImageData);
base::MockCallback<ImageDataFetcherCallback> data_callback1;
base::MockCallback<ImageFetcherCallback> image_callback1;
EXPECT_CALL(data_callback1, Run(kImageData, _));
EXPECT_CALL(image_callback1, Run(ValidImage(), _));
image_fetcher()->FetchImageAndData(
GURL(kImageURL), data_callback1.Get(), image_callback1.Get(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
base::MockCallback<ImageDataFetcherCallback> data_callback2;
base::MockCallback<ImageFetcherCallback> image_callback2;
EXPECT_CALL(data_callback2, Run(kImageData, _));
EXPECT_CALL(image_callback2, Run(ValidImage(), _));
// This call happens before the network request completes.
image_fetcher()->FetchImageAndData(
GURL(kImageURL), data_callback2.Get(), image_callback2.Get(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
base::MockCallback<ImageDataFetcherCallback> data_callback3;
base::MockCallback<ImageFetcherCallback> image_callback3;
EXPECT_CALL(data_callback3, Run(kImageData, _));
EXPECT_CALL(image_callback3, Run(ValidImage(), _));
image_decoder()->SetBeforeImageDecoded(base::BindLambdaForTesting([&]() {
// This happens after the network request completes.
// Shouldn't need to fetch.
test_url_loader_factory()->AddResponse(kImageURL, "", net::HTTP_NOT_FOUND);
image_fetcher()->FetchImageAndData(
GURL(kImageURL), data_callback3.Get(), image_callback3.Get(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
}));
RunUntilIdle();
}
TEST_F(ImageFetcherImplTest, FetchImageAndData2xFail) {
// Fetch an image two times. The fetch fails.
image_decoder()->SetEnabled(false);
test_url_loader_factory()->AddResponse(kImageURL, "", net::HTTP_NOT_FOUND);
base::MockCallback<ImageDataFetcherCallback> data_callback1;
base::MockCallback<ImageFetcherCallback> image_callback1;
EXPECT_CALL(data_callback1, Run("", _));
EXPECT_CALL(image_callback1, Run(EmptyImage(), _));
image_fetcher()->FetchImageAndData(
GURL(kImageURL), data_callback1.Get(), image_callback1.Get(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
base::MockCallback<ImageDataFetcherCallback> data_callback2;
base::MockCallback<ImageFetcherCallback> image_callback2;
EXPECT_CALL(data_callback2, Run("", _));
EXPECT_CALL(image_callback2, Run(EmptyImage(), _));
image_fetcher()->FetchImageAndData(
GURL(kImageURL), data_callback2.Get(), image_callback2.Get(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
RunUntilIdle();
}
TEST_F(ImageFetcherImplTest, FetchOnlyData) {
image_decoder()->SetEnabled(false);
test_url_loader_factory()->AddResponse(kImageURL, kImageData);
base::MockCallback<ImageDataFetcherCallback> data_callback;
EXPECT_CALL(data_callback, Run(kImageData, _));
image_fetcher()->FetchImageAndData(
GURL(kImageURL), data_callback.Get(), ImageFetcherCallback(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
RunUntilIdle();
}
TEST_F(ImageFetcherImplTest, FetchDataThenImage) {
test_url_loader_factory()->AddResponse(kImageURL, kImageData);
base::MockCallback<ImageDataFetcherCallback> data_callback;
EXPECT_CALL(data_callback, Run(kImageData, _));
image_fetcher()->FetchImageAndData(
GURL(kImageURL), data_callback.Get(), ImageFetcherCallback(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
base::MockCallback<ImageFetcherCallback> image_callback;
EXPECT_CALL(image_callback, Run(ValidImage(), _));
image_fetcher()->FetchImageAndData(
GURL(kImageURL), ImageDataFetcherCallback(), image_callback.Get(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
RunUntilIdle();
}
TEST_F(ImageFetcherImplTest, FetchImageThenData) {
test_url_loader_factory()->AddResponse(kImageURL, kImageData);
base::MockCallback<ImageFetcherCallback> image_callback;
EXPECT_CALL(image_callback, Run(ValidImage(), _));
image_fetcher()->FetchImageAndData(
GURL(kImageURL), ImageDataFetcherCallback(), image_callback.Get(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
base::MockCallback<ImageDataFetcherCallback> data_callback;
EXPECT_CALL(data_callback, Run(kImageData, _));
image_decoder()->SetBeforeImageDecoded(base::BindLambdaForTesting([&]() {
// This happens after the network request completes.
// Shouldn't need to fetch.
test_url_loader_factory()->AddResponse(kImageURL, "", net::HTTP_NOT_FOUND);
image_fetcher()->FetchImageAndData(
GURL(kImageURL), data_callback.Get(), ImageFetcherCallback(),
ImageFetcherParams(TRAFFIC_ANNOTATION_FOR_TESTS, kImageUmaName));
}));
RunUntilIdle();
}
} // namespace
} // namespace image_fetcher