Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(252)

Side by Side Diff: chrome/browser/favicon/favicon_tab_helper_browsertest.cc

Issue 934693002: Reload favicon from HTTP cache on Ctrl+Refresh (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // 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
5 #include "chrome/browser/favicon/favicon_tab_helper.h"
6
7 #include "base/run_loop.h"
8 #include "chrome/app/chrome_command_ids.h"
9 #include "chrome/browser/chrome_notification_types.h"
10 #include "chrome/browser/favicon/favicon_handler.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/browser_commands.h"
13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
14 #include "chrome/test/base/in_process_browser_test.h"
15 #include "chrome/test/base/ui_test_utils.h"
16 #include "content/public/browser/notification_observer.h"
17 #include "content/public/browser/notification_registrar.h"
18 #include "content/public/browser/notification_types.h"
19 #include "content/public/browser/resource_dispatcher_host.h"
20 #include "content/public/browser/resource_dispatcher_host_delegate.h"
21 #include "net/base/load_flags.h"
22 #include "net/url_request/url_request.h"
23 #include "net/test/spawned_test_server/spawned_test_server.h"
24 #include "url/url_constants.h"
25
26 namespace {
27
28 // Tracks whether the URL passed to the constructor is requested and whether
29 // the request bypasses the cache.
30 class TestResourceDispatcherHostDelegate
31 : public content::ResourceDispatcherHostDelegate {
32 public:
33 explicit TestResourceDispatcherHostDelegate(const GURL& url)
34 : url_(url), was_requested_(false), bypassed_cache_(false) {}
35 ~TestResourceDispatcherHostDelegate() override {}
36
37 void Reset() {
38 was_requested_ = false;
39 bypassed_cache_ = false;
40 }
41
42 // Resturns whether |url_| was requested.
43 bool was_requested() const { return was_requested_; }
44
45 // Returns whether any of the requests bypassed the HTTP cache.
46 bool bypassed_cache() const { return bypassed_cache_; }
47
48 private:
49 // content::ResourceDispatcherHostDelegate:
50 bool ShouldBeginRequest(const std::string& method,
51 const GURL& url,
52 content::ResourceType resource_type,
53 content::ResourceContext* resource_context) override {
54 return true;
55 }
56
57 void RequestBeginning(
58 net::URLRequest* request,
59 content::ResourceContext* resource_context,
60 content::AppCacheService* appcache_service,
61 content::ResourceType resource_type,
62 ScopedVector<content::ResourceThrottle>* throttles) override {
63 if (request->url() == url_) {
64 was_requested_ = true;
65 if (request->load_flags() & net::LOAD_BYPASS_CACHE)
66 bypassed_cache_ = true;
67 }
68 }
69
70 void DownloadStarting(
71 net::URLRequest* request,
72 content::ResourceContext* resource_context,
73 int child_id,
74 int route_id,
75 int request_id,
76 bool is_content_initiated,
77 bool must_download,
78 ScopedVector<content::ResourceThrottle>* throttles) override {}
79
80 private:
81 GURL url_;
82 bool was_requested_;
83 bool bypassed_cache_;
84
85 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate);
86 };
87
88 // Checks whether the FaviconTabHelper is waiting for a download to complete or
89 // for data from the FaviconService.
90 class FaviconTabHelperPendingTaskChecker {
91 public:
92 virtual ~FaviconTabHelperPendingTaskChecker() {}
93
94 virtual bool HasPendingTasks() = 0;
95 };
96
97 // Waits for the following the finish:
98 // - The pending navigation.
99 // - FaviconHandler's pending favicon database requests.
100 // - FaviconHandler's pending downloads.
101 class PendingTaskWaiter : public content::NotificationObserver {
102 public:
103 PendingTaskWaiter(content::WebContents* web_contents,
104 FaviconTabHelperPendingTaskChecker* checker)
105 : checker_(checker), load_stopped_(false) {
106 registrar_.Add(this, chrome::NOTIFICATION_FAVICON_UPDATED,
107 content::Source<content::WebContents>(web_contents));
108 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
109 content::Source<content::NavigationController>(
110 &web_contents->GetController()));
111 }
112 ~PendingTaskWaiter() override {}
113
114 void Wait() {
115 if (load_stopped_ && !checker_->HasPendingTasks())
116 return;
117
118 base::RunLoop run_loop;
119 quit_closure_ = run_loop.QuitClosure();
120 run_loop.Run();
121 }
122
123 private:
124 // content::NotificationObserver:
125 void Observe(int type,
126 const content::NotificationSource& source,
127 const content::NotificationDetails& details) override {
128 if (type == content::NOTIFICATION_LOAD_STOP)
129 load_stopped_ = true;
130
131 if (!quit_closure_.is_null()) {
132 // We stop waiting based on changes in state to FaviconHandler which occur
133 // immediately after NOTIFICATION_FAVICON_UPDATED is sent. Post a task to
134 // check if we can stop waiting.
135 base::MessageLoopForUI::current()->PostTask(
136 FROM_HERE, base::Bind(&PendingTaskWaiter::EndLoopIfCanStopWaiting,
137 base::Unretained(this)));
138 }
139 }
140
141 void EndLoopIfCanStopWaiting() {
142 if (!quit_closure_.is_null() &&
143 load_stopped_ &&
144 !checker_->HasPendingTasks()) {
145 quit_closure_.Run();
146 }
147 }
148
149 FaviconTabHelperPendingTaskChecker* checker_; // Not owned.
150 bool load_stopped_;
151 base::Closure quit_closure_;
152 content::NotificationRegistrar registrar_;
153
154 DISALLOW_COPY_AND_ASSIGN(PendingTaskWaiter);
155 };
156
157 } // namespace
158
159 class FaviconTabHelperTest : public InProcessBrowserTest,
160 public FaviconTabHelperPendingTaskChecker {
161 public:
162 FaviconTabHelperTest() {}
163 ~FaviconTabHelperTest() override {}
164
165 content::WebContents* web_contents() {
166 return browser()->tab_strip_model()->GetActiveWebContents();
167 }
168
169 // FaviconTabHelperPendingTaskChecker:
170 bool HasPendingTasks() override {
171 FaviconHandler* favicon_handler =
172 FaviconTabHelper::FromWebContents(web_contents())
173 ->favicon_handler_.get();
174 return !favicon_handler->download_requests_.empty() ||
175 favicon_handler->cancelable_task_tracker_.HasTrackedTasks();
176 }
177
178 private:
179 DISALLOW_COPY_AND_ASSIGN(FaviconTabHelperTest);
180 };
181
182 // Test that when a user reloads a page ignoring the cache that the favicon is
183 // is redownloaded and (not returned from either the favicon cache or the HTTP
184 // cache).
185 IN_PROC_BROWSER_TEST_F(FaviconTabHelperTest, ReloadIgnoringCache) {
186 ASSERT_TRUE(test_server()->Start());
187 GURL url = test_server()->GetURL("files/favicon/page_with_favicon.html");
188 GURL icon_url = test_server()->GetURL("files/favicon/icon.ico");
189
190 scoped_ptr<TestResourceDispatcherHostDelegate> delegate(
191 new TestResourceDispatcherHostDelegate(icon_url));
192 content::ResourceDispatcherHost::Get()->SetDelegate(delegate.get());
193
194 // Initial visit in order to populate the cache.
195 {
196 PendingTaskWaiter waiter(web_contents(), this);
197 ui_test_utils::NavigateToURLWithDisposition(
198 browser(), url, CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE);
199 waiter.Wait();
200 }
201 ASSERT_TRUE(delegate->was_requested());
202 EXPECT_FALSE(delegate->bypassed_cache());
203 delegate->Reset();
204
205 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL));
206
207 // A normal visit should fetch the favicon from either the favicon database or
208 // the HTTP cache.
209 {
210 PendingTaskWaiter waiter(web_contents(), this);
211 ui_test_utils::NavigateToURLWithDisposition(
212 browser(), url, CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE);
213 waiter.Wait();
214 }
215 EXPECT_FALSE(delegate->bypassed_cache());
216 delegate->Reset();
217
218 // A reload ingoring the cache should refetch the favicon from the website.
219 {
220 PendingTaskWaiter waiter(web_contents(), this);
221 chrome::ExecuteCommand(browser(), IDC_RELOAD_IGNORING_CACHE);
222 waiter.Wait();
223 }
224 ASSERT_TRUE(delegate->was_requested());
225 EXPECT_TRUE(delegate->bypassed_cache());
226 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698