Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / webui / downloads_dom_handler_browsertest.cc
blob10ebefc1ccb7e9972f1ea08f595310e7d763c629
1 // Copyright (c) 2012 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/auto_reset.h"
6 #include "base/files/scoped_temp_dir.h"
7 #include "base/json/json_reader.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/values.h"
10 #include "chrome/browser/download/download_item_model.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/webui/downloads_dom_handler.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/in_process_browser_test.h"
16 #include "content/public/browser/web_contents.h"
17 #include "content/public/test/mock_download_item.h"
18 #include "content/public/test/mock_download_manager.h"
19 #include "content/public/test/test_utils.h"
21 namespace {
23 // Reads |right_json| into a ListValue |left_list|; returns true if all
24 // key-value pairs in in all dictionaries in |right_list| are also in the
25 // corresponding dictionary in |left_list|. Ignores keys in dictionaries in
26 // |left_list| that are not in the corresponding dictionary in |right_list|.
27 bool ListMatches(base::ListValue* left_list, const std::string& right_json) {
28 scoped_ptr<base::Value> right_value(base::JSONReader::Read(right_json));
29 base::ListValue* right_list = NULL;
30 CHECK(right_value->GetAsList(&right_list));
31 for (size_t i = 0; i < left_list->GetSize(); ++i) {
32 base::DictionaryValue* left_dict = NULL;
33 base::DictionaryValue* right_dict = NULL;
34 CHECK(left_list->GetDictionary(i, &left_dict));
35 CHECK(right_list->GetDictionary(i, &right_dict));
36 for (base::DictionaryValue::Iterator iter(*right_dict);
37 !iter.IsAtEnd(); iter.Advance()) {
38 base::Value* left_value = NULL;
39 if (left_dict->HasKey(iter.key()) &&
40 left_dict->Get(iter.key(), &left_value) &&
41 !iter.value().Equals(left_value)) {
42 LOG(WARNING) << "key \"" << iter.key() << "\" doesn't match ("
43 << iter.value() << " vs. " << *left_value << ")";
44 return false;
48 return true;
51 // A |DownloadsDOMHandler| that doesn't use a real WebUI object, but is real in
52 // all other respects.
53 class MockDownloadsDOMHandler : public DownloadsDOMHandler {
54 public:
55 explicit MockDownloadsDOMHandler(content::DownloadManager* dlm)
56 : DownloadsDOMHandler(dlm),
57 waiting_list_(false),
58 waiting_updated_(false),
59 manager_(nullptr) {
61 ~MockDownloadsDOMHandler() override {}
63 base::ListValue* downloads_list() { return downloads_list_.get(); }
64 base::DictionaryValue* download_updated() { return download_updated_.get(); }
66 void WaitForDownloadsList() {
67 if (downloads_list_)
68 return;
69 base::AutoReset<bool> reset_waiting(&waiting_list_, true);
70 content::RunMessageLoop();
73 void WaitForDownloadUpdated() {
74 if (download_updated_)
75 return;
76 base::AutoReset<bool> reset_waiting(&waiting_updated_, true);
77 content::RunMessageLoop();
80 void ForceSendCurrentDownloads() {
81 ScheduleSendCurrentDownloads();
84 void reset_downloads_list() { downloads_list_.reset(); }
85 void reset_download_updated() { download_updated_.reset(); }
87 void set_manager(content::DownloadManager* manager) { manager_ = manager; }
89 using DownloadsDOMHandler::FinalizeRemovals;
91 protected:
92 content::WebContents* GetWebUIWebContents() override { return NULL; }
94 void CallUpdateAll(const base::ListValue& list) override {
95 downloads_list_.reset(list.DeepCopy());
96 if (waiting_list_) {
97 content::BrowserThread::PostTask(content::BrowserThread::UI,
98 FROM_HERE,
99 base::MessageLoop::QuitClosure());
103 void CallUpdateItem(const base::DictionaryValue& item) override {
104 download_updated_.reset(item.DeepCopy());
105 if (waiting_updated_) {
106 content::BrowserThread::PostTask(content::BrowserThread::UI,
107 FROM_HERE,
108 base::MessageLoop::QuitClosure());
112 content::DownloadManager* GetMainNotifierManager() override {
113 return manager_ ? manager_ : DownloadsDOMHandler::GetMainNotifierManager();
116 private:
117 scoped_ptr<base::ListValue> downloads_list_;
118 scoped_ptr<base::DictionaryValue> download_updated_;
119 bool waiting_list_;
120 bool waiting_updated_;
121 content::DownloadManager* manager_; // weak.
123 DISALLOW_COPY_AND_ASSIGN(MockDownloadsDOMHandler);
126 } // namespace
128 class DownloadsDOMHandlerTest : public InProcessBrowserTest {
129 public:
130 DownloadsDOMHandlerTest() {}
132 ~DownloadsDOMHandlerTest() override {}
134 void SetUpOnMainThread() override {
135 mock_handler_.reset(new MockDownloadsDOMHandler(download_manager()));
136 CHECK(downloads_directory_.CreateUniqueTempDir());
137 browser()->profile()->GetPrefs()->SetFilePath(
138 prefs::kDownloadDefaultDirectory,
139 downloads_directory_.path());
140 CHECK(test_server()->Start());
143 content::DownloadManager* download_manager() {
144 return content::BrowserContext::GetDownloadManager(browser()->profile());
147 void DownloadAnItem() {
148 GURL url = test_server()->GetURL("files/downloads/image.jpg");
149 std::vector<GURL> url_chain;
150 url_chain.push_back(url);
151 base::Time current(base::Time::Now());
152 download_manager()->CreateDownloadItem(
153 1, // id
154 base::FilePath(FILE_PATH_LITERAL("/path/to/file")),
155 base::FilePath(FILE_PATH_LITERAL("/path/to/file")),
156 url_chain,
157 GURL(std::string()),
158 "application/octet-stream",
159 "application/octet-stream",
160 current,
161 current,
162 std::string(),
163 std::string(),
164 128,
165 128,
166 content::DownloadItem::COMPLETE,
167 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
168 content::DOWNLOAD_INTERRUPT_REASON_NONE,
169 false);
171 mock_handler_->ForceSendCurrentDownloads();
172 mock_handler_->WaitForDownloadsList();
173 ASSERT_EQ(1, static_cast<int>(mock_handler_->downloads_list()->GetSize()));
174 EXPECT_TRUE(ListMatches(
175 mock_handler_->downloads_list(),
176 "[{\"file_externally_removed\": false,"
177 " \"file_name\": \"file\","
178 " \"id\": \"1\","
179 " \"otr\": false,"
180 " \"since_string\": \"Today\","
181 " \"state\": \"COMPLETE\","
182 " \"total\": 128}]"));
185 protected:
186 scoped_ptr<MockDownloadsDOMHandler> mock_handler_;
188 private:
189 base::ScopedTempDir downloads_directory_;
191 DISALLOW_COPY_AND_ASSIGN(DownloadsDOMHandlerTest);
194 // Tests removing all items, both when prohibited and when allowed.
195 IN_PROC_BROWSER_TEST_F(DownloadsDOMHandlerTest, RemoveAll) {
196 DownloadAnItem();
198 mock_handler_->reset_downloads_list();
199 browser()->profile()->GetPrefs()->SetBoolean(
200 prefs::kAllowDeletingBrowserHistory, false);
201 mock_handler_->HandleClearAll(NULL);
202 // Attempting to clear all shouldn't do anything when deletion is disabled.
203 mock_handler_->ForceSendCurrentDownloads();
204 mock_handler_->WaitForDownloadsList();
205 ASSERT_EQ(1, static_cast<int>(mock_handler_->downloads_list()->GetSize()));
207 mock_handler_->reset_downloads_list();
208 browser()->profile()->GetPrefs()->SetBoolean(
209 prefs::kAllowDeletingBrowserHistory, true);
210 mock_handler_->HandleClearAll(NULL);
211 mock_handler_->WaitForDownloadsList();
212 EXPECT_EQ(0, static_cast<int>(mock_handler_->downloads_list()->GetSize()));
215 // Tests removing one item, both when prohibited and when allowed.
216 IN_PROC_BROWSER_TEST_F(DownloadsDOMHandlerTest, RemoveOneItem) {
217 DownloadAnItem();
218 base::ListValue item;
219 item.AppendString("1");
221 mock_handler_->reset_downloads_list();
222 browser()->profile()->GetPrefs()->SetBoolean(
223 prefs::kAllowDeletingBrowserHistory, false);
224 mock_handler_->HandleRemove(&item);
225 // Removing an item only sends the new download list if anything was actually
226 // removed, so force it.
227 mock_handler_->ForceSendCurrentDownloads();
228 mock_handler_->WaitForDownloadsList();
229 ASSERT_EQ(1, static_cast<int>(mock_handler_->downloads_list()->GetSize()));
231 mock_handler_->reset_downloads_list();
232 browser()->profile()->GetPrefs()->SetBoolean(
233 prefs::kAllowDeletingBrowserHistory, true);
234 mock_handler_->HandleRemove(&item);
235 mock_handler_->WaitForDownloadsList();
236 EXPECT_EQ(0, static_cast<int>(mock_handler_->downloads_list()->GetSize()));
239 IN_PROC_BROWSER_TEST_F(DownloadsDOMHandlerTest, ClearAllSkipsInProgress) {
240 content::MockDownloadManager manager;
241 mock_handler_->set_manager(&manager);
243 content::MockDownloadItem item;
244 EXPECT_CALL(item, GetState()).WillRepeatedly(
245 testing::Return(content::DownloadItem::IN_PROGRESS));
246 EXPECT_CALL(item, UpdateObservers()).Times(0);
248 std::vector<content::DownloadItem*> items;
249 items.push_back(&item);
250 EXPECT_CALL(manager, GetAllDownloads(testing::_)).WillOnce(
251 testing::SetArgPointee<0>(items));
253 mock_handler_->HandleClearAll(NULL);
254 EXPECT_TRUE(DownloadItemModel(&item).ShouldShowInShelf());
257 // Tests that DownloadsDOMHandler detects new downloads and relays them to the
258 // renderer.
259 // crbug.com/159390: This test fails when daylight savings time ends.
260 IN_PROC_BROWSER_TEST_F(DownloadsDOMHandlerTest, DownloadsRelayed) {
261 DownloadAnItem();
263 mock_handler_->WaitForDownloadUpdated();
264 const base::DictionaryValue* update = mock_handler_->download_updated();
265 ASSERT_TRUE(update);
267 bool removed;
268 ASSERT_TRUE(update->GetBoolean("file_externally_removed", &removed));
269 EXPECT_TRUE(removed);
271 std::string id;
272 ASSERT_TRUE(update->GetString("id", &id));
273 EXPECT_EQ("1", id);
275 mock_handler_->reset_downloads_list();
276 browser()->profile()->GetPrefs()->SetBoolean(
277 prefs::kAllowDeletingBrowserHistory, true);
278 mock_handler_->HandleClearAll(NULL);
279 mock_handler_->WaitForDownloadsList();
280 EXPECT_EQ(0, static_cast<int>(mock_handler_->downloads_list()->GetSize()));
283 // Tests that DownloadsDOMHandler actually calls DownloadItem::Remove() when
284 // it's closed (and removals can no longer be undone).
285 IN_PROC_BROWSER_TEST_F(DownloadsDOMHandlerTest, RemoveCalledOnPageClose) {
286 content::MockDownloadManager manager;
287 mock_handler_->set_manager(&manager);
289 content::MockDownloadItem item;
290 EXPECT_CALL(item, GetId()).WillRepeatedly(testing::Return(1));
291 EXPECT_CALL(item, GetState()).WillRepeatedly(
292 testing::Return(content::DownloadItem::COMPLETE));
294 DownloadItemModel model(&item);
295 EXPECT_TRUE(model.ShouldShowInShelf());
297 EXPECT_CALL(manager, GetDownload(1)).WillRepeatedly(testing::Return(&item));
299 base::ListValue remove;
300 remove.AppendString("1");
301 EXPECT_CALL(item, UpdateObservers()).Times(1);
302 mock_handler_->HandleRemove(&remove);
303 EXPECT_FALSE(model.ShouldShowInShelf());
305 EXPECT_CALL(item, Remove()).Times(1);
306 // Call |mock_handler_->FinalizeRemovals()| instead of |mock_handler_.reset()|
307 // because the vtable is affected during destruction and the fake manager
308 // rigging doesn't work.
309 mock_handler_->FinalizeRemovals();
312 // TODO(benjhayden): Test the extension downloads filter for both
313 // mock_handler_.downloads_list() and mock_handler_.download_updated().
315 // TODO(benjhayden): Test incognito, both downloads_list() and that on-record
316 // calls can't access off-record items.
318 // TODO(benjhayden): Test that bad download ids incoming from the javascript are
319 // dropped on the floor.
321 // TODO(benjhayden): Test that IsTemporary() downloads are not shown.
323 // TODO(benjhayden): Test that RemoveObserver is called on all download items,
324 // including items that crossed IsTemporary() and back.