1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher_service.h"
7 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
8 #include "chrome/test/base/testing_profile.h"
9 #include "content/public/test/test_browser_thread_bundle.h"
10 #include "testing/gtest/include/gtest/gtest.h"
14 class TestNotificationInterface
{
16 virtual ~TestNotificationInterface() {}
17 virtual void OnImageChanged() = 0;
18 virtual void OnRequestFinished() = 0;
21 class TestObserver
: public BitmapFetcherService::Observer
{
23 explicit TestObserver(TestNotificationInterface
* target
) : target_(target
) {}
24 ~TestObserver() override
{ target_
->OnRequestFinished(); }
26 void OnImageChanged(BitmapFetcherService::RequestId request_id
,
27 const SkBitmap
& answers_image
) override
{
28 target_
->OnImageChanged();
32 TestNotificationInterface
* target_
;
34 DISALLOW_COPY_AND_ASSIGN(TestObserver
);
37 class TestService
: public BitmapFetcherService
{
39 explicit TestService(content::BrowserContext
* context
)
40 : BitmapFetcherService(context
) {}
41 ~TestService() override
{}
43 // Create a fetcher, but don't start downloading. That allows side-stepping
44 // the decode step, which requires a utility process.
45 chrome::BitmapFetcher
* CreateFetcher(const GURL
& url
) override
{
46 return new chrome::BitmapFetcher(url
, this);
52 class BitmapFetcherServiceTest
: public testing::Test
,
53 public TestNotificationInterface
{
55 BitmapFetcherServiceTest()
56 : url1_(GURL("http://example.org/sample-image-1.png")),
57 url2_(GURL("http://example.org/sample-image-2.png")) {
60 void SetUp() override
{
61 service_
.reset(new TestService(&profile_
));
62 requests_finished_
= 0;
66 const ScopedVector
<BitmapFetcherRequest
>& requests() const {
67 return service_
->requests_
;
69 const ScopedVector
<chrome::BitmapFetcher
>& active_fetchers() const {
70 return service_
->active_fetchers_
;
72 size_t cache_size() const { return service_
->cache_
.size(); }
74 void OnImageChanged() override
{ images_changed_
++; }
76 void OnRequestFinished() override
{ requests_finished_
++; }
78 // Simulate finishing a URL fetch and decode for the given fetcher.
79 void CompleteFetch(const GURL
& url
) {
80 const chrome::BitmapFetcher
* fetcher
= service_
->FindFetcherForUrl(url
);
83 // Create a non-empty bitmap.
85 image
.allocN32Pixels(2, 2);
86 image
.eraseColor(SK_ColorGREEN
);
88 const_cast<chrome::BitmapFetcher
*>(fetcher
)->OnImageDecoded(image
);
91 void FailFetch(const GURL
& url
) {
92 const chrome::BitmapFetcher
* fetcher
= service_
->FindFetcherForUrl(url
);
94 const_cast<chrome::BitmapFetcher
*>(fetcher
)->OnImageDecoded(SkBitmap());
97 // A failed decode results in a nullptr image.
98 void FailDecode(const GURL
& url
) {
99 const chrome::BitmapFetcher
* fetcher
= service_
->FindFetcherForUrl(url
);
100 ASSERT_TRUE(fetcher
);
101 const_cast<chrome::BitmapFetcher
*>(fetcher
)->OnDecodeImageFailed();
105 scoped_ptr
<BitmapFetcherService
> service_
;
108 int requests_finished_
;
114 content::TestBrowserThreadBundle thread_bundle_
;
115 TestingProfile profile_
;
118 TEST_F(BitmapFetcherServiceTest
, RequestInvalidUrl
) {
119 const BitmapFetcherService::RequestId invalid_request_id
=
120 BitmapFetcherService::REQUEST_ID_INVALID
;
122 ASSERT_FALSE(invalid_url
.is_valid());
124 BitmapFetcherService::RequestId request_id
=
125 service_
->RequestImage(invalid_url
, new TestObserver(this));
126 EXPECT_EQ(invalid_request_id
, request_id
);
129 TEST_F(BitmapFetcherServiceTest
, CancelInvalidRequest
) {
130 service_
->CancelRequest(BitmapFetcherService::REQUEST_ID_INVALID
);
131 service_
->CancelRequest(23);
134 TEST_F(BitmapFetcherServiceTest
, OnlyFirstRequestCreatesFetcher
) {
135 EXPECT_EQ(0U, active_fetchers().size());
137 service_
->RequestImage(url1_
, new TestObserver(this));
138 EXPECT_EQ(1U, active_fetchers().size());
140 service_
->RequestImage(url1_
, new TestObserver(this));
141 EXPECT_EQ(1U, active_fetchers().size());
144 TEST_F(BitmapFetcherServiceTest
, CompletedFetchNotifiesAllObservers
) {
145 service_
->RequestImage(url1_
, new TestObserver(this));
146 service_
->RequestImage(url1_
, new TestObserver(this));
147 service_
->RequestImage(url1_
, new TestObserver(this));
148 service_
->RequestImage(url1_
, new TestObserver(this));
149 EXPECT_EQ(1U, active_fetchers().size());
150 EXPECT_EQ(4U, requests().size());
152 CompleteFetch(url1_
);
153 EXPECT_EQ(4, images_changed_
);
154 EXPECT_EQ(4, requests_finished_
);
157 TEST_F(BitmapFetcherServiceTest
, CancelRequest
) {
158 service_
->RequestImage(url1_
, new TestObserver(this));
159 service_
->RequestImage(url1_
, new TestObserver(this));
160 BitmapFetcherService::RequestId requestId
=
161 service_
->RequestImage(url2_
, new TestObserver(this));
162 service_
->RequestImage(url1_
, new TestObserver(this));
163 service_
->RequestImage(url1_
, new TestObserver(this));
164 EXPECT_EQ(5U, requests().size());
166 service_
->CancelRequest(requestId
);
167 EXPECT_EQ(4U, requests().size());
169 CompleteFetch(url2_
);
170 EXPECT_EQ(0, images_changed_
);
172 CompleteFetch(url1_
);
173 EXPECT_EQ(4, images_changed_
);
176 TEST_F(BitmapFetcherServiceTest
, FailedNullRequestsAreHandled
) {
177 service_
->RequestImage(url1_
, new TestObserver(this));
178 service_
->RequestImage(url2_
, new TestObserver(this));
179 EXPECT_EQ(0U, cache_size());
181 CompleteFetch(url1_
);
182 EXPECT_EQ(1U, cache_size());
185 EXPECT_EQ(1U, cache_size());
187 TEST_F(BitmapFetcherServiceTest
, FailedRequestsDontEnterCache
) {
188 service_
->RequestImage(url1_
, new TestObserver(this));
189 service_
->RequestImage(url2_
, new TestObserver(this));
190 EXPECT_EQ(0U, cache_size());
192 CompleteFetch(url1_
);
193 EXPECT_EQ(1U, cache_size());
196 EXPECT_EQ(1U, cache_size());