OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/browsing_data/clear_site_data_throttle.h" | 5 #include "content/browser/browsing_data/clear_site_data_throttle.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/strings/stringprintf.h" | |
13 #include "base/strings/utf_string_conversions.h" | |
14 #include "base/synchronization/waitable_event.h" | |
15 #include "content/browser/browsing_data/browsing_data_filter_builder_impl.h" | |
16 #include "content/browser/service_worker/service_worker_context_wrapper.h" | |
17 #include "content/public/browser/browser_context.h" | |
18 #include "content/public/browser/browsing_data_remover.h" | |
12 #include "content/public/browser/content_browser_client.h" | 19 #include "content/public/browser/content_browser_client.h" |
20 #include "content/public/browser/storage_partition.h" | |
13 #include "content/public/browser/web_contents.h" | 21 #include "content/public/browser/web_contents.h" |
14 #include "content/public/common/content_switches.h" | 22 #include "content/public/common/content_switches.h" |
23 #include "content/public/test/browser_test_utils.h" | |
24 #include "content/public/test/cache_test_util.h" | |
15 #include "content/public/test/content_browser_test.h" | 25 #include "content/public/test/content_browser_test.h" |
16 #include "content/public/test/content_browser_test_utils.h" | 26 #include "content/public/test/content_browser_test_utils.h" |
27 #include "content/public/test/mock_browsing_data_remover_delegate.h" | |
17 #include "content/public/test/test_navigation_observer.h" | 28 #include "content/public/test/test_navigation_observer.h" |
18 #include "content/shell/browser/shell.h" | 29 #include "content/shell/browser/shell.h" |
19 #include "net/base/escape.h" | 30 #include "net/base/escape.h" |
20 #include "net/base/url_util.h" | 31 #include "net/base/url_util.h" |
32 #include "net/cookies/cookie_store.h" | |
21 #include "net/dns/mock_host_resolver.h" | 33 #include "net/dns/mock_host_resolver.h" |
22 #include "net/test/embedded_test_server/http_request.h" | 34 #include "net/test/embedded_test_server/http_request.h" |
23 #include "net/test/embedded_test_server/http_response.h" | 35 #include "net/test/embedded_test_server/http_response.h" |
36 #include "net/url_request/url_request_context.h" | |
37 #include "net/url_request/url_request_context_getter.h" | |
24 #include "storage/browser/quota/quota_settings.h" | 38 #include "storage/browser/quota/quota_settings.h" |
25 #include "testing/gmock/include/gmock/gmock.h" | 39 #include "testing/gmock/include/gmock/gmock.h" |
26 #include "url/origin.h" | 40 #include "url/origin.h" |
27 #include "url/url_constants.h" | 41 #include "url/url_constants.h" |
28 | 42 |
29 using testing::_; | 43 using testing::_; |
30 | 44 |
31 namespace content { | 45 namespace content { |
32 | 46 |
33 namespace { | 47 namespace { |
34 | 48 |
35 class MockContentBrowserClient : public ContentBrowserClient { | |
36 public: | |
37 MOCK_METHOD6(ClearSiteData, | |
38 void(content::BrowserContext* browser_context, | |
39 const url::Origin& origin, | |
40 bool remove_cookies, | |
41 bool remove_storage, | |
42 bool remove_cache, | |
43 const base::Closure& callback)); | |
44 | |
45 void GetQuotaSettings( | |
46 content::BrowserContext* context, | |
47 content::StoragePartition* partition, | |
48 const storage::OptionalQuotaSettingsCallback& callback) override { | |
49 callback.Run(storage::GetHardCodedSettings(100 * 1024 * 1024)); | |
50 } | |
51 }; | |
52 | |
53 class TestContentBrowserClient : public MockContentBrowserClient { | |
54 public: | |
55 void ClearSiteData(content::BrowserContext* browser_context, | |
56 const url::Origin& origin, | |
57 bool remove_cookies, | |
58 bool remove_storage, | |
59 bool remove_cache, | |
60 const base::Closure& callback) override { | |
61 // Record the method call and run the |callback|. | |
62 MockContentBrowserClient::ClearSiteData(browser_context, origin, | |
63 remove_cookies, remove_storage, | |
64 remove_cache, callback); | |
65 callback.Run(); | |
66 } | |
67 }; | |
68 | |
69 // Adds a key=value pair to the url's query. | 49 // Adds a key=value pair to the url's query. |
70 void AddQuery(GURL* url, const std::string& key, const std::string& value) { | 50 void AddQuery(GURL* url, const std::string& key, const std::string& value) { |
71 *url = GURL(url->spec() + (url->has_query() ? "&" : "?") + key + "=" + | 51 *url = GURL(url->spec() + (url->has_query() ? "&" : "?") + key + "=" + |
72 net::EscapeQueryParamValue(value, false)); | 52 net::EscapeQueryParamValue(value, false)); |
73 } | 53 } |
74 | 54 |
55 // A helper function to synchronize with JS side of the tests. JS can append | |
56 // information to the loaded website's title and C++ will wait until that | |
57 // happens. | |
58 void WaitForTitle(const Shell* shell, const char* expected_title) { | |
59 base::string16 expected_title_16 = base::ASCIIToUTF16(expected_title); | |
60 TitleWatcher title_watcher(shell->web_contents(), expected_title_16); | |
61 ASSERT_EQ(expected_title_16, title_watcher.WaitAndGetTitle()); | |
mmenke
2017/05/25 19:23:09
I don't think we want to depend on the implementat
msramek
2017/05/30 21:58:45
Sorry, I don't understand. TitleWatcher constructo
mmenke
2017/05/30 22:58:35
TitleWatcher starts watching, which is rather impo
msramek
2017/06/01 22:02:27
Acknowledged. That's true, but indeed isn't the ca
| |
62 } | |
63 | |
75 // A value of the Clear-Site-Data header that requests cookie deletion. Reused | 64 // A value of the Clear-Site-Data header that requests cookie deletion. Reused |
76 // in tests that need a valid header but do not depend on its value. | 65 // in tests that need a valid header but do not depend on its value. |
77 static const char* kClearCookiesHeader = "{ \"types\": [ \"cookies\" ] }"; | 66 static const char* kClearCookiesHeader = "{ \"types\": [ \"cookies\" ] }"; |
78 | 67 |
68 // A helper class to observe BrowsingDataRemover deletion tasks coming from | |
69 // ClearSiteData. | |
70 class TestBrowsingDataRemoverDelegate : public MockBrowsingDataRemoverDelegate { | |
71 public: | |
72 // Sets a test expectation that a Clear-Site-Data header call from |origin|, | |
73 // instructing to delete |cookies|, |storage|, and |cache|, will schedule | |
74 // the corresponding BrowsingDataRemover deletion tasks. | |
75 void ExpectClearSiteDataCall(const url::Origin& origin, | |
76 bool cookies, | |
77 bool storage, | |
78 bool cache) { | |
79 const int origin_type_mask = | |
mmenke
2017/05/25 19:23:09
kOriginTypeMatch
msramek
2017/05/30 21:58:45
Done.
| |
80 BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB | | |
81 BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB; | |
82 | |
83 if (cookies) { | |
84 int data_type_mask = BrowsingDataRemover::DATA_TYPE_COOKIES | | |
85 BrowsingDataRemover::DATA_TYPE_CHANNEL_IDS; | |
86 | |
87 BrowsingDataFilterBuilderImpl filter_builder( | |
88 BrowsingDataFilterBuilder::WHITELIST); | |
89 filter_builder.AddRegisterableDomain(origin.host()); | |
90 ExpectCall(base::Time(), base::Time::Max(), data_type_mask, | |
91 origin_type_mask, std::move(filter_builder)); | |
92 } | |
93 if (storage || cache) { | |
94 int data_type_mask = | |
95 (storage ? BrowsingDataRemover::DATA_TYPE_DOM_STORAGE : 0) | | |
96 (cache ? BrowsingDataRemover::DATA_TYPE_CACHE : 0); | |
97 | |
98 BrowsingDataFilterBuilderImpl filter_builder( | |
99 BrowsingDataFilterBuilder::WHITELIST); | |
100 filter_builder.AddOrigin(origin); | |
101 ExpectCall(base::Time(), base::Time::Max(), data_type_mask, | |
102 origin_type_mask, std::move(filter_builder)); | |
103 } | |
104 } | |
105 | |
106 // A shortcut for the above method, but with only cookies deleted. This is | |
107 // useful for most tests that use |kClearCookiesHeader|. | |
108 void ExpectClearSiteDataCookiesCall(const url::Origin& origin) { | |
109 ExpectClearSiteDataCall(origin, true, false, false); | |
110 } | |
111 }; | |
112 | |
79 } // namespace | 113 } // namespace |
80 | 114 |
81 class ClearSiteDataThrottleBrowserTest : public ContentBrowserTest { | 115 class ClearSiteDataThrottleBrowserTest : public ContentBrowserTest { |
82 public: | 116 public: |
83 void SetUpCommandLine(base::CommandLine* command_line) override { | 117 void SetUpCommandLine(base::CommandLine* command_line) override { |
84 ContentBrowserTest::SetUpCommandLine(command_line); | 118 ContentBrowserTest::SetUpCommandLine(command_line); |
85 command_line->AppendSwitch( | 119 command_line->AppendSwitch( |
86 switches::kEnableExperimentalWebPlatformFeatures); | 120 switches::kEnableExperimentalWebPlatformFeatures); |
87 | 121 |
88 // We're redirecting all hosts to localhost even on HTTPS, so we'll get | 122 // We're redirecting all hosts to localhost even on HTTPS, so we'll get |
89 // certificate errors. | 123 // certificate errors. |
90 command_line->AppendSwitch(switches::kIgnoreCertificateErrors); | 124 command_line->AppendSwitch(switches::kIgnoreCertificateErrors); |
91 } | 125 } |
92 | 126 |
93 void SetUpOnMainThread() override { | 127 void SetUpOnMainThread() override { |
94 ContentBrowserTest::SetUpOnMainThread(); | 128 ContentBrowserTest::SetUpOnMainThread(); |
95 | 129 |
96 SetBrowserClientForTesting(&test_client_); | 130 BrowserContext::GetBrowsingDataRemover(browser_context()) |
131 ->SetEmbedderDelegate(&embedder_delegate_); | |
97 | 132 |
98 // Set up HTTP and HTTPS test servers that handle all hosts. | 133 // Set up HTTP and HTTPS test servers that handle all hosts. |
99 host_resolver()->AddRule("*", "127.0.0.1"); | 134 host_resolver()->AddRule("*", "127.0.0.1"); |
100 | 135 |
101 embedded_test_server()->RegisterRequestHandler( | 136 embedded_test_server()->RegisterRequestHandler( |
102 base::Bind(&ClearSiteDataThrottleBrowserTest::HandleRequest, | 137 base::Bind(&ClearSiteDataThrottleBrowserTest::HandleRequest, |
103 base::Unretained(this))); | 138 base::Unretained(this))); |
104 ASSERT_TRUE(embedded_test_server()->Start()); | 139 ASSERT_TRUE(embedded_test_server()->Start()); |
105 | 140 |
106 https_server_.reset(new net::EmbeddedTestServer( | 141 https_server_.reset(new net::EmbeddedTestServer( |
107 net::test_server::EmbeddedTestServer::TYPE_HTTPS)); | 142 net::test_server::EmbeddedTestServer::TYPE_HTTPS)); |
108 https_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_OK); | 143 https_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_OK); |
109 https_server_->RegisterRequestHandler( | 144 https_server_->RegisterRequestHandler( |
110 base::Bind(&ClearSiteDataThrottleBrowserTest::HandleRequest, | 145 base::Bind(&ClearSiteDataThrottleBrowserTest::HandleRequest, |
111 base::Unretained(this))); | 146 base::Unretained(this))); |
112 ASSERT_TRUE(https_server_->Start()); | 147 ASSERT_TRUE(https_server_->Start()); |
148 | |
149 // Initialize the cookie store pointer on the IO thread. | |
150 base::WaitableEvent waitable_event( | |
151 base::WaitableEvent::ResetPolicy::MANUAL, | |
152 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
153 BrowserThread::PostTask( | |
154 BrowserThread::IO, FROM_HERE, | |
155 base::BindOnce( | |
156 &ClearSiteDataThrottleBrowserTest::InitializeCookieStore, | |
157 base::Unretained(this), | |
158 base::Unretained( | |
159 BrowserContext::GetDefaultStoragePartition(browser_context()) | |
160 ->GetURLRequestContext()), | |
161 base::Unretained(&waitable_event))); | |
162 waitable_event.Wait(); | |
mmenke
2017/05/25 19:23:10
optional: I think RunLoops are a lot more common
msramek
2017/05/30 21:58:45
Done. (Changed to RunLoops)
| |
113 } | 163 } |
114 | 164 |
115 TestContentBrowserClient* GetContentBrowserClient() { return &test_client_; } | 165 BrowserContext* browser_context() { |
166 return shell()->web_contents()->GetBrowserContext(); | |
167 } | |
168 | |
169 void InitializeCookieStore( | |
mmenke
2017/05/25 19:23:10
Why is this needed? Can't AddCookie/GetCookie tak
msramek
2017/05/30 21:58:45
We need to do two things on the IO thread:
1. Call
| |
170 net::URLRequestContextGetter* request_context_getter, | |
171 base::WaitableEvent* waitable_event) { | |
172 cookie_store_ = | |
173 request_context_getter->GetURLRequestContext()->cookie_store(); | |
174 waitable_event->Signal(); | |
175 } | |
176 | |
177 // Adds a cookie for the |url|. Used in the cookie integration tests. | |
178 void AddCookie(const GURL& url) { | |
179 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
180 base::WaitableEvent waitable_event( | |
181 base::WaitableEvent::ResetPolicy::MANUAL, | |
182 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
183 BrowserThread::PostTask( | |
184 BrowserThread::IO, FROM_HERE, | |
185 base::BindOnce( | |
186 &net::CookieStore::SetCookieWithOptionsAsync, | |
187 base::Unretained(cookie_store_), url, "A=1", net::CookieOptions(), | |
188 base::Bind(&ClearSiteDataThrottleBrowserTest::AddCookieCallback, | |
189 base::Unretained(this), | |
190 base::Unretained(&waitable_event)))); | |
191 waitable_event.Wait(); | |
192 } | |
193 | |
194 // Retrieves the list of all cookies. Used in the cookie integration tests. | |
195 net::CookieList GetCookies() { | |
196 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
197 base::WaitableEvent waitable_event( | |
198 base::WaitableEvent::ResetPolicy::MANUAL, | |
199 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
200 net::CookieList cookie_list; | |
201 BrowserThread::PostTask( | |
202 BrowserThread::IO, FROM_HERE, | |
203 base::BindOnce( | |
204 &net::CookieStore::GetAllCookiesAsync, | |
205 base::Unretained(cookie_store_), | |
206 base::Bind(&ClearSiteDataThrottleBrowserTest::GetCookiesCallback, | |
207 base::Unretained(this), | |
208 base::Unretained(&waitable_event), | |
209 base::Unretained(&cookie_list)))); | |
210 waitable_event.Wait(); | |
211 return cookie_list; | |
212 } | |
213 | |
214 // Adds a service worker. Used in the storage integration tests. | |
215 void AddServiceWorker(const std::string& origin) { | |
216 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
217 ServiceWorkerContextWrapper* service_worker_context = | |
218 static_cast<ServiceWorkerContextWrapper*>( | |
219 BrowserContext::GetDefaultStoragePartition(browser_context()) | |
220 ->GetServiceWorkerContext()); | |
221 | |
222 GURL html_url = https_server()->GetURL(origin, "/worker_setup.html"); | |
223 GURL js_url = https_server()->GetURL(origin, "/?file=worker.js"); | |
224 base::RunLoop run_loop; | |
225 | |
226 BrowserThread::PostTask( | |
227 BrowserThread::IO, FROM_HERE, | |
228 base::BindOnce( | |
229 &ServiceWorkerContextWrapper::RegisterServiceWorker, | |
230 base::Unretained(service_worker_context), html_url, js_url, | |
231 base::Bind( | |
232 &ClearSiteDataThrottleBrowserTest::AddServiceWorkerCallback, | |
233 base::Unretained(this), base::Unretained(&run_loop)))); | |
234 run_loop.Run(); | |
235 } | |
236 | |
237 // Retrieves the list of all service workers. Used in the storage integration | |
238 // tests. | |
239 std::vector<ServiceWorkerUsageInfo> GetServiceWorkers() { | |
240 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
241 ServiceWorkerContextWrapper* service_worker_context = | |
242 static_cast<ServiceWorkerContextWrapper*>( | |
243 BrowserContext::GetDefaultStoragePartition(browser_context()) | |
244 ->GetServiceWorkerContext()); | |
245 | |
246 std::vector<ServiceWorkerUsageInfo> service_workers; | |
247 base::WaitableEvent waitable_event( | |
248 base::WaitableEvent::ResetPolicy::MANUAL, | |
249 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
250 | |
251 BrowserThread::PostTask( | |
252 BrowserThread::IO, FROM_HERE, | |
253 base::BindOnce( | |
254 &ServiceWorkerContextWrapper::GetAllOriginsInfo, | |
255 base::Unretained(service_worker_context), | |
256 base::Bind( | |
257 &ClearSiteDataThrottleBrowserTest::GetServiceWorkersCallback, | |
258 base::Unretained(this), base::Unretained(&waitable_event), | |
259 base::Unretained(&service_workers)))); | |
260 waitable_event.Wait(); | |
261 | |
262 return service_workers; | |
263 } | |
264 | |
265 TestBrowsingDataRemoverDelegate* delegate() { return &embedder_delegate_; } | |
116 | 266 |
117 net::EmbeddedTestServer* https_server() { return https_server_.get(); } | 267 net::EmbeddedTestServer* https_server() { return https_server_.get(); } |
118 | 268 |
119 private: | 269 private: |
120 // Handles all requests. If the request url query contains a "header" key, | 270 // Handles all requests. |
121 // responds with the "Clear-Site-Data" header of the corresponding value. | 271 // |
122 // If the query contains a "redirect" key, responds with a redirect to a url | 272 // Supports the following <key>=<value> query parameters in the url: |
123 // given by the corresponding value. | 273 // <key>="header" responds with the header "Clear-Site-Data: <value>" |
274 // <key>="redirect" responds with a redirect to the url <value> | |
275 // <key>="html" responds with a text/html content <value> | |
276 // <key>="file" responds with the content of file <value> | |
124 // | 277 // |
125 // Example: "https://localhost/?header={}&redirect=example.com" will respond | 278 // Example: "https://localhost/?header={}&redirect=example.com" will respond |
126 // with headers | 279 // with headers |
127 // Clear-Site-Data: {} | 280 // Clear-Site-Data: {} |
128 // Location: example.com | 281 // Location: example.com |
282 // | |
283 // Example: "https://localhost/?html=<html><head></head><body></body></html>" | |
284 // will respond with the header | |
285 // Content-Type: text/html | |
286 // and content | |
287 // <html><head></head><body></body></html> | |
288 // | |
289 // Example: "https://localhost/?file=file.html | |
mmenke
2017/05/25 19:23:10
+"
msramek
2017/05/30 21:58:45
Done.
| |
290 // will respond with the header | |
291 // Content-Type: text/html | |
292 // and content from the file content/test/data/file.html | |
129 std::unique_ptr<net::test_server::HttpResponse> HandleRequest( | 293 std::unique_ptr<net::test_server::HttpResponse> HandleRequest( |
130 const net::test_server::HttpRequest& request) { | 294 const net::test_server::HttpRequest& request) { |
131 std::unique_ptr<net::test_server::BasicHttpResponse> response( | 295 std::unique_ptr<net::test_server::BasicHttpResponse> response( |
132 new net::test_server::BasicHttpResponse()); | 296 new net::test_server::BasicHttpResponse()); |
133 | 297 |
134 std::string value; | 298 std::string value; |
135 if (net::GetValueForKeyInQuery(request.GetURL(), "header", &value)) | 299 if (net::GetValueForKeyInQuery(request.GetURL(), "header", &value)) |
136 response->AddCustomHeader("Clear-Site-Data", value); | 300 response->AddCustomHeader("Clear-Site-Data", value); |
137 | 301 |
138 if (net::GetValueForKeyInQuery(request.GetURL(), "redirect", &value)) { | 302 if (net::GetValueForKeyInQuery(request.GetURL(), "redirect", &value)) { |
139 response->set_code(net::HTTP_FOUND); | 303 response->set_code(net::HTTP_FOUND); |
140 response->AddCustomHeader("Location", value); | 304 response->AddCustomHeader("Location", value); |
141 } else { | 305 } else { |
142 response->set_code(net::HTTP_OK); | 306 response->set_code(net::HTTP_OK); |
143 } | 307 } |
144 | 308 |
309 if (net::GetValueForKeyInQuery(request.GetURL(), "html", &value)) { | |
310 response->set_content_type("text/html"); | |
311 response->set_content(value); | |
312 | |
313 // The "html" parameter is telling the server what to serve, and the XSS | |
314 // auditor will complain if its |value| contains JS code. Disable that | |
315 // protection. | |
316 response->AddCustomHeader("X-XSS-Protection", "0"); | |
317 } | |
318 | |
319 if (net::GetValueForKeyInQuery(request.GetURL(), "file", &value)) { | |
320 base::FilePath path(GetTestFilePath("browsing_data", value.c_str())); | |
321 base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); | |
322 EXPECT_TRUE(file.IsValid()); | |
323 int64_t length = file.GetLength(); | |
324 EXPECT_GE(length, 0); | |
325 std::unique_ptr<char[]> buffer(new char[length + 1]); | |
326 file.Read(0, buffer.get(), length); | |
327 buffer[length] = '\0'; | |
328 | |
329 if (path.Extension() == FILE_PATH_LITERAL(".js")) | |
330 response->set_content_type("application/javascript"); | |
331 else if (path.Extension() == FILE_PATH_LITERAL(".html")) | |
332 response->set_content_type("text/html"); | |
333 else | |
334 NOTREACHED(); | |
335 | |
336 response->set_content(buffer.get()); | |
337 } | |
338 | |
145 return std::move(response); | 339 return std::move(response); |
146 } | 340 } |
147 | 341 |
148 TestContentBrowserClient test_client_; | 342 // Callback handler for AddCookie(). |
343 void AddCookieCallback(base::WaitableEvent* waitable_event, bool success) { | |
mmenke
2017/05/25 19:23:10
static?
msramek
2017/05/30 21:58:45
Done.
| |
344 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
345 ASSERT_TRUE(success); | |
346 waitable_event->Signal(); | |
347 } | |
348 | |
349 // Callback handler for GetCookies(). | |
350 void GetCookiesCallback(base::WaitableEvent* waitable_event, | |
mmenke
2017/05/25 19:23:09
static?
msramek
2017/05/30 21:58:45
Done.
| |
351 net::CookieList* out_cookie_list, | |
352 const net::CookieList& cookie_list) { | |
353 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
354 *out_cookie_list = cookie_list; | |
355 waitable_event->Signal(); | |
356 } | |
357 | |
358 // Callback handler for AddServiceWorker(). | |
359 void AddServiceWorkerCallback(base::RunLoop* run_loop, bool success) { | |
360 ASSERT_TRUE(success); | |
361 run_loop->Quit(); | |
362 } | |
363 | |
364 // Callback handler for GetServiceWorkers(). | |
365 void GetServiceWorkersCallback( | |
366 base::WaitableEvent* waitable_event, | |
367 std::vector<ServiceWorkerUsageInfo>* out_service_workers, | |
368 const std::vector<ServiceWorkerUsageInfo>& service_workers) { | |
369 *out_service_workers = service_workers; | |
370 waitable_event->Signal(); | |
371 } | |
372 | |
149 std::unique_ptr<net::EmbeddedTestServer> https_server_; | 373 std::unique_ptr<net::EmbeddedTestServer> https_server_; |
374 TestBrowsingDataRemoverDelegate embedder_delegate_; | |
375 | |
376 net::CookieStore* cookie_store_; | |
150 }; | 377 }; |
151 | 378 |
152 // Tests that the header is recognized on the beginning, in the middle, and on | 379 // Tests that the header is recognized on the beginning, in the middle, and on |
153 // the end of a redirect chain. Each of the three parts of the chain may or | 380 // the end of a navigation redirect chain. Each of the three parts of the chain |
154 // may not send the header, so there are 8 configurations to test. | 381 // may or may not send the header, so there are 8 configurations to test. |
155 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, Redirect) { | 382 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, RedirectNavigation) { |
156 GURL base_urls[3] = { | 383 GURL base_urls[3] = { |
157 https_server()->GetURL("origin1.com", "/"), | 384 https_server()->GetURL("origin1.com", "/"), |
158 https_server()->GetURL("origin2.com", "/foo/bar"), | 385 https_server()->GetURL("origin2.com", "/foo/bar"), |
159 https_server()->GetURL("origin3.com", "/index.html"), | 386 https_server()->GetURL("origin3.com", "/index.html"), |
160 }; | 387 }; |
161 | 388 |
162 // Iterate through the configurations. URLs whose index is matched by the mask | 389 // Iterate through the configurations. URLs whose index is matched by the mask |
163 // will send the header, the others won't. | 390 // will send the header, the others won't. |
164 for (int mask = 0; mask < (1 << 3); ++mask) { | 391 for (int mask = 0; mask < (1 << 3); ++mask) { |
165 GURL urls[3]; | 392 GURL urls[3]; |
166 | 393 |
167 // Set up the expectations. | 394 // Set up the expectations. |
168 for (int i = 0; i < 3; ++i) { | 395 for (int i = 0; i < 3; ++i) { |
169 urls[i] = base_urls[i]; | 396 urls[i] = base_urls[i]; |
170 if (mask & (1 << i)) | 397 if (mask & (1 << i)) |
171 AddQuery(&urls[i], "header", kClearCookiesHeader); | 398 AddQuery(&urls[i], "header", kClearCookiesHeader); |
172 | 399 |
173 EXPECT_CALL(*GetContentBrowserClient(), | 400 if (mask & (1 << i)) |
174 ClearSiteData(shell()->web_contents()->GetBrowserContext(), | 401 delegate()->ExpectClearSiteDataCookiesCall(url::Origin(urls[i])); |
175 url::Origin(urls[i]), _, _, _, _)) | |
176 .Times((mask & (1 << i)) ? 1 : 0); | |
177 } | 402 } |
178 | 403 |
179 // Set up redirects between urls 0 --> 1 --> 2. | 404 // Set up redirects between urls 0 --> 1 --> 2. |
180 AddQuery(&urls[1], "redirect", urls[2].spec()); | 405 AddQuery(&urls[1], "redirect", urls[2].spec()); |
181 AddQuery(&urls[0], "redirect", urls[1].spec()); | 406 AddQuery(&urls[0], "redirect", urls[1].spec()); |
182 | 407 |
183 // Navigate to the first url of the redirect chain. | 408 // Navigate to the first url of the redirect chain. |
184 NavigateToURL(shell(), urls[0]); | 409 NavigateToURL(shell(), urls[0]); |
185 | 410 |
186 // We reached the end of the redirect chain. | 411 // We reached the end of the redirect chain. |
187 EXPECT_EQ(urls[2], shell()->web_contents()->GetURL()); | 412 EXPECT_EQ(urls[2], shell()->web_contents()->GetURL()); |
188 | 413 |
189 testing::Mock::VerifyAndClearExpectations(GetContentBrowserClient()); | 414 delegate()->VerifyAndClearExpectations(); |
190 } | 415 } |
191 } | 416 } |
192 | 417 |
418 // Tests that the header is recognized on the beginning, in the middle, and on | |
419 // the end of a resource load redirect chain. Each of the three parts of the | |
420 // chain may or may not send the header, so there are 8 configurations to test. | |
421 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, RedirectResourceLoad) { | |
422 GURL base_urls[3] = { | |
mmenke
2017/05/25 19:23:09
These don't mean the same thing as https_server()-
msramek
2017/05/30 21:58:45
I added the paths here partially to document the m
| |
423 https_server()->GetURL("origin1.com", "/image.png"), | |
424 https_server()->GetURL("origin2.com", "/redirected-image.png"), | |
425 https_server()->GetURL("origin3.com", "/actual-image.png"), | |
mmenke
2017/05/25 19:23:09
Worth noting that actual-image actually just ends
msramek
2017/05/30 21:58:45
As mentioned in the above comment, I renamed the p
| |
426 }; | |
427 | |
428 // Iterate through the configurations. URLs whose index is matched by the mask | |
429 // will send the header, the others won't. | |
430 for (int mask = 0; mask < (1 << 3); ++mask) { | |
431 GURL urls[3]; | |
432 | |
433 // Set up the expectations. | |
434 for (int i = 0; i < 3; ++i) { | |
435 urls[i] = base_urls[i]; | |
436 if (mask & (1 << i)) | |
437 AddQuery(&urls[i], "header", kClearCookiesHeader); | |
438 | |
439 if (mask & (1 << i)) | |
440 delegate()->ExpectClearSiteDataCookiesCall(url::Origin(urls[i])); | |
441 } | |
442 | |
443 // Set up redirects between urls 0 --> 1 --> 2. | |
444 AddQuery(&urls[1], "redirect", urls[2].spec()); | |
445 AddQuery(&urls[0], "redirect", urls[1].spec()); | |
446 | |
447 // Navigate to a page that embeds "https://origin1.com/image.png" | |
448 // and observe the loading of that resource. | |
449 GURL page_with_image = https_server()->GetURL("origin4.com", "/index.html"); | |
450 std::string content_with_image = | |
451 "<html><head></head><body>" | |
452 "<img src=\"" + | |
453 urls[0].spec() + | |
454 "\" />" | |
455 "</body></html>"; | |
456 AddQuery(&page_with_image, "html", content_with_image); | |
457 NavigateToURL(shell(), page_with_image); | |
458 | |
459 delegate()->VerifyAndClearExpectations(); | |
460 } | |
461 } | |
462 | |
193 // Tests that the Clear-Site-Data header is ignored for insecure origins. | 463 // Tests that the Clear-Site-Data header is ignored for insecure origins. |
194 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, Insecure) { | 464 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, InsecureNavigation) { |
195 // ClearSiteData() should not be called on HTTP. | 465 // ClearSiteData() should not be called on HTTP. |
196 GURL url = embedded_test_server()->GetURL("example.com", "/"); | 466 GURL url = embedded_test_server()->GetURL("example.com", "/"); |
197 AddQuery(&url, "header", kClearCookiesHeader); | 467 AddQuery(&url, "header", kClearCookiesHeader); |
198 ASSERT_FALSE(url.SchemeIsCryptographic()); | 468 ASSERT_FALSE(url.SchemeIsCryptographic()); |
199 | 469 |
200 EXPECT_CALL(*GetContentBrowserClient(), ClearSiteData(_, _, _, _, _, _)) | |
201 .Times(0); | |
202 | |
203 NavigateToURL(shell(), url); | 470 NavigateToURL(shell(), url); |
471 | |
472 // We do not expect any calls to have been made. | |
473 delegate()->VerifyAndClearExpectations(); | |
474 } | |
475 | |
476 // Tests that the Clear-Site-Data header is honored for secure resource loads | |
477 // and ignored for insecure ones. | |
mmenke
2017/05/25 19:23:10
This doesn't check the header is ignored for insec
msramek
2017/05/30 21:58:45
It does? This test tries all four combinations - i
mmenke
2017/05/30 22:58:35
Hrm...not sure what I was thinking. I'll take ano
| |
478 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, | |
479 SecureAndInsecureResourceLoad) { | |
480 GURL insecure_image = | |
481 embedded_test_server()->GetURL("example.com", "/image.png"); | |
482 GURL secure_image = https_server()->GetURL("example.com", "/image.png"); | |
483 | |
484 ASSERT_TRUE(secure_image.SchemeIsCryptographic()); | |
485 ASSERT_FALSE(insecure_image.SchemeIsCryptographic()); | |
486 | |
487 AddQuery(&secure_image, "header", kClearCookiesHeader); | |
488 AddQuery(&insecure_image, "header", kClearCookiesHeader); | |
489 | |
490 std::string content_with_insecure_image = | |
491 "<html><head></head><body>" | |
492 "<img src=\"" + | |
493 insecure_image.spec() + | |
494 "\" />" | |
495 "</body></html>"; | |
496 | |
497 std::string content_with_secure_image = | |
498 "<html><head></head><body>" | |
499 "<img src=\"" + | |
500 secure_image.spec() + | |
501 "\" />" | |
502 "</body></html>"; | |
503 | |
504 // Test insecure resources. | |
505 GURL insecure_page = embedded_test_server()->GetURL("example.com", "/"); | |
506 GURL secure_page = https_server()->GetURL("example.com", "/"); | |
507 | |
508 AddQuery(&insecure_page, "html", content_with_insecure_image); | |
509 AddQuery(&secure_page, "html", content_with_insecure_image); | |
510 | |
511 // Insecure resource on an insecure page does not execute Clear-Site-Data. | |
512 NavigateToURL(shell(), insecure_page); | |
513 | |
514 // Insecure resource on a secure page does not execute Clear-Site-Data. | |
515 NavigateToURL(shell(), secure_page); | |
516 | |
517 // We do not expect any calls to have been made. | |
518 delegate()->VerifyAndClearExpectations(); | |
519 | |
520 // Test secure resources. | |
521 insecure_page = embedded_test_server()->GetURL("example.com", "/"); | |
522 secure_page = https_server()->GetURL("example.com", "/"); | |
523 | |
524 AddQuery(&insecure_page, "html", content_with_secure_image); | |
525 AddQuery(&secure_page, "html", content_with_secure_image); | |
526 | |
527 // Secure resource on an insecure page does execute Clear-Site-Data. | |
528 delegate()->ExpectClearSiteDataCookiesCall(url::Origin(secure_image)); | |
529 | |
530 NavigateToURL(shell(), secure_page); | |
531 delegate()->VerifyAndClearExpectations(); | |
532 | |
533 // Secure resource on a secure page does execute Clear-Site-Data. | |
534 delegate()->ExpectClearSiteDataCookiesCall(url::Origin(secure_image)); | |
535 | |
536 NavigateToURL(shell(), secure_page); | |
537 delegate()->VerifyAndClearExpectations(); | |
538 } | |
539 | |
540 // Tests that the Clear-Site-Data header is ignored for service worker resource | |
541 // loads. | |
542 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, ServiceWorker) { | |
543 GURL origin1 = https_server()->GetURL("origin1.com", "/"); | |
544 GURL origin2 = https_server()->GetURL("origin2.com", "/"); | |
545 GURL origin3 = https_server()->GetURL("origin3.com", "/"); | |
546 GURL origin4 = https_server()->GetURL("origin4.com", "/"); | |
547 | |
548 // Navigation to worker_setup.html will install a service worker. Since | |
549 // the installation is asynchronous, the JS side will inform us about it in | |
550 // the page title. | |
551 GURL url = origin1; | |
552 AddQuery(&url, "file", "worker_setup.html"); | |
553 NavigateToURL(shell(), url); | |
554 WaitForTitle(shell(), "service worker is ready"); | |
555 | |
556 // The service worker will now serve a page containing several images, which | |
557 // the browser will try to fetch. The service worker will be instructed | |
558 // to handle some of the fetches itself, while others will be handled by | |
559 // the testing server. The setup is the following: | |
560 // | |
561 // origin1.com/resource (-> server; should respect header) | |
562 // origin1.com/resource_from_sw (-> service worker; should not respect header) | |
563 // origin2.com/resource_from_sw (-> service worker; should not respect header) | |
564 // origin2.com/resource (-> server; should respect header) | |
565 // origin3.com/resource_from_sw (-> service worker; should not respect header) | |
566 // origin3.com/resource_from_sw (-> service worker; should not respect header) | |
567 // origin4.com/resource (-> server; should respect header) | |
568 // origin4.com/resource (-> server; should respect header) | |
mmenke
2017/05/25 19:23:09
Out of paranoia, and since we check ordering, woul
msramek
2017/05/30 21:58:44
Done. That's fine, I like paranoid tests :)
Inter
mmenke
2017/05/31 16:25:33
I didn't realize it wasn't fetching sequentially..
| |
569 // | |
570 // |origin1| and |origin2| are used to test that there is no difference | |
571 // between same-origin and third-party fetches. Clear-Site-Data should be | |
572 // called once for each of these origins - caused by the "/resource" fetch, | |
573 // but not by the "/resource_from_sw" fetch. |origin3| and |origin4| prove | |
574 // that the number of calls is dependent on the number of network responses, | |
575 // i.e. that it isn't always 1 as in the case of |origin1| and |origin2|. | |
576 delegate()->ExpectClearSiteDataCookiesCall(url::Origin(origin1)); | |
577 delegate()->ExpectClearSiteDataCookiesCall(url::Origin(origin2)); | |
578 delegate()->ExpectClearSiteDataCookiesCall(url::Origin(origin4)); | |
579 delegate()->ExpectClearSiteDataCookiesCall(url::Origin(origin4)); | |
580 | |
581 url = https_server()->GetURL("origin1.com", "/anything-in-workers-scope"); | |
582 AddQuery(&url, "origin1", origin1.spec()); | |
583 AddQuery(&url, "origin2", origin2.spec()); | |
584 AddQuery(&url, "origin3", origin3.spec()); | |
585 AddQuery(&url, "origin4", origin4.spec()); | |
586 NavigateToURL(shell(), url); | |
587 WaitForTitle(shell(), "done"); | |
588 delegate()->VerifyAndClearExpectations(); | |
589 } | |
590 | |
591 // Tests that Clear-Site-Data is only executed on a resource fetch | |
592 // if credentials are allowed in that fetch. | |
593 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, Credentials) { | |
594 GURL page_template = https_server()->GetURL("origin1.com", "/"); | |
595 GURL same_origin_resource = | |
596 https_server()->GetURL("origin1.com", "/resource"); | |
597 GURL different_origin_resource = | |
598 https_server()->GetURL("origin2.com", "/resource"); | |
599 | |
600 AddQuery(&same_origin_resource, "header", kClearCookiesHeader); | |
601 AddQuery(&different_origin_resource, "header", kClearCookiesHeader); | |
602 | |
603 const struct TestCase { | |
604 bool same_origin; | |
605 std::string credentials; | |
606 bool should_run; | |
607 } kTestCases[] = { | |
608 {true, "", false}, | |
609 {true, "omit", false}, | |
610 {true, "same-origin", true}, | |
611 {true, "include", true}, | |
612 {false, "", false}, | |
613 {false, "omit", false}, | |
614 {false, "same-origin", false}, | |
615 {false, "include", true}, | |
616 }; | |
617 | |
618 for (const TestCase& test_case : kTestCases) { | |
619 const GURL& resource = test_case.same_origin ? same_origin_resource | |
620 : different_origin_resource; | |
621 std::string credentials = | |
622 test_case.credentials.empty() | |
623 ? "" | |
624 : "credentials: '" + test_case.credentials + "'"; | |
625 | |
626 // Fetch a resource. Note that the script also handles fetch() error which | |
627 // might be thrown for third-party fetches because of missing | |
628 // Access-Control-Allow-Origin. However, that only affects the visibility | |
629 // of the response; the header will still be processed. | |
630 std::string content = base::StringPrintf( | |
631 "<html><head></head><body><script>" | |
632 "fetch('%s', {%s})" | |
633 ".then(function() { document.title = 'done'; })" | |
634 ".catch(function() { document.title = 'done'; })" | |
635 "</script></body></html>", | |
636 resource.spec().c_str(), credentials.c_str()); | |
637 | |
638 GURL page = page_template; | |
639 AddQuery(&page, "html", content); | |
640 | |
641 if (test_case.should_run) | |
642 delegate()->ExpectClearSiteDataCookiesCall(url::Origin(resource)); | |
643 | |
644 NavigateToURL(shell(), page); | |
645 WaitForTitle(shell(), "done"); | |
646 delegate()->VerifyAndClearExpectations(); | |
647 } | |
648 } | |
649 | |
650 // Tests that the credentials flag is correctly taken into account when it | |
651 // interpretation changes after redirect. | |
652 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, | |
653 CredentialsOnRedirect) { | |
654 GURL urls[2] = { | |
655 https_server()->GetURL("origin1.com", "/image.png"), | |
656 https_server()->GetURL("origin2.com", "/image.png"), | |
657 }; | |
658 | |
659 AddQuery(&urls[0], "header", kClearCookiesHeader); | |
660 AddQuery(&urls[1], "header", kClearCookiesHeader); | |
661 | |
662 AddQuery(&urls[0], "redirect", urls[1].spec()); | |
663 | |
664 // Fetch a resource on origin1.com, which will redirect to origin2.com. | |
665 // Both URLs will respond with Clear-Site-Data. Since the credentials mode is | |
666 // 'same-origin', the LOAD_DO_NOT_SAVE_COOKIES flag will be set while | |
667 // processing the response from origin1.com, but not while processing the | |
668 // response from origin2.com. Therefore, the deletion will only be executed | |
669 // for origin1.com. | |
670 // | |
671 // Note that the script also handles fetch() error which might be thrown for | |
672 // third-party fetches because of missing Access-Control-Allow-Origin. | |
673 // However, that only affects the visibility of the response; the header will | |
674 // still be processed. | |
675 std::string content = base::StringPrintf( | |
676 "<html><head></head><body><script>" | |
677 "fetch('%s', {'credentials': 'same-origin'})" | |
678 ".then(function() { document.title = 'done'; })" | |
679 ".catch(function() { document.title = 'done'; })" | |
680 "</script></body></html>", | |
681 urls[0].spec().c_str()); | |
682 | |
683 delegate()->ExpectClearSiteDataCookiesCall(url::Origin(urls[0])); | |
684 | |
685 GURL page = https_server()->GetURL("origin1.com", "/"); | |
686 AddQuery(&page, "html", content); | |
687 | |
688 NavigateToURL(shell(), page); | |
689 WaitForTitle(shell(), "done"); | |
690 delegate()->VerifyAndClearExpectations(); | |
204 } | 691 } |
205 | 692 |
206 // Tests that ClearSiteData() is called for the correct datatypes. | 693 // Tests that ClearSiteData() is called for the correct datatypes. |
207 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, Types) { | 694 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, Types) { |
208 GURL base_url = https_server()->GetURL("example.com", "/"); | 695 GURL base_url = https_server()->GetURL("example.com", "/"); |
209 | 696 |
210 struct TestCase { | 697 struct TestCase { |
211 const char* value; | 698 const char* value; |
212 bool remove_cookies; | 699 bool remove_cookies; |
213 bool remove_storage; | 700 bool remove_storage; |
214 bool remove_cache; | 701 bool remove_cache; |
215 } test_cases[] = { | 702 } test_cases[] = { |
216 {"{ \"types\": [ \"cookies\" ] }", true, false, false}, | 703 {"{ \"types\": [ \"cookies\" ] }", true, false, false}, |
217 {"{ \"types\": [ \"storage\" ] }", false, true, false}, | 704 {"{ \"types\": [ \"storage\" ] }", false, true, false}, |
218 {"{ \"types\": [ \"cache\" ] }", false, false, true}, | 705 {"{ \"types\": [ \"cache\" ] }", false, false, true}, |
219 {"{ \"types\": [ \"cookies\", \"storage\" ] }", true, true, false}, | 706 {"{ \"types\": [ \"cookies\", \"storage\" ] }", true, true, false}, |
220 {"{ \"types\": [ \"cookies\", \"cache\" ] }", true, false, true}, | 707 {"{ \"types\": [ \"cookies\", \"cache\" ] }", true, false, true}, |
221 {"{ \"types\": [ \"storage\", \"cache\" ] }", false, true, true}, | 708 {"{ \"types\": [ \"storage\", \"cache\" ] }", false, true, true}, |
222 {"{ \"types\": [ \"cookies\", \"storage\", \"cache\" ] }", true, true, | 709 {"{ \"types\": [ \"cookies\", \"storage\", \"cache\" ] }", true, true, |
223 true}, | 710 true}, |
224 }; | 711 }; |
225 | 712 |
226 for (const TestCase& test_case : test_cases) { | 713 for (const TestCase& test_case : test_cases) { |
227 GURL url = base_url; | 714 GURL url = base_url; |
228 AddQuery(&url, "header", test_case.value); | 715 AddQuery(&url, "header", test_case.value); |
229 | 716 |
230 EXPECT_CALL( | 717 delegate()->ExpectClearSiteDataCall( |
231 *GetContentBrowserClient(), | 718 url::Origin(url), test_case.remove_cookies, test_case.remove_storage, |
232 ClearSiteData(shell()->web_contents()->GetBrowserContext(), | 719 test_case.remove_cache); |
233 url::Origin(url), test_case.remove_cookies, | |
234 test_case.remove_storage, test_case.remove_cache, _)); | |
235 | 720 |
236 NavigateToURL(shell(), url); | 721 NavigateToURL(shell(), url); |
237 | 722 |
238 testing::Mock::VerifyAndClearExpectations(GetContentBrowserClient()); | 723 delegate()->VerifyAndClearExpectations(); |
239 } | 724 } |
240 } | 725 } |
241 | 726 |
727 // Integration test for the deletion of cookies. | |
728 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, | |
729 CookiesIntegrationTest) { | |
730 AddCookie(https_server()->GetURL("origin1.com", "/abc")); | |
731 AddCookie(https_server()->GetURL("subdomain.origin1.com", "/")); | |
732 AddCookie(https_server()->GetURL("origin2.com", "/def")); | |
733 AddCookie(https_server()->GetURL("subdomain.origin2.com", "/")); | |
734 | |
735 // There are four cookies on two eTLD+1s. | |
736 net::CookieList cookies = GetCookies(); | |
737 EXPECT_EQ(4u, cookies.size()); | |
738 | |
739 // Let Clear-Site-Data delete the "cookies" of "origin1.com". | |
740 GURL url = https_server()->GetURL("origin1.com", "/clear-site-data"); | |
741 AddQuery(&url, "header", kClearCookiesHeader); | |
742 NavigateToURL(shell(), url); | |
743 | |
744 // Only the "origin2.com" eTLD now has cookies. | |
745 cookies = GetCookies(); | |
746 EXPECT_EQ(2u, cookies.size()); | |
mmenke
2017/05/25 19:23:10
ASSERT_EQ?
msramek
2017/05/30 21:58:45
Done.
| |
747 EXPECT_EQ(cookies[1].Domain(), "subdomain.origin2.com"); | |
748 EXPECT_EQ(cookies[0].Domain(), "origin2.com"); | |
mmenke
2017/05/25 19:23:10
nit: Why the flipped order?
msramek
2017/05/30 21:58:45
Done. Flipped, no reason :)
| |
749 } | |
750 | |
751 // Integration test for the unregistering of service workers. | |
752 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, | |
753 StorageServiceWorkersIntegrationTest) { | |
754 AddServiceWorker("origin1.com"); | |
755 AddServiceWorker("origin2.com"); | |
756 | |
757 // There are two service workers installed on two origins. | |
758 std::vector<ServiceWorkerUsageInfo> service_workers = GetServiceWorkers(); | |
759 EXPECT_EQ(2u, service_workers.size()); | |
760 | |
761 // Let Clear-Site-Data delete the "storage" of "origin1.com". | |
762 GURL url = https_server()->GetURL("origin1.com", "/clear-site-data"); | |
mmenke
2017/05/25 19:23:09
Why doesn't origin1's SW intercept this and return
msramek
2017/05/30 21:58:45
That's a great question :) Apparently I confused t
| |
763 AddQuery(&url, "header", "{ \"types\": [ \"storage\" ] }"); | |
764 NavigateToURL(shell(), url); | |
765 | |
766 // Only "origin2.com" now has a service worker. | |
767 service_workers = GetServiceWorkers(); | |
768 EXPECT_EQ(1u, service_workers.size()); | |
mmenke
2017/05/25 19:23:10
ASSERT_EQ?
msramek
2017/05/30 21:58:45
Done.
| |
769 EXPECT_EQ(service_workers[0].origin, | |
770 https_server()->GetURL("origin2.com", "/")); | |
771 } | |
772 | |
773 // TODO(msramek): Add integration tests for other storage datatypes, such as | |
774 // local storage, indexed DB, etc. | |
775 | |
776 // Integration test for the deletion of cache entries. | |
777 // NOTE: This test might be flaky. disk_cache::Backend calls back before cache | |
778 // entries are actually written to the disk. Other tests using CacheTestUtil | |
779 // show that a timeout of around 1s between cache operations is necessary to | |
780 // avoid flakiness. | |
781 IN_PROC_BROWSER_TEST_F(ClearSiteDataThrottleBrowserTest, CacheIntegrationTest) { | |
782 const int kTimeoutMs = 1000; | |
783 | |
784 CacheTestUtil util( | |
785 BrowserContext::GetDefaultStoragePartition(browser_context())); | |
786 std::string url1 = https_server()->GetURL("origin1.com", "/foo").spec(); | |
787 std::string url2 = https_server()->GetURL("origin1.com", "/bar").spec(); | |
788 std::string url3 = https_server()->GetURL("origin2.com", "/foo").spec(); | |
789 std::string url4 = https_server()->GetURL("origin2.com", "/bar").spec(); | |
790 | |
791 std::set<std::string> entries_to_create = {url1, url2, url3, url4}; | |
792 util.CreateCacheEntries(entries_to_create); | |
793 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(kTimeoutMs)); | |
794 | |
795 // There are four cache entries on two origins. | |
796 std::vector<std::string> cache_keys = util.GetEntryKeys(); | |
797 EXPECT_EQ(4u, cache_keys.size()); | |
798 | |
799 // Let Clear-Site-Data delete the "cache" of "origin1.com". | |
800 GURL url = https_server()->GetURL("origin1.com", "/clear-site-data"); | |
801 AddQuery(&url, "header", "{ \"types\": [ \"cache\" ] }"); | |
802 NavigateToURL(shell(), url); | |
803 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(kTimeoutMs)); | |
804 | |
805 // Only "origin2.com" now has cache entries. | |
806 cache_keys = util.GetEntryKeys(); | |
807 EXPECT_EQ(2u, cache_keys.size()); | |
808 std::sort(cache_keys.begin(), cache_keys.end()); | |
809 EXPECT_EQ(url4, cache_keys[0]); | |
810 EXPECT_EQ(url3, cache_keys[1]); | |
811 } | |
812 | |
242 } // namespace content | 813 } // namespace content |
OLD | NEW |