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

Side by Side Diff: chrome/browser/component/navigation_interception/intercept_navigation_resource_throttle_unittest.cc

Issue 11293017: Move navigation interception component to content/components (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add findbugs suppression for compatibility code. Created 8 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/synchronization/waitable_event.h"
10 #include "chrome/browser/component/navigation_interception/intercept_navigation_ resource_throttle.h"
11 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/browser/resource_context.h"
14 #include "content/public/browser/resource_controller.h"
15 #include "content/public/browser/resource_dispatcher_host.h"
16 #include "content/public/browser/resource_dispatcher_host_delegate.h"
17 #include "content/public/browser/resource_request_info.h"
18 #include "content/public/browser/resource_throttle.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/browser/web_contents_delegate.h"
21 #include "content/public/test/mock_resource_context.h"
22 #include "content/public/test/test_browser_thread.h"
23 #include "net/url_request/url_request.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 using namespace content;
28 using namespace navigation_interception;
29 using namespace ::testing;
30
31 namespace {
32
33 const char* kTestUrl = "http://www.test.com/";
34 const char* kUnsafeTestUrl = "about:crash";
35
36 void ContinueTestCase() {
37 BrowserThread::PostTask(
38 BrowserThread::UI,
39 FROM_HERE,
40 MessageLoop::QuitClosure());
41 }
42
43 } // namespace
44
45 // MockInterceptCallbackReceiver ----------------------------------------------
46
47 class MockInterceptCallbackReceiver {
48 public:
49 MOCK_METHOD4(ShouldIgnoreNavigation, bool(RenderViewHost* source,
50 const GURL& url,
51 const content::Referrer& referrer,
52 bool has_user_gesture));
53 };
54
55 // MockResourceController -----------------------------------------------------
56 class MockResourceController
57 : public content::ResourceController {
58 public:
59 enum Status {
60 UNKNOWN,
61 RESUMED,
62 CANCELLED
63 };
64
65 MockResourceController()
66 : status_(UNKNOWN) {
67 }
68
69 Status status() const { return status_; }
70
71 // content::ResourceController
72 virtual void Cancel() {
73 NOTREACHED();
74 }
75 virtual void CancelAndIgnore() {
76 status_ = CANCELLED;
77 ContinueTestCase();
78 }
79 virtual void CancelWithError(int error_code) {
80 NOTREACHED();
81 }
82 virtual void Resume() {
83 DCHECK(status_ == UNKNOWN);
84 status_ = RESUMED;
85 ContinueTestCase();
86 }
87
88 private:
89 Status status_;
90 };
91
92 // TestIOThreadState ----------------------------------------------------------
93
94 class TestIOThreadState {
95 public:
96 TestIOThreadState(const GURL& url, int render_process_id, int render_view_id,
97 MockInterceptCallbackReceiver* callback_receiver)
98 : request_(url, NULL, resource_context_.GetRequestContext()),
99 throttle_(NULL) {
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
101 if (render_process_id != MSG_ROUTING_NONE &&
102 render_view_id != MSG_ROUTING_NONE) {
103 ResourceRequestInfo::AllocateForTesting(&request_,
104 ResourceType::MAIN_FRAME,
105 &resource_context_,
106 render_process_id,
107 render_view_id);
108 }
109 throttle_.reset(new InterceptNavigationResourceThrottle(
110 &request_,
111 base::Bind(&MockInterceptCallbackReceiver::ShouldIgnoreNavigation,
112 base::Unretained(callback_receiver))));
113 throttle_->set_controller_for_testing(&throttle_controller_);
114 }
115
116 void ThrottleWillStartRequest(bool* defer) {
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
118 throttle_->WillStartRequest(defer);
119 }
120
121 bool request_resumed() const {
122 return throttle_controller_.status() ==
123 MockResourceController::RESUMED;
124 }
125
126 bool request_cancelled() const {
127 return throttle_controller_.status() ==
128 MockResourceController::CANCELLED;
129 }
130
131 private:
132 content::MockResourceContext resource_context_;
133 net::URLRequest request_;
134 scoped_ptr<InterceptNavigationResourceThrottle> throttle_;
135 MockResourceController throttle_controller_;
136 };
137
138 // InterceptNavigationResourceThrottleTest ------------------------------------
139
140 class InterceptNavigationResourceThrottleTest
141 : public ChromeRenderViewHostTestHarness {
142 public:
143 InterceptNavigationResourceThrottleTest()
144 : mock_callback_receiver_(new MockInterceptCallbackReceiver()),
145 ui_thread_(BrowserThread::UI, &message_loop_),
146 io_thread_(BrowserThread::IO),
147 io_thread_state_(NULL) {
148 }
149
150 virtual void SetUp() OVERRIDE {
151 ChromeRenderViewHostTestHarness::SetUp();
152
153 io_thread_.StartIOThread();
154 }
155
156 virtual void TearDown() OVERRIDE {
157 if (web_contents())
158 web_contents()->SetDelegate(NULL);
159
160 BrowserThread::PostTask(
161 BrowserThread::IO,
162 FROM_HERE,
163 base::Bind(&base::DeletePointer<TestIOThreadState>, io_thread_state_));
164
165 RenderViewHostTestHarness::TearDown();
166 }
167
168 void SetIOThreadState(TestIOThreadState* io_thread_state) {
169 io_thread_state_ = io_thread_state;
170 }
171
172 void RunThrottleWillStartRequestOnIOThread(
173 const GURL& url,
174 int render_process_id,
175 int render_view_id,
176 bool* defer) {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
178 TestIOThreadState* io_thread_state =
179 new TestIOThreadState(url, render_process_id, render_view_id,
180 mock_callback_receiver_.get());
181
182 SetIOThreadState(io_thread_state);
183 io_thread_state->ThrottleWillStartRequest(defer);
184
185 if (!*defer) {
186 ContinueTestCase();
187 }
188 }
189
190 protected:
191 enum ShouldIgnoreNavigationCallbackAction {
192 IgnoreNavigation,
193 DontIgnoreNavigation
194 };
195
196 void SetUpWebContentsDelegateAndRunMessageLoop(
197 ShouldIgnoreNavigationCallbackAction callback_action,
198 bool* defer) {
199
200 ON_CALL(*mock_callback_receiver_,
201 ShouldIgnoreNavigation(_, _, _, _))
202 .WillByDefault(Return(callback_action == IgnoreNavigation));
203 EXPECT_CALL(*mock_callback_receiver_,
204 ShouldIgnoreNavigation(rvh(), Eq(GURL(kTestUrl)), _, _))
205 .Times(1);
206
207 BrowserThread::PostTask(
208 BrowserThread::IO,
209 FROM_HERE,
210 base::Bind(
211 &InterceptNavigationResourceThrottleTest::
212 RunThrottleWillStartRequestOnIOThread,
213 base::Unretained(this),
214 GURL(kTestUrl),
215 web_contents()->GetRenderViewHost()->GetProcess()->GetID(),
216 web_contents()->GetRenderViewHost()->GetRoutingID(),
217 base::Unretained(defer)));
218
219 // Wait for the request to finish processing.
220 message_loop_.Run();
221 }
222
223 void WaitForPreviouslyScheduledIoThreadWork() {
224 base::WaitableEvent io_thread_work_done(true, false);
225 BrowserThread::PostTask(
226 BrowserThread::IO,
227 FROM_HERE,
228 base::Bind(
229 &base::WaitableEvent::Signal,
230 base::Unretained(&io_thread_work_done)));
231 io_thread_work_done.Wait();
232 }
233
234 scoped_ptr<MockInterceptCallbackReceiver> mock_callback_receiver_;
235 content::TestBrowserThread ui_thread_;
236 content::TestBrowserThread io_thread_;
237 TestIOThreadState* io_thread_state_;
238 };
239
240 TEST_F(InterceptNavigationResourceThrottleTest,
241 RequestDeferredAndResumedIfNavigationNotIgnored) {
242 bool defer = false;
243 SetUpWebContentsDelegateAndRunMessageLoop(DontIgnoreNavigation, &defer);
244
245 EXPECT_TRUE(defer);
246 EXPECT_TRUE(io_thread_state_);
247 EXPECT_TRUE(io_thread_state_->request_resumed());
248 }
249
250 TEST_F(InterceptNavigationResourceThrottleTest,
251 RequestDeferredAndCancelledIfNavigationIgnored) {
252 bool defer = false;
253 SetUpWebContentsDelegateAndRunMessageLoop(IgnoreNavigation, &defer);
254
255 EXPECT_TRUE(defer);
256 EXPECT_TRUE(io_thread_state_);
257 EXPECT_TRUE(io_thread_state_->request_cancelled());
258 }
259
260 TEST_F(InterceptNavigationResourceThrottleTest,
261 NoCallbackMadeIfContentsDeletedWhileThrottleRunning) {
262 bool defer = false;
263
264 // The tested scenario is when the WebContents is deleted after the
265 // ResourceThrottle has finished processing on the IO thread but before the
266 // UI thread callback has been processed.
267 BrowserThread::PostTask(
268 BrowserThread::UI,
269 FROM_HERE,
270 base::Bind(
271 &RenderViewHostTestHarness::DeleteContents,
272 base::Unretained(this)));
273
274 EXPECT_CALL(*mock_callback_receiver_,
275 ShouldIgnoreNavigation(_, _, _, _))
276 .Times(0);
277
278 BrowserThread::PostTask(
279 BrowserThread::IO,
280 FROM_HERE,
281 base::Bind(
282 &InterceptNavigationResourceThrottleTest::
283 RunThrottleWillStartRequestOnIOThread,
284 base::Unretained(this),
285 GURL(kTestUrl),
286 web_contents()->GetRenderViewHost()->GetProcess()->GetID(),
287 web_contents()->GetRenderViewHost()->GetRoutingID(),
288 base::Unretained(&defer)));
289
290 WaitForPreviouslyScheduledIoThreadWork();
291
292 // The WebContents will now be deleted and only after that will the UI-thread
293 // callback posted by the ResourceThrottle be executed.
294 message_loop_.Run();
295
296 EXPECT_TRUE(defer);
297 EXPECT_TRUE(io_thread_state_);
298 EXPECT_TRUE(io_thread_state_->request_resumed());
299 }
300
301 TEST_F(InterceptNavigationResourceThrottleTest,
302 RequestNotDeferredForRequestNotAssociatedWithARenderView) {
303 bool defer = false;
304
305 BrowserThread::PostTask(
306 BrowserThread::IO,
307 FROM_HERE,
308 base::Bind(
309 &InterceptNavigationResourceThrottleTest::
310 RunThrottleWillStartRequestOnIOThread,
311 base::Unretained(this),
312 GURL(kTestUrl),
313 MSG_ROUTING_NONE,
314 MSG_ROUTING_NONE,
315 base::Unretained(&defer)));
316
317 // Wait for the request to finish processing.
318 message_loop_.Run();
319
320 EXPECT_FALSE(defer);
321 }
322
323 TEST_F(InterceptNavigationResourceThrottleTest,
324 CallbackCalledWithFilteredUrl) {
325 bool defer = false;
326
327 ON_CALL(*mock_callback_receiver_,
328 ShouldIgnoreNavigation(_, Ne(GURL(kUnsafeTestUrl)), _, _))
329 .WillByDefault(Return(false));
330 EXPECT_CALL(*mock_callback_receiver_,
331 ShouldIgnoreNavigation(_, Ne(GURL(kUnsafeTestUrl)), _, _))
332 .Times(1);
333
334 BrowserThread::PostTask(
335 BrowserThread::IO,
336 FROM_HERE,
337 base::Bind(
338 &InterceptNavigationResourceThrottleTest::
339 RunThrottleWillStartRequestOnIOThread,
340 base::Unretained(this),
341 GURL(kUnsafeTestUrl),
342 web_contents()->GetRenderViewHost()->GetProcess()->GetID(),
343 web_contents()->GetRenderViewHost()->GetRoutingID(),
344 base::Unretained(&defer)));
345
346 // Wait for the request to finish processing.
347 message_loop_.Run();
348 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698