Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / dom_distiller / core / task_tracker_unittest.cc
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 "components/dom_distiller/core/task_tracker.h"
6
7 #include "base/run_loop.h"
8 #include "components/dom_distiller/core/article_distillation_update.h"
9 #include "components/dom_distiller/core/article_entry.h"
10 #include "components/dom_distiller/core/distilled_content_store.h"
11 #include "components/dom_distiller/core/fake_distiller.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 using testing::Return;
15 using testing::_;
16
17 namespace dom_distiller {
18 namespace test {
19
20 class FakeViewRequestDelegate : public ViewRequestDelegate {
21  public:
22   virtual ~FakeViewRequestDelegate() {}
23   MOCK_METHOD1(OnArticleReady,
24                void(const DistilledArticleProto* article_proto));
25   MOCK_METHOD1(OnArticleUpdated,
26                void(ArticleDistillationUpdate article_update));
27 };
28
29 class MockContentStore : public DistilledContentStore {
30  public:
31   MOCK_METHOD2(LoadContent,
32                void(const ArticleEntry& entry, LoadCallback callback));
33   MOCK_METHOD3(SaveContent,
34                void(const ArticleEntry& entry,
35                     const DistilledArticleProto& proto,
36                     SaveCallback callback));
37 };
38
39 class TestCancelCallback {
40  public:
41   TestCancelCallback() : cancelled_(false) {}
42   TaskTracker::CancelCallback GetCallback() {
43     return base::Bind(&TestCancelCallback::Cancel, base::Unretained(this));
44   }
45   void Cancel(TaskTracker*) { cancelled_ = true; }
46   bool Cancelled() { return cancelled_; }
47
48  private:
49   bool cancelled_;
50 };
51
52 class MockSaveCallback {
53  public:
54   MOCK_METHOD3(Save,
55                void(const ArticleEntry&, const DistilledArticleProto*, bool));
56 };
57
58 class DomDistillerTaskTrackerTest : public testing::Test {
59  public:
60   void SetUp() override {
61     message_loop_.reset(new base::MessageLoop());
62     entry_id_ = "id0";
63     page_0_url_ = GURL("http://www.example.com/1");
64     page_1_url_ = GURL("http://www.example.com/2");
65   }
66
67   ArticleEntry GetDefaultEntry() {
68     ArticleEntry entry;
69     entry.set_entry_id(entry_id_);
70     ArticleEntryPage* page0 = entry.add_pages();
71     ArticleEntryPage* page1 = entry.add_pages();
72     page0->set_url(page_0_url_.spec());
73     page1->set_url(page_1_url_.spec());
74     return entry;
75   }
76
77  protected:
78   scoped_ptr<base::MessageLoop> message_loop_;
79   std::string entry_id_;
80   GURL page_0_url_;
81   GURL page_1_url_;
82 };
83
84 TEST_F(DomDistillerTaskTrackerTest, TestHasEntryId) {
85   MockDistillerFactory distiller_factory;
86   TestCancelCallback cancel_callback;
87   TaskTracker task_tracker(
88       GetDefaultEntry(), cancel_callback.GetCallback(), NULL);
89   EXPECT_TRUE(task_tracker.HasEntryId(entry_id_));
90   EXPECT_FALSE(task_tracker.HasEntryId("other_id"));
91 }
92
93 TEST_F(DomDistillerTaskTrackerTest, TestHasUrl) {
94   MockDistillerFactory distiller_factory;
95   TestCancelCallback cancel_callback;
96   TaskTracker task_tracker(
97       GetDefaultEntry(), cancel_callback.GetCallback(), NULL);
98   EXPECT_TRUE(task_tracker.HasUrl(page_0_url_));
99   EXPECT_TRUE(task_tracker.HasUrl(page_1_url_));
100   EXPECT_FALSE(task_tracker.HasUrl(GURL("http://other.url/")));
101 }
102
103 TEST_F(DomDistillerTaskTrackerTest, TestViewerCancelled) {
104   MockDistillerFactory distiller_factory;
105   TestCancelCallback cancel_callback;
106   TaskTracker task_tracker(
107       GetDefaultEntry(), cancel_callback.GetCallback(), NULL);
108
109   FakeViewRequestDelegate viewer_delegate;
110   FakeViewRequestDelegate viewer_delegate2;
111   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
112   scoped_ptr<ViewerHandle> handle2(task_tracker.AddViewer(&viewer_delegate2));
113
114   EXPECT_FALSE(cancel_callback.Cancelled());
115   handle.reset();
116   EXPECT_FALSE(cancel_callback.Cancelled());
117   handle2.reset();
118   EXPECT_TRUE(cancel_callback.Cancelled());
119 }
120
121 TEST_F(DomDistillerTaskTrackerTest, TestViewerCancelledWithSaveRequest) {
122   MockDistillerFactory distiller_factory;
123   TestCancelCallback cancel_callback;
124   TaskTracker task_tracker(
125       GetDefaultEntry(), cancel_callback.GetCallback(), NULL);
126
127   FakeViewRequestDelegate viewer_delegate;
128   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
129   EXPECT_FALSE(cancel_callback.Cancelled());
130
131   MockSaveCallback save_callback;
132   task_tracker.AddSaveCallback(
133       base::Bind(&MockSaveCallback::Save, base::Unretained(&save_callback)));
134   handle.reset();
135
136   // Since there is a pending save request, the task shouldn't be cancelled.
137   EXPECT_FALSE(cancel_callback.Cancelled());
138 }
139
140 TEST_F(DomDistillerTaskTrackerTest, TestViewerNotifiedOnDistillationComplete) {
141   MockDistillerFactory distiller_factory;
142   FakeDistiller* distiller = new FakeDistiller(true);
143   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
144       .WillOnce(Return(distiller));
145   TestCancelCallback cancel_callback;
146   TaskTracker task_tracker(
147       GetDefaultEntry(), cancel_callback.GetCallback(), NULL);
148
149   FakeViewRequestDelegate viewer_delegate;
150   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
151   base::RunLoop().RunUntilIdle();
152
153   EXPECT_CALL(viewer_delegate, OnArticleReady(_));
154
155   task_tracker.StartDistiller(&distiller_factory,
156                               scoped_ptr<DistillerPage>().Pass());
157   base::RunLoop().RunUntilIdle();
158
159   EXPECT_FALSE(cancel_callback.Cancelled());
160 }
161
162 TEST_F(DomDistillerTaskTrackerTest, TestDistillerFails) {
163   MockDistillerFactory distiller_factory;
164   FakeDistiller* distiller = new FakeDistiller(false);
165   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
166       .WillOnce(Return(distiller));
167
168   TestCancelCallback cancel_callback;
169   TaskTracker task_tracker(
170       GetDefaultEntry(), cancel_callback.GetCallback(), NULL);
171
172   FakeViewRequestDelegate viewer_delegate;
173   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
174   base::RunLoop().RunUntilIdle();
175
176   EXPECT_CALL(viewer_delegate, OnArticleReady(_));
177
178   task_tracker.StartDistiller(&distiller_factory,
179                               scoped_ptr<DistillerPage>().Pass());
180   distiller->RunDistillerCallback(
181       scoped_ptr<DistilledArticleProto>(new DistilledArticleProto));
182   base::RunLoop().RunUntilIdle();
183
184   EXPECT_FALSE(cancel_callback.Cancelled());
185 }
186
187 TEST_F(DomDistillerTaskTrackerTest,
188        TestSaveCallbackCalledOnDistillationComplete) {
189   MockDistillerFactory distiller_factory;
190   FakeDistiller* distiller = new FakeDistiller(true);
191   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
192       .WillOnce(Return(distiller));
193   TestCancelCallback cancel_callback;
194   TaskTracker task_tracker(
195       GetDefaultEntry(), cancel_callback.GetCallback(), NULL);
196
197   MockSaveCallback save_callback;
198   task_tracker.AddSaveCallback(
199       base::Bind(&MockSaveCallback::Save, base::Unretained(&save_callback)));
200   base::RunLoop().RunUntilIdle();
201
202   EXPECT_CALL(save_callback, Save(_, _, _));
203
204   task_tracker.StartDistiller(&distiller_factory,
205                               scoped_ptr<DistillerPage>().Pass());
206   base::RunLoop().RunUntilIdle();
207
208   EXPECT_TRUE(cancel_callback.Cancelled());
209 }
210
211 DistilledArticleProto CreateDistilledArticleForEntry(
212     const ArticleEntry& entry) {
213   DistilledArticleProto article;
214   for (int i = 0; i < entry.pages_size(); ++i) {
215     DistilledPageProto* page = article.add_pages();
216     page->set_url(entry.pages(i).url());
217     page->set_html("<div>" + entry.pages(i).url() + "</div>");
218   }
219   return article;
220 }
221
222 TEST_F(DomDistillerTaskTrackerTest, TestBlobFetcher) {
223   ArticleEntry entry_with_blob = GetDefaultEntry();
224   DistilledArticleProto stored_distilled_article =
225       CreateDistilledArticleForEntry(entry_with_blob);
226   InMemoryContentStore content_store(kDefaultMaxNumCachedEntries);
227   content_store.InjectContent(entry_with_blob, stored_distilled_article);
228   TestCancelCallback cancel_callback;
229
230   TaskTracker task_tracker(
231       entry_with_blob, cancel_callback.GetCallback(), &content_store);
232
233   FakeViewRequestDelegate viewer_delegate;
234   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
235   base::RunLoop().RunUntilIdle();
236
237   const DistilledArticleProto* distilled_article;
238
239   EXPECT_CALL(viewer_delegate, OnArticleReady(_))
240       .WillOnce(testing::SaveArg<0>(&distilled_article));
241
242   task_tracker.StartBlobFetcher();
243   base::RunLoop().RunUntilIdle();
244
245   EXPECT_EQ(stored_distilled_article.SerializeAsString(),
246             distilled_article->SerializeAsString());
247
248   EXPECT_FALSE(cancel_callback.Cancelled());
249 }
250
251 TEST_F(DomDistillerTaskTrackerTest, TestBlobFetcherFinishesFirst) {
252   MockDistillerFactory distiller_factory;
253   FakeDistiller* distiller = new FakeDistiller(false);
254   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
255       .WillOnce(Return(distiller));
256
257   ArticleEntry entry_with_blob = GetDefaultEntry();
258   DistilledArticleProto stored_distilled_article =
259       CreateDistilledArticleForEntry(entry_with_blob);
260   InMemoryContentStore content_store(kDefaultMaxNumCachedEntries);
261   content_store.InjectContent(entry_with_blob, stored_distilled_article);
262   TestCancelCallback cancel_callback;
263   TaskTracker task_tracker(
264       entry_with_blob, cancel_callback.GetCallback(), &content_store);
265
266   FakeViewRequestDelegate viewer_delegate;
267   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
268   base::RunLoop().RunUntilIdle();
269
270   DistilledArticleProto distilled_article;
271
272   EXPECT_CALL(viewer_delegate, OnArticleReady(_))
273       .WillOnce(testing::SaveArgPointee<0>(&distilled_article));
274   bool distiller_destroyed = false;
275   EXPECT_CALL(*distiller, Die())
276       .WillOnce(testing::Assign(&distiller_destroyed, true));
277
278   task_tracker.StartDistiller(&distiller_factory,
279                               scoped_ptr<DistillerPage>().Pass());
280   task_tracker.StartBlobFetcher();
281   base::RunLoop().RunUntilIdle();
282
283   testing::Mock::VerifyAndClearExpectations(&viewer_delegate);
284   EXPECT_EQ(stored_distilled_article.SerializeAsString(),
285             distilled_article.SerializeAsString());
286
287   EXPECT_TRUE(distiller_destroyed);
288   EXPECT_FALSE(cancel_callback.Cancelled());
289   base::RunLoop().RunUntilIdle();
290 }
291
292 TEST_F(DomDistillerTaskTrackerTest, TestBlobFetcherWithoutBlob) {
293   MockDistillerFactory distiller_factory;
294   FakeDistiller* distiller = new FakeDistiller(false);
295   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
296       .WillOnce(Return(distiller));
297
298   ArticleEntry entry(GetDefaultEntry());
299   InMemoryContentStore content_store(kDefaultMaxNumCachedEntries);
300   scoped_ptr<DistilledArticleProto> distilled_article(
301       new DistilledArticleProto(CreateDistilledArticleForEntry(entry)));
302
303   TestCancelCallback cancel_callback;
304   TaskTracker task_tracker(
305       GetDefaultEntry(), cancel_callback.GetCallback(), &content_store);
306
307   FakeViewRequestDelegate viewer_delegate;
308   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
309   base::RunLoop().RunUntilIdle();
310
311   task_tracker.StartBlobFetcher();
312   task_tracker.StartDistiller(&distiller_factory,
313                               scoped_ptr<DistillerPage>().Pass());
314
315   // OnArticleReady shouldn't be called until distillation finishes (i.e. the
316   // blob fetcher shouldn't return distilled content).
317   EXPECT_CALL(viewer_delegate, OnArticleReady(_)).Times(0);
318   base::RunLoop().RunUntilIdle();
319
320   EXPECT_CALL(viewer_delegate, OnArticleReady(_));
321   distiller->RunDistillerCallback(distilled_article.Pass());
322   base::RunLoop().RunUntilIdle();
323
324   EXPECT_FALSE(cancel_callback.Cancelled());
325 }
326
327 TEST_F(DomDistillerTaskTrackerTest, TestDistillerFailsFirst) {
328   MockDistillerFactory distiller_factory;
329   FakeDistiller* distiller = new FakeDistiller(false);
330   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
331       .WillOnce(Return(distiller));
332
333   ArticleEntry entry(GetDefaultEntry());
334   MockContentStore content_store;
335
336   TestCancelCallback cancel_callback;
337   TaskTracker task_tracker(
338       GetDefaultEntry(), cancel_callback.GetCallback(), &content_store);
339
340   FakeViewRequestDelegate viewer_delegate;
341   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
342
343   DistilledContentStore::LoadCallback content_store_load_callback;
344   EXPECT_CALL(content_store, LoadContent(_, _))
345       .WillOnce(testing::SaveArg<1>(&content_store_load_callback));
346
347   task_tracker.StartDistiller(&distiller_factory,
348                               scoped_ptr<DistillerPage>().Pass());
349   task_tracker.StartBlobFetcher();
350
351   EXPECT_CALL(viewer_delegate, OnArticleReady(_)).Times(0);
352   distiller->RunDistillerCallback(
353       scoped_ptr<DistilledArticleProto>(new DistilledArticleProto));
354   base::RunLoop().RunUntilIdle();
355
356   EXPECT_CALL(viewer_delegate, OnArticleReady(_));
357   content_store_load_callback.Run(
358       true,
359       scoped_ptr<DistilledArticleProto>(
360           new DistilledArticleProto(CreateDistilledArticleForEntry(entry))));
361   base::RunLoop().RunUntilIdle();
362
363   EXPECT_FALSE(cancel_callback.Cancelled());
364 }
365
366 TEST_F(DomDistillerTaskTrackerTest, ContentIsSaved) {
367   MockDistillerFactory distiller_factory;
368   FakeDistiller* distiller = new FakeDistiller(false);
369   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
370       .WillOnce(Return(distiller));
371
372   ArticleEntry entry(GetDefaultEntry());
373   DistilledArticleProto distilled_article =
374       CreateDistilledArticleForEntry(entry);
375
376   MockContentStore content_store;
377   TestCancelCallback cancel_callback;
378   TaskTracker task_tracker(
379       GetDefaultEntry(), cancel_callback.GetCallback(), &content_store);
380
381   FakeViewRequestDelegate viewer_delegate;
382   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
383
384   DistilledArticleProto stored_distilled_article;
385   DistilledContentStore::LoadCallback content_store_load_callback;
386   EXPECT_CALL(content_store, SaveContent(_, _, _))
387       .WillOnce(testing::SaveArg<1>(&stored_distilled_article));
388
389   task_tracker.StartDistiller(&distiller_factory,
390                               scoped_ptr<DistillerPage>().Pass());
391
392   EXPECT_CALL(viewer_delegate, OnArticleReady(_));
393   distiller->RunDistillerCallback(scoped_ptr<DistilledArticleProto>(
394       new DistilledArticleProto(distilled_article)));
395   base::RunLoop().RunUntilIdle();
396
397   ASSERT_EQ(stored_distilled_article.SerializeAsString(),
398             distilled_article.SerializeAsString());
399   EXPECT_FALSE(cancel_callback.Cancelled());
400 }
401
402 }  // namespace test
403 }  // namespace dom_distiller