146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file. 446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/bind.h" 646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/message_loop/message_loop.h" 746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/run_loop.h" 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/dom_distiller/core/article_entry.h" 946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/dom_distiller/core/distilled_content_store.h" 1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/dom_distiller/core/proto/distilled_article.pb.h" 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace dom_distiller { 1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace { 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)ArticleEntry CreateEntry(std::string entry_id, 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string page_url1, 1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string page_url2, 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string page_url3) { 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ArticleEntry entry; 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) entry.set_entry_id(entry_id); 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!page_url1.empty()) { 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ArticleEntryPage* page = entry.add_pages(); 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) page->set_url(page_url1); 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!page_url2.empty()) { 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ArticleEntryPage* page = entry.add_pages(); 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) page->set_url(page_url2); 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!page_url3.empty()) { 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ArticleEntryPage* page = entry.add_pages(); 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) page->set_url(page_url3); 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return entry; 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)DistilledArticleProto CreateDistilledArticleForEntry( 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ArticleEntry& entry) { 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DistilledArticleProto article; 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (int i = 0; i < entry.pages_size(); ++i) { 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DistilledPageProto* page = article.add_pages(); 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) page->set_url(entry.pages(i).url()); 4446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) page->set_html("<div>" + entry.pages(i).url() + "</div>"); 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return article; 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class InMemoryContentStoreTest : public testing::Test { 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void OnLoadCallback(bool success, scoped_ptr<DistilledArticleProto> proto) { 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) load_success_ = success; 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) loaded_proto_ = proto.Pass(); 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void OnSaveCallback(bool success) { save_success_ = success; } 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) protected: 6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // testing::Test implementation: 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void SetUp() OVERRIDE { 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_.reset(new InMemoryContentStore(kDefaultMaxNumCachedEntries)); 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) save_success_ = false; 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) load_success_ = false; 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) loaded_proto_.reset(); 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<InMemoryContentStore> store_; 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool save_success_; 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool load_success_; 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<DistilledArticleProto> loaded_proto_; 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Tests whether saving and then loading a single article works as expected. 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(InMemoryContentStoreTest, SaveAndLoadSingleArticle) { 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop loop; 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ArticleEntry entry = CreateEntry("test-id", "url1", "url2", "url3"); 7946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DistilledArticleProto stored_proto = 8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateDistilledArticleForEntry(entry); 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->SaveContent(entry, 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) stored_proto, 8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnSaveCallback, 8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(save_success_); 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) save_success_ = false; 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->LoadContent(entry, 9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnLoadCallback, 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(load_success_); 9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(stored_proto.SerializeAsString(), 9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) loaded_proto_->SerializeAsString()); 9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Tests that loading articles which have never been stored, yields a callback 9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// where success is false. 10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(InMemoryContentStoreTest, LoadNonExistentArticle) { 10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop loop; 10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ArticleEntry entry = CreateEntry("bogus-id", "url1", "url2", "url3"); 10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->LoadContent(entry, 10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnLoadCallback, 10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_FALSE(load_success_); 10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Verifies that content store can store multiple articles, and that ordering 11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// of save and store does not matter when the total number of articles does not 11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// exceed |kDefaultMaxNumCachedEntries|. 11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(InMemoryContentStoreTest, SaveAndLoadMultipleArticles) { 11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop loop; 11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Store first article. 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ArticleEntry first_entry = CreateEntry("first", "url1", "url2", "url3"); 11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DistilledArticleProto first_stored_proto = 11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateDistilledArticleForEntry(first_entry); 11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->SaveContent(first_entry, 12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) first_stored_proto, 12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnSaveCallback, 12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(save_success_); 12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) save_success_ = false; 12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Store second article. 12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ArticleEntry second_entry = 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateEntry("second", "url4", "url5", "url6"); 13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DistilledArticleProto second_stored_proto = 13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateDistilledArticleForEntry(second_entry); 13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->SaveContent(second_entry, 13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) second_stored_proto, 13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnSaveCallback, 13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(save_success_); 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) save_success_ = false; 13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Load second article. 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->LoadContent(second_entry, 14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnLoadCallback, 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(load_success_); 14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) load_success_ = false; 14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(second_stored_proto.SerializeAsString(), 14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) loaded_proto_->SerializeAsString()); 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) loaded_proto_.reset(); 15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Load first article. 15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->LoadContent(first_entry, 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnLoadCallback, 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(load_success_); 15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(first_stored_proto.SerializeAsString(), 15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) loaded_proto_->SerializeAsString()); 15946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 16046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Verifies that the content store does not store unlimited number of articles, 16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// but expires the oldest ones when the limit for number of articles is reached. 16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_F(InMemoryContentStoreTest, SaveAndLoadMoreThanMaxArticles) { 16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop loop; 16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Create a new store with only |kMaxNumArticles| articles as the limit. 16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const int kMaxNumArticles = 3; 16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_.reset(new InMemoryContentStore(kMaxNumArticles)); 16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Store first article. 17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ArticleEntry first_entry = CreateEntry("first", "url1", "url2", "url3"); 17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DistilledArticleProto first_stored_proto = 17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateDistilledArticleForEntry(first_entry); 17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->SaveContent(first_entry, 17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) first_stored_proto, 17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnSaveCallback, 17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(save_success_); 18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) save_success_ = false; 18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Store second article. 18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ArticleEntry second_entry = 184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateEntry("second", "url4", "url5", "url6"); 18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DistilledArticleProto second_stored_proto = 18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateDistilledArticleForEntry(second_entry); 18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->SaveContent(second_entry, 18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) second_stored_proto, 18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnSaveCallback, 19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(save_success_); 19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) save_success_ = false; 19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Store third article. 196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ArticleEntry third_entry = CreateEntry("third", "url7", "url8", "url9"); 19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DistilledArticleProto third_stored_proto = 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateDistilledArticleForEntry(third_entry); 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->SaveContent(third_entry, 20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) third_stored_proto, 20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnSaveCallback, 20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(save_success_); 20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) save_success_ = false; 20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Load first article. This will make the first article the most recent 20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // accessed article. 20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->LoadContent(first_entry, 21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnLoadCallback, 21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(load_success_); 21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) load_success_ = false; 21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_EQ(first_stored_proto.SerializeAsString(), 21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) loaded_proto_->SerializeAsString()); 21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) loaded_proto_.reset(); 21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Store fourth article. 22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const ArticleEntry fourth_entry = 221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateEntry("fourth", "url10", "url11", "url12"); 22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const DistilledArticleProto fourth_stored_proto = 22346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) CreateDistilledArticleForEntry(fourth_entry); 22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->SaveContent(fourth_entry, 22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) fourth_stored_proto, 22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnSaveCallback, 22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_TRUE(save_success_); 23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) save_success_ = false; 23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Load second article, which by now is the oldest accessed article, since 23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the first article has been loaded once. 23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) store_->LoadContent(second_entry, 23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnLoadCallback, 23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Unretained(this))); 23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Since the store can only contain |kMaxNumArticles| entries, this load 23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // should fail. 24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_FALSE(load_success_); 24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Tests whether saving and then loading a single article works as expected. 244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(InMemoryContentStoreTest, LookupArticleByURL) { 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop loop; 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ArticleEntry entry = CreateEntry("test-id", "url1", "url2", "url3"); 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const DistilledArticleProto stored_proto = 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateDistilledArticleForEntry(entry); 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) store_->SaveContent(entry, 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) stored_proto, 251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnSaveCallback, 252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Unretained(this))); 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(save_success_); 255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) save_success_ = false; 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Create an entry where the entry ID does not match, but the first URL does. 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ArticleEntry lookup_entry1 = CreateEntry("lookup-id", "url1", "", ""); 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) store_->LoadContent(lookup_entry1, 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnLoadCallback, 261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Unretained(this))); 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(load_success_); 264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(stored_proto.SerializeAsString(), 265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) loaded_proto_->SerializeAsString()); 266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Create an entry where the entry ID does not match, but the second URL does. 268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ArticleEntry lookup_entry2 = 269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateEntry("lookup-id", "bogus", "url2", ""); 270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) store_->LoadContent(lookup_entry2, 271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnLoadCallback, 272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Unretained(this))); 273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(load_success_); 275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(stored_proto.SerializeAsString(), 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) loaded_proto_->SerializeAsString()); 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Verifies that the content store does not store unlimited number of articles, 280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// but expires the oldest ones when the limit for number of articles is reached. 281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(InMemoryContentStoreTest, LoadArticleByURLAfterExpungedFromCache) { 282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop loop; 283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Create a new store with only |kMaxNumArticles| articles as the limit. 285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const int kMaxNumArticles = 1; 286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) store_.reset(new InMemoryContentStore(kMaxNumArticles)); 287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Store an article. 289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ArticleEntry first_entry = CreateEntry("first", "url1", "url2", "url3"); 290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const DistilledArticleProto first_stored_proto = 291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateDistilledArticleForEntry(first_entry); 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) store_->SaveContent(first_entry, 293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) first_stored_proto, 294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnSaveCallback, 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Unretained(this))); 296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(save_success_); 298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) save_success_ = false; 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Looking up the first entry by URL should succeed when it is still in the 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // cache. 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ArticleEntry first_entry_lookup = 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateEntry("lookup-id", "url1", "", ""); 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) store_->LoadContent(first_entry_lookup, 305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnLoadCallback, 306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Unretained(this))); 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(load_success_); 309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(first_stored_proto.SerializeAsString(), 310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) loaded_proto_->SerializeAsString()); 311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Store second article. This will remove the first article from the cache. 313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ArticleEntry second_entry = 314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateEntry("second", "url4", "url5", "url6"); 315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const DistilledArticleProto second_stored_proto = 316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CreateDistilledArticleForEntry(second_entry); 317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) store_->SaveContent(second_entry, 318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) second_stored_proto, 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnSaveCallback, 320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Unretained(this))); 321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_TRUE(save_success_); 323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) save_success_ = false; 324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Looking up the first entry by URL should fail when it is not in the cache. 326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) store_->LoadContent(first_entry_lookup, 327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&InMemoryContentStoreTest::OnLoadCallback, 328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Unretained(this))); 329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->RunUntilIdle(); 330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(load_success_); 331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace dom_distiller 334