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.h" 6 7 #include "base/compiler_specific.h" 8 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/ui/browser.h" 10 #include "chrome/test/base/in_process_browser_test.h" 11 #include "content/public/test/test_utils.h" 12 #include "net/base/load_flags.h" 13 #include "net/http/http_status_code.h" 14 #include "net/url_request/test_url_fetcher_factory.h" 15 #include "net/url_request/url_fetcher.h" 16 #include "net/url_request/url_request_status.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 #include "third_party/skia/include/core/SkBitmap.h" 19 #include "ui/gfx/codec/png_codec.h" 20 #include "ui/gfx/size.h" 21 #include "ui/gfx/skia_util.h" 22 23 const bool kAsyncCall = true; 24 const bool kSyncCall = false; 25 26 namespace chrome { 27 28 // Class to catch events from the BitmapFetcher for testing. 29 class BitmapFetcherTestDelegate : public BitmapFetcherDelegate { 30 public: 31 explicit BitmapFetcherTestDelegate(bool async) : called_(false), 32 success_(false), 33 async_(async) {} 34 35 virtual ~BitmapFetcherTestDelegate() { 36 EXPECT_TRUE(called_); 37 } 38 39 // Method inherited from BitmapFetcherDelegate. 40 virtual void OnFetchComplete(const GURL url, 41 const SkBitmap* bitmap) OVERRIDE { 42 called_ = true; 43 url_ = url; 44 if (bitmap) { 45 success_ = true; 46 bitmap->deepCopyTo(&bitmap_); 47 } 48 // For async calls, we need to quit the run loop so the test can continue. 49 if (async_) 50 run_loop_.Quit(); 51 } 52 53 // Waits until OnFetchComplete() is called. Should only be used for 54 // async tests. 55 void Wait() { 56 ASSERT_TRUE(async_); 57 run_loop_.Run(); 58 } 59 60 GURL url() const { return url_; } 61 bool success() const { return success_; } 62 const SkBitmap& bitmap() const { return bitmap_; } 63 64 private: 65 base::RunLoop run_loop_; 66 bool called_; 67 GURL url_; 68 bool success_; 69 bool async_; 70 SkBitmap bitmap_; 71 72 DISALLOW_COPY_AND_ASSIGN(BitmapFetcherTestDelegate); 73 }; 74 75 class BitmapFetcherBrowserTest : public InProcessBrowserTest { 76 public: 77 virtual void SetUp() OVERRIDE { 78 url_fetcher_factory_.reset( 79 new net::FakeURLFetcherFactory(&url_fetcher_impl_factory_)); 80 InProcessBrowserTest::SetUp(); 81 } 82 83 protected: 84 net::URLFetcherImplFactory url_fetcher_impl_factory_; 85 scoped_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_; 86 }; 87 88 // WARNING: These tests work with --single_process, but not 89 // --single-process. The reason is that the sandbox does not get created 90 // for us by the test process if --single-process is used. 91 92 IN_PROC_BROWSER_TEST_F(BitmapFetcherBrowserTest, StartTest) { 93 GURL url("http://example.com/this-should-work"); 94 95 // Put some realistic looking bitmap data into the url_fetcher. 96 SkBitmap image; 97 98 // Put a real bitmap into "image". 2x2 bitmap of green 32 bit pixels. 99 image.allocN32Pixels(2, 2); 100 image.eraseColor(SK_ColorGREEN); 101 102 // Encode the bits as a PNG. 103 std::vector<unsigned char> compressed; 104 ASSERT_TRUE(gfx::PNGCodec::EncodeBGRASkBitmap(image, true, &compressed)); 105 106 // Copy the bits into the string, and put them into the FakeURLFetcher. 107 std::string image_string(compressed.begin(), compressed.end()); 108 109 // Set up a delegate to wait for the callback. 110 BitmapFetcherTestDelegate delegate(kAsyncCall); 111 112 BitmapFetcher fetcher(url, &delegate); 113 114 url_fetcher_factory_->SetFakeResponse( 115 url, image_string, net::HTTP_OK, net::URLRequestStatus::SUCCESS); 116 117 // We expect that the image decoder will get called and return 118 // an image in a callback to OnImageDecoded(). 119 fetcher.Start( 120 browser()->profile()->GetRequestContext(), 121 std::string(), 122 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, 123 net::LOAD_NORMAL); 124 125 // Blocks until test delegate is notified via a callback. 126 delegate.Wait(); 127 128 ASSERT_TRUE(delegate.success()); 129 130 // Make sure we get back the bitmap we expect. 131 const SkBitmap& found_image = delegate.bitmap(); 132 EXPECT_TRUE(gfx::BitmapsAreEqual(image, found_image)); 133 } 134 135 IN_PROC_BROWSER_TEST_F(BitmapFetcherBrowserTest, OnImageDecodedTest) { 136 GURL url("http://example.com/this-should-work-as-well"); 137 SkBitmap image; 138 139 // Put a real bitmap into "image". 2x2 bitmap of green 16 bit pixels. 140 image.allocN32Pixels(2, 2); 141 image.eraseColor(SK_ColorGREEN); 142 143 BitmapFetcherTestDelegate delegate(kSyncCall); 144 145 BitmapFetcher fetcher(url, &delegate); 146 147 fetcher.OnImageDecoded(NULL, image); 148 149 // Ensure image is marked as succeeded. 150 EXPECT_TRUE(delegate.success()); 151 152 // Test that the image is what we expect. 153 EXPECT_TRUE(gfx::BitmapsAreEqual(image, delegate.bitmap())); 154 } 155 156 IN_PROC_BROWSER_TEST_F(BitmapFetcherBrowserTest, OnURLFetchFailureTest) { 157 GURL url("http://example.com/this-should-be-fetch-failure"); 158 159 // We intentionally put no data into the bitmap to simulate a failure. 160 161 // Set up a delegate to wait for the callback. 162 BitmapFetcherTestDelegate delegate(kAsyncCall); 163 164 BitmapFetcher fetcher(url, &delegate); 165 166 url_fetcher_factory_->SetFakeResponse(url, 167 std::string(), 168 net::HTTP_INTERNAL_SERVER_ERROR, 169 net::URLRequestStatus::FAILED); 170 171 fetcher.Start( 172 browser()->profile()->GetRequestContext(), 173 std::string(), 174 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, 175 net::LOAD_NORMAL); 176 177 // Blocks until test delegate is notified via a callback. 178 delegate.Wait(); 179 180 EXPECT_FALSE(delegate.success()); 181 } 182 183 IN_PROC_BROWSER_TEST_F(BitmapFetcherBrowserTest, HandleImageFailedTest) { 184 GURL url("http://example.com/this-should-be-a-decode-failure"); 185 BitmapFetcherTestDelegate delegate(kAsyncCall); 186 BitmapFetcher fetcher(url, &delegate); 187 url_fetcher_factory_->SetFakeResponse(url, 188 std::string("Not a real bitmap"), 189 net::HTTP_OK, 190 net::URLRequestStatus::SUCCESS); 191 192 fetcher.Start( 193 browser()->profile()->GetRequestContext(), 194 std::string(), 195 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE, 196 net::LOAD_NORMAL); 197 198 // Blocks until test delegate is notified via a callback. 199 delegate.Wait(); 200 201 EXPECT_FALSE(delegate.success()); 202 } 203 204 } // namespace chrome 205