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 #import "ios/chrome/browser/enhanced_bookmarks/bookmark_image_service_ios.h"
7 #import <UIKit/UIKit.h>
9 #include "base/files/file_path.h"
10 #include "base/mac/bind_objc_block.h"
11 #include "base/mac/scoped_nsobject.h"
12 #include "base/macros.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/path_service.h"
15 #include "base/strings/sys_string_conversions.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "components/bookmarks/browser/bookmark_model.h"
18 #include "components/bookmarks/test/test_bookmark_client.h"
19 #include "components/enhanced_bookmarks/enhanced_bookmark_model.h"
20 #include "components/enhanced_bookmarks/test_image_store.h"
21 #include "ios/chrome/browser/chrome_paths.h"
22 #include "ios/web/public/test/test_web_thread.h"
23 #include "net/test/embedded_test_server/embedded_test_server.h"
24 #include "net/url_request/url_request_context_getter.h"
25 #include "net/url_request/url_request_test_util.h"
26 #include "testing/gtest_mac.h"
27 #include "testing/platform_test.h"
31 class LocalTestImageStore : public TestImageStore {
33 LocalTestImageStore() : TestImageStore() {
34 sequence_checker_.DetachFromSequence();
36 ~LocalTestImageStore() override {}
39 DISALLOW_COPY_AND_ASSIGN(LocalTestImageStore);
42 class BookmarkImagesIOSTest : public PlatformTest {
44 BookmarkImagesIOSTest()
45 : message_loop_(base::MessageLoop::TYPE_IO),
46 ui_thread_(web::WebThread::UI, &message_loop_),
47 io_thread_(web::WebThread::IO, &message_loop_),
48 request_context_getter_(
49 new net::TestURLRequestContextGetter(message_loop_.task_runner())) {
52 ~BookmarkImagesIOSTest() override {}
54 void SetUp() override {
55 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
56 PlatformTest::SetUp();
61 void TearDown() override {
62 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
65 PlatformTest::TearDown();
68 bool WaitUntilLoop(bool (^condition)()) {
69 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
70 base::Time maxDate = base::Time::Now() + base::TimeDelta::FromSeconds(10);
71 while (!condition()) {
72 if (base::Time::Now() > maxDate)
74 message_loop_.RunUntilIdle();
75 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
80 GURL get_bookmark_url() { return test_server_->GetURL("/index.html"); }
82 GURL get_image_bookmark_url() { return test_server_->GetURL("/image.jpg"); }
84 GURL get_missing_image_bookmark_url() {
85 return test_server_->GetURL("/no-such-image.jpg");
89 bookmarks::TestBookmarkClient bookmark_client_;
90 scoped_ptr<bookmarks::BookmarkModel> bookmark_model_;
91 scoped_ptr<enhanced_bookmarks::EnhancedBookmarkModel>
92 enhanced_bookmark_model_;
93 scoped_ptr<BookmarkImageServiceIOS> bookmark_image_service_;
94 base::MessageLoop message_loop_;
95 web::TestWebThread ui_thread_;
96 web::TestWebThread io_thread_;
97 scoped_refptr<base::SequencedWorkerPool> pool_;
98 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
99 scoped_ptr<net::test_server::EmbeddedTestServer> test_server_;
102 void StartTestServer() {
103 base::FilePath test_data_dir;
104 ASSERT_TRUE(PathService::Get(ios::DIR_TEST_DATA, &test_data_dir));
105 test_data_dir = test_data_dir.AppendASCII("webdata/bookmarkimages");
107 test_server_.reset(new net::test_server::EmbeddedTestServer);
108 ASSERT_TRUE(test_server_->InitializeAndWaitUntilReady());
109 test_server_->ServeFilesFromDirectory(test_data_dir);
112 void ShutdownTestServer() {
113 ASSERT_TRUE(test_server_->ShutdownAndWaitUntilComplete());
114 test_server_.reset();
117 void SetUpServices() {
118 pool_ = new base::SequencedWorkerPool(1, "BookmarkImagesIOSTest");
119 bookmark_model_ = bookmark_client_.CreateModel();
120 enhanced_bookmark_model_.reset(
121 new enhanced_bookmarks::EnhancedBookmarkModel(bookmark_model_.get(),
123 bookmark_image_service_.reset(new BookmarkImageServiceIOS(
124 make_scoped_ptr(new LocalTestImageStore),
125 enhanced_bookmark_model_.get(), request_context_getter_.get(), pool_));
128 void TearDownServices() {
129 // Needs to call Shutdown on KeyedService to emulate the two-phase
130 // shutdown process of DependencyManager.
131 bookmark_image_service_->Shutdown();
132 enhanced_bookmark_model_->Shutdown();
133 bookmark_model_->Shutdown();
136 bookmark_image_service_.reset();
137 enhanced_bookmark_model_.reset();
138 bookmark_model_.reset();
142 DISALLOW_COPY_AND_ASSIGN(BookmarkImagesIOSTest);
145 TEST_F(BookmarkImagesIOSTest, GetNoImage) {
146 __block bool success = false;
147 __block bool done = false;
148 bookmark_image_service_->SalientImageResizedForUrl(
149 get_bookmark_url(), CGSizeMake(100, 100), false,
151 ^(scoped_refptr<enhanced_bookmarks::ImageRecord> imageRecord) {
152 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
154 success = imageRecord->image->IsEmpty();
157 EXPECT_TRUE(WaitUntilLoop(^{
160 EXPECT_TRUE(success);
163 TEST_F(BookmarkImagesIOSTest, GetNoImageFromURLInBookmark) {
164 const bookmarks::BookmarkNode* node = bookmark_model_->AddURL(
165 bookmark_model_->mobile_node(), 0, base::ASCIIToUTF16("Whatever"),
168 ASSERT_TRUE(enhanced_bookmark_model_->SetAllImages(
170 GURL(), // original URL.
172 get_missing_image_bookmark_url(), // Thumbnail URL.
175 __block scoped_ptr<gfx::Image> returnedImage;
176 __block GURL returnedImageUrl;
177 __block bool done = false;
178 bookmark_image_service_->SalientImageResizedForUrl(
179 get_bookmark_url(), CGSizeMake(100, 100), false,
181 ^(scoped_refptr<enhanced_bookmarks::ImageRecord> imageRecord) {
182 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
184 returnedImage = imageRecord->image.Pass();
185 returnedImageUrl = imageRecord->url;
188 EXPECT_TRUE(WaitUntilLoop(^{
191 EXPECT_TRUE(returnedImage->IsEmpty());
192 EXPECT_EQ(returnedImageUrl, get_missing_image_bookmark_url());
195 TEST_F(BookmarkImagesIOSTest, getImageFromURLInBookmark) {
196 const bookmarks::BookmarkNode* node = bookmark_model_->AddURL(
197 bookmark_model_->mobile_node(), 0, base::ASCIIToUTF16("Whatever"),
199 ASSERT_TRUE(enhanced_bookmark_model_->SetAllImages(node, GURL(), 10,
201 get_image_bookmark_url(),
203 368)); // thumbnail url.
205 __block scoped_ptr<gfx::Image> returnedImage;
206 __block GURL returnedImageUrl;
207 __block bool done = false;
208 bookmark_image_service_->SalientImageResizedForUrl(
209 get_bookmark_url(), CGSizeMake(100, 100), false,
211 ^(scoped_refptr<enhanced_bookmarks::ImageRecord> imageRecord) {
212 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
214 returnedImage = imageRecord->image.Pass();
215 returnedImageUrl = imageRecord->url;
218 EXPECT_TRUE(WaitUntilLoop(^{
221 EXPECT_FALSE(returnedImage->IsEmpty());
222 EXPECT_EQ(returnedImageUrl, get_image_bookmark_url());