blob: d605184b5afcb6c59e23465797c29d551d94db63 [file] [log] [blame]
rdsmitha43ecbb2015-06-12 02:21:451// Copyright 2015 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
avi655876a2015-12-25 07:18:155#include <stddef.h>
6
rdsmitha43ecbb2015-06-12 02:21:457#include "base/logging.h"
avi655876a2015-12-25 07:18:158#include "base/macros.h"
rdsmitha43ecbb2015-06-12 02:21:459#include "base/strings/stringprintf.h"
10#include "chrome/browser/download/chrome_download_manager_delegate.h"
11#include "chrome/browser/download/download_service.h"
12#include "chrome/browser/download/download_service_factory.h"
13#include "chrome/browser/profiles/profile_manager.h"
14#include "chrome/test/base/test_browser_window.h"
15#include "chrome/test/base/testing_browser_process.h"
16#include "chrome/test/base/testing_profile.h"
17#include "chrome/test/base/testing_profile_manager.h"
18#include "components/keyed_service/core/keyed_service.h"
19#include "content/public/browser/browser_context.h"
20#include "content/public/test/test_browser_thread_bundle.h"
brettw00899e62016-11-12 02:10:1721#include "extensions/features/features.h"
rdsmitha43ecbb2015-06-12 02:21:4522#include "testing/gtest/include/gtest/gtest.h"
23
rdsmith2e417d02015-06-15 18:18:3424class TestingDownloadService : public DownloadService {
rdsmitha43ecbb2015-06-12 02:21:4525 public:
rdsmith2e417d02015-06-15 18:18:3426 TestingDownloadService() : download_count_(0) {}
27 ~TestingDownloadService() override {}
rdsmitha43ecbb2015-06-12 02:21:4528
29 // All methods that aren't expected to be called in the execution of
30 // this unit test are marked to result in test failure. Using a simple
31 // mock for this class should be re-evaluated if any of these
32 // methods are being called; it may mean that a more fully featured
33 // DownloadService implementation is needed.
34
35 void SetDownloadCount(int download_count) {
36 download_count_ = download_count;
37 }
38
39 // DownloadService
40 ChromeDownloadManagerDelegate* GetDownloadManagerDelegate() override {
41 ADD_FAILURE();
42 return nullptr;
43 }
44
45 DownloadHistory* GetDownloadHistory() override {
46 ADD_FAILURE();
47 return nullptr;
48 }
49
brettw00899e62016-11-12 02:10:1750#if BUILDFLAG(ENABLE_EXTENSIONS)
rdsmitha43ecbb2015-06-12 02:21:4551 extensions::ExtensionDownloadsEventRouter* GetExtensionEventRouter()
52 override {
53 ADD_FAILURE();
54 return nullptr;
55 }
56#endif
57 bool HasCreatedDownloadManager() override { return true; }
58
59 int NonMaliciousDownloadCount() const override { return download_count_; }
60
61 void CancelDownloads() override {}
62
63 void SetDownloadManagerDelegateForTesting(
dcheng9603ab92016-04-08 04:17:3264 std::unique_ptr<ChromeDownloadManagerDelegate> delegate) override {
rdsmitha43ecbb2015-06-12 02:21:4565 ADD_FAILURE();
66 }
67
68 bool IsShelfEnabled() override {
69 return true;
70 }
71
72 // KeyedService
73 void Shutdown() override {}
74
75 private:
76 int download_count_;
77
rdsmith2e417d02015-06-15 18:18:3478 DISALLOW_COPY_AND_ASSIGN(TestingDownloadService);
rdsmitha43ecbb2015-06-12 02:21:4579};
80
dcheng9603ab92016-04-08 04:17:3281static std::unique_ptr<KeyedService> CreateTestingDownloadService(
rdsmitha43ecbb2015-06-12 02:21:4582 content::BrowserContext* browser_context) {
dcheng9603ab92016-04-08 04:17:3283 return std::unique_ptr<KeyedService>(new TestingDownloadService());
rdsmitha43ecbb2015-06-12 02:21:4584}
85
86class BrowserCloseTest : public testing::Test {
87 public:
88 BrowserCloseTest()
89 : profile_manager_(TestingBrowserProcess::GetGlobal()), name_index_(0) {}
90
91 ~BrowserCloseTest() override {}
92
93 void SetUp() override { ASSERT_TRUE(profile_manager_.SetUp()); }
94
95 void TearDown() override {
96 for (auto& browser_window_pair : browser_windows_) {
97 while (!browser_window_pair.second.empty()) {
98 TestBrowserWindow* window = browser_window_pair.second.back();
99 browser_window_pair.second.pop_back();
100 delete window;
101 }
102 }
103 for (auto& browser_pair : browsers_) {
104 while (!browser_pair.second.empty()) {
105 Browser* browser = browser_pair.second.back();
106 browser_pair.second.pop_back();
107 delete browser;
108 }
109 }
110 }
111
112 // Create a profile with the specified number of windows and downloads
113 // associated with it.
114 Profile* CreateProfile(int windows, int downloads) {
115 std::string name(base::StringPrintf("Profile_%d", ++name_index_));
116 TestingProfile* profile = profile_manager_.CreateTestingProfile(name);
117
118 ConfigureCreatedProfile(profile, windows, downloads);
119
120 return profile;
121 }
122
123 Profile* CreateIncognitoProfile(Profile* profile,
124 int windows,
125 int downloads) {
126 Profile* otr_profile = profile->GetOffTheRecordProfile();
127
128 ConfigureCreatedProfile(otr_profile, windows, downloads);
129
130 return otr_profile;
131 }
132
133 Browser* GetProfileBrowser(Profile* profile, int index) {
134 CHECK(browsers_.end() != browsers_.find(profile));
135 CHECK_GT(browsers_[profile].size(), static_cast<size_t>(index));
136
137 return browsers_[profile][index];
138 }
139
140 private:
141 void ConfigureCreatedProfile(Profile* profile,
142 int num_windows,
143 int num_downloads) {
144 DownloadServiceFactory::GetInstance()->SetTestingFactory(
rdsmith2e417d02015-06-15 18:18:34145 profile, &CreateTestingDownloadService);
rdsmitha43ecbb2015-06-12 02:21:45146 DownloadService* download_service(
147 DownloadServiceFactory::GetForBrowserContext(profile));
rdsmith2e417d02015-06-15 18:18:34148 TestingDownloadService* mock_download_service(
149 static_cast<TestingDownloadService*>(download_service));
rdsmitha43ecbb2015-06-12 02:21:45150 mock_download_service->SetDownloadCount(num_downloads);
151
152 CHECK(browser_windows_.end() == browser_windows_.find(profile));
153 CHECK(browsers_.end() == browsers_.find(profile));
154
155 std::vector<TestBrowserWindow*> windows;
156 std::vector<Browser*> browsers;
157 for (int i = 0; i < num_windows; ++i) {
158 TestBrowserWindow* window = new TestBrowserWindow();
scottmg851949002016-02-09 20:09:44159 Browser::CreateParams params(profile);
rdsmitha43ecbb2015-06-12 02:21:45160 params.type = Browser::TYPE_TABBED;
161 params.window = window;
162 Browser* browser = new Browser(params);
163
164 windows.push_back(window);
165 browsers.push_back(browser);
166 }
167
168 browser_windows_[profile] = windows;
169 browsers_[profile] = browsers;
170 }
171
172 // Note that the vector elements are all owned by this class and must be
173 // cleaned up.
174 std::map<Profile*, std::vector<TestBrowserWindow*>> browser_windows_;
175 std::map<Profile*, std::vector<Browser*>> browsers_;
176
177 content::TestBrowserThreadBundle thread_bundle_;
178 TestingProfileManager profile_manager_;
179 int name_index_;
180};
181
182// Last window close (incognito window) will trigger warning.
183TEST_F(BrowserCloseTest, LastWindowIncognito) {
184 Profile* profile = CreateProfile(0, 0);
185 Profile* incognito_profile = CreateIncognitoProfile(profile, 1, 1);
186 Browser* browser = GetProfileBrowser(incognito_profile, 0);
187
188 int num_downloads_blocking = 0;
189 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN,
190 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
191 EXPECT_EQ(num_downloads_blocking, 1);
192}
193
194// Last incognito window close triggers incognito warning.
195TEST_F(BrowserCloseTest, LastIncognito) {
196 Profile* profile = CreateProfile(1, 0);
197 Profile* incognito_profile = CreateIncognitoProfile(profile, 1, 1);
198 Browser* browser(GetProfileBrowser(incognito_profile, 0));
199
200 int num_downloads_blocking = 0;
201 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE,
202 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
203 EXPECT_EQ(num_downloads_blocking, 1);
204}
205
206// Last incognito window close with no downloads => no warning.
207TEST_F(BrowserCloseTest, LastIncognitoNoDownloads) {
208 Profile* profile = CreateProfile(0, 0);
209 Profile* incognito_profile = CreateIncognitoProfile(profile, 1, 0);
210 Browser* browser = GetProfileBrowser(incognito_profile, 0);
211
212 int num_downloads_blocking = 0;
213 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK,
214 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
215}
216
217// Last incognito window with window+download on another incognito profile
218// => no warning.
219TEST_F(BrowserCloseTest, NoIncognitoCrossChat) {
220 Profile* profile1 = CreateProfile(0, 0);
221 Profile* incognito_profile1 = CreateIncognitoProfile(profile1, 1, 0);
222 Profile* profile2 = CreateProfile(0, 0);
223 CreateIncognitoProfile(profile2, 1, 1);
224
225 Browser* browser = GetProfileBrowser(incognito_profile1, 0);
226
227 int num_downloads_blocking = 0;
228 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK,
229 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
230}
231
232// Non-last incognito window => no warning.
233TEST_F(BrowserCloseTest, NonLastIncognito) {
234 Profile* profile = CreateProfile(0, 0);
235 Profile* incognito_profile = CreateIncognitoProfile(profile, 2, 1);
236 Browser* browser = GetProfileBrowser(incognito_profile, 0);
237
238 int num_downloads_blocking = 0;
239 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK,
240 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
241}
242
243// Non-last regular window => no warning.
244TEST_F(BrowserCloseTest, NonLastRegular) {
245 Profile* profile = CreateProfile(2, 1);
246 Browser* browser = GetProfileBrowser(profile, 0);
247
248 int num_downloads_blocking = 0;
249 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK,
250 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
251}
252
253// Last regular window triggers browser close warning.
254TEST_F(BrowserCloseTest, LastRegular) {
255 Profile* profile = CreateProfile(1, 1);
256 Browser* browser = GetProfileBrowser(profile, 0);
257
258 int num_downloads_blocking = 0;
259 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN,
260 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
261 EXPECT_EQ(num_downloads_blocking, 1);
262}
263
264// Last regular window triggers browser close warning if download is on a
265// different profile.
266TEST_F(BrowserCloseTest, LastRegularDifferentProfile) {
267 Profile* profile1 = CreateProfile(1, 0);
268 CreateProfile(0, 1);
269
270 Browser* browser = GetProfileBrowser(profile1, 0);
271
272 int num_downloads_blocking = 0;
273 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN,
274 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
275 EXPECT_EQ(num_downloads_blocking, 1);
276}
277
278// Last regular + incognito window + download => no warning.
279TEST_F(BrowserCloseTest, LastRegularPlusIncognito) {
280 Profile* profile = CreateProfile(1, 0);
281 CreateIncognitoProfile(profile, 1, 1);
282
283 Browser* browser = GetProfileBrowser(profile, 0);
284
285 int num_downloads_blocking = 0;
286 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK,
287 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
288}
289
290// Last regular window + window on other profile => no warning.
291TEST_F(BrowserCloseTest, LastRegularPlusOtherProfile) {
292 Profile* profile = CreateProfile(1, 1);
293 CreateProfile(1, 0);
294
295 Browser* browser = GetProfileBrowser(profile, 0);
296
297 int num_downloads_blocking = 0;
298 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK,
299 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
300}
301
302// Last regular window + window on other incognito profile => no warning.
303TEST_F(BrowserCloseTest, LastRegularPlusOtherIncognito) {
304 Profile* profile1 = CreateProfile(1, 0);
305 Profile* profile2 = CreateProfile(0, 0);
306 CreateIncognitoProfile(profile2, 1, 1);
307
308 Browser* browser = GetProfileBrowser(profile1, 0);
309
310 int num_downloads_blocking = 0;
311 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK,
312 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
313}
314
315// Last regular + download + incognito window => no warning.
316TEST_F(BrowserCloseTest, LastRegularPlusIncognito2) {
317 Profile* profile = CreateProfile(1, 1);
318 CreateIncognitoProfile(profile, 1, 0);
319
320 Browser* browser = GetProfileBrowser(profile, 0);
321
322 int num_downloads_blocking = 0;
323 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_OK,
324 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
325}
326
327// Multiple downloads are recognized.
328TEST_F(BrowserCloseTest, Plural) {
329 Profile* profile = CreateProfile(1, 2);
330
331 Browser* browser = GetProfileBrowser(profile, 0);
332
333 int num_downloads_blocking = 0;
334 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_BROWSER_SHUTDOWN,
335 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
336 EXPECT_EQ(2, num_downloads_blocking);
337}
338
339// Multiple downloads are recognized for incognito.
340TEST_F(BrowserCloseTest, PluralIncognito) {
341 Profile* profile = CreateProfile(1, 0);
342 Profile* incognito_profile = CreateIncognitoProfile(profile, 1, 2);
343
344 Browser* browser = GetProfileBrowser(incognito_profile, 0);
345
346 int num_downloads_blocking = 0;
347 EXPECT_EQ(Browser::DOWNLOAD_CLOSE_LAST_WINDOW_IN_INCOGNITO_PROFILE,
348 browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
349 EXPECT_EQ(2, num_downloads_blocking);
350}