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