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. 4 5 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher_service.h" 6 7 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h" 8 #include "chrome/test/base/testing_profile.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 namespace { 12 13 class TestNotificationInterface { 14 public: 15 virtual ~TestNotificationInterface() {} 16 virtual void OnImageChanged() = 0; 17 virtual void OnRequestFinished() = 0; 18 }; 19 20 class TestObserver : public BitmapFetcherService::Observer { 21 public: 22 explicit TestObserver(TestNotificationInterface* target) : target_(target) {} 23 virtual ~TestObserver() { target_->OnRequestFinished(); } 24 25 virtual void OnImageChanged(BitmapFetcherService::RequestId request_id, 26 const SkBitmap& answers_image) OVERRIDE { 27 target_->OnImageChanged(); 28 } 29 30 TestNotificationInterface* target_; 31 }; 32 33 class TestService : public BitmapFetcherService { 34 public: 35 explicit TestService(content::BrowserContext* context) 36 : BitmapFetcherService(context) {} 37 virtual ~TestService() {} 38 39 // Create a fetcher, but don't start downloading. That allows side-stepping 40 // the decode step, which requires a utility process. 41 virtual chrome::BitmapFetcher* CreateFetcher(const GURL& url) OVERRIDE { 42 return new chrome::BitmapFetcher(url, this); 43 } 44 }; 45 46 } // namespace 47 48 class BitmapFetcherServiceTest : public testing::Test, 49 public TestNotificationInterface { 50 public: 51 virtual void SetUp() OVERRIDE { 52 service_.reset(new TestService(&profile_)); 53 requestsFinished_ = 0; 54 imagesChanged_ = 0; 55 url1_ = GURL("http://example.org/sample-image-1.png"); 56 url2_ = GURL("http://example.org/sample-image-2.png"); 57 } 58 59 const ScopedVector<BitmapFetcherRequest>& requests() { 60 return service_->requests_; 61 } 62 const ScopedVector<chrome::BitmapFetcher>& active_fetchers() { 63 return service_->active_fetchers_; 64 } 65 size_t cache_size() { return service_->cache_.size(); } 66 67 virtual void OnImageChanged() OVERRIDE { imagesChanged_++; } 68 69 virtual void OnRequestFinished() OVERRIDE { requestsFinished_++; } 70 71 // Simulate finishing a URL fetch and decode for the given fetcher. 72 void CompleteFetch(const GURL& url) { 73 const chrome::BitmapFetcher* fetcher = service_->FindFetcherForUrl(url); 74 ASSERT_TRUE(NULL != fetcher); 75 76 // Create a non-empty bitmap. 77 SkBitmap image; 78 image.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); 79 image.allocPixels(); 80 image.eraseColor(SK_ColorGREEN); 81 82 const_cast<chrome::BitmapFetcher*>(fetcher)->OnImageDecoded(NULL, image); 83 } 84 85 void FailFetch(const GURL& url) { 86 const chrome::BitmapFetcher* fetcher = service_->FindFetcherForUrl(url); 87 ASSERT_TRUE(NULL != fetcher); 88 const_cast<chrome::BitmapFetcher*>(fetcher) 89 ->OnImageDecoded(NULL, SkBitmap()); 90 } 91 92 protected: 93 scoped_ptr<BitmapFetcherService> service_; 94 95 int imagesChanged_; 96 int requestsFinished_; 97 98 GURL url1_; 99 GURL url2_; 100 101 private: 102 TestingProfile profile_; 103 }; 104 105 TEST_F(BitmapFetcherServiceTest, CancelInvalidRequest) { 106 service_->CancelRequest(BitmapFetcherService::REQUEST_ID_INVALID); 107 service_->CancelRequest(23); 108 } 109 110 TEST_F(BitmapFetcherServiceTest, OnlyFirstRequestCreatesFetcher) { 111 EXPECT_EQ(0U, active_fetchers().size()); 112 113 service_->RequestImage(url1_, new TestObserver(this)); 114 EXPECT_EQ(1U, active_fetchers().size()); 115 116 service_->RequestImage(url1_, new TestObserver(this)); 117 EXPECT_EQ(1U, active_fetchers().size()); 118 } 119 120 TEST_F(BitmapFetcherServiceTest, CompletedFetchNotifiesAllObservers) { 121 service_->RequestImage(url1_, new TestObserver(this)); 122 service_->RequestImage(url1_, new TestObserver(this)); 123 service_->RequestImage(url1_, new TestObserver(this)); 124 service_->RequestImage(url1_, new TestObserver(this)); 125 EXPECT_EQ(1U, active_fetchers().size()); 126 EXPECT_EQ(4U, requests().size()); 127 128 CompleteFetch(url1_); 129 EXPECT_EQ(4, imagesChanged_); 130 EXPECT_EQ(4, requestsFinished_); 131 } 132 133 TEST_F(BitmapFetcherServiceTest, CancelRequest) { 134 service_->RequestImage(url1_, new TestObserver(this)); 135 service_->RequestImage(url1_, new TestObserver(this)); 136 BitmapFetcherService::RequestId requestId = 137 service_->RequestImage(url2_, new TestObserver(this)); 138 service_->RequestImage(url1_, new TestObserver(this)); 139 service_->RequestImage(url1_, new TestObserver(this)); 140 EXPECT_EQ(5U, requests().size()); 141 142 service_->CancelRequest(requestId); 143 EXPECT_EQ(4U, requests().size()); 144 145 CompleteFetch(url2_); 146 EXPECT_EQ(0, imagesChanged_); 147 148 CompleteFetch(url1_); 149 EXPECT_EQ(4, imagesChanged_); 150 } 151 152 TEST_F(BitmapFetcherServiceTest, FailedRequestsDontEnterCache) { 153 service_->RequestImage(url1_, new TestObserver(this)); 154 service_->RequestImage(url2_, new TestObserver(this)); 155 EXPECT_EQ(0U, cache_size()); 156 157 CompleteFetch(url1_); 158 EXPECT_EQ(1U, cache_size()); 159 160 FailFetch(url2_); 161 EXPECT_EQ(1U, cache_size()); 162 } 163