[Cleanup] Used scoped pointers in KeyedServiceFactory's SetTestingFactory functions.
[chromium-blink-merge.git] / chrome / browser / download / download_ui_controller_unittest.cc
blob015f93a26118beb9fa8fdea3733b535f8ad385f7
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.
5 #include "base/bind.h"
6 #include "base/callback.h"
7 #include "base/files/file_path.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/observer_list.h"
12 #include "chrome/browser/download/download_history.h"
13 #include "chrome/browser/download/download_service.h"
14 #include "chrome/browser/download/download_service_factory.h"
15 #include "chrome/browser/download/download_ui_controller.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
18 #include "components/history/core/browser/download_row.h"
19 #include "content/public/test/mock_download_item.h"
20 #include "content/public/test/mock_download_manager.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 using content::MockDownloadItem;
25 using content::MockDownloadManager;
26 using history::HistoryService;
27 using testing::AnyNumber;
28 using testing::Assign;
29 using testing::Return;
30 using testing::ReturnRefOfCopy;
31 using testing::SaveArg;
32 using testing::_;
34 namespace {
36 // A DownloadUIController::Delegate that stores the DownloadItem* for the last
37 // download that was sent to the UI.
38 class TestDelegate : public DownloadUIController::Delegate {
39 public:
40 explicit TestDelegate(base::WeakPtr<content::DownloadItem*> receiver);
41 ~TestDelegate() override {}
43 private:
44 void OnNewDownloadReady(content::DownloadItem* item) override;
46 base::WeakPtr<content::DownloadItem*> receiver_;
49 TestDelegate::TestDelegate(base::WeakPtr<content::DownloadItem*> receiver)
50 : receiver_(receiver) {
53 void TestDelegate::OnNewDownloadReady(content::DownloadItem* item) {
54 if (receiver_.get())
55 *receiver_ = item;
58 // A DownloadService that returns a custom DownloadHistory.
59 class TestDownloadService : public DownloadService {
60 public:
61 explicit TestDownloadService(Profile* profile);
62 ~TestDownloadService() override;
64 void set_download_history(scoped_ptr<DownloadHistory> download_history) {
65 download_history_.swap(download_history);
67 DownloadHistory* GetDownloadHistory() override;
69 private:
70 scoped_ptr<DownloadHistory> download_history_;
73 TestDownloadService::TestDownloadService(Profile* profile)
74 : DownloadService(profile) {
77 TestDownloadService::~TestDownloadService() {
80 DownloadHistory* TestDownloadService::GetDownloadHistory() {
81 return download_history_.get();
84 // The test fixture:
85 class DownloadUIControllerTest : public ChromeRenderViewHostTestHarness {
86 public:
87 DownloadUIControllerTest();
89 protected:
90 // testing::Test
91 void SetUp() override;
93 // Returns a TestDelegate. Invoking OnNewDownloadReady on the returned
94 // delegate results in the DownloadItem* being stored in |notified_item_|.
95 scoped_ptr<DownloadUIController::Delegate> GetTestDelegate();
97 MockDownloadManager* manager() { return manager_.get(); }
99 // Returns the DownloadManager::Observer registered by a test case. This is
100 // the DownloadUIController's observer for all current test cases.
101 content::DownloadManager::Observer* manager_observer() {
102 return manager_observer_;
105 // The most recent DownloadItem that was passed into OnNewDownloadReady().
106 content::DownloadItem* notified_item() { return notified_item_; }
108 // DownloadHistory performs a query of existing downloads when it is first
109 // instantiated. This method returns the completion callback for that query.
110 // It can be used to inject history downloads.
111 const HistoryService::DownloadQueryCallback& history_query_callback() const {
112 return history_adapter_->download_query_callback_;
115 // DownloadManager::Observer registered by DownloadHistory.
116 content::DownloadManager::Observer* download_history_manager_observer() {
117 return download_history_manager_observer_;
120 scoped_ptr<MockDownloadItem> CreateMockInProgressDownload();
122 private:
123 // A private history adapter that stores the DownloadQueryCallback when
124 // QueryDownloads is called.
125 class HistoryAdapter : public DownloadHistory::HistoryAdapter {
126 public:
127 HistoryAdapter() : DownloadHistory::HistoryAdapter(NULL) {}
128 HistoryService::DownloadQueryCallback download_query_callback_;
130 private:
131 void QueryDownloads(
132 const HistoryService::DownloadQueryCallback& callback) override {
133 download_query_callback_ = callback;
137 // Constructs and returns a TestDownloadService.
138 static scoped_ptr<KeyedService> TestingDownloadServiceFactory(
139 content::BrowserContext* browser_context);
141 scoped_ptr<MockDownloadManager> manager_;
142 content::DownloadManager::Observer* download_history_manager_observer_;
143 content::DownloadManager::Observer* manager_observer_;
144 content::DownloadItem* notified_item_;
145 base::WeakPtrFactory<content::DownloadItem*> notified_item_receiver_factory_;
147 HistoryAdapter* history_adapter_;
150 // static
151 scoped_ptr<KeyedService>
152 DownloadUIControllerTest::TestingDownloadServiceFactory(
153 content::BrowserContext* browser_context) {
154 return make_scoped_ptr(
155 new TestDownloadService(Profile::FromBrowserContext(browser_context)));
158 DownloadUIControllerTest::DownloadUIControllerTest()
159 : download_history_manager_observer_(NULL),
160 manager_observer_(NULL),
161 notified_item_(NULL),
162 notified_item_receiver_factory_(&notified_item_) {
165 void DownloadUIControllerTest::SetUp() {
166 ChromeRenderViewHostTestHarness::SetUp();
168 manager_.reset(new testing::StrictMock<MockDownloadManager>());
169 EXPECT_CALL(*manager_, AddObserver(_))
170 .WillOnce(SaveArg<0>(&download_history_manager_observer_));
171 EXPECT_CALL(*manager_,
172 RemoveObserver(testing::Eq(
173 testing::ByRef(download_history_manager_observer_))))
174 .WillOnce(testing::Assign(
175 &download_history_manager_observer_,
176 static_cast<content::DownloadManager::Observer*>(NULL)));
177 EXPECT_CALL(*manager_, GetAllDownloads(_)).Times(AnyNumber());
179 scoped_ptr<HistoryAdapter> history_adapter(new HistoryAdapter);
180 history_adapter_ = history_adapter.get();
181 scoped_ptr<DownloadHistory> download_history(
182 new DownloadHistory(manager_.get(), history_adapter.Pass()));
183 ASSERT_TRUE(download_history_manager_observer_);
185 EXPECT_CALL(*manager_, AddObserver(_))
186 .WillOnce(SaveArg<0>(&manager_observer_));
187 EXPECT_CALL(*manager_,
188 RemoveObserver(testing::Eq(testing::ByRef(manager_observer_))))
189 .WillOnce(testing::Assign(
190 &manager_observer_,
191 static_cast<content::DownloadManager::Observer*>(NULL)));
192 TestDownloadService* download_service = static_cast<TestDownloadService*>(
193 DownloadServiceFactory::GetInstance()->SetTestingFactoryAndUse(
194 browser_context(), &TestingDownloadServiceFactory));
195 ASSERT_TRUE(download_service);
196 download_service->set_download_history(download_history.Pass());
199 scoped_ptr<MockDownloadItem>
200 DownloadUIControllerTest::CreateMockInProgressDownload() {
201 scoped_ptr<MockDownloadItem> item(
202 new testing::StrictMock<MockDownloadItem>());
203 EXPECT_CALL(*item, GetBrowserContext())
204 .WillRepeatedly(Return(browser_context()));
205 EXPECT_CALL(*item, GetId()).WillRepeatedly(Return(1));
206 EXPECT_CALL(*item, GetTargetFilePath()).WillRepeatedly(
207 ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
208 EXPECT_CALL(*item, GetFullPath()).WillRepeatedly(
209 ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
210 EXPECT_CALL(*item, GetState())
211 .WillRepeatedly(Return(content::DownloadItem::IN_PROGRESS));
212 EXPECT_CALL(*item, GetUrlChain())
213 .WillRepeatedly(testing::ReturnRefOfCopy(std::vector<GURL>()));
214 EXPECT_CALL(*item, GetReferrerUrl())
215 .WillRepeatedly(testing::ReturnRefOfCopy(GURL()));
216 EXPECT_CALL(*item, GetStartTime()).WillRepeatedly(Return(base::Time()));
217 EXPECT_CALL(*item, GetEndTime()).WillRepeatedly(Return(base::Time()));
218 EXPECT_CALL(*item, GetETag()).WillRepeatedly(ReturnRefOfCopy(std::string()));
219 EXPECT_CALL(*item, GetLastModifiedTime())
220 .WillRepeatedly(ReturnRefOfCopy(std::string()));
221 EXPECT_CALL(*item, GetDangerType())
222 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
223 EXPECT_CALL(*item, GetLastReason())
224 .WillRepeatedly(Return(content::DOWNLOAD_INTERRUPT_REASON_NONE));
225 EXPECT_CALL(*item, GetReceivedBytes()).WillRepeatedly(Return(0));
226 EXPECT_CALL(*item, GetTotalBytes()).WillRepeatedly(Return(0));
227 EXPECT_CALL(*item, GetTargetDisposition()).WillRepeatedly(
228 Return(content::DownloadItem::TARGET_DISPOSITION_OVERWRITE));
229 EXPECT_CALL(*item, GetOpened()).WillRepeatedly(Return(false));
230 EXPECT_CALL(*item, GetMimeType()).WillRepeatedly(Return(std::string()));
231 EXPECT_CALL(*item, GetURL()).WillRepeatedly(testing::ReturnRefOfCopy(GURL()));
232 EXPECT_CALL(*item, IsTemporary()).WillRepeatedly(Return(false));
233 return item.Pass();
236 scoped_ptr<DownloadUIController::Delegate>
237 DownloadUIControllerTest::GetTestDelegate() {
238 scoped_ptr<DownloadUIController::Delegate> delegate(
239 new TestDelegate(notified_item_receiver_factory_.GetWeakPtr()));
240 return delegate.Pass();
243 // New downloads should be presented to the UI when GetTargetFilePath() returns
244 // a non-empty path. I.e. once the download target has been determined.
245 TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyBasic) {
246 scoped_ptr<MockDownloadItem> item(CreateMockInProgressDownload());
247 DownloadUIController controller(manager(), GetTestDelegate());
248 EXPECT_CALL(*item, GetTargetFilePath())
249 .WillOnce(ReturnRefOfCopy(base::FilePath()));
251 ASSERT_TRUE(manager_observer());
252 manager_observer()->OnDownloadCreated(manager(), item.get());
254 // The destination for the download hasn't been determined yet. It should not
255 // be displayed.
256 EXPECT_FALSE(notified_item());
258 // Once the destination has been determined, then it should be displayed.
259 EXPECT_CALL(*item, GetTargetFilePath())
260 .WillOnce(ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("foo"))));
261 item->NotifyObserversDownloadUpdated();
263 EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), notified_item());
266 // A download that's created in an interrupted state should also be displayed.
267 TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyBasic_Interrupted) {
268 scoped_ptr<MockDownloadItem> item = CreateMockInProgressDownload();
269 DownloadUIController controller(manager(), GetTestDelegate());
270 EXPECT_CALL(*item, GetState())
271 .WillRepeatedly(Return(content::DownloadItem::INTERRUPTED));
273 ASSERT_TRUE(manager_observer());
274 manager_observer()->OnDownloadCreated(manager(), item.get());
275 EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), notified_item());
278 // Downloads that have a target path on creation and are in the IN_PROGRESS
279 // state should be displayed in the UI immediately without requiring an
280 // additional OnDownloadUpdated() notification.
281 TEST_F(DownloadUIControllerTest, DownloadUIController_NotifyReadyOnCreate) {
282 scoped_ptr<MockDownloadItem> item(CreateMockInProgressDownload());
283 DownloadUIController controller(manager(), GetTestDelegate());
285 ASSERT_TRUE(manager_observer());
286 manager_observer()->OnDownloadCreated(manager(), item.get());
287 EXPECT_EQ(static_cast<content::DownloadItem*>(item.get()), notified_item());
290 // The UI shouldn't be notified of downloads that were restored from history.
291 TEST_F(DownloadUIControllerTest, DownloadUIController_HistoryDownload) {
292 DownloadUIController controller(manager(), GetTestDelegate());
293 // DownloadHistory should already have been created. It performs a query of
294 // existing downloads upon creation. We'll use the callback to inject a
295 // history download.
296 ASSERT_FALSE(history_query_callback().is_null());
298 // download_history_manager_observer is the DownloadManager::Observer
299 // registered by the DownloadHistory. DownloadHistory relies on the
300 // OnDownloadCreated notification to mark a download as having been restored
301 // from history.
302 ASSERT_TRUE(download_history_manager_observer());
304 scoped_ptr<std::vector<history::DownloadRow> > history_downloads;
305 history_downloads.reset(new std::vector<history::DownloadRow>());
306 history_downloads->push_back(history::DownloadRow());
307 history_downloads->front().id = 1;
309 std::vector<GURL> url_chain;
310 GURL url;
311 scoped_ptr<MockDownloadItem> item = CreateMockInProgressDownload();
313 EXPECT_CALL(*item, GetOriginalMimeType());
314 EXPECT_CALL(*manager(), CheckForHistoryFilesRemoval());
317 testing::InSequence s;
318 testing::MockFunction<void()> mock_function;
319 // DownloadHistory will immediately try to create a download using the info
320 // we push through the query callback. When DownloadManager::CreateDownload
321 // is called, we need to first invoke the OnDownloadCreated callback for
322 // DownloadHistory before returning the DownloadItem since that's the
323 // sequence of events expected by DownloadHistory.
324 base::Closure history_on_created_callback =
325 base::Bind(&content::DownloadManager::Observer::OnDownloadCreated,
326 base::Unretained(download_history_manager_observer()),
327 manager(),
328 item.get());
329 EXPECT_CALL(*manager(), MockCreateDownloadItem(_)).WillOnce(
330 testing::DoAll(testing::InvokeWithoutArgs(&history_on_created_callback,
331 &base::Closure::Run),
332 Return(item.get())));
333 EXPECT_CALL(mock_function, Call());
335 history_query_callback().Run(history_downloads.Pass());
336 mock_function.Call();
339 // Now pass along the notification to the OnDownloadCreated observer from
340 // DownloadUIController. It should ignore the download since it's marked as
341 // being restored from history.
342 ASSERT_TRUE(manager_observer());
343 manager_observer()->OnDownloadCreated(manager(), item.get());
345 // Finally, the expectation we've been waiting for:
346 EXPECT_FALSE(notified_item());
349 } // namespace