OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/dom_distiller/core/dom_distiller_service.h" | 5 #include "components/dom_distiller/core/dom_distiller_service.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
13 #include "components/dom_distiller/core/article_entry.h" | 13 #include "components/dom_distiller/core/article_entry.h" |
14 #include "components/dom_distiller/core/dom_distiller_model.h" | 14 #include "components/dom_distiller/core/dom_distiller_model.h" |
15 #include "components/dom_distiller/core/dom_distiller_store.h" | 15 #include "components/dom_distiller/core/dom_distiller_store.h" |
16 #include "components/dom_distiller/core/dom_distiller_test_util.h" | 16 #include "components/dom_distiller/core/dom_distiller_test_util.h" |
17 #include "components/dom_distiller/core/fake_db.h" | |
18 #include "components/dom_distiller/core/fake_distiller.h" | 17 #include "components/dom_distiller/core/fake_distiller.h" |
19 #include "components/dom_distiller/core/fake_distiller_page.h" | 18 #include "components/dom_distiller/core/fake_distiller_page.h" |
20 #include "components/dom_distiller/core/task_tracker.h" | 19 #include "components/dom_distiller/core/task_tracker.h" |
| 20 #include "components/leveldb_proto/testing/fake_db.h" |
21 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
23 | 23 |
| 24 using leveldb_proto::test::FakeDB; |
24 using testing::Invoke; | 25 using testing::Invoke; |
25 using testing::Return; | 26 using testing::Return; |
26 using testing::_; | 27 using testing::_; |
27 | 28 |
28 namespace dom_distiller { | 29 namespace dom_distiller { |
29 namespace test { | 30 namespace test { |
30 | 31 |
31 namespace { | 32 namespace { |
32 | 33 |
33 class FakeViewRequestDelegate : public ViewRequestDelegate { | 34 class FakeViewRequestDelegate : public ViewRequestDelegate { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 return CreateArticleWithURL("http://www.example.com/default_article_page1") | 73 return CreateArticleWithURL("http://www.example.com/default_article_page1") |
73 .Pass(); | 74 .Pass(); |
74 } | 75 } |
75 | 76 |
76 } // namespace | 77 } // namespace |
77 | 78 |
78 class DomDistillerServiceTest : public testing::Test { | 79 class DomDistillerServiceTest : public testing::Test { |
79 public: | 80 public: |
80 virtual void SetUp() { | 81 virtual void SetUp() { |
81 main_loop_.reset(new base::MessageLoop()); | 82 main_loop_.reset(new base::MessageLoop()); |
82 FakeDB* fake_db = new FakeDB(&db_model_); | 83 FakeDB<ArticleEntry>* fake_db = new FakeDB<ArticleEntry>(&db_model_); |
83 FakeDB::EntryMap store_model; | 84 FakeDB<ArticleEntry>::EntryMap store_model; |
84 store_ = test::util::CreateStoreWithFakeDB(fake_db, store_model); | 85 store_ = |
| 86 test::util::CreateStoreWithFakeDB(fake_db, store_model); |
85 distiller_factory_ = new MockDistillerFactory(); | 87 distiller_factory_ = new MockDistillerFactory(); |
86 distiller_page_factory_ = new MockDistillerPageFactory(); | 88 distiller_page_factory_ = new MockDistillerPageFactory(); |
87 service_.reset(new DomDistillerService( | 89 service_.reset(new DomDistillerService( |
88 scoped_ptr<DomDistillerStoreInterface>(store_), | 90 scoped_ptr<DomDistillerStoreInterface>(store_), |
89 scoped_ptr<DistillerFactory>(distiller_factory_), | 91 scoped_ptr<DistillerFactory>(distiller_factory_), |
90 scoped_ptr<DistillerPageFactory>(distiller_page_factory_))); | 92 scoped_ptr<DistillerPageFactory>(distiller_page_factory_))); |
91 fake_db->InitCallback(true); | 93 fake_db->InitCallback(true); |
92 fake_db->LoadCallback(true); | 94 fake_db->LoadCallback(true); |
93 } | 95 } |
94 | 96 |
95 virtual void TearDown() { | 97 virtual void TearDown() { |
96 base::RunLoop().RunUntilIdle(); | 98 base::RunLoop().RunUntilIdle(); |
97 store_ = NULL; | 99 store_ = NULL; |
98 distiller_factory_ = NULL; | 100 distiller_factory_ = NULL; |
99 service_.reset(); | 101 service_.reset(); |
100 } | 102 } |
101 | 103 |
102 protected: | 104 protected: |
103 // store is owned by service_. | 105 // store is owned by service_. |
104 DomDistillerStoreInterface* store_; | 106 DomDistillerStoreInterface* store_; |
105 MockDistillerFactory* distiller_factory_; | 107 MockDistillerFactory* distiller_factory_; |
106 MockDistillerPageFactory* distiller_page_factory_; | 108 MockDistillerPageFactory* distiller_page_factory_; |
107 scoped_ptr<DomDistillerService> service_; | 109 scoped_ptr<DomDistillerService> service_; |
108 scoped_ptr<base::MessageLoop> main_loop_; | 110 scoped_ptr<base::MessageLoop> main_loop_; |
109 FakeDB::EntryMap db_model_; | 111 FakeDB<ArticleEntry>::EntryMap db_model_; |
110 }; | 112 }; |
111 | 113 |
112 TEST_F(DomDistillerServiceTest, TestViewEntry) { | 114 TEST_F(DomDistillerServiceTest, TestViewEntry) { |
113 FakeDistiller* distiller = new FakeDistiller(false); | 115 FakeDistiller* distiller = new FakeDistiller(false); |
114 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) | 116 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
115 .WillOnce(Return(distiller)); | 117 .WillOnce(Return(distiller)); |
116 | 118 |
117 GURL url("http://www.example.com/p1"); | 119 GURL url("http://www.example.com/p1"); |
118 std::string entry_id("id0"); | 120 std::string entry_id("id0"); |
119 ArticleEntry entry; | 121 ArticleEntry entry; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 FakeDistiller* distiller = new FakeDistiller(false); | 239 FakeDistiller* distiller = new FakeDistiller(false); |
238 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) | 240 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
239 .WillOnce(Return(distiller)); | 241 .WillOnce(Return(distiller)); |
240 | 242 |
241 GURL url("http://www.example.com/p1"); | 243 GURL url("http://www.example.com/p1"); |
242 | 244 |
243 MockArticleAvailableCallback article_cb; | 245 MockArticleAvailableCallback article_cb; |
244 EXPECT_CALL(article_cb, DistillationCompleted(true)); | 246 EXPECT_CALL(article_cb, DistillationCompleted(true)); |
245 | 247 |
246 std::string entry_id = | 248 std::string entry_id = |
247 service_->AddToList(url, | 249 service_->AddToList(url, service_->CreateDefaultDistillerPage().Pass(), |
248 service_->CreateDefaultDistillerPage().Pass(), | |
249 ArticleCallback(&article_cb)); | 250 ArticleCallback(&article_cb)); |
250 | 251 |
251 ASSERT_FALSE(distiller->GetArticleCallback().is_null()); | 252 ASSERT_FALSE(distiller->GetArticleCallback().is_null()); |
252 EXPECT_EQ(url, distiller->GetUrl()); | 253 EXPECT_EQ(url, distiller->GetUrl()); |
253 | 254 |
254 scoped_ptr<DistilledArticleProto> proto = CreateArticleWithURL(url.spec()); | 255 scoped_ptr<DistilledArticleProto> proto = CreateArticleWithURL(url.spec()); |
255 RunDistillerCallback(distiller, proto.Pass()); | 256 RunDistillerCallback(distiller, proto.Pass()); |
256 | 257 |
257 ArticleEntry entry; | 258 ArticleEntry entry; |
258 EXPECT_TRUE(store_->GetEntryByUrl(url, &entry)); | 259 EXPECT_TRUE(store_->GetEntryByUrl(url, &entry)); |
(...skipping 10 matching lines...) Expand all Loading... |
269 service_->AddObserver(&observer); | 270 service_->AddObserver(&observer); |
270 | 271 |
271 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) | 272 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
272 .WillOnce(Return(distiller)); | 273 .WillOnce(Return(distiller)); |
273 | 274 |
274 MockArticleAvailableCallback article_cb; | 275 MockArticleAvailableCallback article_cb; |
275 EXPECT_CALL(article_cb, DistillationCompleted(false)); | 276 EXPECT_CALL(article_cb, DistillationCompleted(false)); |
276 | 277 |
277 GURL url("http://www.example.com/p1"); | 278 GURL url("http://www.example.com/p1"); |
278 std::string entry_id = | 279 std::string entry_id = |
279 service_->AddToList(url, | 280 service_->AddToList(url, service_->CreateDefaultDistillerPage().Pass(), |
280 service_->CreateDefaultDistillerPage().Pass(), | |
281 ArticleCallback(&article_cb)); | 281 ArticleCallback(&article_cb)); |
282 | 282 |
283 // Remove entry will cause the |article_cb| to be called with false value. | 283 // Remove entry will cause the |article_cb| to be called with false value. |
284 service_->RemoveEntry(entry_id); | 284 service_->RemoveEntry(entry_id); |
285 base::RunLoop().RunUntilIdle(); | 285 base::RunLoop().RunUntilIdle(); |
286 } | 286 } |
287 | 287 |
288 TEST_F(DomDistillerServiceTest, TestMultipleObservers) { | 288 TEST_F(DomDistillerServiceTest, TestMultipleObservers) { |
289 FakeDistiller* distiller = new FakeDistiller(false); | 289 FakeDistiller* distiller = new FakeDistiller(false); |
290 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) | 290 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
(...skipping 11 matching lines...) Expand all Loading... |
302 url, service_->CreateDefaultDistillerPage().Pass(), article_cb); | 302 url, service_->CreateDefaultDistillerPage().Pass(), article_cb); |
303 | 303 |
304 // Distillation should notify all observers that article is added. | 304 // Distillation should notify all observers that article is added. |
305 std::vector<DomDistillerObserver::ArticleUpdate> expected_updates; | 305 std::vector<DomDistillerObserver::ArticleUpdate> expected_updates; |
306 DomDistillerObserver::ArticleUpdate update; | 306 DomDistillerObserver::ArticleUpdate update; |
307 update.entry_id = entry_id; | 307 update.entry_id = entry_id; |
308 update.update_type = DomDistillerObserver::ArticleUpdate::ADD; | 308 update.update_type = DomDistillerObserver::ArticleUpdate::ADD; |
309 expected_updates.push_back(update); | 309 expected_updates.push_back(update); |
310 | 310 |
311 for (int i = 0; i < kObserverCount; ++i) { | 311 for (int i = 0; i < kObserverCount; ++i) { |
312 EXPECT_CALL( | 312 EXPECT_CALL(observers[i], ArticleEntriesUpdated( |
313 observers[i], | 313 util::HasExpectedUpdates(expected_updates))); |
314 ArticleEntriesUpdated(util::HasExpectedUpdates(expected_updates))); | |
315 } | 314 } |
316 | 315 |
317 scoped_ptr<DistilledArticleProto> proto = CreateDefaultArticle(); | 316 scoped_ptr<DistilledArticleProto> proto = CreateDefaultArticle(); |
318 RunDistillerCallback(distiller, proto.Pass()); | 317 RunDistillerCallback(distiller, proto.Pass()); |
319 | 318 |
320 // Remove should notify all observers that article is removed. | 319 // Remove should notify all observers that article is removed. |
321 update.update_type = DomDistillerObserver::ArticleUpdate::REMOVE; | 320 update.update_type = DomDistillerObserver::ArticleUpdate::REMOVE; |
322 expected_updates.clear(); | 321 expected_updates.clear(); |
323 expected_updates.push_back(update); | 322 expected_updates.push_back(update); |
324 for (int i = 0; i < kObserverCount; ++i) { | 323 for (int i = 0; i < kObserverCount; ++i) { |
325 EXPECT_CALL( | 324 EXPECT_CALL(observers[i], ArticleEntriesUpdated( |
326 observers[i], | 325 util::HasExpectedUpdates(expected_updates))); |
327 ArticleEntriesUpdated(util::HasExpectedUpdates(expected_updates))); | |
328 } | 326 } |
329 | 327 |
330 service_->RemoveEntry(entry_id); | 328 service_->RemoveEntry(entry_id); |
331 base::RunLoop().RunUntilIdle(); | 329 base::RunLoop().RunUntilIdle(); |
332 } | 330 } |
333 | 331 |
334 TEST_F(DomDistillerServiceTest, TestMultipleCallbacks) { | 332 TEST_F(DomDistillerServiceTest, TestMultipleCallbacks) { |
335 FakeDistiller* distiller = new FakeDistiller(false); | 333 FakeDistiller* distiller = new FakeDistiller(false); |
336 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) | 334 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
337 .WillOnce(Return(distiller)); | 335 .WillOnce(Return(distiller)); |
338 | 336 |
339 const int kClientsCount = 5; | 337 const int kClientsCount = 5; |
340 MockArticleAvailableCallback article_cb[kClientsCount]; | 338 MockArticleAvailableCallback article_cb[kClientsCount]; |
341 // Adding a URL and then distilling calls all clients. | 339 // Adding a URL and then distilling calls all clients. |
342 GURL url("http://www.example.com/p1"); | 340 GURL url("http://www.example.com/p1"); |
343 const std::string entry_id = | 341 const std::string entry_id = |
344 service_->AddToList(url, | 342 service_->AddToList(url, service_->CreateDefaultDistillerPage().Pass(), |
345 service_->CreateDefaultDistillerPage().Pass(), | |
346 ArticleCallback(&article_cb[0])); | 343 ArticleCallback(&article_cb[0])); |
347 EXPECT_CALL(article_cb[0], DistillationCompleted(true)); | 344 EXPECT_CALL(article_cb[0], DistillationCompleted(true)); |
348 | 345 |
349 for (int i = 1; i < kClientsCount; ++i) { | 346 for (int i = 1; i < kClientsCount; ++i) { |
350 EXPECT_EQ(entry_id, | 347 EXPECT_EQ(entry_id, service_->AddToList( |
351 service_->AddToList(url, | 348 url, service_->CreateDefaultDistillerPage().Pass(), |
352 service_->CreateDefaultDistillerPage().Pass(), | 349 ArticleCallback(&article_cb[i]))); |
353 ArticleCallback(&article_cb[i]))); | |
354 EXPECT_CALL(article_cb[i], DistillationCompleted(true)); | 350 EXPECT_CALL(article_cb[i], DistillationCompleted(true)); |
355 } | 351 } |
356 | 352 |
357 scoped_ptr<DistilledArticleProto> proto = CreateArticleWithURL(url.spec()); | 353 scoped_ptr<DistilledArticleProto> proto = CreateArticleWithURL(url.spec()); |
358 RunDistillerCallback(distiller, proto.Pass()); | 354 RunDistillerCallback(distiller, proto.Pass()); |
359 | 355 |
360 // Add the same url again, all callbacks should be called with true. | 356 // Add the same url again, all callbacks should be called with true. |
361 for (int i = 0; i < kClientsCount; ++i) { | 357 for (int i = 0; i < kClientsCount; ++i) { |
362 EXPECT_CALL(article_cb[i], DistillationCompleted(true)); | 358 EXPECT_CALL(article_cb[i], DistillationCompleted(true)); |
363 EXPECT_EQ(entry_id, | 359 EXPECT_EQ(entry_id, service_->AddToList( |
364 service_->AddToList(url, | 360 url, service_->CreateDefaultDistillerPage().Pass(), |
365 service_->CreateDefaultDistillerPage().Pass(), | 361 ArticleCallback(&article_cb[i]))); |
366 ArticleCallback(&article_cb[i]))); | |
367 } | 362 } |
368 | 363 |
369 base::RunLoop().RunUntilIdle(); | 364 base::RunLoop().RunUntilIdle(); |
370 } | 365 } |
371 | 366 |
372 TEST_F(DomDistillerServiceTest, TestMultipleCallbacksOnRemove) { | 367 TEST_F(DomDistillerServiceTest, TestMultipleCallbacksOnRemove) { |
373 FakeDistiller* distiller = new FakeDistiller(false); | 368 FakeDistiller* distiller = new FakeDistiller(false); |
374 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) | 369 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
375 .WillOnce(Return(distiller)); | 370 .WillOnce(Return(distiller)); |
376 | 371 |
377 const int kClientsCount = 5; | 372 const int kClientsCount = 5; |
378 MockArticleAvailableCallback article_cb[kClientsCount]; | 373 MockArticleAvailableCallback article_cb[kClientsCount]; |
379 // Adding a URL and remove the entry before distillation. Callback should be | 374 // Adding a URL and remove the entry before distillation. Callback should be |
380 // called with false. | 375 // called with false. |
381 GURL url("http://www.example.com/p1"); | 376 GURL url("http://www.example.com/p1"); |
382 const std::string entry_id = | 377 const std::string entry_id = |
383 service_->AddToList(url, | 378 service_->AddToList(url, service_->CreateDefaultDistillerPage().Pass(), |
384 service_->CreateDefaultDistillerPage().Pass(), | |
385 ArticleCallback(&article_cb[0])); | 379 ArticleCallback(&article_cb[0])); |
386 | 380 |
387 EXPECT_CALL(article_cb[0], DistillationCompleted(false)); | 381 EXPECT_CALL(article_cb[0], DistillationCompleted(false)); |
388 for (int i = 1; i < kClientsCount; ++i) { | 382 for (int i = 1; i < kClientsCount; ++i) { |
389 EXPECT_EQ(entry_id, | 383 EXPECT_EQ(entry_id, service_->AddToList( |
390 service_->AddToList(url, | 384 url, service_->CreateDefaultDistillerPage().Pass(), |
391 service_->CreateDefaultDistillerPage().Pass(), | 385 ArticleCallback(&article_cb[i]))); |
392 ArticleCallback(&article_cb[i]))); | |
393 EXPECT_CALL(article_cb[i], DistillationCompleted(false)); | 386 EXPECT_CALL(article_cb[i], DistillationCompleted(false)); |
394 } | 387 } |
395 | 388 |
396 service_->RemoveEntry(entry_id); | 389 service_->RemoveEntry(entry_id); |
397 base::RunLoop().RunUntilIdle(); | 390 base::RunLoop().RunUntilIdle(); |
398 } | 391 } |
399 | 392 |
400 TEST_F(DomDistillerServiceTest, TestMultiplePageArticle) { | 393 TEST_F(DomDistillerServiceTest, TestMultiplePageArticle) { |
401 FakeDistiller* distiller = new FakeDistiller(false); | 394 FakeDistiller* distiller = new FakeDistiller(false); |
402 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) | 395 EXPECT_CALL(*distiller_factory_, CreateDistillerImpl()) |
403 .WillOnce(Return(distiller)); | 396 .WillOnce(Return(distiller)); |
404 | 397 |
405 const int kPageCount = 8; | 398 const int kPageCount = 8; |
406 | 399 |
407 std::string base_url("http://www.example.com/p"); | 400 std::string base_url("http://www.example.com/p"); |
408 GURL pages_url[kPageCount]; | 401 GURL pages_url[kPageCount]; |
409 for (int page_num = 0; page_num < kPageCount; ++page_num) { | 402 for (int page_num = 0; page_num < kPageCount; ++page_num) { |
410 pages_url[page_num] = GURL(base_url + base::IntToString(page_num)); | 403 pages_url[page_num] = GURL(base_url + base::IntToString(page_num)); |
411 } | 404 } |
412 | 405 |
413 MockArticleAvailableCallback article_cb; | 406 MockArticleAvailableCallback article_cb; |
414 EXPECT_CALL(article_cb, DistillationCompleted(true)); | 407 EXPECT_CALL(article_cb, DistillationCompleted(true)); |
415 | 408 |
416 std::string entry_id = | 409 std::string entry_id = service_->AddToList( |
417 service_->AddToList(pages_url[0], | 410 pages_url[0], service_->CreateDefaultDistillerPage().Pass(), |
418 service_->CreateDefaultDistillerPage().Pass(), | 411 ArticleCallback(&article_cb)); |
419 ArticleCallback(&article_cb)); | |
420 | 412 |
421 ArticleEntry entry; | 413 ArticleEntry entry; |
422 ASSERT_FALSE(distiller->GetArticleCallback().is_null()); | 414 ASSERT_FALSE(distiller->GetArticleCallback().is_null()); |
423 EXPECT_EQ(pages_url[0], distiller->GetUrl()); | 415 EXPECT_EQ(pages_url[0], distiller->GetUrl()); |
424 | 416 |
425 // Create the article with pages to pass to the distiller. | 417 // Create the article with pages to pass to the distiller. |
426 scoped_ptr<DistilledArticleProto> proto = | 418 scoped_ptr<DistilledArticleProto> proto = |
427 CreateArticleWithURL(pages_url[0].spec()); | 419 CreateArticleWithURL(pages_url[0].spec()); |
428 for (int page_num = 1; page_num < kPageCount; ++page_num) { | 420 for (int page_num = 1; page_num < kPageCount; ++page_num) { |
429 DistilledPageProto* distilled_page = proto->add_pages(); | 421 DistilledPageProto* distilled_page = proto->add_pages(); |
(...skipping 17 matching lines...) Expand all Loading... |
447 EXPECT_TRUE(store_->GetEntryByUrl(pages_url[page_num], &entry)); | 439 EXPECT_TRUE(store_->GetEntryByUrl(pages_url[page_num], &entry)); |
448 } | 440 } |
449 | 441 |
450 service_->RemoveEntry(entry_id); | 442 service_->RemoveEntry(entry_id); |
451 base::RunLoop().RunUntilIdle(); | 443 base::RunLoop().RunUntilIdle(); |
452 EXPECT_EQ(0u, store_->GetEntries().size()); | 444 EXPECT_EQ(0u, store_->GetEntries().size()); |
453 } | 445 } |
454 | 446 |
455 } // namespace test | 447 } // namespace test |
456 } // namespace dom_distiller | 448 } // namespace dom_distiller |
OLD | NEW |