#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/history/archived_database.h"
#include "chrome/browser/history/expire_history_backend.h"
#include "chrome/common/thumbnail_score.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/tools/profiles/thumbnail-inl.h"
+#include "components/bookmarks/core/browser/bookmark_model.h"
+#include "components/bookmarks/core/browser/bookmark_utils.h"
+#include "components/bookmarks/core/test/test_bookmark_client.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
public BroadcastNotificationDelegate {
public:
ExpireHistoryTest()
- : bookmark_model_(NULL),
+ : bookmark_model_(bookmark_client_.CreateModel(false)),
ui_thread_(BrowserThread::UI, &message_loop_),
db_thread_(BrowserThread::DB, &message_loop_),
- expirer_(this, &bookmark_model_),
- now_(Time::Now()) {
- }
+ expirer_(this, bookmark_model_.get()),
+ now_(Time::Now()) {}
protected:
// Called by individual tests when they want data populated.
void AddExampleSourceData(const GURL& url, URLID* id);
// Returns true if the given favicon/thumanil has an entry in the DB.
- bool HasFavicon(chrome::FaviconID favicon_id);
+ bool HasFavicon(favicon_base::FaviconID favicon_id);
bool HasThumbnail(URLID url_id);
- chrome::FaviconID GetFavicon(const GURL& page_url,
- chrome::IconType icon_type);
+ favicon_base::FaviconID GetFavicon(const GURL& page_url,
+ favicon_base::IconType icon_type);
// EXPECTs that each URL-specific history thing (basically, everything but
- // favicons) is gone.
- void EnsureURLInfoGone(const URLRow& row);
+ // favicons) is gone, the reason being either that it was |archived|, or
+ // manually deleted.
+ void EnsureURLInfoGone(const URLRow& row, bool archived);
+
+ // Returns whether a NOTIFICATION_HISTORY_URLS_MODIFIED was sent for |url|.
+ bool ModifiedNotificationSent(const GURL& url);
// Clears the list of notifications received.
void ClearLastNotifications() {
}
void StarURL(const GURL& url) {
- bookmark_model_.AddURL(
- bookmark_model_.bookmark_bar_node(), 0, base::string16(), url);
+ bookmark_model_->AddURL(
+ bookmark_model_->bookmark_bar_node(), 0, base::string16(), url);
}
static bool IsStringInFile(const base::FilePath& filename, const char* str);
// This must be destroyed last.
base::ScopedTempDir tmp_dir_;
- BookmarkModel bookmark_model_;
+ test::TestBookmarkClient bookmark_client_;
+ scoped_ptr<BookmarkModel> bookmark_model_;
base::MessageLoopForUI message_loop_;
content::TestBrowserThread ui_thread_;
thumb_db_.reset();
}
- // BroadcastNotificationDelegate implementation.
+ // BroadcastNotificationDelegate:
virtual void BroadcastNotifications(
int type,
scoped_ptr<HistoryDetails> details) OVERRIDE {
// store them so we can tell that the correct notifications were sent.
notifications_.push_back(std::make_pair(type, details.release()));
}
- virtual void NotifySyncURLsDeleted(
- bool all_history,
- bool archived,
- URLRows* rows) OVERRIDE {}
+ virtual void NotifySyncURLsModified(URLRows* rows) OVERRIDE {}
+ virtual void NotifySyncURLsDeleted(bool all_history,
+ bool archived,
+ URLRows* rows) OVERRIDE {}
};
// The example data consists of 4 visits. The middle two visits are to the
// Two favicons. The first two URLs will share the same one, while the last
// one will have a unique favicon.
- chrome::FaviconID favicon1 = thumb_db_->AddFavicon(
- GURL("http://favicon/url1"), chrome::FAVICON);
- chrome::FaviconID favicon2 = thumb_db_->AddFavicon(
- GURL("http://favicon/url2"), chrome::FAVICON);
+ favicon_base::FaviconID favicon1 =
+ thumb_db_->AddFavicon(GURL("http://favicon/url1"), favicon_base::FAVICON);
+ favicon_base::FaviconID favicon2 =
+ thumb_db_->AddFavicon(GURL("http://favicon/url2"), favicon_base::FAVICON);
// Three URLs.
URLRow url_row1(GURL("http://www.google.com/1"));
main_db_->AddVisit(&visit_row4, SOURCE_FIREFOX_IMPORTED);
}
-bool ExpireHistoryTest::HasFavicon(chrome::FaviconID favicon_id) {
+bool ExpireHistoryTest::HasFavicon(favicon_base::FaviconID favicon_id) {
if (!thumb_db_.get() || favicon_id == 0)
return false;
return thumb_db_->GetFaviconHeader(favicon_id, NULL, NULL);
}
-chrome::FaviconID ExpireHistoryTest::GetFavicon(const GURL& page_url,
- chrome::IconType icon_type) {
+favicon_base::FaviconID ExpireHistoryTest::GetFavicon(
+ const GURL& page_url,
+ favicon_base::IconType icon_type) {
std::vector<IconMapping> icon_mappings;
if (thumb_db_->GetIconMappingsForPageURL(page_url, icon_type,
&icon_mappings)) {
return top_sites_->GetPageThumbnail(url, false, &data);
}
-void ExpireHistoryTest::EnsureURLInfoGone(const URLRow& row) {
+void ExpireHistoryTest::EnsureURLInfoGone(const URLRow& row, bool archived) {
+ // The passed in |row| must originate from |main_db_| so that its ID will be
+ // set to what had been in effect in |main_db_| before the deletion.
+ ASSERT_NE(0, row.id());
+
// Verify the URL no longer exists.
URLRow temp_row;
EXPECT_FALSE(main_db_->GetURLRow(row.id(), &temp_row));
if (notifications_[i].first == chrome::NOTIFICATION_HISTORY_URLS_DELETED) {
URLsDeletedDetails* details = reinterpret_cast<URLsDeletedDetails*>(
notifications_[i].second);
- EXPECT_FALSE(details->archived);
+ EXPECT_EQ(archived, details->archived);
const history::URLRows& rows(details->rows);
- if (std::find_if(rows.begin(), rows.end(),
- history::URLRow::URLRowHasURL(row.url())) != rows.end()) {
+ history::URLRows::const_iterator it_row = std::find_if(
+ rows.begin(), rows.end(), history::URLRow::URLRowHasURL(row.url()));
+ if (it_row != rows.end()) {
+ // Further verify that the ID is set to what had been in effect in the
+ // main database before the deletion. The InMemoryHistoryBackend relies
+ // on this to delete its cached copy of the row.
+ EXPECT_EQ(row.id(), it_row->id());
found_delete_notification = true;
}
- } else {
- EXPECT_NE(notifications_[i].first,
- chrome::NOTIFICATION_HISTORY_URL_VISITED);
- EXPECT_NE(notifications_[i].first,
- chrome::NOTIFICATION_HISTORY_URLS_MODIFIED);
+ } else if (notifications_[i].first ==
+ chrome::NOTIFICATION_HISTORY_URLS_MODIFIED) {
+ const history::URLRows& rows =
+ static_cast<URLsModifiedDetails*>(notifications_[i].second)->
+ changed_urls;
+ EXPECT_TRUE(
+ std::find_if(rows.begin(), rows.end(),
+ history::URLRow::URLRowHasURL(row.url())) ==
+ rows.end());
}
}
EXPECT_TRUE(found_delete_notification);
}
+bool ExpireHistoryTest::ModifiedNotificationSent(const GURL& url) {
+ for (size_t i = 0; i < notifications_.size(); i++) {
+ if (notifications_[i].first == chrome::NOTIFICATION_HISTORY_URLS_MODIFIED) {
+ const history::URLRows& rows =
+ static_cast<URLsModifiedDetails*>(notifications_[i].second)->
+ changed_urls;
+ if (std::find_if(rows.begin(), rows.end(),
+ history::URLRow::URLRowHasURL(url)) != rows.end())
+ return true;
+ }
+ }
+ return false;
+}
+
TEST_F(ExpireHistoryTest, DeleteFaviconsIfPossible) {
// Add a favicon record.
const GURL favicon_url("http://www.google.com/favicon.ico");
- chrome::FaviconID icon_id = thumb_db_->AddFavicon(
- favicon_url, chrome::FAVICON);
+ favicon_base::FaviconID icon_id =
+ thumb_db_->AddFavicon(favicon_url, favicon_base::FAVICON);
EXPECT_TRUE(icon_id);
EXPECT_TRUE(HasFavicon(icon_id));
// The favicon should be deletable with no users.
- std::set<chrome::FaviconID> favicon_set;
- std::set<GURL> expired_favicons;
- favicon_set.insert(icon_id);
- expirer_.DeleteFaviconsIfPossible(favicon_set, &expired_favicons);
- EXPECT_FALSE(HasFavicon(icon_id));
- EXPECT_EQ(1U, expired_favicons.size());
- EXPECT_EQ(1U, expired_favicons.count(favicon_url));
+ {
+ ExpireHistoryBackend::DeleteEffects effects;
+ effects.affected_favicons.insert(icon_id);
+ expirer_.DeleteFaviconsIfPossible(&effects);
+ EXPECT_FALSE(HasFavicon(icon_id));
+ EXPECT_EQ(1U, effects.deleted_favicons.size());
+ EXPECT_EQ(1U, effects.deleted_favicons.count(favicon_url));
+ }
// Add back the favicon.
- icon_id = thumb_db_->AddFavicon(
- favicon_url, chrome::TOUCH_ICON);
+ icon_id = thumb_db_->AddFavicon(favicon_url, favicon_base::TOUCH_ICON);
EXPECT_TRUE(icon_id);
EXPECT_TRUE(HasFavicon(icon_id));
thumb_db_->AddIconMapping(row.url(), icon_id);
// Favicon should not be deletable.
- favicon_set.clear();
- favicon_set.insert(icon_id);
- expired_favicons.clear();
- expirer_.DeleteFaviconsIfPossible(favicon_set, &expired_favicons);
- EXPECT_TRUE(HasFavicon(icon_id));
- EXPECT_TRUE(expired_favicons.empty());
+ {
+ ExpireHistoryBackend::DeleteEffects effects;
+ effects.affected_favicons.insert(icon_id);
+ expirer_.DeleteFaviconsIfPossible(&effects);
+ EXPECT_TRUE(HasFavicon(icon_id));
+ EXPECT_TRUE(effects.deleted_favicons.empty());
+ }
}
// static
// Verify things are the way we expect with a URL row, favicon, thumbnail.
URLRow last_row;
ASSERT_TRUE(main_db_->GetURLRow(url_ids[2], &last_row));
- chrome::FaviconID favicon_id = GetFavicon(last_row.url(), chrome::FAVICON);
+ favicon_base::FaviconID favicon_id =
+ GetFavicon(last_row.url(), favicon_base::FAVICON);
EXPECT_TRUE(HasFavicon(favicon_id));
// TODO(sky): fix this, see comment in HasThumbnail.
// EXPECT_TRUE(HasThumbnail(url_ids[2]));
expirer_.DeleteURL(last_row.url());
// All the normal data + the favicon should be gone.
- EnsureURLInfoGone(last_row);
- EXPECT_FALSE(GetFavicon(last_row.url(), chrome::FAVICON));
+ EnsureURLInfoGone(last_row, false);
+ EXPECT_FALSE(GetFavicon(last_row.url(), favicon_base::FAVICON));
EXPECT_FALSE(HasFavicon(favicon_id));
}
// Verify things are the way we expect with a URL row, favicon, thumbnail.
URLRow last_row;
ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &last_row));
- chrome::FaviconID favicon_id = GetFavicon(last_row.url(), chrome::FAVICON);
+ favicon_base::FaviconID favicon_id =
+ GetFavicon(last_row.url(), favicon_base::FAVICON);
EXPECT_TRUE(HasFavicon(favicon_id));
// TODO(sky): fix this, see comment in HasThumbnail.
// EXPECT_TRUE(HasThumbnail(url_ids[1]));
expirer_.DeleteURL(last_row.url());
// All the normal data except the favicon should be gone.
- EnsureURLInfoGone(last_row);
+ EnsureURLInfoGone(last_row, false);
EXPECT_TRUE(HasFavicon(favicon_id));
}
ASSERT_TRUE(main_db_->GetRowForURL(url, &url_row));
// And the favicon should exist.
- chrome::FaviconID favicon_id = GetFavicon(url_row.url(), chrome::FAVICON);
+ favicon_base::FaviconID favicon_id =
+ GetFavicon(url_row.url(), favicon_base::FAVICON);
EXPECT_TRUE(HasFavicon(favicon_id));
// And no visits.
// ASSERT_TRUE(HasThumbnail(url_row.id()));
// Unstar the URL and delete again.
- bookmark_utils::RemoveAllBookmarks(&bookmark_model_, url);
+ bookmark_utils::RemoveAllBookmarks(bookmark_model_.get(), url);
+ ClearLastNotifications();
expirer_.DeleteURL(url);
// Now it should be completely deleted.
- EnsureURLInfoGone(url_row);
+ EnsureURLInfoGone(url_row, false);
}
// Deletes multiple URLs at once. The favicon for the third one but
// Verify things are the way we expect with URL rows, favicons,
// thumbnails.
URLRow rows[3];
- chrome::FaviconID favicon_ids[3];
+ favicon_base::FaviconID favicon_ids[3];
std::vector<GURL> urls;
// Push back a bogus URL (which shouldn't change anything).
urls.push_back(GURL());
for (size_t i = 0; i < arraysize(rows); ++i) {
ASSERT_TRUE(main_db_->GetURLRow(url_ids[i], &rows[i]));
- favicon_ids[i] = GetFavicon(rows[i].url(), chrome::FAVICON);
+ favicon_ids[i] = GetFavicon(rows[i].url(), favicon_base::FAVICON);
EXPECT_TRUE(HasFavicon(favicon_ids[i]));
// TODO(sky): fix this, see comment in HasThumbnail.
// EXPECT_TRUE(HasThumbnail(url_ids[i]));
// First one should still be around (since it was starred).
ASSERT_TRUE(main_db_->GetRowForURL(rows[0].url(), &rows[0]));
- EnsureURLInfoGone(rows[1]);
- EnsureURLInfoGone(rows[2]);
+ EnsureURLInfoGone(rows[1], false);
+ EnsureURLInfoGone(rows[2], false);
EXPECT_TRUE(HasFavicon(favicon_ids[0]));
EXPECT_TRUE(HasFavicon(favicon_ids[1]));
EXPECT_FALSE(HasFavicon(favicon_ids[2]));
EXPECT_EQ(1U, visits.size());
// Verify that the middle URL visit time and visit counts were updated.
+ EXPECT_TRUE(ModifiedNotificationSent(url_row1.url()));
URLRow temp_row;
ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row));
EXPECT_TRUE(visit_times[2] == url_row1.last_visit()); // Previous value.
EXPECT_EQ(0, temp_row.typed_count());
// Verify that the middle URL's favicon and thumbnail is still there.
- chrome::FaviconID favicon_id = GetFavicon(url_row1.url(), chrome::FAVICON);
+ favicon_base::FaviconID favicon_id =
+ GetFavicon(url_row1.url(), favicon_base::FAVICON);
EXPECT_TRUE(HasFavicon(favicon_id));
// TODO(sky): fix this, see comment in HasThumbnail.
// EXPECT_TRUE(HasThumbnail(url_row1.id()));
// Verify that the last URL was deleted.
- chrome::FaviconID favicon_id2 = GetFavicon(url_row2.url(), chrome::FAVICON);
- EnsureURLInfoGone(url_row2);
+ favicon_base::FaviconID favicon_id2 =
+ GetFavicon(url_row2.url(), favicon_base::FAVICON);
+ EnsureURLInfoGone(url_row2, false);
EXPECT_FALSE(HasFavicon(favicon_id2));
}
EXPECT_EQ(1U, visits.size());
// Verify that the middle URL visit time and visit counts were updated.
+ EXPECT_TRUE(ModifiedNotificationSent(url_row1.url()));
URLRow temp_row;
ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row));
EXPECT_TRUE(visit_times[2] == url_row1.last_visit()); // Previous value.
EXPECT_EQ(0, temp_row.typed_count());
// Verify that the middle URL's favicon and thumbnail is still there.
- chrome::FaviconID favicon_id = GetFavicon(url_row1.url(), chrome::FAVICON);
+ favicon_base::FaviconID favicon_id =
+ GetFavicon(url_row1.url(), favicon_base::FAVICON);
EXPECT_TRUE(HasFavicon(favicon_id));
// TODO(sky): fix this, see comment in HasThumbnail.
// EXPECT_TRUE(HasThumbnail(url_row1.id()));
// Verify that the last URL was deleted.
- chrome::FaviconID favicon_id2 = GetFavicon(url_row2.url(), chrome::FAVICON);
- EnsureURLInfoGone(url_row2);
+ favicon_base::FaviconID favicon_id2 =
+ GetFavicon(url_row2.url(), favicon_base::FAVICON);
+ EnsureURLInfoGone(url_row2, false);
EXPECT_FALSE(HasFavicon(favicon_id2));
}
EXPECT_EQ(1U, visits.size());
// Verify that the middle URL visit time and visit counts were updated.
+ EXPECT_TRUE(ModifiedNotificationSent(url_row1.url()));
URLRow temp_row;
ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row));
EXPECT_TRUE(visit_times[2] == url_row1.last_visit()); // Previous value.
EXPECT_EQ(0, temp_row.typed_count());
// Verify that the middle URL's favicon and thumbnail is still there.
- chrome::FaviconID favicon_id = GetFavicon(url_row1.url(), chrome::FAVICON);
+ favicon_base::FaviconID favicon_id =
+ GetFavicon(url_row1.url(), favicon_base::FAVICON);
EXPECT_TRUE(HasFavicon(favicon_id));
// TODO(sky): fix this, see comment in HasThumbnail.
// EXPECT_TRUE(HasThumbnail(url_row1.id()));
EXPECT_TRUE(new_url_row1.last_visit() == visit_times[1]);
EXPECT_TRUE(new_url_row2.last_visit().is_null()); // No last visit time.
- // Visit/typed count should not be updated for bookmarks.
+ // Visit/typed count should be updated.
+ EXPECT_TRUE(ModifiedNotificationSent(url_row1.url()));
+ EXPECT_TRUE(ModifiedNotificationSent(url_row2.url()));
EXPECT_EQ(0, new_url_row1.typed_count());
EXPECT_EQ(1, new_url_row1.visit_count());
EXPECT_EQ(0, new_url_row2.typed_count());
// that may have been updated since the time threshold. Since the URL still
// exists in history, this should not be a privacy problem, we only update
// the visit counts in this case for consistency anyway.
- chrome::FaviconID favicon_id = GetFavicon(url_row1.url(), chrome::FAVICON);
+ favicon_base::FaviconID favicon_id =
+ GetFavicon(url_row1.url(), favicon_base::FAVICON);
EXPECT_TRUE(HasFavicon(favicon_id));
// TODO(sky): fix this, see comment in HasThumbnail.
// EXPECT_TRUE(HasThumbnail(new_url_row1.id()));
- favicon_id = GetFavicon(url_row1.url(), chrome::FAVICON);
+ favicon_id = GetFavicon(url_row1.url(), favicon_base::FAVICON);
EXPECT_TRUE(HasFavicon(favicon_id));
// TODO(sky): fix this, see comment in HasThumbnail.
// EXPECT_TRUE(HasThumbnail(new_url_row2.id()));
Time visit_times[4];
AddExampleData(url_ids, visit_times);
- URLRow url_row1, url_row2;
+ URLRow url_row0, url_row1, url_row2;
+ ASSERT_TRUE(main_db_->GetURLRow(url_ids[0], &url_row0));
ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &url_row1));
ASSERT_TRUE(main_db_->GetURLRow(url_ids[2], &url_row2));
// Archive the oldest two visits. This will actually result in deleting them
- // since their transition types are empty (not important).
+ // since their transition types are empty.
expirer_.ArchiveHistoryBefore(visit_times[1]);
- // The first URL should be deleted, the second should not be affected.
+ // The first URL should be deleted, the second should not.
URLRow temp_row;
- EXPECT_FALSE(main_db_->GetURLRow(url_ids[0], &temp_row));
+ EnsureURLInfoGone(url_row0, true);
EXPECT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row));
+ EXPECT_TRUE(ModifiedNotificationSent(url_row1.url()));
EXPECT_TRUE(main_db_->GetURLRow(url_ids[2], &temp_row));
// Make sure the archived database has nothing in it.
// Now archive one more visit so that the middle URL should be removed. This
// one will actually be archived instead of deleted.
+ ClearLastNotifications();
expirer_.ArchiveHistoryBefore(visit_times[2]);
- EXPECT_FALSE(main_db_->GetURLRow(url_ids[1], &temp_row));
+ EnsureURLInfoGone(url_row1, true);
EXPECT_TRUE(main_db_->GetURLRow(url_ids[2], &temp_row));
// Make sure the archived database has an entry for the second URL.
StarURL(url_row1.url());
// Now archive the first three visits (first two URLs). The first two visits
- // should be, the third deleted, but the URL records should not.
+ // should be deleted, the third archived.
expirer_.ArchiveHistoryBefore(visit_times[2]);
// The first URL should have its visit deleted, but it should still be present
ASSERT_TRUE(main_db_->GetURLRow(url_ids[0], &temp_row));
// Note that the ID is different in the archived DB, so look up by URL.
EXPECT_FALSE(archived_db_->GetRowForURL(temp_row.url(), NULL));
+ EXPECT_TRUE(ModifiedNotificationSent(url_row0.url()));
VisitVector visits;
main_db_->GetVisitsForURL(temp_row.id(), &visits);
EXPECT_EQ(0U, visits.size());
// archived. It should be present in both the main DB (because it's starred)
// and the archived DB (for the archived visit).
ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row));
+ EXPECT_TRUE(ModifiedNotificationSent(url_row1.url()));
main_db_->GetVisitsForURL(temp_row.id(), &visits);
EXPECT_EQ(0U, visits.size());
// The third URL should be unchanged.
EXPECT_TRUE(main_db_->GetURLRow(url_ids[2], &temp_row));
EXPECT_FALSE(archived_db_->GetRowForURL(temp_row.url(), NULL));
+ EXPECT_FALSE(ModifiedNotificationSent(temp_row.url()));
}
// Tests the return values from ArchiveSomeOldHistory. The rest of the