15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
56d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/compiler_specific.h"
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/profiles/profile.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/test/test_utils.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "net/base/load_flags.h"
130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "net/http/http_status_code.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/url_request/url_fetcher.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/url_request/url_request_status.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/size.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/skia_util.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const bool kAsyncCall = true;
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const bool kSyncCall = false;
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace chrome {
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Class to catch events from the BitmapFetcher for testing.
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BitmapFetcherTestDelegate : public BitmapFetcherDelegate {
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  explicit BitmapFetcherTestDelegate(bool async) : called_(false),
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                   success_(false),
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                   async_(async) {}
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~BitmapFetcherTestDelegate() {
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_TRUE(called_);
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Method inherited from BitmapFetcherDelegate.
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void OnFetchComplete(const GURL url,
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                               const SkBitmap* bitmap) OVERRIDE {
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    called_ = true;
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    url_ = url;
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (bitmap) {
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      success_ = true;
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      bitmap->deepCopyTo(&bitmap_);
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // For async calls, we need to quit the run loop so the test can continue.
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (async_)
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      run_loop_.Quit();
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Waits until OnFetchComplete() is called. Should only be used for
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // async tests.
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Wait() {
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ASSERT_TRUE(async_);
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    run_loop_.Run();
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL url() const { return url_; }
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool success() const { return success_; }
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const SkBitmap& bitmap() const { return bitmap_; }
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::RunLoop run_loop_;
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool called_;
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GURL url_;
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool success_;
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool async_;
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SkBitmap bitmap_;
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BitmapFetcherTestDelegate);
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BitmapFetcherBrowserTest : public InProcessBrowserTest {
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    url_fetcher_factory_.reset(
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        new net::FakeURLFetcherFactory(&url_fetcher_impl_factory_));
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    InProcessBrowserTest::SetUp();
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  net::URLFetcherImplFactory url_fetcher_impl_factory_;
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_;
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// WARNING:  These tests work with --single_process, but not
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// --single-process.  The reason is that the sandbox does not get created
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// for us by the test process if --single-process is used.
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
92116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(BitmapFetcherBrowserTest, StartTest) {
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL url("http://example.com/this-should-work");
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Put some realistic looking bitmap data into the url_fetcher.
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SkBitmap image;
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Put a real bitmap into "image".  2x2 bitmap of green 32 bit pixels.
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  image.allocN32Pixels(2, 2);
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  image.eraseColor(SK_ColorGREEN);
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Encode the bits as a PNG.
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::vector<unsigned char> compressed;
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(gfx::PNGCodec::EncodeBGRASkBitmap(image, true, &compressed));
105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Copy the bits into the string, and put them into the FakeURLFetcher.
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string image_string(compressed.begin(), compressed.end());
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Set up a delegate to wait for the callback.
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BitmapFetcherTestDelegate delegate(kAsyncCall);
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BitmapFetcher fetcher(url, &delegate);
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  url_fetcher_factory_->SetFakeResponse(
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      url, image_string, net::HTTP_OK, net::URLRequestStatus::SUCCESS);
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // We expect that the image decoder will get called and return
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // an image in a callback to OnImageDecoded().
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  fetcher.Start(
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      browser()->profile()->GetRequestContext(),
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      std::string(),
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      net::LOAD_NORMAL);
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Blocks until test delegate is notified via a callback.
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  delegate.Wait();
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(delegate.success());
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Make sure we get back the bitmap we expect.
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const SkBitmap& found_image = delegate.bitmap();
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(gfx::BitmapsAreEqual(image, found_image));
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BitmapFetcherBrowserTest, OnImageDecodedTest) {
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL url("http://example.com/this-should-work-as-well");
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SkBitmap image;
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Put a real bitmap into "image".  2x2 bitmap of green 16 bit pixels.
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  image.allocN32Pixels(2, 2);
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  image.eraseColor(SK_ColorGREEN);
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BitmapFetcherTestDelegate delegate(kSyncCall);
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BitmapFetcher fetcher(url, &delegate);
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  fetcher.OnImageDecoded(NULL, image);
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Ensure image is marked as succeeded.
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(delegate.success());
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Test that the image is what we expect.
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(gfx::BitmapsAreEqual(image, delegate.bitmap()));
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BitmapFetcherBrowserTest, OnURLFetchFailureTest) {
1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL url("http://example.com/this-should-be-fetch-failure");
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // We intentionally put no data into the bitmap to simulate a failure.
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Set up a delegate to wait for the callback.
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BitmapFetcherTestDelegate delegate(kAsyncCall);
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BitmapFetcher fetcher(url, &delegate);
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  url_fetcher_factory_->SetFakeResponse(url,
1670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                        std::string(),
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        net::HTTP_INTERNAL_SERVER_ERROR,
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                        net::URLRequestStatus::FAILED);
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  fetcher.Start(
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      browser()->profile()->GetRequestContext(),
173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      std::string(),
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      net::LOAD_NORMAL);
176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Blocks until test delegate is notified via a callback.
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  delegate.Wait();
179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(delegate.success());
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
183116680a4aac90f2aa7413d9095a592090648e557Ben MurdochIN_PROC_BROWSER_TEST_F(BitmapFetcherBrowserTest, HandleImageFailedTest) {
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL url("http://example.com/this-should-be-a-decode-failure");
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BitmapFetcherTestDelegate delegate(kAsyncCall);
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BitmapFetcher fetcher(url, &delegate);
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  url_fetcher_factory_->SetFakeResponse(url,
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        std::string("Not a real bitmap"),
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        net::HTTP_OK,
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        net::URLRequestStatus::SUCCESS);
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  fetcher.Start(
193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      browser()->profile()->GetRequestContext(),
194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      std::string(),
195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      net::LOAD_NORMAL);
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Blocks until test delegate is notified via a callback.
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  delegate.Wait();
200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(delegate.success());
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace chrome
205