OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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 "components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h" |
| 6 |
| 7 #include <memory> |
| 8 #include <string> |
| 9 #include <utility> |
| 10 |
| 11 #include "base/bind.h" |
| 12 #include "base/macros.h" |
| 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "components/bookmarks/browser/bookmark_model.h" |
| 16 #include "components/bookmarks/browser/bookmark_node.h" |
| 17 #include "components/bookmarks/test/test_bookmark_client.h" |
| 18 #include "components/ntp_snippets/bookmarks/bookmark_last_visit_utils.h" |
| 19 #include "components/ntp_snippets/category.h" |
| 20 #include "components/ntp_snippets/mock_content_suggestions_provider_observer.h" |
| 21 #include "components/prefs/testing_pref_service.h" |
| 22 #include "testing/gmock/include/gmock/gmock.h" |
| 23 #include "testing/gtest/include/gtest/gtest.h" |
| 24 #include "url/gurl.h" |
| 25 |
| 26 namespace ntp_snippets { |
| 27 |
| 28 namespace { |
| 29 |
| 30 using ::testing::StrictMock; |
| 31 using ::testing::_; |
| 32 using ::testing::Eq; |
| 33 using ::testing::IsEmpty; |
| 34 using ::testing::Property; |
| 35 using ::testing::UnorderedElementsAre; |
| 36 |
| 37 class BookmarkSuggestionsProviderTest : public ::testing::Test { |
| 38 public: |
| 39 BookmarkSuggestionsProviderTest() |
| 40 : model_(bookmarks::TestBookmarkClient::CreateModel()) { |
| 41 EXPECT_CALL(observer_, OnNewSuggestions(_, Category::FromKnownCategory( |
| 42 KnownCategories::BOOKMARKS), |
| 43 IsEmpty())) |
| 44 .RetiresOnSaturation(); |
| 45 EXPECT_CALL(observer_, |
| 46 OnCategoryStatusChanged( |
| 47 _, Category::FromKnownCategory(KnownCategories::BOOKMARKS), |
| 48 CategoryStatus::AVAILABLE_LOADING)) |
| 49 .RetiresOnSaturation(); |
| 50 EXPECT_CALL(observer_, |
| 51 OnCategoryStatusChanged( |
| 52 _, Category::FromKnownCategory(KnownCategories::BOOKMARKS), |
| 53 CategoryStatus::AVAILABLE)) |
| 54 .RetiresOnSaturation(); |
| 55 BookmarkSuggestionsProvider::RegisterProfilePrefs(test_prefs_.registry()); |
| 56 provider_ = base::MakeUnique<BookmarkSuggestionsProvider>( |
| 57 &observer_, model_.get(), &test_prefs_); |
| 58 } |
| 59 |
| 60 protected: |
| 61 std::unique_ptr<bookmarks::BookmarkModel> model_; |
| 62 StrictMock<MockContentSuggestionsProviderObserver> observer_; |
| 63 TestingPrefServiceSimple test_prefs_; |
| 64 std::unique_ptr<BookmarkSuggestionsProvider> provider_; |
| 65 }; |
| 66 |
| 67 TEST_F(BookmarkSuggestionsProviderTest, |
| 68 ShouldProvideBookmarkSuggestions) { |
| 69 GURL url("http://my-new-bookmarked.url"); |
| 70 // Note, this update to the model does not trigger OnNewSuggestions() on the |
| 71 // observer as the provider realizes no new nodes were added. |
| 72 // don't have new data. |
| 73 model_->AddURL(model_->bookmark_bar_node(), 0, |
| 74 base::ASCIIToUTF16("cool page's title"), url); |
| 75 |
| 76 // Once we provided the last-visited meta information, an update with the |
| 77 // suggestion containing the bookmark should follow. |
| 78 EXPECT_CALL( |
| 79 observer_, |
| 80 OnNewSuggestions( |
| 81 _, Category::FromKnownCategory(KnownCategories::BOOKMARKS), |
| 82 UnorderedElementsAre(Property(&ContentSuggestion::url, GURL(url))))); |
| 83 UpdateBookmarkOnURLVisitedInMainFrame(model_.get(), url, |
| 84 /*is_mobile_platform=*/true); |
| 85 } |
| 86 |
| 87 TEST_F(BookmarkSuggestionsProviderTest, |
| 88 ShouldEnsureToBeClearedBookmarksDontAppearAfterClear) { |
| 89 // Set up the provider with 2 entries: one dismissed and one active. |
| 90 |
| 91 // Add one bookmark (the one to be not dismissed) -- this will trigger a |
| 92 // notification. |
| 93 GURL active_bookmark("http://my-active-bookmarked.url"); |
| 94 EXPECT_CALL(observer_, |
| 95 OnNewSuggestions( |
| 96 _, Category::FromKnownCategory(KnownCategories::BOOKMARKS), |
| 97 UnorderedElementsAre(Property(&ContentSuggestion::url, |
| 98 GURL(active_bookmark))))); |
| 99 model_->AddURL(model_->bookmark_bar_node(), 0, |
| 100 base::ASCIIToUTF16("cool page's title"), active_bookmark); |
| 101 UpdateBookmarkOnURLVisitedInMainFrame(model_.get(), active_bookmark, |
| 102 /*is_mobile_platform=*/true); |
| 103 |
| 104 // Add the other bookmark -- this will trigger another notification. Then |
| 105 // marks it was dismissed. |
| 106 GURL dismissed_bookmark("http://my-dismissed-bookmark.url"); |
| 107 EXPECT_CALL( |
| 108 observer_, |
| 109 OnNewSuggestions( |
| 110 _, Category::FromKnownCategory(KnownCategories::BOOKMARKS), |
| 111 UnorderedElementsAre( |
| 112 Property(&ContentSuggestion::url, GURL(active_bookmark)), |
| 113 Property(&ContentSuggestion::url, GURL(dismissed_bookmark))))); |
| 114 const bookmarks::BookmarkNode* dismissed_node = model_->AddURL( |
| 115 model_->bookmark_bar_node(), 1, base::ASCIIToUTF16("cool page's title"), |
| 116 dismissed_bookmark); |
| 117 UpdateBookmarkOnURLVisitedInMainFrame(model_.get(), dismissed_bookmark, |
| 118 /*is_mobile_platform=*/true); |
| 119 // According to the ContentSugestionsProvider contract, solely dismissing an |
| 120 // item should not result in another OnNewSuggestions() call. |
| 121 static_cast<ContentSuggestionsProvider*>(provider_.get()) |
| 122 ->DismissSuggestion(ContentSuggestion::ID( |
| 123 Category::FromKnownCategory(KnownCategories::BOOKMARKS), |
| 124 dismissed_bookmark.spec())); |
| 125 EXPECT_THAT(IsDismissedFromNTPForBookmark(*dismissed_node), Eq(true)); |
| 126 |
| 127 // Clear history and make sure the suggestions actually get removed. |
| 128 EXPECT_CALL(observer_, OnNewSuggestions(_, Category::FromKnownCategory( |
| 129 KnownCategories::BOOKMARKS), |
| 130 IsEmpty())); |
| 131 static_cast<ContentSuggestionsProvider*>(provider_.get()) |
| 132 ->ClearHistory(base::Time(), base::Time::Max(), |
| 133 base::Bind([] (const GURL& url) { return true; })); |
| 134 |
| 135 // Verify the dismissed marker is gone. |
| 136 EXPECT_THAT(IsDismissedFromNTPForBookmark(*dismissed_node), Eq(false)); |
| 137 } |
| 138 |
| 139 // TODO(tschumann): There are plenty of test cases missing. Most importantly: |
| 140 // -- Remove a bookmark from the model |
| 141 // -- verifying handling of threshold time |
| 142 // -- dealing with fetches before the model is loaded. |
| 143 |
| 144 } // namespace |
| 145 } // namespace ntp_snippets |
| 146 |
OLD | NEW |