Upstream version 7.36.149.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_CONST_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   virtual 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,
163        TestSaveCallbackCalledOnDistillationComplete) {
164   MockDistillerFactory distiller_factory;
165   FakeDistiller* distiller = new FakeDistiller(true);
166   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
167       .WillOnce(Return(distiller));
168   TestCancelCallback cancel_callback;
169   TaskTracker task_tracker(
170       GetDefaultEntry(), cancel_callback.GetCallback(), NULL);
171
172   MockSaveCallback save_callback;
173   task_tracker.AddSaveCallback(
174       base::Bind(&MockSaveCallback::Save, base::Unretained(&save_callback)));
175   base::RunLoop().RunUntilIdle();
176
177   EXPECT_CALL(save_callback, Save(_, _, _));
178
179   task_tracker.StartDistiller(&distiller_factory,
180                               scoped_ptr<DistillerPage>().Pass());
181   base::RunLoop().RunUntilIdle();
182
183   EXPECT_TRUE(cancel_callback.Cancelled());
184 }
185
186 DistilledArticleProto CreateDistilledArticleForEntry(
187     const ArticleEntry& entry) {
188   DistilledArticleProto article;
189   for (int i = 0; i < entry.pages_size(); ++i) {
190     DistilledPageProto* page = article.add_pages();
191     page->set_url(entry.pages(i).url());
192     page->set_html("<div>" + entry.pages(i).url() + "</div>");
193   }
194   return article;
195 }
196
197 TEST_F(DomDistillerTaskTrackerTest, TestBlobFetcher) {
198   ArticleEntry entry_with_blob = GetDefaultEntry();
199   DistilledArticleProto stored_distilled_article =
200       CreateDistilledArticleForEntry(entry_with_blob);
201   InMemoryContentStore content_store;
202   content_store.InjectContent(entry_with_blob, stored_distilled_article);
203   TestCancelCallback cancel_callback;
204
205   TaskTracker task_tracker(
206       entry_with_blob, cancel_callback.GetCallback(), &content_store);
207
208   FakeViewRequestDelegate viewer_delegate;
209   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
210   base::RunLoop().RunUntilIdle();
211
212   const DistilledArticleProto* distilled_article;
213
214   EXPECT_CALL(viewer_delegate, OnArticleReady(_))
215       .WillOnce(testing::SaveArg<0>(&distilled_article));
216
217   task_tracker.StartBlobFetcher();
218   base::RunLoop().RunUntilIdle();
219
220   EXPECT_EQ(stored_distilled_article.SerializeAsString(),
221             distilled_article->SerializeAsString());
222
223   EXPECT_FALSE(cancel_callback.Cancelled());
224 }
225
226 TEST_F(DomDistillerTaskTrackerTest, TestBlobFetcherFinishesFirst) {
227   MockDistillerFactory distiller_factory;
228   FakeDistiller* distiller = new FakeDistiller(false);
229   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
230       .WillOnce(Return(distiller));
231
232   ArticleEntry entry_with_blob = GetDefaultEntry();
233   DistilledArticleProto stored_distilled_article =
234       CreateDistilledArticleForEntry(entry_with_blob);
235   InMemoryContentStore content_store;
236   content_store.InjectContent(entry_with_blob, stored_distilled_article);
237   TestCancelCallback cancel_callback;
238   TaskTracker task_tracker(
239       entry_with_blob, cancel_callback.GetCallback(), &content_store);
240
241   FakeViewRequestDelegate viewer_delegate;
242   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
243   base::RunLoop().RunUntilIdle();
244
245   DistilledArticleProto distilled_article;
246
247   EXPECT_CALL(viewer_delegate, OnArticleReady(_))
248       .WillOnce(testing::SaveArgPointee<0>(&distilled_article));
249   bool distiller_destroyed = false;
250   EXPECT_CALL(*distiller, Die())
251       .WillOnce(testing::Assign(&distiller_destroyed, true));
252
253   task_tracker.StartDistiller(&distiller_factory,
254                               scoped_ptr<DistillerPage>().Pass());
255   task_tracker.StartBlobFetcher();
256   base::RunLoop().RunUntilIdle();
257
258   testing::Mock::VerifyAndClearExpectations(&viewer_delegate);
259   EXPECT_EQ(stored_distilled_article.SerializeAsString(),
260             distilled_article.SerializeAsString());
261
262   EXPECT_TRUE(distiller_destroyed);
263   EXPECT_FALSE(cancel_callback.Cancelled());
264   base::RunLoop().RunUntilIdle();
265 }
266
267 TEST_F(DomDistillerTaskTrackerTest, TestBlobFetcherWithoutBlob) {
268   MockDistillerFactory distiller_factory;
269   FakeDistiller* distiller = new FakeDistiller(false);
270   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
271       .WillOnce(Return(distiller));
272
273   ArticleEntry entry(GetDefaultEntry());
274   InMemoryContentStore content_store;
275   scoped_ptr<DistilledArticleProto> distilled_article(
276       new DistilledArticleProto(CreateDistilledArticleForEntry(entry)));
277
278   TestCancelCallback cancel_callback;
279   TaskTracker task_tracker(
280       GetDefaultEntry(), cancel_callback.GetCallback(), &content_store);
281
282   FakeViewRequestDelegate viewer_delegate;
283   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
284   base::RunLoop().RunUntilIdle();
285
286   task_tracker.StartBlobFetcher();
287   task_tracker.StartDistiller(&distiller_factory,
288                               scoped_ptr<DistillerPage>().Pass());
289
290   // OnArticleReady shouldn't be called until distillation finishes (i.e. the
291   // blob fetcher shouldn't return distilled content).
292   EXPECT_CALL(viewer_delegate, OnArticleReady(_)).Times(0);
293   base::RunLoop().RunUntilIdle();
294
295   EXPECT_CALL(viewer_delegate, OnArticleReady(_));
296   distiller->RunDistillerCallback(distilled_article.Pass());
297   base::RunLoop().RunUntilIdle();
298
299   EXPECT_FALSE(cancel_callback.Cancelled());
300 }
301
302 TEST_F(DomDistillerTaskTrackerTest, TestDistillerFailsFirst) {
303   MockDistillerFactory distiller_factory;
304   FakeDistiller* distiller = new FakeDistiller(false);
305   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
306       .WillOnce(Return(distiller));
307
308   ArticleEntry entry(GetDefaultEntry());
309   MockContentStore content_store;
310
311   TestCancelCallback cancel_callback;
312   TaskTracker task_tracker(
313       GetDefaultEntry(), cancel_callback.GetCallback(), &content_store);
314
315   FakeViewRequestDelegate viewer_delegate;
316   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
317
318   DistilledContentStore::LoadCallback content_store_load_callback;
319   EXPECT_CALL(content_store, LoadContent(_, _))
320       .WillOnce(testing::SaveArg<1>(&content_store_load_callback));
321
322   task_tracker.StartDistiller(&distiller_factory,
323                               scoped_ptr<DistillerPage>().Pass());
324   task_tracker.StartBlobFetcher();
325
326   EXPECT_CALL(viewer_delegate, OnArticleReady(_)).Times(0);
327   distiller->RunDistillerCallback(
328       scoped_ptr<DistilledArticleProto>(new DistilledArticleProto));
329   base::RunLoop().RunUntilIdle();
330
331   EXPECT_CALL(viewer_delegate, OnArticleReady(_));
332   content_store_load_callback.Run(
333       true,
334       scoped_ptr<DistilledArticleProto>(
335           new DistilledArticleProto(CreateDistilledArticleForEntry(entry))));
336   base::RunLoop().RunUntilIdle();
337
338   EXPECT_FALSE(cancel_callback.Cancelled());
339 }
340
341 TEST_F(DomDistillerTaskTrackerTest, ContentIsSaved) {
342   MockDistillerFactory distiller_factory;
343   FakeDistiller* distiller = new FakeDistiller(false);
344   EXPECT_CALL(distiller_factory, CreateDistillerImpl())
345       .WillOnce(Return(distiller));
346
347   ArticleEntry entry(GetDefaultEntry());
348   DistilledArticleProto distilled_article =
349       CreateDistilledArticleForEntry(entry);
350
351   MockContentStore content_store;
352   TestCancelCallback cancel_callback;
353   TaskTracker task_tracker(
354       GetDefaultEntry(), cancel_callback.GetCallback(), &content_store);
355
356   FakeViewRequestDelegate viewer_delegate;
357   scoped_ptr<ViewerHandle> handle(task_tracker.AddViewer(&viewer_delegate));
358
359   DistilledArticleProto stored_distilled_article;
360   DistilledContentStore::LoadCallback content_store_load_callback;
361   EXPECT_CALL(content_store, SaveContent(_, _, _))
362       .WillOnce(testing::SaveArg<1>(&stored_distilled_article));
363
364   task_tracker.StartDistiller(&distiller_factory,
365                               scoped_ptr<DistillerPage>().Pass());
366
367   EXPECT_CALL(viewer_delegate, OnArticleReady(_));
368   distiller->RunDistillerCallback(scoped_ptr<DistilledArticleProto>(
369       new DistilledArticleProto(distilled_article)));
370   base::RunLoop().RunUntilIdle();
371
372   ASSERT_EQ(stored_distilled_article.SerializeAsString(),
373             distilled_article.SerializeAsString());
374   EXPECT_FALSE(cancel_callback.Cancelled());
375 }
376
377 }  // namespace test
378 }  // namespace dom_distiller