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/search/instant_service.h"
6
7 #include <vector>
8
9 #include "base/files/file_util.h"
10 #include "base/path_service.h"
11 #include "base/task/thread_pool/thread_pool_instance.h"
12 #include "base/test/mock_callback.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/search/background/ntp_background_service.h"
15 #include "chrome/browser/search/instant_service_observer.h"
16 #include "chrome/browser/search/instant_unittest_base.h"
17 #include "chrome/browser/themes/theme_properties.h"
18 #include "chrome/browser/themes/theme_service.h"
19 #include "chrome/browser/themes/theme_service_factory.h"
20 #include "chrome/common/chrome_paths.h"
21 #include "chrome/common/pref_names.h"
22 #include "chrome/common/search/instant_types.h"
23 #include "chrome/common/url_constants.h"
24 #include "components/ntp_tiles/features.h"
25 #include "components/ntp_tiles/ntp_tile.h"
26 #include "components/ntp_tiles/section_type.h"
27 #include "components/search/ntp_features.h"
28 #include "components/sync_preferences/testing_pref_service_syncable.h"
29 #include "content/public/test/test_utils.h"
30 #include "testing/gmock/include/gmock/gmock.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "ui/native_theme/test_native_theme.h"
33 #include "url/gurl.h"
34
35 namespace {
36
37 class MockInstantServiceObserver : public InstantServiceObserver {
38 public:
39 MOCK_METHOD1(NtpThemeChanged, void(const NtpTheme&));
40 MOCK_METHOD1(MostVisitedInfoChanged, void(const InstantMostVisitedInfo&));
41 };
42
GetBackgroundInfoAsDict(const GURL & background_url)43 base::DictionaryValue GetBackgroundInfoAsDict(const GURL& background_url) {
44 base::DictionaryValue background_info;
45 background_info.SetKey("background_url", base::Value(background_url.spec()));
46 background_info.SetKey("attribution_line_1", base::Value(std::string()));
47 background_info.SetKey("attribution_line_2", base::Value(std::string()));
48 background_info.SetKey("attribution_action_url", base::Value(std::string()));
49 background_info.SetKey("collection_id", base::Value(std::string()));
50 background_info.SetKey("resume_token", base::Value(std::string()));
51 background_info.SetKey("refresh_timestamp", base::Value(0));
52 return background_info;
53 }
54
GetReferenceTime()55 base::Time GetReferenceTime() {
56 base::Time::Exploded exploded_reference_time;
57 exploded_reference_time.year = 2019;
58 exploded_reference_time.month = 1;
59 exploded_reference_time.day_of_month = 1;
60 exploded_reference_time.day_of_week = 1;
61 exploded_reference_time.hour = 0;
62 exploded_reference_time.minute = 0;
63 exploded_reference_time.second = 0;
64 exploded_reference_time.millisecond = 0;
65
66 base::Time out_time;
67 EXPECT_TRUE(
68 base::Time::FromLocalExploded(exploded_reference_time, &out_time));
69 return out_time;
70 }
71
72 class MockInstantService : public InstantService {
73 public:
MockInstantService(Profile * profile)74 explicit MockInstantService(Profile* profile) : InstantService(profile) {}
75 ~MockInstantService() override = default;
76
77 MOCK_METHOD0(ResetCustomLinks, bool());
78 MOCK_METHOD0(ResetCustomBackgroundNtpTheme, void());
79 };
80
CheckBackgroundColor(SkColor color,const base::DictionaryValue * background_info)81 bool CheckBackgroundColor(SkColor color,
82 const base::DictionaryValue* background_info) {
83 if (!background_info)
84 return false;
85
86 const base::Value* background_color =
87 background_info->FindKey(kNtpCustomBackgroundMainColor);
88 if (!background_color)
89 return false;
90
91 return color == static_cast<uint32_t>(background_color->GetInt());
92 }
93 } // namespace
94
95 using InstantServiceTest = InstantUnitTestBase;
96
TEST_F(InstantServiceTest,GetNTPTileSuggestion)97 TEST_F(InstantServiceTest, GetNTPTileSuggestion) {
98 ntp_tiles::NTPTile some_tile;
99 some_tile.source = ntp_tiles::TileSource::TOP_SITES;
100 some_tile.title_source = ntp_tiles::TileTitleSource::TITLE_TAG;
101 ntp_tiles::NTPTilesVector suggestions{some_tile};
102
103 std::map<ntp_tiles::SectionType, ntp_tiles::NTPTilesVector> suggestions_map;
104 suggestions_map[ntp_tiles::SectionType::PERSONALIZED] = suggestions;
105
106 instant_service_->OnURLsAvailable(suggestions_map);
107
108 auto items = instant_service_->most_visited_info_->items;
109 ASSERT_EQ(1, (int)items.size());
110 EXPECT_EQ(ntp_tiles::TileSource::TOP_SITES, items[0].source);
111 EXPECT_EQ(ntp_tiles::TileTitleSource::TITLE_TAG, items[0].title_source);
112 }
113
TEST_F(InstantServiceTest,DoesToggleMostVisitedOrCustomLinks)114 TEST_F(InstantServiceTest, DoesToggleMostVisitedOrCustomLinks) {
115 sync_preferences::TestingPrefServiceSyncable* pref_service =
116 profile()->GetTestingPrefService();
117 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
118 ASSERT_FALSE(pref_service->GetBoolean(prefs::kNtpUseMostVisitedTiles));
119 ASSERT_FALSE(instant_service_->most_visited_info_->use_most_visited);
120
121 // Enable most visited tiles.
122 EXPECT_TRUE(instant_service_->ToggleMostVisitedOrCustomLinks());
123 EXPECT_TRUE(pref_service->GetBoolean(prefs::kNtpUseMostVisitedTiles));
124 EXPECT_TRUE(instant_service_->most_visited_info_->use_most_visited);
125
126 // Disable most visited tiles.
127 EXPECT_TRUE(instant_service_->ToggleMostVisitedOrCustomLinks());
128 EXPECT_FALSE(pref_service->GetBoolean(prefs::kNtpUseMostVisitedTiles));
129 EXPECT_FALSE(instant_service_->most_visited_info_->use_most_visited);
130
131 // Should do nothing if this is a non-Google NTP.
132 SetUserSelectedDefaultSearchProvider("https://www.search.com");
133 EXPECT_FALSE(instant_service_->ToggleMostVisitedOrCustomLinks());
134 EXPECT_FALSE(pref_service->GetBoolean(prefs::kNtpUseMostVisitedTiles));
135 EXPECT_FALSE(instant_service_->most_visited_info_->use_most_visited);
136 }
137
TEST_F(InstantServiceTest,DoesToggleShortcutsVisibility)138 TEST_F(InstantServiceTest, DoesToggleShortcutsVisibility) {
139 testing::StrictMock<MockInstantServiceObserver> mock_observer;
140 instant_service_->AddObserver(&mock_observer);
141
142 sync_preferences::TestingPrefServiceSyncable* pref_service =
143 profile()->GetTestingPrefService();
144 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
145 ASSERT_TRUE(pref_service->GetBoolean(prefs::kNtpShortcutsVisible));
146 ASSERT_TRUE(instant_service_->most_visited_info_->is_visible);
147
148 // Hide shortcuts.
149 EXPECT_CALL(mock_observer, MostVisitedInfoChanged(testing::_)).Times(0);
150 EXPECT_TRUE(instant_service_->ToggleShortcutsVisibility(false));
151 EXPECT_FALSE(pref_service->GetBoolean(prefs::kNtpShortcutsVisible));
152 EXPECT_FALSE(instant_service_->most_visited_info_->is_visible);
153 task_environment()->RunUntilIdle();
154
155 // Show shortcuts, and check that a notification was sent.
156 EXPECT_CALL(mock_observer, MostVisitedInfoChanged(testing::_)).Times(1);
157 EXPECT_TRUE(instant_service_->ToggleShortcutsVisibility(true));
158 EXPECT_TRUE(pref_service->GetBoolean(prefs::kNtpShortcutsVisible));
159 EXPECT_TRUE(instant_service_->most_visited_info_->is_visible);
160
161 // Should do nothing if this is a non-Google NTP.
162 EXPECT_CALL(mock_observer, MostVisitedInfoChanged(testing::_)).Times(0);
163 SetUserSelectedDefaultSearchProvider("https://www.search.com");
164 EXPECT_FALSE(instant_service_->ToggleShortcutsVisibility(false));
165 EXPECT_TRUE(pref_service->GetBoolean(prefs::kNtpShortcutsVisible));
166 EXPECT_TRUE(instant_service_->most_visited_info_->is_visible);
167 }
168
TEST_F(InstantServiceTest,DisableUndoCustomLinkActionForNonGoogleSearchProvider)169 TEST_F(InstantServiceTest,
170 DisableUndoCustomLinkActionForNonGoogleSearchProvider) {
171 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
172 EXPECT_TRUE(instant_service_->UndoCustomLinkAction());
173
174 SetUserSelectedDefaultSearchProvider("https://www.search.com");
175 EXPECT_FALSE(instant_service_->UndoCustomLinkAction());
176 }
177
TEST_F(InstantServiceTest,DisableResetCustomLinksForNonGoogleSearchProvider)178 TEST_F(InstantServiceTest, DisableResetCustomLinksForNonGoogleSearchProvider) {
179 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
180 EXPECT_TRUE(instant_service_->ResetCustomLinks());
181
182 SetUserSelectedDefaultSearchProvider("https://www.search.com");
183 EXPECT_FALSE(instant_service_->ResetCustomLinks());
184 }
185
TEST_F(InstantServiceTest,IsCustomLinksEnabled)186 TEST_F(InstantServiceTest, IsCustomLinksEnabled) {
187 sync_preferences::TestingPrefServiceSyncable* pref_service =
188 profile()->GetTestingPrefService();
189
190 // Test that custom links are only enabled when Most Visited is toggled off
191 // and this is a Google NTP.
192 pref_service->SetBoolean(prefs::kNtpUseMostVisitedTiles, false);
193 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
194 EXPECT_TRUE(instant_service_->IsCustomLinksEnabled());
195
196 // All other cases should return false.
197 SetUserSelectedDefaultSearchProvider("https://www.search.com");
198 EXPECT_FALSE(instant_service_->IsCustomLinksEnabled());
199 pref_service->SetBoolean(prefs::kNtpUseMostVisitedTiles, true);
200 EXPECT_FALSE(instant_service_->IsCustomLinksEnabled());
201 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
202 EXPECT_FALSE(instant_service_->IsCustomLinksEnabled());
203 }
204
TEST_F(InstantServiceTest,SetCustomBackgroundURL)205 TEST_F(InstantServiceTest, SetCustomBackgroundURL) {
206 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
207 const GURL kUrl("https://www.foo.com");
208
209 instant_service_->AddValidBackdropUrlForTesting(kUrl);
210 instant_service_->SetCustomBackgroundInfo(kUrl, "", "", GURL(), "");
211
212 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
213 EXPECT_EQ(kUrl, theme->custom_background_url);
214 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
215 }
216
TEST_F(InstantServiceTest,SetCustomBackgroundURLInvalidURL)217 TEST_F(InstantServiceTest, SetCustomBackgroundURLInvalidURL) {
218 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
219 const GURL kInvalidUrl("foo");
220 const GURL kValidUrl("https://www.foo.com");
221 instant_service_->AddValidBackdropUrlForTesting(kValidUrl);
222 instant_service_->SetCustomBackgroundInfo(kValidUrl, "", "", GURL(), "");
223
224 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
225 EXPECT_EQ(kValidUrl.spec(), theme->custom_background_url.spec());
226
227 instant_service_->SetCustomBackgroundInfo(kInvalidUrl, "", "", GURL(), "");
228
229 theme = instant_service_->GetInitializedNtpTheme();
230 EXPECT_EQ("", theme->custom_background_url.spec());
231 EXPECT_FALSE(instant_service_->IsCustomBackgroundSet());
232 }
233
TEST_F(InstantServiceTest,SetCustomBackgroundInfo)234 TEST_F(InstantServiceTest, SetCustomBackgroundInfo) {
235 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
236 const GURL kUrl("https://www.foo.com");
237 const std::string kAttributionLine1 = "foo";
238 const std::string kAttributionLine2 = "bar";
239 const GURL kActionUrl("https://www.bar.com");
240 instant_service_->AddValidBackdropUrlForTesting(kUrl);
241 instant_service_->SetCustomBackgroundInfo(kUrl, kAttributionLine1,
242 kAttributionLine2, kActionUrl, "");
243
244 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
245 EXPECT_EQ(kUrl, theme->custom_background_url);
246 EXPECT_EQ(kAttributionLine1, theme->custom_background_attribution_line_1);
247 EXPECT_EQ(kAttributionLine2, theme->custom_background_attribution_line_2);
248 EXPECT_EQ(kActionUrl, theme->custom_background_attribution_action_url);
249 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
250 }
251
TEST_F(InstantServiceTest,ChangingSearchProviderClearsNtpThemeAndPref)252 TEST_F(InstantServiceTest, ChangingSearchProviderClearsNtpThemeAndPref) {
253 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
254 const GURL kUrl("https://www.foo.com");
255 const std::string kAttributionLine1 = "foo";
256 const std::string kAttributionLine2 = "bar";
257 const GURL kActionUrl("https://www.bar.com");
258
259 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
260 instant_service_->AddValidBackdropUrlForTesting(kUrl);
261 instant_service_->SetCustomBackgroundInfo(kUrl, kAttributionLine1,
262 kAttributionLine2, kActionUrl, "");
263
264 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
265 EXPECT_EQ(kUrl, theme->custom_background_url);
266 EXPECT_EQ(kAttributionLine1, theme->custom_background_attribution_line_1);
267 EXPECT_EQ(kAttributionLine2, theme->custom_background_attribution_line_2);
268 EXPECT_EQ(kActionUrl, theme->custom_background_attribution_action_url);
269 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
270
271 SetUserSelectedDefaultSearchProvider("https://www.search.com");
272 instant_service_->UpdateNtpTheme();
273
274 theme = instant_service_->GetInitializedNtpTheme();
275 EXPECT_EQ(GURL(), theme->custom_background_url);
276 EXPECT_EQ("", theme->custom_background_attribution_line_1);
277 EXPECT_EQ("", theme->custom_background_attribution_line_2);
278 EXPECT_EQ(GURL(), theme->custom_background_attribution_action_url);
279 EXPECT_FALSE(instant_service_->IsCustomBackgroundSet());
280
281 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
282 instant_service_->UpdateNtpTheme();
283
284 theme = instant_service_->GetInitializedNtpTheme();
285 EXPECT_EQ(GURL(), theme->custom_background_url);
286 EXPECT_EQ("", theme->custom_background_attribution_line_1);
287 EXPECT_EQ("", theme->custom_background_attribution_line_2);
288 EXPECT_EQ(GURL(), theme->custom_background_attribution_action_url);
289 EXPECT_FALSE(instant_service_->IsCustomBackgroundSet());
290 }
291
TEST_F(InstantServiceTest,LocalBackgroundImageCopyCreated)292 TEST_F(InstantServiceTest, LocalBackgroundImageCopyCreated) {
293 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
294 const GURL kUrl("chrome-search://local-ntp/background.jpg");
295
296 base::FilePath profile_path = profile()->GetPath();
297 base::FilePath path(profile_path.AppendASCII("test_file"));
298 base::FilePath copy_path(profile_path.AppendASCII(
299 chrome::kChromeSearchLocalNtpBackgroundFilename));
300
301 base::WriteFile(path, "background_image", 16);
302
303 instant_service_->SelectLocalBackgroundImage(path);
304
305 task_environment()->RunUntilIdle();
306
307 bool file_exists = base::PathExists(copy_path);
308
309 EXPECT_EQ(true, file_exists);
310 EXPECT_EQ(true, profile()->GetTestingPrefService()->GetBoolean(
311 prefs::kNtpCustomBackgroundLocalToDevice));
312 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
313 }
314
TEST_F(InstantServiceTest,ChangingSearchProviderRemovesLocalBackgroundImageCopy)315 TEST_F(InstantServiceTest,
316 ChangingSearchProviderRemovesLocalBackgroundImageCopy) {
317 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
318 base::FilePath profile_path = profile()->GetPath();
319 base::FilePath path(profile_path.AppendASCII(
320 chrome::kChromeSearchLocalNtpBackgroundFilename));
321
322 base::WriteFile(path, "background_image", 16);
323
324 SetUserSelectedDefaultSearchProvider("https://www.search.com");
325 instant_service_->UpdateNtpTheme();
326
327 task_environment()->RunUntilIdle();
328
329 bool file_exists = base::PathExists(path);
330
331 EXPECT_EQ(false, file_exists);
332 EXPECT_EQ(false, profile()->GetTestingPrefService()->GetBoolean(
333 prefs::kNtpCustomBackgroundLocalToDevice));
334 EXPECT_FALSE(instant_service_->IsCustomBackgroundSet());
335 }
336
TEST_F(InstantServiceTest,SettingUrlRemovesLocalBackgroundImageCopy)337 TEST_F(InstantServiceTest, SettingUrlRemovesLocalBackgroundImageCopy) {
338 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
339 const GURL kUrl("https://www.foo.com");
340
341 base::FilePath profile_path = profile()->GetPath();
342 base::FilePath path(profile_path.AppendASCII(
343 chrome::kChromeSearchLocalNtpBackgroundFilename));
344
345 base::WriteFile(path, "background_image", 16);
346
347 instant_service_->AddValidBackdropUrlForTesting(kUrl);
348 instant_service_->SetCustomBackgroundInfo(kUrl, "", "", GURL(), "");
349 instant_service_->UpdateNtpTheme();
350
351 task_environment()->RunUntilIdle();
352
353 bool file_exists = base::PathExists(path);
354
355 EXPECT_EQ(false, file_exists);
356 EXPECT_EQ(false, profile()->GetTestingPrefService()->GetBoolean(
357 prefs::kNtpCustomBackgroundLocalToDevice));
358 ASSERT_TRUE(instant_service_->IsCustomBackgroundSet());
359 }
360
TEST_F(InstantServiceTest,CustomBackgroundAttributionActionUrlReset)361 TEST_F(InstantServiceTest, CustomBackgroundAttributionActionUrlReset) {
362 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
363 const GURL kUrl("https://www.foo.com");
364 const std::string kAttributionLine1 = "foo";
365 const std::string kAttributionLine2 = "bar";
366 const GURL kHttpsActionUrl("https://www.bar.com");
367 const GURL kHttpActionUrl("http://www.bar.com");
368
369 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
370 instant_service_->AddValidBackdropUrlForTesting(kUrl);
371 instant_service_->SetCustomBackgroundInfo(
372 kUrl, kAttributionLine1, kAttributionLine2, kHttpsActionUrl, "");
373
374 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
375 EXPECT_EQ(kHttpsActionUrl, theme->custom_background_attribution_action_url);
376 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
377
378 instant_service_->SetCustomBackgroundInfo(
379 kUrl, kAttributionLine1, kAttributionLine2, kHttpActionUrl, "");
380
381 theme = instant_service_->GetInitializedNtpTheme();
382 EXPECT_EQ(GURL(), theme->custom_background_attribution_action_url);
383 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
384
385 instant_service_->SetCustomBackgroundInfo(
386 kUrl, kAttributionLine1, kAttributionLine2, kHttpsActionUrl, "");
387
388 theme = instant_service_->GetInitializedNtpTheme();
389 EXPECT_EQ(kHttpsActionUrl, theme->custom_background_attribution_action_url);
390 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
391
392 instant_service_->SetCustomBackgroundInfo(kUrl, kAttributionLine1,
393 kAttributionLine2, GURL(), "");
394
395 theme = instant_service_->GetInitializedNtpTheme();
396 EXPECT_EQ(GURL(), theme->custom_background_attribution_action_url);
397 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
398 }
399
TEST_F(InstantServiceTest,UpdatingPrefUpdatesNtpTheme)400 TEST_F(InstantServiceTest, UpdatingPrefUpdatesNtpTheme) {
401 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
402 const GURL kUrlFoo("https://www.foo.com");
403 const GURL kUrlBar("https://www.bar.com");
404
405 sync_preferences::TestingPrefServiceSyncable* pref_service =
406 profile()->GetTestingPrefService();
407 pref_service->SetUserPref(
408 prefs::kNtpCustomBackgroundDict,
409 std::make_unique<base::Value>(GetBackgroundInfoAsDict(kUrlFoo)));
410
411 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
412 EXPECT_EQ(kUrlFoo, theme->custom_background_url);
413 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
414
415 pref_service->SetUserPref(
416 prefs::kNtpCustomBackgroundDict,
417 std::make_unique<base::Value>(GetBackgroundInfoAsDict(kUrlBar)));
418
419 theme = instant_service_->GetInitializedNtpTheme();
420 EXPECT_EQ(kUrlBar, theme->custom_background_url);
421 EXPECT_EQ(false,
422 pref_service->GetBoolean(prefs::kNtpCustomBackgroundLocalToDevice));
423 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
424 }
425
TEST_F(InstantServiceTest,SetLocalImage)426 TEST_F(InstantServiceTest, SetLocalImage) {
427 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
428 const GURL kUrl("chrome-search://local-ntp/background.jpg?123456789");
429
430 sync_preferences::TestingPrefServiceSyncable* pref_service =
431 profile()->GetTestingPrefService();
432
433 base::FilePath profile_path = profile()->GetPath();
434 base::FilePath path(profile_path.AppendASCII(
435 chrome::kChromeSearchLocalNtpBackgroundFilename));
436 base::WriteFile(path, "background_image", 16);
437 base::ThreadPoolInstance::Get()->FlushForTesting();
438
439 instant_service_->SelectLocalBackgroundImage(path);
440 task_environment()->RunUntilIdle();
441
442 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
443 EXPECT_TRUE(base::StartsWith(theme->custom_background_url.spec(),
444 chrome::kChromeSearchLocalNtpBackgroundUrl,
445 base::CompareCase::SENSITIVE));
446 EXPECT_TRUE(
447 pref_service->GetBoolean(prefs::kNtpCustomBackgroundLocalToDevice));
448 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
449 }
450
TEST_F(InstantServiceTest,SyncPrefOverridesAndRemovesLocalImage)451 TEST_F(InstantServiceTest, SyncPrefOverridesAndRemovesLocalImage) {
452 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
453 const GURL kUrl("https://www.foo.com/");
454
455 sync_preferences::TestingPrefServiceSyncable* pref_service =
456 profile()->GetTestingPrefService();
457
458 base::FilePath profile_path = profile()->GetPath();
459 base::FilePath path(profile_path.AppendASCII(
460 chrome::kChromeSearchLocalNtpBackgroundFilename));
461 base::WriteFile(path, "background_image", 16);
462 base::ThreadPoolInstance::Get()->FlushForTesting();
463
464 instant_service_->SelectLocalBackgroundImage(path);
465 task_environment()->RunUntilIdle();
466
467 EXPECT_TRUE(
468 pref_service->GetBoolean(prefs::kNtpCustomBackgroundLocalToDevice));
469 EXPECT_TRUE(base::PathExists(path));
470
471 // Update theme info via Sync.
472 pref_service->SetUserPref(
473 prefs::kNtpCustomBackgroundDict,
474 std::make_unique<base::Value>(GetBackgroundInfoAsDict(kUrl)));
475 task_environment()->RunUntilIdle();
476
477 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
478 EXPECT_EQ(kUrl, theme->custom_background_url);
479 EXPECT_FALSE(
480 pref_service->GetBoolean(prefs::kNtpCustomBackgroundLocalToDevice));
481 EXPECT_FALSE(base::PathExists(path));
482 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
483 }
484
TEST_F(InstantServiceTest,ValidateBackdropUrls)485 TEST_F(InstantServiceTest, ValidateBackdropUrls) {
486 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
487 const GURL kBackdropUrl1("https://www.foo.com");
488 const GURL kBackdropUrl2("https://www.bar.com");
489 const GURL kNonBackdropUrl1("https://www.test.com");
490 const GURL kNonBackdropUrl2("https://www.foo.com/path");
491
492 instant_service_->AddValidBackdropUrlForTesting(kBackdropUrl1);
493 instant_service_->AddValidBackdropUrlForTesting(kBackdropUrl2);
494
495 instant_service_->SetCustomBackgroundInfo(kBackdropUrl1, "", "", GURL(), "");
496 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
497 EXPECT_EQ(kBackdropUrl1, theme->custom_background_url);
498 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
499
500 instant_service_->SetCustomBackgroundInfo(kNonBackdropUrl1, "", "", GURL(),
501 "");
502 theme = instant_service_->GetInitializedNtpTheme();
503 EXPECT_EQ(GURL(), theme->custom_background_url);
504 EXPECT_FALSE(instant_service_->IsCustomBackgroundSet());
505
506 instant_service_->SetCustomBackgroundInfo(kBackdropUrl2, "", "", GURL(), "");
507 theme = instant_service_->GetInitializedNtpTheme();
508 EXPECT_EQ(kBackdropUrl2, theme->custom_background_url);
509 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
510
511 instant_service_->SetCustomBackgroundInfo(kNonBackdropUrl2, "", "", GURL(),
512 "");
513 theme = instant_service_->GetInitializedNtpTheme();
514 EXPECT_EQ(GURL(), theme->custom_background_url);
515 EXPECT_FALSE(instant_service_->IsCustomBackgroundSet());
516 }
517
TEST_F(InstantServiceTest,TestNoNtpTheme)518 TEST_F(InstantServiceTest, TestNoNtpTheme) {
519 instant_service_->theme_ = nullptr;
520 EXPECT_NE(nullptr, instant_service_->GetInitializedNtpTheme());
521
522 instant_service_->theme_ = nullptr;
523 // As |FallbackToDefaultNtpTheme| uses |theme_| it should initialize it
524 // otherwise the test should crash.
525 instant_service_->FallbackToDefaultNtpTheme();
526 EXPECT_NE(nullptr, instant_service_->theme_);
527 }
528
TEST_F(InstantServiceTest,TestResetToDefault)529 TEST_F(InstantServiceTest, TestResetToDefault) {
530 MockInstantService mock_instant_service_(profile());
531 EXPECT_CALL(mock_instant_service_, ResetCustomLinks());
532 EXPECT_CALL(mock_instant_service_, ResetCustomBackgroundNtpTheme());
533 mock_instant_service_.ResetToDefault();
534 }
535
536 class InstantServiceThemeTest : public InstantServiceTest {
537 public:
InstantServiceThemeTest()538 InstantServiceThemeTest() {}
~InstantServiceThemeTest()539 ~InstantServiceThemeTest() override {}
540
theme()541 ui::TestNativeTheme* theme() { return &theme_; }
542
543 private:
544 ui::TestNativeTheme theme_;
545
546 DISALLOW_COPY_AND_ASSIGN(InstantServiceThemeTest);
547 };
548
TEST_F(InstantServiceTest,LocalImageDoesNotHaveAttribution)549 TEST_F(InstantServiceTest, LocalImageDoesNotHaveAttribution) {
550 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
551 const GURL kUrl("https://www.foo.com");
552 const std::string kAttributionLine1 = "foo";
553 const std::string kAttributionLine2 = "bar";
554 const GURL kActionUrl("https://www.bar.com");
555
556 sync_preferences::TestingPrefServiceSyncable* pref_service =
557 profile()->GetTestingPrefService();
558 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
559 instant_service_->AddValidBackdropUrlForTesting(kUrl);
560 instant_service_->SetCustomBackgroundInfo(kUrl, kAttributionLine1,
561 kAttributionLine2, kActionUrl, "");
562
563 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
564 ASSERT_EQ(kAttributionLine1, theme->custom_background_attribution_line_1);
565 ASSERT_EQ(kAttributionLine2, theme->custom_background_attribution_line_2);
566 ASSERT_EQ(kActionUrl, theme->custom_background_attribution_action_url);
567 ASSERT_TRUE(instant_service_->IsCustomBackgroundSet());
568
569 base::FilePath profile_path = profile()->GetPath();
570 base::FilePath path(profile_path.AppendASCII(
571 chrome::kChromeSearchLocalNtpBackgroundFilename));
572 base::WriteFile(path, "background_image", 16);
573 base::ThreadPoolInstance::Get()->FlushForTesting();
574
575 instant_service_->SelectLocalBackgroundImage(path);
576 task_environment()->RunUntilIdle();
577
578 theme = instant_service_->GetInitializedNtpTheme();
579 EXPECT_TRUE(base::StartsWith(theme->custom_background_url.spec(),
580 chrome::kChromeSearchLocalNtpBackgroundUrl,
581 base::CompareCase::SENSITIVE));
582 EXPECT_TRUE(
583 pref_service->GetBoolean(prefs::kNtpCustomBackgroundLocalToDevice));
584 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
585 EXPECT_EQ("", theme->custom_background_attribution_line_1);
586 EXPECT_EQ("", theme->custom_background_attribution_line_2);
587 EXPECT_EQ(GURL(), theme->custom_background_attribution_action_url);
588 }
589
TEST_F(InstantServiceTest,TestUpdateCustomBackgroundColor)590 TEST_F(InstantServiceTest, TestUpdateCustomBackgroundColor) {
591 SkBitmap bitmap;
592 bitmap.allocN32Pixels(32, 32);
593 bitmap.eraseColor(SK_ColorRED);
594 gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmap);
595 sync_preferences::TestingPrefServiceSyncable* pref_service =
596 profile()->GetTestingPrefService();
597
598 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
599
600 // Background color will not update if no background is set.
601 instant_service_->UpdateCustomBackgroundColorAsync(
602 base::TimeTicks::Now(), image, image_fetcher::RequestMetadata());
603 task_environment()->RunUntilIdle();
604 EXPECT_FALSE(CheckBackgroundColor(
605 SK_ColorRED,
606 pref_service->GetDictionary(prefs::kNtpCustomBackgroundDict)));
607
608 const GURL kUrl("https://www.foo.com");
609 const std::string kAttributionLine1 = "foo";
610 const std::string kAttributionLine2 = "bar";
611 const GURL kActionUrl("https://www.bar.com");
612
613 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
614 instant_service_->AddValidBackdropUrlForTesting(kUrl);
615 instant_service_->SetCustomBackgroundInfo(kUrl, kAttributionLine1,
616 kAttributionLine2, kActionUrl, "");
617
618 // Background color will not update if background timestamp has changed.
619 instant_service_->UpdateCustomBackgroundColorAsync(
620 base::TimeTicks::Now(), image, image_fetcher::RequestMetadata());
621 task_environment()->RunUntilIdle();
622 EXPECT_FALSE(CheckBackgroundColor(
623 SK_ColorRED,
624 pref_service->GetDictionary(prefs::kNtpCustomBackgroundDict)));
625
626 // Background color should update.
627 instant_service_->UpdateCustomBackgroundColorAsync(
628 instant_service_->GetBackgroundUpdatedTimestampForTesting(), image,
629 image_fetcher::RequestMetadata());
630 task_environment()->RunUntilIdle();
631 EXPECT_TRUE(CheckBackgroundColor(
632 SK_ColorRED,
633 pref_service->GetDictionary(prefs::kNtpCustomBackgroundDict)));
634 }
635
TEST_F(InstantServiceTest,LocalImageDoesNotUpdateCustomBackgroundColor)636 TEST_F(InstantServiceTest, LocalImageDoesNotUpdateCustomBackgroundColor) {
637 SkBitmap bitmap;
638 bitmap.allocN32Pixels(32, 32);
639 bitmap.eraseColor(SK_ColorRED);
640 gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmap);
641 sync_preferences::TestingPrefServiceSyncable* pref_service =
642 profile()->GetTestingPrefService();
643
644 base::FilePath profile_path = profile()->GetPath();
645 base::FilePath path(profile_path.AppendASCII("test_file"));
646 base::FilePath copy_path(profile_path.AppendASCII(
647 chrome::kChromeSearchLocalNtpBackgroundFilename));
648 base::WriteFile(path, "background_image", 16);
649
650 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
651
652 const GURL kUrl("https://www.foo.com");
653 const std::string kAttributionLine1 = "foo";
654 const std::string kAttributionLine2 = "bar";
655 const GURL kActionUrl("https://www.bar.com");
656
657 SetUserSelectedDefaultSearchProvider("{google:baseURL}");
658 instant_service_->AddValidBackdropUrlForTesting(kUrl);
659 instant_service_->SetCustomBackgroundInfo(kUrl, kAttributionLine1,
660 kAttributionLine2, kActionUrl, "");
661 base::TimeTicks time_set =
662 instant_service_->GetBackgroundUpdatedTimestampForTesting();
663
664 instant_service_->SelectLocalBackgroundImage(path);
665 task_environment()->RunUntilIdle();
666
667 // Background color will not update if a local image was uploaded in the
668 // meantime.
669 instant_service_->UpdateCustomBackgroundColorAsync(
670 time_set, image, image_fetcher::RequestMetadata());
671 task_environment()->RunUntilIdle();
672 EXPECT_FALSE(CheckBackgroundColor(
673 SK_ColorRED,
674 pref_service->GetDictionary(prefs::kNtpCustomBackgroundDict)));
675 }
676
TEST_F(InstantServiceTest,SetCustomBackgroundCollectionId)677 TEST_F(InstantServiceTest, SetCustomBackgroundCollectionId) {
678 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
679 const std::string kInvalidId("aarrtt");
680 const std::string kValidId("art");
681
682 // A valid id should update the pref/background.
683 CollectionImage image;
684 image.collection_id = kValidId;
685 image.image_url = GURL("https://www.test.com/");
686 instant_service_->SetNextCollectionImageForTesting(image);
687
688 instant_service_->AddValidBackdropCollectionForTesting(kValidId);
689 instant_service_->SetCustomBackgroundInfo(GURL(), "", "", GURL(), kValidId);
690 task_environment()->RunUntilIdle();
691
692 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
693 EXPECT_EQ(kValidId, theme->collection_id);
694 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
695
696 // An invalid id should clear the pref/background.
697 CollectionImage image2;
698 instant_service_->SetNextCollectionImageForTesting(image2);
699 instant_service_->SetCustomBackgroundInfo(GURL(), "", "", GURL(), kInvalidId);
700 task_environment()->RunUntilIdle();
701
702 theme = instant_service_->GetInitializedNtpTheme();
703 EXPECT_EQ(std::string(), theme->collection_id);
704 EXPECT_FALSE(instant_service_->IsCustomBackgroundSet());
705 }
706
TEST_F(InstantServiceTest,CollectionIdTakePriorityOverBackgroundURL)707 TEST_F(InstantServiceTest, CollectionIdTakePriorityOverBackgroundURL) {
708 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
709 const std::string kValidId("art");
710 const GURL kUrl("https://www.foo.com/");
711
712 CollectionImage image;
713 image.collection_id = kValidId;
714 image.image_url = GURL("https://www.test.com/");
715 instant_service_->SetNextCollectionImageForTesting(image);
716 instant_service_->AddValidBackdropUrlForTesting(kUrl);
717 instant_service_->AddValidBackdropCollectionForTesting(kValidId);
718
719 instant_service_->SetCustomBackgroundInfo(kUrl, "", "", GURL(), kValidId);
720 task_environment()->RunUntilIdle();
721
722 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
723 EXPECT_EQ(kValidId, theme->collection_id);
724 EXPECT_EQ("https://www.test.com/", theme->custom_background_url);
725 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
726 }
727
TEST_F(InstantServiceTest,RefreshesBackgroundAfter24Hours)728 TEST_F(InstantServiceTest, RefreshesBackgroundAfter24Hours) {
729 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
730 const std::string kValidId("art");
731 const GURL kImageUrl1("https://www.test.com/1/");
732 const GURL kImageUrl2("https://www.test.com/2/");
733
734 instant_service_->SetClockForTesting(clock_);
735 clock_->SetNow(GetReferenceTime());
736
737 // A valid id should update the pref/background.
738 CollectionImage image;
739 image.collection_id = kValidId;
740 image.image_url = kImageUrl1;
741 instant_service_->SetNextCollectionImageForTesting(image);
742
743 instant_service_->AddValidBackdropCollectionForTesting(kValidId);
744 instant_service_->SetCustomBackgroundInfo(GURL(), "", "", GURL(), kValidId);
745 task_environment()->RunUntilIdle();
746
747 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
748 EXPECT_EQ(kValidId, theme->collection_id);
749 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
750
751 CollectionImage image2;
752 image2.collection_id = kValidId;
753 image2.image_url = kImageUrl2;
754 instant_service_->SetNextCollectionImageForTesting(image2);
755
756 // Should not refresh background.
757 theme = instant_service_->GetInitializedNtpTheme();
758 task_environment()->RunUntilIdle();
759 EXPECT_EQ(kValidId, theme->collection_id);
760 EXPECT_EQ(kImageUrl1, theme->custom_background_url);
761 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
762
763 clock_->Advance(base::TimeDelta::FromHours(25));
764
765 // Should refresh background after >24 hours.
766 theme = instant_service_->GetInitializedNtpTheme();
767 task_environment()->RunUntilIdle();
768 EXPECT_EQ(kValidId, theme->collection_id);
769 EXPECT_EQ(kImageUrl2, theme->custom_background_url);
770 EXPECT_TRUE(instant_service_->IsCustomBackgroundSet());
771 }
772
TEST_F(InstantServiceTest,SetNTPElementsNtpTheme)773 TEST_F(InstantServiceTest, SetNTPElementsNtpTheme) {
774 const auto& theme_provider =
775 ThemeService::GetThemeProviderForProfile(profile());
776 SkColor default_text_color =
777 theme_provider.GetColor(ThemeProperties::COLOR_NTP_TEXT);
778 SkColor default_logo_color =
779 theme_provider.GetColor(ThemeProperties::COLOR_NTP_LOGO);
780 SkColor default_shortcut_color =
781 theme_provider.GetColor(ThemeProperties::COLOR_NTP_SHORTCUT);
782
783 ASSERT_FALSE(instant_service_->IsCustomBackgroundSet());
784
785 // Check defaults when no theme and no custom backgrounds is set.
786 NtpTheme* theme = instant_service_->GetInitializedNtpTheme();
787 EXPECT_EQ(default_text_color, theme->text_color);
788 EXPECT_FALSE(theme->logo_alternate);
789 EXPECT_EQ(default_logo_color, theme->logo_color);
790 EXPECT_EQ(default_shortcut_color, theme->shortcut_color);
791
792 // Install colors, theme update should trigger SetNTPElementsNtpTheme() and
793 // update NTP themed elements info.
794 ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile());
795 content::WindowedNotificationObserver theme_change_observer(
796 chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
797 content::Source<ThemeService>(theme_service));
798 theme_service->BuildAutogeneratedThemeFromColor(SK_ColorRED);
799 theme_change_observer.Wait();
800
801 theme = instant_service_->GetInitializedNtpTheme();
802 EXPECT_NE(default_text_color, theme->text_color);
803 EXPECT_TRUE(theme->logo_alternate);
804 EXPECT_NE(default_logo_color, theme->logo_color);
805 EXPECT_NE(default_shortcut_color, theme->shortcut_color);
806
807 // Setting a custom background should call SetNTPElementsNtpTheme() and
808 // update NTP themed elements info.
809 const GURL kUrl("https://www.foo.com");
810 instant_service_->AddValidBackdropUrlForTesting(kUrl);
811 instant_service_->SetCustomBackgroundInfo(kUrl, "", "", GURL(), "");
812 ASSERT_TRUE(instant_service_->IsCustomBackgroundSet());
813
814 theme = instant_service_->GetInitializedNtpTheme();
815 EXPECT_NE(default_text_color, theme->text_color);
816 EXPECT_TRUE(theme->logo_alternate);
817 EXPECT_EQ(default_logo_color, theme->logo_color);
818 // The shortcut color with a background set should always use the light mode
819 // default regardless of system setting.
820 EXPECT_EQ(ThemeProperties::GetDefaultColor(
821 ThemeProperties::COLOR_NTP_SHORTCUT, false),
822 theme->shortcut_color);
823 }
824