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

Side by Side Diff: content/components/navigation_interception/intercept_navigation_resource_throttle_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698