Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / suggestions / image_manager_unittest.cc
blob1c797ad9f6b07360a67d2b5258343bfb3b02129a
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 <string>
7 #include "base/files/file_path.h"
8 #include "base/run_loop.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "components/leveldb_proto/proto_database.h"
11 #include "components/leveldb_proto/testing/fake_db.h"
12 #include "components/suggestions/image_encoder.h"
13 #include "components/suggestions/image_fetcher.h"
14 #include "components/suggestions/image_fetcher_delegate.h"
15 #include "components/suggestions/image_manager.h"
16 #include "components/suggestions/proto/suggestions.pb.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/gfx/image/image_skia.h"
20 #include "url/gurl.h"
22 using ::testing::Return;
23 using ::testing::StrictMock;
24 using ::testing::_;
26 namespace suggestions {
28 const char kTestUrl1[] = "http://go.com/";
29 const char kTestUrl2[] = "http://goal.com/";
30 const char kTestImagePath[] = "files/image_decoding/droids.png";
31 const char kInvalidImagePath[] = "files/DOESNOTEXIST";
33 using leveldb_proto::test::FakeDB;
34 using suggestions::ImageData;
35 using suggestions::ImageManager;
37 typedef base::hash_map<std::string, ImageData> EntryMap;
39 void AddEntry(const ImageData& d, EntryMap* map) { (*map)[d.url()] = d; }
41 class MockImageFetcher : public suggestions::ImageFetcher {
42 public:
43 MockImageFetcher() {}
44 virtual ~MockImageFetcher() {}
45 MOCK_METHOD3(StartOrQueueNetworkRequest,
46 void(const GURL&, const GURL&,
47 base::Callback<void(const GURL&, const SkBitmap*)>));
48 MOCK_METHOD1(SetImageFetcherDelegate, void(ImageFetcherDelegate*));
51 class ImageManagerTest : public testing::Test {
52 public:
53 ImageManagerTest()
54 : mock_image_fetcher_(NULL),
55 num_callback_null_called_(0),
56 num_callback_valid_called_(0) {}
58 void SetUp() override {
59 fake_db_ = new FakeDB<ImageData>(&db_model_);
60 image_manager_.reset(CreateImageManager(fake_db_));
63 void TearDown() override {
64 fake_db_ = NULL;
65 db_model_.clear();
66 image_manager_.reset();
69 void InitializeDefaultImageMapAndDatabase(ImageManager* image_manager,
70 FakeDB<ImageData>* fake_db) {
71 CHECK(image_manager);
72 CHECK(fake_db);
74 suggestions::SuggestionsProfile suggestions_profile;
75 suggestions::ChromeSuggestion* suggestion =
76 suggestions_profile.add_suggestions();
77 suggestion->set_url(kTestUrl1);
78 suggestion->set_thumbnail(kTestImagePath);
80 image_manager->Initialize(suggestions_profile);
82 // Initialize empty database.
83 fake_db->InitCallback(true);
84 fake_db->LoadCallback(true);
87 ImageData GetSampleImageData(const std::string& url) {
88 // Create test bitmap.
89 SkBitmap bm;
90 // Being careful with the Bitmap. There are memory-related issue in
91 // crbug.com/101781.
92 bm.allocN32Pixels(4, 4);
93 bm.eraseColor(SK_ColorRED);
94 ImageData data;
95 data.set_url(url);
96 std::vector<unsigned char> encoded;
97 EXPECT_TRUE(EncodeSkBitmapToJPEG(bm, &encoded));
98 data.set_data(std::string(encoded.begin(), encoded.end()));
99 return data;
102 void OnImageAvailable(base::RunLoop* loop, const GURL& url,
103 const SkBitmap* bitmap) {
104 if (bitmap) {
105 num_callback_valid_called_++;
106 } else {
107 num_callback_null_called_++;
109 loop->Quit();
112 ImageManager* CreateImageManager(FakeDB<ImageData>* fake_db) {
113 mock_image_fetcher_ = new StrictMock<MockImageFetcher>();
114 EXPECT_CALL(*mock_image_fetcher_, SetImageFetcherDelegate(_));
115 return new ImageManager(
116 scoped_ptr<ImageFetcher>(mock_image_fetcher_),
117 scoped_ptr<leveldb_proto::ProtoDatabase<ImageData>>(fake_db),
118 FakeDB<ImageData>::DirectoryForTestDB(),
119 base::ThreadTaskRunnerHandle::Get());
122 EntryMap db_model_;
123 // Owned by the ImageManager under test.
124 FakeDB<ImageData>* fake_db_;
126 MockImageFetcher* mock_image_fetcher_;
128 int num_callback_null_called_;
129 int num_callback_valid_called_;
131 base::MessageLoop message_loop_;
133 // Under test.
134 scoped_ptr<ImageManager> image_manager_;
137 TEST_F(ImageManagerTest, InitializeTest) {
138 SuggestionsProfile suggestions_profile;
139 ChromeSuggestion* suggestion = suggestions_profile.add_suggestions();
140 suggestion->set_url(kTestUrl1);
141 suggestion->set_thumbnail(kTestImagePath);
143 image_manager_->Initialize(suggestions_profile);
145 GURL output;
146 EXPECT_TRUE(image_manager_->GetImageURL(GURL(kTestUrl1), &output));
147 EXPECT_EQ(GURL(kTestImagePath), output);
149 EXPECT_FALSE(image_manager_->GetImageURL(GURL("http://b.com"), &output));
152 TEST_F(ImageManagerTest, AddImageURL) {
153 InitializeDefaultImageMapAndDatabase(image_manager_.get(), fake_db_);
155 GURL output;
156 // Try a URL the ImageManager doesn't know about.
157 ASSERT_FALSE(image_manager_->GetImageURL(GURL(kTestUrl2), &output));
159 // Explicitly add the URL and try again.
160 image_manager_->AddImageURL(GURL(kTestUrl2), GURL(kTestImagePath));
161 EXPECT_TRUE(image_manager_->GetImageURL(GURL(kTestUrl2), &output));
162 EXPECT_EQ(GURL(kTestImagePath), output);
165 TEST_F(ImageManagerTest, GetImageForURLNetwork) {
166 InitializeDefaultImageMapAndDatabase(image_manager_.get(), fake_db_);
168 // We expect the fetcher to go to network and call the callback.
169 EXPECT_CALL(*mock_image_fetcher_, StartOrQueueNetworkRequest(_, _, _));
171 // Fetch existing URL.
172 base::RunLoop run_loop;
173 image_manager_->GetImageForURL(GURL(kTestUrl1),
174 base::Bind(&ImageManagerTest::OnImageAvailable,
175 base::Unretained(this), &run_loop));
177 // Will not go to network and use the fetcher since URL is invalid.
178 // Fetch non-existing URL.
179 image_manager_->GetImageForURL(GURL(kTestUrl2),
180 base::Bind(&ImageManagerTest::OnImageAvailable,
181 base::Unretained(this), &run_loop));
182 run_loop.Run();
184 EXPECT_EQ(1, num_callback_null_called_);
187 TEST_F(ImageManagerTest, GetImageForURLNetworkCacheHit) {
188 SuggestionsProfile suggestions_profile;
189 ChromeSuggestion* suggestion = suggestions_profile.add_suggestions();
190 suggestion->set_url(kTestUrl1);
191 // The URL we set is invalid, to show that it will fail from network.
192 suggestion->set_thumbnail(kInvalidImagePath);
194 // Create the ImageManager with an added entry in the database.
195 AddEntry(GetSampleImageData(kTestUrl1), &db_model_);
196 FakeDB<ImageData>* fake_db = new FakeDB<ImageData>(&db_model_);
197 image_manager_.reset(CreateImageManager(fake_db));
198 image_manager_->Initialize(suggestions_profile);
199 fake_db->InitCallback(true);
200 fake_db->LoadCallback(true);
201 // Expect something in the cache.
202 auto encoded_image =
203 image_manager_->GetEncodedImageFromCache(GURL(kTestUrl1));
204 EXPECT_NE(nullptr, encoded_image);
206 base::RunLoop run_loop;
207 image_manager_->GetImageForURL(GURL(kTestUrl1),
208 base::Bind(&ImageManagerTest::OnImageAvailable,
209 base::Unretained(this), &run_loop));
210 run_loop.Run();
212 EXPECT_EQ(0, num_callback_null_called_);
213 EXPECT_EQ(1, num_callback_valid_called_);
216 } // namespace suggestions