1 // Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include <memory>
6 #include <vector>
7
8 #include "include/base/cef_callback.h"
9 #include "include/base/cef_lock.h"
10 #include "include/cef_file_util.h"
11 #include "include/cef_waitable_event.h"
12 #include "include/wrapper/cef_closure_task.h"
13 #include "include/wrapper/cef_resource_manager.h"
14 #include "include/wrapper/cef_scoped_temp_dir.h"
15 #include "include/wrapper/cef_stream_resource_handler.h"
16 #include "tests/ceftests/routing_test_handler.h"
17 #include "tests/ceftests/test_util.h"
18 #include "tests/gtest/include/gtest/gtest.h"
19 #include "tests/shared/browser/file_util.h"
20
21 namespace {
22
CreateMessage(const std::string & name,const std::string & value)23 std::string CreateMessage(const std::string& name, const std::string& value) {
24 return name + ":" + value;
25 }
26
27 // The returned contents execute a JavaScript callback containing |message|.
CreateContents(const std::string & message)28 std::string CreateContents(const std::string& message) {
29 return "<html><body>" + message +
30 "<script>"
31 "window.testQuery({request:'" +
32 message +
33 "'});"
34 "</script></html></body>";
35 }
36
WriteFile(const std::string & path,const std::string & contents)37 void WriteFile(const std::string& path, const std::string& contents) {
38 int contents_size = static_cast<int>(contents.size());
39 int write_ct =
40 client::file_util::WriteFile(path, contents.data(), contents_size);
41 EXPECT_EQ(contents_size, write_ct);
42 }
43
CreateContentsResourceHandler(const std::string & message)44 CefRefPtr<CefResourceHandler> CreateContentsResourceHandler(
45 const std::string& message) {
46 const std::string& contents = CreateContents(message);
47 CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
48 static_cast<void*>(const_cast<char*>(contents.data())),
49 contents.length());
50 return new CefStreamResourceHandler("text/html", stream);
51 }
52
53 const char kDoneMsg[] = "ResourceManagerTestHandler.Done";
54 const char kNotHandled[] = "NotHandled";
55
56 // Browser side.
57 class ResourceManagerTestHandler : public RoutingTestHandler {
58 public:
59 struct State {
State__anon6aa340460111::ResourceManagerTestHandler::State60 State() : manager_(new CefResourceManager()), expected_message_ct_(0) {}
61
62 CefRefPtr<CefResourceManager> manager_;
63
64 // Set of URLs that will be loaded.
65 std::vector<std::string> urls_;
66
67 // Set of messages that were received.
68 std::vector<std::string> messages_;
69
70 // If non-zero the test will not complete until the expected number of
71 // messages have been received.
72 size_t expected_message_ct_;
73 };
74
ResourceManagerTestHandler(State * state)75 explicit ResourceManagerTestHandler(State* state)
76 : state_(state), current_url_(0) {
77 EXPECT_TRUE(state_);
78 EXPECT_TRUE(state_->manager_.get());
79 EXPECT_TRUE(!state_->urls_.empty());
80 EXPECT_TRUE(state_->messages_.empty());
81 }
82
RunTest()83 void RunTest() override {
84 // Create the browser.
85 CreateBrowser(GetNextURL());
86
87 SetTestTimeout(IsChromeRuntimeEnabled() ? 10000 : 5000);
88 }
89
OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request,CefRefPtr<CefCallback> callback)90 cef_return_value_t OnBeforeResourceLoad(
91 CefRefPtr<CefBrowser> browser,
92 CefRefPtr<CefFrame> frame,
93 CefRefPtr<CefRequest> request,
94 CefRefPtr<CefCallback> callback) override {
95 if (IsChromeRuntimeEnabled() && request->GetResourceType() == RT_FAVICON) {
96 // Ignore favicon requests.
97 return RV_CANCEL;
98 }
99
100 return state_->manager_->OnBeforeResourceLoad(browser, frame, request,
101 callback);
102 }
103
GetResourceHandler(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefRefPtr<CefRequest> request)104 CefRefPtr<CefResourceHandler> GetResourceHandler(
105 CefRefPtr<CefBrowser> browser,
106 CefRefPtr<CefFrame> frame,
107 CefRefPtr<CefRequest> request) override {
108 // The ProviderDoNothing test destroys the manager before the handler.
109 if (state_->manager_) {
110 CefRefPtr<CefResourceHandler> handler =
111 state_->manager_->GetResourceHandler(browser, frame, request);
112 if (handler.get())
113 return handler;
114 }
115
116 return CreateContentsResourceHandler(CreateMessage(kDoneMsg, kNotHandled));
117 }
118
OnQuery(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int64 query_id,const CefString & request,bool persistent,CefRefPtr<Callback> callback)119 bool OnQuery(CefRefPtr<CefBrowser> browser,
120 CefRefPtr<CefFrame> frame,
121 int64 query_id,
122 const CefString& request,
123 bool persistent,
124 CefRefPtr<Callback> callback) override {
125 state_->messages_.push_back(request);
126 callback->Success("");
127
128 CefPostTask(TID_UI, base::BindOnce(&ResourceManagerTestHandler::Continue,
129 this, browser));
130
131 return true;
132 }
133
134 // Wait a bit before destroying the test. Used with ProviderDoNothing.
DelayedDestroyTest()135 void DelayedDestroyTest() {
136 CefPostDelayedTask(
137 TID_UI, base::BindOnce(&ResourceManagerTestHandler::DestroyTest, this),
138 100);
139 }
140
141 private:
Continue(CefRefPtr<CefBrowser> browser)142 void Continue(CefRefPtr<CefBrowser> browser) {
143 if (state_->expected_message_ct_ == 0) {
144 // Load each URL sequentially.
145 const std::string& next_url = GetNextURL();
146 if (next_url.empty())
147 DestroyTest();
148 else
149 browser->GetMainFrame()->LoadURL(next_url);
150 } else if (state_->messages_.size() == state_->expected_message_ct_) {
151 DestroyTest();
152 }
153 }
154
GetNextURL()155 std::string GetNextURL() {
156 if (current_url_ >= state_->urls_.size())
157 return std::string();
158 return state_->urls_[current_url_++];
159 }
160
161 State* state_;
162 size_t current_url_;
163
164 IMPLEMENT_REFCOUNTING(ResourceManagerTestHandler);
165 };
166
167 } // namespace
168
169 // Test with no providers.
TEST(ResourceManagerTest,NoProviders)170 TEST(ResourceManagerTest, NoProviders) {
171 const char kUrl[] = "http://test.com/ResourceManagerTest";
172
173 ResourceManagerTestHandler::State state;
174 state.urls_.push_back(kUrl);
175
176 CefRefPtr<ResourceManagerTestHandler> handler =
177 new ResourceManagerTestHandler(&state);
178 handler->ExecuteTest();
179
180 ReleaseAndWaitForDestructor(handler);
181
182 state.manager_ = nullptr;
183
184 // Should get the message returned from GetResourceHandler when the request is
185 // not handled.
186 EXPECT_EQ(state.messages_.size(), 1U);
187 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
188 }
189
190 namespace {
191
192 // Content provider that tracks execution state.
193 class TestProvider : public CefResourceManager::Provider {
194 public:
195 struct State {
196 TrackCallback got_on_request_;
197 TrackCallback got_on_request_canceled_;
198 TrackCallback got_destruct_;
199 base::OnceClosure destruct_callback_;
200 std::string request_url_;
201 };
202
TestProvider(State * state)203 explicit TestProvider(State* state) : state_(state) { EXPECT_TRUE(state_); }
204
~TestProvider()205 ~TestProvider() {
206 CEF_REQUIRE_IO_THREAD();
207 state_->got_destruct_.yes();
208 if (!state_->destruct_callback_.is_null())
209 std::move(state_->destruct_callback_).Run();
210 }
211
OnRequest(scoped_refptr<CefResourceManager::Request> request)212 bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
213 CEF_REQUIRE_IO_THREAD();
214 EXPECT_FALSE(state_->got_on_request_);
215 EXPECT_FALSE(state_->got_on_request_canceled_);
216
217 state_->got_on_request_.yes();
218 state_->request_url_ = request->url();
219
220 return false;
221 }
222
OnRequestCanceled(scoped_refptr<CefResourceManager::Request> request)223 void OnRequestCanceled(
224 scoped_refptr<CefResourceManager::Request> request) override {
225 CEF_REQUIRE_IO_THREAD();
226 EXPECT_TRUE(state_->got_on_request_);
227 EXPECT_FALSE(state_->got_on_request_canceled_);
228
229 state_->got_on_request_canceled_.yes();
230 EXPECT_STREQ(state_->request_url_.c_str(), request->url().c_str());
231 }
232
233 private:
234 State* state_;
235
236 DISALLOW_COPY_AND_ASSIGN(TestProvider);
237 };
238
239 // Helper that blocks on destruction of 1 or more TestProviders.
240 class ProviderDestructHelper {
241 public:
ProviderDestructHelper(int expected_count)242 explicit ProviderDestructHelper(int expected_count)
243 : expected_count_(expected_count),
244 event_(CefWaitableEvent::CreateWaitableEvent(true, false)) {
245 CHECK_GT(expected_count_, 0);
246 }
247
callback()248 base::OnceClosure callback() {
249 return base::BindOnce(
250 [](ProviderDestructHelper* self) { self->DestructCallback(); },
251 base::Unretained(this));
252 }
253
Wait()254 void Wait() { event_->Wait(); }
255
256 private:
DestructCallback()257 void DestructCallback() {
258 bool signal = false;
259
260 {
261 base::AutoLock lock_scope(lock_);
262 CHECK_LT(current_count_, expected_count_);
263 if (++current_count_ == expected_count_)
264 signal = true;
265 }
266
267 if (signal) {
268 // Don't access any members after calling Signal(), which causes |this| to
269 // be deleted on a different thread.
270 auto event = event_;
271 event->Signal();
272 }
273 }
274
275 const int expected_count_;
276 int current_count_ = 0;
277 CefRefPtr<CefWaitableEvent> event_;
278 base::Lock lock_;
279 };
280
281 // Test that that the URL retrieved via Request::url() is parsed as expected.
282 // Fragment or query components in any order should be removed.
TestUrlParsing(const char * kUrl)283 void TestUrlParsing(const char* kUrl) {
284 const char kRequestUrl[] = "http://test.com/ResourceManagerTest";
285
286 ResourceManagerTestHandler::State state;
287 state.urls_.push_back(kUrl);
288
289 TestProvider::State provider_state;
290
291 ProviderDestructHelper destruct_helper(1);
292 provider_state.destruct_callback_ = destruct_helper.callback();
293
294 state.manager_->AddProvider(new TestProvider(&provider_state), 0,
295 std::string());
296
297 CefRefPtr<ResourceManagerTestHandler> handler =
298 new ResourceManagerTestHandler(&state);
299 handler->ExecuteTest();
300
301 ReleaseAndWaitForDestructor(handler);
302
303 state.manager_ = nullptr;
304
305 // Wait for the manager to be deleted.
306 destruct_helper.Wait();
307
308 // The provider is called.
309 EXPECT_TRUE(provider_state.got_on_request_);
310 EXPECT_FALSE(provider_state.got_on_request_canceled_);
311 EXPECT_TRUE(provider_state.got_destruct_);
312
313 // The expected URL is received.
314 EXPECT_STREQ(kRequestUrl, provider_state.request_url_.c_str());
315
316 // The request is not handled.
317 EXPECT_EQ(state.messages_.size(), 1U);
318 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
319 }
320
321 } // namespace
322
TEST(ResourceManagerTest,UrlParsingNoQueryOrFragment)323 TEST(ResourceManagerTest, UrlParsingNoQueryOrFragment) {
324 TestUrlParsing("http://test.com/ResourceManagerTest");
325 }
326
TEST(ResourceManagerTest,UrlParsingWithQuery)327 TEST(ResourceManagerTest, UrlParsingWithQuery) {
328 TestUrlParsing("http://test.com/ResourceManagerTest?foo=bar&choo=too");
329 }
330
TEST(ResourceManagerTest,UrlParsingWithFragment)331 TEST(ResourceManagerTest, UrlParsingWithFragment) {
332 TestUrlParsing("http://test.com/ResourceManagerTest#some/fragment");
333 }
334
TEST(ResourceManagerTest,UrlParsingWithQueryAndFragment)335 TEST(ResourceManagerTest, UrlParsingWithQueryAndFragment) {
336 TestUrlParsing("http://test.com/ResourceManagerTest?foo=bar#some/fragment");
337 }
338
TEST(ResourceManagerTest,UrlParsingWithFragmentAndQuery)339 TEST(ResourceManagerTest, UrlParsingWithFragmentAndQuery) {
340 TestUrlParsing("http://test.com/ResourceManagerTest#some/fragment?foo=bar");
341 }
342
343 namespace {
344
345 const char kProviderId[] = "provider";
346
347 // Content provider that performs simple tests.
348 class SimpleTestProvider : public TestProvider {
349 public:
350 enum Mode {
351 NOT_HANDLED,
352 CONTINUE,
353 STOP,
354 REMOVE,
355 REMOVE_ALL,
356 DO_NOTHING,
357 };
358
SimpleTestProvider(State * state,Mode mode,CefResourceManager * manager)359 SimpleTestProvider(State* state, Mode mode, CefResourceManager* manager)
360 : TestProvider(state), mode_(mode), manager_(manager) {}
361
SimpleTestProvider(State * state,Mode mode,CefResourceManager * manager,base::OnceClosure do_nothing_callback)362 SimpleTestProvider(State* state,
363 Mode mode,
364 CefResourceManager* manager,
365 base::OnceClosure do_nothing_callback)
366 : TestProvider(state),
367 mode_(mode),
368 manager_(manager),
369 do_nothing_callback_(std::move(do_nothing_callback)) {}
370
OnRequest(scoped_refptr<CefResourceManager::Request> request)371 bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
372 TestProvider::OnRequest(request);
373
374 if (mode_ == NOT_HANDLED)
375 return false;
376 else if (mode_ == CONTINUE)
377 request->Continue(nullptr);
378 else if (mode_ == STOP)
379 request->Stop();
380 else if (mode_ == REMOVE)
381 manager_->RemoveProviders(kProviderId);
382 else if (mode_ == REMOVE_ALL)
383 manager_->RemoveAllProviders();
384 else if (mode_ == DO_NOTHING) {
385 EXPECT_FALSE(do_nothing_callback_.is_null());
386 std::move(do_nothing_callback_).Run();
387 }
388
389 return true;
390 }
391
392 private:
393 Mode mode_;
394 CefResourceManager* manager_; // Weak reference.
395 base::OnceClosure do_nothing_callback_;
396
397 DISALLOW_COPY_AND_ASSIGN(SimpleTestProvider);
398 };
399
400 } // namespace
401
402 // Test with multiple providers that do not handle the request.
TEST(ResourceManagerTest,ProviderNotHandled)403 TEST(ResourceManagerTest, ProviderNotHandled) {
404 const char kUrl[] = "http://test.com/ResourceManagerTest";
405
406 ResourceManagerTestHandler::State state;
407 state.urls_.push_back(kUrl);
408
409 TestProvider::State provider_state1;
410 TestProvider::State provider_state2;
411
412 ProviderDestructHelper destruct_helper(2);
413 provider_state1.destruct_callback_ = destruct_helper.callback();
414 provider_state2.destruct_callback_ = destruct_helper.callback();
415
416 state.manager_->AddProvider(
417 new SimpleTestProvider(&provider_state1, SimpleTestProvider::NOT_HANDLED,
418 nullptr),
419 0, std::string());
420 state.manager_->AddProvider(
421 new SimpleTestProvider(&provider_state2, SimpleTestProvider::NOT_HANDLED,
422 nullptr),
423 0, std::string());
424
425 CefRefPtr<ResourceManagerTestHandler> handler =
426 new ResourceManagerTestHandler(&state);
427 handler->ExecuteTest();
428
429 ReleaseAndWaitForDestructor(handler);
430
431 state.manager_ = nullptr;
432
433 // Wait for the manager to be deleted.
434 destruct_helper.Wait();
435
436 // All providers are called.
437 EXPECT_TRUE(provider_state1.got_on_request_);
438 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
439 EXPECT_TRUE(provider_state1.got_destruct_);
440
441 EXPECT_TRUE(provider_state2.got_on_request_);
442 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
443 EXPECT_TRUE(provider_state2.got_destruct_);
444
445 EXPECT_EQ(state.messages_.size(), 1U);
446 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
447 }
448
449 // Test with multiple providers that all continue.
TEST(ResourceManagerTest,ProviderContinue)450 TEST(ResourceManagerTest, ProviderContinue) {
451 const char kUrl[] = "http://test.com/ResourceManagerTest";
452
453 ResourceManagerTestHandler::State state;
454 state.urls_.push_back(kUrl);
455
456 TestProvider::State provider_state1;
457 TestProvider::State provider_state2;
458
459 ProviderDestructHelper destruct_helper(2);
460 provider_state1.destruct_callback_ = destruct_helper.callback();
461 provider_state2.destruct_callback_ = destruct_helper.callback();
462
463 state.manager_->AddProvider(
464 new SimpleTestProvider(&provider_state1, SimpleTestProvider::CONTINUE,
465 nullptr),
466 0, std::string());
467 state.manager_->AddProvider(
468 new SimpleTestProvider(&provider_state2, SimpleTestProvider::CONTINUE,
469 nullptr),
470 0, std::string());
471
472 CefRefPtr<ResourceManagerTestHandler> handler =
473 new ResourceManagerTestHandler(&state);
474 handler->ExecuteTest();
475
476 ReleaseAndWaitForDestructor(handler);
477
478 state.manager_ = nullptr;
479
480 // Wait for the manager to be deleted.
481 destruct_helper.Wait();
482
483 // All providers are called.
484 EXPECT_TRUE(provider_state1.got_on_request_);
485 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
486 EXPECT_TRUE(provider_state1.got_destruct_);
487
488 EXPECT_TRUE(provider_state2.got_on_request_);
489 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
490 EXPECT_TRUE(provider_state2.got_destruct_);
491
492 EXPECT_EQ(state.messages_.size(), 1U);
493 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
494 }
495
496 // Test with multiple providers where the first one stops.
TEST(ResourceManagerTest,ProviderStop)497 TEST(ResourceManagerTest, ProviderStop) {
498 const char kUrl[] = "http://test.com/ResourceManagerTest";
499
500 ResourceManagerTestHandler::State state;
501 state.urls_.push_back(kUrl);
502
503 TestProvider::State provider_state1;
504 TestProvider::State provider_state2;
505
506 ProviderDestructHelper destruct_helper(2);
507 provider_state1.destruct_callback_ = destruct_helper.callback();
508 provider_state2.destruct_callback_ = destruct_helper.callback();
509
510 state.manager_->AddProvider(
511 new SimpleTestProvider(&provider_state1, SimpleTestProvider::STOP,
512 nullptr),
513 0, std::string());
514 state.manager_->AddProvider(
515 new SimpleTestProvider(&provider_state2, SimpleTestProvider::CONTINUE,
516 nullptr),
517 0, std::string());
518
519 CefRefPtr<ResourceManagerTestHandler> handler =
520 new ResourceManagerTestHandler(&state);
521 handler->ExecuteTest();
522
523 ReleaseAndWaitForDestructor(handler);
524
525 state.manager_ = nullptr;
526
527 // Wait for the manager to be deleted.
528 destruct_helper.Wait();
529
530 // 1st provider is called.
531 EXPECT_TRUE(provider_state1.got_on_request_);
532 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
533 EXPECT_TRUE(provider_state1.got_destruct_);
534
535 // 2nd provider is not called because the 1st provider stopped.
536 EXPECT_FALSE(provider_state2.got_on_request_);
537 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
538 EXPECT_TRUE(provider_state2.got_destruct_);
539
540 EXPECT_EQ(state.messages_.size(), 1U);
541 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
542 }
543
544 // Test with multiple providers where the first one removes multiple providers
545 // including itself.
TEST(ResourceManagerTest,ProviderRemove)546 TEST(ResourceManagerTest, ProviderRemove) {
547 const char kUrl[] = "http://test.com/ResourceManagerTest";
548
549 ResourceManagerTestHandler::State state;
550 state.urls_.push_back(kUrl);
551
552 TestProvider::State provider_state1;
553 TestProvider::State provider_state2;
554 TestProvider::State provider_state3;
555
556 ProviderDestructHelper destruct_helper(3);
557 provider_state1.destruct_callback_ = destruct_helper.callback();
558 provider_state2.destruct_callback_ = destruct_helper.callback();
559 provider_state3.destruct_callback_ = destruct_helper.callback();
560
561 state.manager_->AddProvider(
562 new SimpleTestProvider(&provider_state1, SimpleTestProvider::REMOVE,
563 state.manager_.get()),
564 0, kProviderId);
565 state.manager_->AddProvider(
566 new SimpleTestProvider(&provider_state2, SimpleTestProvider::CONTINUE,
567 nullptr),
568 0, kProviderId);
569 state.manager_->AddProvider(
570 new SimpleTestProvider(&provider_state3, SimpleTestProvider::CONTINUE,
571 nullptr),
572 1, std::string());
573
574 CefRefPtr<ResourceManagerTestHandler> handler =
575 new ResourceManagerTestHandler(&state);
576 handler->ExecuteTest();
577
578 ReleaseAndWaitForDestructor(handler);
579
580 state.manager_ = nullptr;
581
582 // Wait for the manager to be deleted.
583 destruct_helper.Wait();
584
585 // 1st provider is called and canceled.
586 EXPECT_TRUE(provider_state1.got_on_request_);
587 EXPECT_TRUE(provider_state1.got_on_request_canceled_);
588 EXPECT_TRUE(provider_state1.got_destruct_);
589
590 // 2nd provider is removed with the 1st provider due to sharing the same
591 // identifier.
592 EXPECT_FALSE(provider_state2.got_on_request_);
593 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
594 EXPECT_TRUE(provider_state2.got_destruct_);
595
596 // 3rd provider is called.
597 EXPECT_TRUE(provider_state3.got_on_request_);
598 EXPECT_FALSE(provider_state3.got_on_request_canceled_);
599 EXPECT_TRUE(provider_state3.got_destruct_);
600
601 EXPECT_EQ(state.messages_.size(), 1U);
602 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
603 }
604
605 // Test with multiple providers where the first provider removes all.
TEST(ResourceManagerTest,ProviderRemoveAll)606 TEST(ResourceManagerTest, ProviderRemoveAll) {
607 const char kUrl[] = "http://test.com/ResourceManagerTest";
608
609 ResourceManagerTestHandler::State state;
610 state.urls_.push_back(kUrl);
611
612 TestProvider::State provider_state1;
613 TestProvider::State provider_state2;
614 TestProvider::State provider_state3;
615
616 ProviderDestructHelper destruct_helper(3);
617 provider_state1.destruct_callback_ = destruct_helper.callback();
618 provider_state2.destruct_callback_ = destruct_helper.callback();
619 provider_state3.destruct_callback_ = destruct_helper.callback();
620
621 state.manager_->AddProvider(
622 new SimpleTestProvider(&provider_state1, SimpleTestProvider::REMOVE_ALL,
623 state.manager_.get()),
624 0, std::string());
625 state.manager_->AddProvider(
626 new SimpleTestProvider(&provider_state2, SimpleTestProvider::CONTINUE,
627 nullptr),
628 0, std::string());
629 state.manager_->AddProvider(
630 new SimpleTestProvider(&provider_state3, SimpleTestProvider::CONTINUE,
631 nullptr),
632 1, std::string());
633
634 CefRefPtr<ResourceManagerTestHandler> handler =
635 new ResourceManagerTestHandler(&state);
636 handler->ExecuteTest();
637
638 ReleaseAndWaitForDestructor(handler);
639
640 state.manager_ = nullptr;
641
642 // Wait for the manager to be deleted.
643 destruct_helper.Wait();
644
645 // 1st provider is called and canceled.
646 EXPECT_TRUE(provider_state1.got_on_request_);
647 EXPECT_TRUE(provider_state1.got_on_request_canceled_);
648 EXPECT_TRUE(provider_state1.got_destruct_);
649
650 // 2nd and 3rd providers are not called due to removal.
651 EXPECT_FALSE(provider_state2.got_on_request_);
652 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
653 EXPECT_TRUE(provider_state2.got_destruct_);
654
655 EXPECT_FALSE(provider_state3.got_on_request_);
656 EXPECT_FALSE(provider_state3.got_on_request_canceled_);
657 EXPECT_TRUE(provider_state3.got_destruct_);
658
659 EXPECT_EQ(state.messages_.size(), 1U);
660 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
661 }
662
663 // Test with multiple providers that do not continue and will be destroyed when
664 // the manager is destroyed.
TEST(ResourceManagerTest,ProviderDoNothing)665 TEST(ResourceManagerTest, ProviderDoNothing) {
666 const char kUrl[] = "http://test.com/ResourceManagerTest";
667
668 ResourceManagerTestHandler::State state;
669 state.urls_.push_back(kUrl);
670
671 TestProvider::State provider_state1;
672 TestProvider::State provider_state2;
673
674 ProviderDestructHelper destruct_helper(2);
675 provider_state1.destruct_callback_ = destruct_helper.callback();
676 provider_state2.destruct_callback_ = destruct_helper.callback();
677
678 CefRefPtr<ResourceManagerTestHandler> handler =
679 new ResourceManagerTestHandler(&state);
680
681 // DelayedDestroyTest will be executed from SimpleTestHandler::OnRequest.
682 state.manager_->AddProvider(
683 new SimpleTestProvider(
684 &provider_state1, SimpleTestProvider::DO_NOTHING, nullptr,
685 base::BindOnce(&ResourceManagerTestHandler::DelayedDestroyTest,
686 handler)),
687 0, std::string());
688 state.manager_->AddProvider(
689 new SimpleTestProvider(&provider_state2, SimpleTestProvider::DO_NOTHING,
690 nullptr),
691 0, std::string());
692
693 handler->ExecuteTest();
694
695 // Destroy the resource manager before the handler so that pending requests
696 // are canceled. ResourceManagerTestHandler::GetResourceHandler will be called
697 // after the manager is destroyed.
698 state.manager_ = nullptr;
699
700 // Wait for the manager to be deleted.
701 destruct_helper.Wait();
702
703 ReleaseAndWaitForDestructor(handler);
704
705 // Only the first provider is called. It will be canceled when the manager is
706 // destroyed.
707 EXPECT_TRUE(provider_state1.got_on_request_);
708 EXPECT_TRUE(provider_state1.got_on_request_canceled_);
709 EXPECT_TRUE(provider_state1.got_destruct_);
710
711 EXPECT_FALSE(provider_state2.got_on_request_);
712 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
713 EXPECT_TRUE(provider_state2.got_destruct_);
714
715 // Nothing completed.
716 EXPECT_EQ(state.messages_.size(), 0U);
717 }
718
719 // Test AddContentProvider.
TEST(ResourceManagerTest,ContentProvider)720 TEST(ResourceManagerTest, ContentProvider) {
721 const char kUrl1[] = "http://test.com/ResourceManagerTest1";
722 const char kUrl2[] = "http://test.com/ResourceManagerTest2";
723 const char kUrl3[] = "http://test.com/ResourceManagerTest3";
724
725 const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
726 const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
727 const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);
728
729 ResourceManagerTestHandler::State state;
730 state.urls_.push_back(kUrl1);
731 state.urls_.push_back(kUrl2);
732 state.urls_.push_back(kUrl3);
733
734 // Only the first 2 URLs will be handled.
735 state.manager_->AddContentProvider(kUrl1, CreateContents(success1_message),
736 "text/html", 0, std::string());
737 state.manager_->AddContentProvider(kUrl2, CreateContents(success2_message),
738 "text/html", 0, std::string());
739
740 CefRefPtr<ResourceManagerTestHandler> handler =
741 new ResourceManagerTestHandler(&state);
742 handler->ExecuteTest();
743
744 ReleaseAndWaitForDestructor(handler);
745
746 state.manager_ = nullptr;
747
748 // Wait for the manager to be deleted.
749 WaitForIOThread();
750
751 // Both providers are called and return the expected results.
752 EXPECT_EQ(state.messages_.size(), 3U);
753 EXPECT_EQ(success1_message, state.messages_[0]);
754 EXPECT_EQ(success2_message, state.messages_[1]);
755 EXPECT_EQ(not_handled_message, state.messages_[2]);
756 }
757
758 // Test AddDirectoryProvider.
TEST(ResourceManagerTest,DirectoryProvider)759 TEST(ResourceManagerTest, DirectoryProvider) {
760 const char kUrlBase[] = "http://test.com/ResourceManager";
761 const char kFile1[] = "File1.html";
762 const char kFile2[] = "File2.html";
763 const char kFile3[] = "File3.html";
764 const char kFile4[] = "File4.html";
765
766 const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
767 const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
768 const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
769 const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);
770
771 ResourceManagerTestHandler::State state;
772 state.urls_.push_back(kUrlBase + std::string("/") + kFile1);
773 state.urls_.push_back(kUrlBase + std::string("/") + kFile2);
774 state.urls_.push_back(kUrlBase + std::string("/sub/") + kFile3);
775 state.urls_.push_back(kUrlBase + std::string("/") + kFile4);
776
777 CefScopedTempDir scoped_dir;
778 EXPECT_TRUE(scoped_dir.CreateUniqueTempDir());
779
780 // Write the files to disk.
781 const std::string& temp_dir = scoped_dir.GetPath();
782 WriteFile(client::file_util::JoinPath(temp_dir, kFile1),
783 CreateContents(success1_message));
784 WriteFile(client::file_util::JoinPath(temp_dir, kFile2),
785 CreateContents(success2_message));
786
787 // Also include a subdirectory.
788 const std::string& sub_dir = client::file_util::JoinPath(temp_dir, "sub");
789 EXPECT_TRUE(CefCreateDirectory(sub_dir));
790 WriteFile(client::file_util::JoinPath(sub_dir, kFile3),
791 CreateContents(success3_message));
792
793 state.manager_->AddDirectoryProvider(kUrlBase, temp_dir, 0, std::string());
794
795 CefRefPtr<ResourceManagerTestHandler> handler =
796 new ResourceManagerTestHandler(&state);
797 handler->ExecuteTest();
798
799 ReleaseAndWaitForDestructor(handler);
800
801 state.manager_ = nullptr;
802
803 // Wait for the manager to be deleted.
804 WaitForIOThread();
805
806 EXPECT_TRUE(scoped_dir.Delete());
807
808 // The first 3 URLs are handled.
809 EXPECT_EQ(state.messages_.size(), 4U);
810 EXPECT_EQ(success1_message, state.messages_[0]);
811 EXPECT_EQ(success2_message, state.messages_[1]);
812 EXPECT_EQ(success3_message, state.messages_[2]);
813 EXPECT_EQ(not_handled_message, state.messages_[3]);
814 }
815
816 // Test AddArchiveProvider.
TEST(ResourceManagerTest,ArchiveProvider)817 TEST(ResourceManagerTest, ArchiveProvider) {
818 const char kUrlBase[] = "http://test.com/ResourceManager";
819 const char kFile1[] = "File1.html";
820 const char kFile2[] = "File2.html";
821 const char kFile3[] = "File3.html";
822 const char kFile4[] = "File4.html";
823
824 const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
825 const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
826 const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
827 const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);
828
829 ResourceManagerTestHandler::State state;
830 state.urls_.push_back(kUrlBase + std::string("/") + kFile1);
831 state.urls_.push_back(kUrlBase + std::string("/") + kFile2);
832 state.urls_.push_back(kUrlBase + std::string("/sub/") + kFile3);
833 state.urls_.push_back(kUrlBase + std::string("/") + kFile4);
834
835 // Only the first 2 URLs will be handled.
836 CefScopedTempDir scoped_dir;
837 EXPECT_TRUE(scoped_dir.CreateUniqueTempDir());
838
839 const std::string& temp_dir = scoped_dir.GetPath();
840
841 // Write the files to disk.
842 const std::string& file_dir = client::file_util::JoinPath(temp_dir, "files");
843 EXPECT_TRUE(CefCreateDirectory(file_dir));
844 WriteFile(client::file_util::JoinPath(file_dir, kFile1),
845 CreateContents(success1_message));
846 WriteFile(client::file_util::JoinPath(file_dir, kFile2),
847 CreateContents(success2_message));
848
849 // Also include a subdirectory.
850 const std::string& sub_dir = client::file_util::JoinPath(file_dir, "sub");
851 EXPECT_TRUE(CefCreateDirectory(sub_dir));
852 WriteFile(client::file_util::JoinPath(sub_dir, kFile3),
853 CreateContents(success3_message));
854
855 const std::string& archive_path =
856 client::file_util::JoinPath(temp_dir, "archive.zip");
857
858 // Create the archive file.
859 EXPECT_TRUE(CefZipDirectory(file_dir, archive_path, false));
860
861 state.manager_->AddArchiveProvider(kUrlBase, archive_path, std::string(), 0,
862 std::string());
863
864 CefRefPtr<ResourceManagerTestHandler> handler =
865 new ResourceManagerTestHandler(&state);
866 handler->ExecuteTest();
867
868 ReleaseAndWaitForDestructor(handler);
869
870 state.manager_ = nullptr;
871
872 // Wait for the manager to be deleted.
873 WaitForIOThread();
874
875 EXPECT_TRUE(scoped_dir.Delete());
876
877 // The first 3 URLs are handled.
878 EXPECT_EQ(state.messages_.size(), 4U);
879 EXPECT_EQ(success1_message, state.messages_[0]);
880 EXPECT_EQ(success2_message, state.messages_[1]);
881 EXPECT_EQ(success3_message, state.messages_[2]);
882 EXPECT_EQ(not_handled_message, state.messages_[3]);
883 }
884
885 namespace {
886
887 // Content provider that only handles a single request.
888 class OneShotProvider : public CefResourceManager::Provider {
889 public:
OneShotProvider(const std::string & content,base::OnceClosure destruct_callback)890 OneShotProvider(const std::string& content,
891 base::OnceClosure destruct_callback)
892 : done_(false),
893 content_(content),
894 destruct_callback_(std::move(destruct_callback)) {
895 EXPECT_FALSE(content.empty());
896 }
897
~OneShotProvider()898 ~OneShotProvider() {
899 CEF_REQUIRE_IO_THREAD();
900 std::move(destruct_callback_).Run();
901 }
902
OnRequest(scoped_refptr<CefResourceManager::Request> request)903 bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
904 CEF_REQUIRE_IO_THREAD();
905
906 if (done_) {
907 // Provider only handles a single request.
908 return false;
909 }
910
911 done_ = true;
912
913 CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
914 static_cast<void*>(const_cast<char*>(content_.data())),
915 content_.length());
916
917 request->Continue(new CefStreamResourceHandler("text/html", stream));
918 return true;
919 }
920
921 private:
922 bool done_;
923 std::string content_;
924 base::OnceClosure destruct_callback_;
925
926 DISALLOW_COPY_AND_ASSIGN(OneShotProvider);
927 };
928
929 } // namespace
930
931 // Test that providers are called in the expected order and return expected
932 // results.
TEST(ResourceManagerTest,ProviderOrder)933 TEST(ResourceManagerTest, ProviderOrder) {
934 const char kUrl1[] = "http://test.com/ResourceManagerTest1";
935 const char kUrl2[] = "http://test.com/ResourceManagerTest2";
936 const char kUrl3[] = "http://test.com/ResourceManagerTest3";
937 const char kUrl4[] = "http://test.com/ResourceManagerTest4";
938 const char kUrl5[] = "http://test.com/ResourceManagerTest5";
939
940 const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
941 const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
942 const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
943 const std::string& success4_message = CreateMessage(kDoneMsg, "Success4");
944 const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);
945
946 ResourceManagerTestHandler::State state;
947 state.urls_.push_back(kUrl1);
948 state.urls_.push_back(kUrl2);
949 state.urls_.push_back(kUrl3);
950 state.urls_.push_back(kUrl4);
951 state.urls_.push_back(kUrl5);
952
953 ProviderDestructHelper destruct_helper(4);
954
955 // Resulting order should be sequential; success1 .. success4.
956 state.manager_->AddProvider(
957 new OneShotProvider(CreateContents(success2_message),
958 destruct_helper.callback()),
959 0, std::string());
960 state.manager_->AddProvider(
961 new OneShotProvider(CreateContents(success1_message),
962 destruct_helper.callback()),
963 -100, std::string());
964 state.manager_->AddProvider(
965 new OneShotProvider(CreateContents(success4_message),
966 destruct_helper.callback()),
967 100, std::string());
968 state.manager_->AddProvider(
969 new OneShotProvider(CreateContents(success3_message),
970 destruct_helper.callback()),
971 0, std::string());
972
973 CefRefPtr<ResourceManagerTestHandler> handler =
974 new ResourceManagerTestHandler(&state);
975 handler->ExecuteTest();
976
977 ReleaseAndWaitForDestructor(handler);
978
979 state.manager_ = nullptr;
980
981 // Wait for the manager to be deleted.
982 destruct_helper.Wait();
983
984 EXPECT_EQ(state.messages_.size(), 5U);
985 EXPECT_EQ(success1_message, state.messages_[0]);
986 EXPECT_EQ(success2_message, state.messages_[1]);
987 EXPECT_EQ(success3_message, state.messages_[2]);
988 EXPECT_EQ(success4_message, state.messages_[3]);
989 EXPECT_EQ(not_handled_message, state.messages_[4]);
990 }
991
992 namespace {
993
994 // Content provider that returns the path component as the result.
995 class EchoProvider : public CefResourceManager::Provider {
996 public:
EchoProvider(const std::string & base_url)997 EchoProvider(const std::string& base_url) : base_url_(base_url) {
998 EXPECT_TRUE(!base_url_.empty());
999 }
1000
OnRequest(scoped_refptr<CefResourceManager::Request> request)1001 bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
1002 CEF_REQUIRE_IO_THREAD();
1003
1004 const std::string& url = request->url();
1005 if (url.find(base_url_) != 0U) {
1006 // Not handled by this provider.
1007 return false;
1008 }
1009
1010 const std::string& content = CreateContents(url);
1011
1012 // Parse the URL to identify the delay.
1013 int delay = atoi(url.substr(base_url_.size()).data());
1014 EXPECT_GE(delay, 0);
1015
1016 CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
1017 static_cast<void*>(const_cast<char*>(content.data())),
1018 content.length());
1019
1020 CefRefPtr<CefStreamResourceHandler> handler(
1021 new CefStreamResourceHandler("text/html", stream));
1022 CefPostDelayedTask(TID_IO,
1023 base::BindOnce(&CefResourceManager::Request::Continue,
1024 request, handler),
1025 delay);
1026
1027 return true;
1028 }
1029
1030 private:
1031 std::string base_url_;
1032
1033 DISALLOW_COPY_AND_ASSIGN(EchoProvider);
1034 };
1035
1036 } // namespace
1037
1038 // Test that many requests pending at the same time complete in the expected
1039 // order and return correct results.
TEST(ResourceManagerTest,ManyRequests)1040 TEST(ResourceManagerTest, ManyRequests) {
1041 const char kUrl[] = "http://test.com/ResourceManagerTest";
1042 const char kBaseUrl[] = "http://test.com/ResourceManagerSubTest/";
1043
1044 ResourceManagerTestHandler::State state;
1045 state.urls_.push_back(kUrl);
1046
1047 state.expected_message_ct_ = 50U;
1048
1049 // Build a page with lots of iframes.
1050 std::stringstream ss;
1051 ss << "<html><body>";
1052 for (size_t i = 0U; i < state.expected_message_ct_; ++i) {
1053 ss << "<iframe src=\"" << kBaseUrl << (i * 10) << "\"></iframe>";
1054 }
1055 ss << "</body></html>";
1056
1057 state.manager_->AddContentProvider(kUrl, ss.str(), "text/html", 0,
1058 std::string());
1059 state.manager_->AddProvider(new EchoProvider(kBaseUrl), 0, std::string());
1060
1061 CefRefPtr<ResourceManagerTestHandler> handler =
1062 new ResourceManagerTestHandler(&state);
1063 handler->ExecuteTest();
1064
1065 ReleaseAndWaitForDestructor(handler);
1066
1067 state.manager_ = nullptr;
1068
1069 // Wait for the manager to be deleted.
1070 WaitForIOThread();
1071
1072 EXPECT_EQ(state.messages_.size(), state.expected_message_ct_);
1073
1074 // Requests should complete in order due to the delay.
1075 for (size_t i = 0; i < state.messages_.size(); ++i) {
1076 ss.str("");
1077 ss << kBaseUrl << (i * 10);
1078 EXPECT_EQ(ss.str(), state.messages_[i]);
1079 }
1080 }
1081
1082 namespace {
1083
1084 // Content provider that only handles a single request and then removes itself
1085 // from the manager.
1086 class OneShotRemovalProvider : public TestProvider {
1087 public:
OneShotRemovalProvider(State * state,const std::string & content,CefResourceManager * manager,const std::string & identifier,bool remove_before_continue)1088 OneShotRemovalProvider(State* state,
1089 const std::string& content,
1090 CefResourceManager* manager,
1091 const std::string& identifier,
1092 bool remove_before_continue)
1093 : TestProvider(state),
1094 content_(content),
1095 manager_(manager),
1096 identifier_(identifier),
1097 remove_before_continue_(remove_before_continue) {
1098 EXPECT_FALSE(content.empty());
1099 }
1100
OnRequest(scoped_refptr<CefResourceManager::Request> request)1101 bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
1102 TestProvider::OnRequest(request);
1103
1104 CefRefPtr<CefStreamReader> stream = CefStreamReader::CreateForData(
1105 static_cast<void*>(const_cast<char*>(content_.data())),
1106 content_.length());
1107
1108 if (remove_before_continue_) {
1109 // Removing the provider before continuing should trigger a call to
1110 // OnRequestCanceled.
1111 if (identifier_.empty())
1112 manager_->RemoveAllProviders();
1113 else
1114 manager_->RemoveProviders(identifier_);
1115 }
1116
1117 request->Continue(new CefStreamResourceHandler("text/html", stream));
1118
1119 if (!remove_before_continue_) {
1120 // The request has already completed so OnRequestCanceled is not called.
1121 if (identifier_.empty())
1122 manager_->RemoveAllProviders();
1123 else
1124 manager_->RemoveProviders(identifier_);
1125 }
1126
1127 return true;
1128 }
1129
1130 private:
1131 std::string content_;
1132 CefResourceManager* manager_; // Weak reference.
1133 std::string identifier_;
1134 bool remove_before_continue_;
1135
1136 DISALLOW_COPY_AND_ASSIGN(OneShotRemovalProvider);
1137 };
1138
1139 } // namespace
1140
1141 // Test that removal of the current provider after continue has the expected
1142 // results.
TEST(ResourceManagerTest,RemoveProviderAfterContinue)1143 TEST(ResourceManagerTest, RemoveProviderAfterContinue) {
1144 const char kUrl1[] = "http://test.com/ResourceManagerTest1";
1145 const char kUrl2[] = "http://test.com/ResourceManagerTest2";
1146 const char kUrl3[] = "http://test.com/ResourceManagerTest3";
1147 const char kUrl4[] = "http://test.com/ResourceManagerTest4";
1148
1149 const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
1150 const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
1151 const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
1152 const std::string& success4_message = CreateMessage(kDoneMsg, "Success4");
1153 const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);
1154
1155 ResourceManagerTestHandler::State state;
1156 state.urls_.push_back(kUrl1);
1157 state.urls_.push_back(kUrl2);
1158 state.urls_.push_back(kUrl3);
1159 state.urls_.push_back(kUrl4);
1160
1161 TestProvider::State provider_state1;
1162 TestProvider::State provider_state2;
1163 TestProvider::State provider_state3;
1164 TestProvider::State provider_state4;
1165
1166 ProviderDestructHelper destruct_helper(4);
1167 provider_state1.destruct_callback_ = destruct_helper.callback();
1168 provider_state2.destruct_callback_ = destruct_helper.callback();
1169 provider_state3.destruct_callback_ = destruct_helper.callback();
1170 provider_state4.destruct_callback_ = destruct_helper.callback();
1171
1172 const char kIdentifier1[] = "id1";
1173 const char kIdentifier2[] = "id2";
1174 const char kIdentifier4[] = "id4";
1175
1176 // Resulting order should be sequential; success1 .. success4.
1177 state.manager_->AddProvider(
1178 new OneShotRemovalProvider(&provider_state2,
1179 CreateContents(success2_message),
1180 state.manager_.get(), kIdentifier2, false),
1181 0, kIdentifier2);
1182 state.manager_->AddProvider(
1183 new OneShotRemovalProvider(&provider_state1,
1184 CreateContents(success1_message),
1185 state.manager_.get(), kIdentifier1, false),
1186 -100, kIdentifier1);
1187 state.manager_->AddProvider(
1188 new OneShotRemovalProvider(&provider_state4,
1189 CreateContents(success4_message),
1190 state.manager_.get(), kIdentifier4, false),
1191 100, kIdentifier4);
1192 // Will be removed at the same time as #2 and therefore never called.
1193 state.manager_->AddProvider(
1194 new OneShotRemovalProvider(&provider_state3,
1195 CreateContents(success3_message),
1196 state.manager_.get(), kIdentifier2, false),
1197 0, kIdentifier2);
1198
1199 CefRefPtr<ResourceManagerTestHandler> handler =
1200 new ResourceManagerTestHandler(&state);
1201 handler->ExecuteTest();
1202
1203 ReleaseAndWaitForDestructor(handler);
1204
1205 state.manager_ = nullptr;
1206
1207 // Wait for the manager to be deleted.
1208 destruct_helper.Wait();
1209
1210 // All providers except for 3 (which is removed at the same time as 2 and
1211 // therefore never executed) should complete.
1212 EXPECT_EQ(state.messages_.size(), 4U);
1213 EXPECT_EQ(success1_message, state.messages_[0]);
1214 EXPECT_EQ(success2_message, state.messages_[1]);
1215 EXPECT_EQ(success4_message, state.messages_[2]);
1216 EXPECT_EQ(not_handled_message, state.messages_[3]);
1217
1218 EXPECT_TRUE(provider_state1.got_on_request_);
1219 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
1220 EXPECT_TRUE(provider_state1.got_destruct_);
1221
1222 EXPECT_TRUE(provider_state2.got_on_request_);
1223 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
1224 EXPECT_TRUE(provider_state2.got_destruct_);
1225
1226 // Removed at the same time as 2 and therefore not executed.
1227 EXPECT_FALSE(provider_state3.got_on_request_);
1228 EXPECT_FALSE(provider_state3.got_on_request_canceled_);
1229 EXPECT_TRUE(provider_state3.got_destruct_);
1230
1231 EXPECT_TRUE(provider_state4.got_on_request_);
1232 EXPECT_FALSE(provider_state4.got_on_request_canceled_);
1233 EXPECT_TRUE(provider_state4.got_destruct_);
1234 }
1235
1236 // Test that removal of the current provider before continue has the expected
1237 // results.
TEST(ResourceManagerTest,RemoveProviderBeforeContinue)1238 TEST(ResourceManagerTest, RemoveProviderBeforeContinue) {
1239 const char kUrl1[] = "http://test.com/ResourceManagerTest1";
1240 const char kUrl2[] = "http://test.com/ResourceManagerTest2";
1241 const char kUrl3[] = "http://test.com/ResourceManagerTest3";
1242 const char kUrl4[] = "http://test.com/ResourceManagerTest4";
1243
1244 const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
1245 const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
1246 const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
1247 const std::string& success4_message = CreateMessage(kDoneMsg, "Success4");
1248 const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);
1249
1250 ResourceManagerTestHandler::State state;
1251 state.urls_.push_back(kUrl1);
1252 state.urls_.push_back(kUrl2);
1253 state.urls_.push_back(kUrl3);
1254 state.urls_.push_back(kUrl4);
1255
1256 TestProvider::State provider_state1;
1257 TestProvider::State provider_state2;
1258 TestProvider::State provider_state3;
1259 TestProvider::State provider_state4;
1260
1261 ProviderDestructHelper destruct_helper(4);
1262 provider_state1.destruct_callback_ = destruct_helper.callback();
1263 provider_state2.destruct_callback_ = destruct_helper.callback();
1264 provider_state3.destruct_callback_ = destruct_helper.callback();
1265 provider_state4.destruct_callback_ = destruct_helper.callback();
1266
1267 const char kIdentifier1[] = "id1";
1268 const char kIdentifier2[] = "id2";
1269 const char kIdentifier4[] = "id4";
1270
1271 // Resulting order should be sequential; success1 .. success4.
1272 state.manager_->AddProvider(
1273 new OneShotRemovalProvider(&provider_state2,
1274 CreateContents(success2_message),
1275 state.manager_.get(), kIdentifier2, true),
1276 0, kIdentifier2);
1277 state.manager_->AddProvider(
1278 new OneShotRemovalProvider(&provider_state1,
1279 CreateContents(success1_message),
1280 state.manager_.get(), kIdentifier1, true),
1281 -100, kIdentifier1);
1282 state.manager_->AddProvider(
1283 new OneShotRemovalProvider(&provider_state4,
1284 CreateContents(success4_message),
1285 state.manager_.get(), kIdentifier4, true),
1286 100, kIdentifier4);
1287 state.manager_->AddProvider(
1288 new OneShotRemovalProvider(&provider_state3,
1289 CreateContents(success3_message),
1290 state.manager_.get(), kIdentifier2, true),
1291 0, kIdentifier2);
1292
1293 CefRefPtr<ResourceManagerTestHandler> handler =
1294 new ResourceManagerTestHandler(&state);
1295 handler->ExecuteTest();
1296
1297 ReleaseAndWaitForDestructor(handler);
1298
1299 state.manager_ = nullptr;
1300
1301 // Wait for the manager to be deleted.
1302 destruct_helper.Wait();
1303
1304 // No providers should complete.
1305 EXPECT_EQ(state.messages_.size(), 4U);
1306 EXPECT_EQ(not_handled_message, state.messages_[0]);
1307 EXPECT_EQ(not_handled_message, state.messages_[1]);
1308 EXPECT_EQ(not_handled_message, state.messages_[2]);
1309 EXPECT_EQ(not_handled_message, state.messages_[3]);
1310
1311 // All providers except 3 should be called and then canceled.
1312 EXPECT_TRUE(provider_state1.got_on_request_);
1313 EXPECT_TRUE(provider_state1.got_on_request_canceled_);
1314 EXPECT_TRUE(provider_state1.got_destruct_);
1315
1316 EXPECT_TRUE(provider_state2.got_on_request_);
1317 EXPECT_TRUE(provider_state2.got_on_request_canceled_);
1318 EXPECT_TRUE(provider_state2.got_destruct_);
1319
1320 // Removed at the same time as 2 and therefore not executed.
1321 EXPECT_FALSE(provider_state3.got_on_request_);
1322 EXPECT_FALSE(provider_state3.got_on_request_canceled_);
1323 EXPECT_TRUE(provider_state3.got_destruct_);
1324
1325 EXPECT_TRUE(provider_state4.got_on_request_);
1326 EXPECT_TRUE(provider_state4.got_on_request_canceled_);
1327 EXPECT_TRUE(provider_state4.got_destruct_);
1328 }
1329
1330 // Test that removal of all providers after continue has the expected results.
TEST(ResourceManagerTest,RemoveAllProvidersAfterContinue)1331 TEST(ResourceManagerTest, RemoveAllProvidersAfterContinue) {
1332 const char kUrl1[] = "http://test.com/ResourceManagerTest1";
1333 const char kUrl2[] = "http://test.com/ResourceManagerTest2";
1334 const char kUrl3[] = "http://test.com/ResourceManagerTest3";
1335 const char kUrl4[] = "http://test.com/ResourceManagerTest4";
1336
1337 const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
1338 const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
1339 const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
1340 const std::string& success4_message = CreateMessage(kDoneMsg, "Success4");
1341 const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);
1342
1343 ResourceManagerTestHandler::State state;
1344 state.urls_.push_back(kUrl1);
1345 state.urls_.push_back(kUrl2);
1346 state.urls_.push_back(kUrl3);
1347 state.urls_.push_back(kUrl4);
1348
1349 TestProvider::State provider_state1;
1350 TestProvider::State provider_state2;
1351 TestProvider::State provider_state3;
1352 TestProvider::State provider_state4;
1353
1354 ProviderDestructHelper destruct_helper(4);
1355 provider_state1.destruct_callback_ = destruct_helper.callback();
1356 provider_state2.destruct_callback_ = destruct_helper.callback();
1357 provider_state3.destruct_callback_ = destruct_helper.callback();
1358 provider_state4.destruct_callback_ = destruct_helper.callback();
1359
1360 // Resulting order should be sequential; success1 .. success4.
1361 state.manager_->AddProvider(
1362 new OneShotRemovalProvider(&provider_state2,
1363 CreateContents(success2_message),
1364 state.manager_.get(), std::string(), false),
1365 0, std::string());
1366 state.manager_->AddProvider(
1367 new OneShotRemovalProvider(&provider_state1,
1368 CreateContents(success1_message),
1369 state.manager_.get(), std::string(), false),
1370 -100, std::string());
1371 state.manager_->AddProvider(
1372 new OneShotRemovalProvider(&provider_state4,
1373 CreateContents(success4_message),
1374 state.manager_.get(), std::string(), false),
1375 100, std::string());
1376 // Will be removed at the same time as #2 and therefore never called.
1377 state.manager_->AddProvider(
1378 new OneShotRemovalProvider(&provider_state3,
1379 CreateContents(success3_message),
1380 state.manager_.get(), std::string(), false),
1381 0, std::string());
1382
1383 CefRefPtr<ResourceManagerTestHandler> handler =
1384 new ResourceManagerTestHandler(&state);
1385 handler->ExecuteTest();
1386
1387 ReleaseAndWaitForDestructor(handler);
1388
1389 state.manager_ = nullptr;
1390
1391 // Wait for the manager to be deleted.
1392 destruct_helper.Wait();
1393
1394 // Only the 1st provider should complete
1395 EXPECT_EQ(state.messages_.size(), 4U);
1396 EXPECT_EQ(success1_message, state.messages_[0]);
1397 EXPECT_EQ(not_handled_message, state.messages_[1]);
1398 EXPECT_EQ(not_handled_message, state.messages_[2]);
1399 EXPECT_EQ(not_handled_message, state.messages_[3]);
1400
1401 EXPECT_TRUE(provider_state1.got_on_request_);
1402 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
1403 EXPECT_TRUE(provider_state1.got_destruct_);
1404
1405 EXPECT_FALSE(provider_state2.got_on_request_);
1406 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
1407 EXPECT_TRUE(provider_state2.got_destruct_);
1408
1409 EXPECT_FALSE(provider_state3.got_on_request_);
1410 EXPECT_FALSE(provider_state3.got_on_request_canceled_);
1411 EXPECT_TRUE(provider_state3.got_destruct_);
1412
1413 EXPECT_FALSE(provider_state4.got_on_request_);
1414 EXPECT_FALSE(provider_state4.got_on_request_canceled_);
1415 EXPECT_TRUE(provider_state4.got_destruct_);
1416 }
1417
1418 // Test that removal of all providers before continue has the expected results.
TEST(ResourceManagerTest,RemoveAllProvidersBeforeContinue)1419 TEST(ResourceManagerTest, RemoveAllProvidersBeforeContinue) {
1420 const char kUrl1[] = "http://test.com/ResourceManagerTest1";
1421 const char kUrl2[] = "http://test.com/ResourceManagerTest2";
1422 const char kUrl3[] = "http://test.com/ResourceManagerTest3";
1423 const char kUrl4[] = "http://test.com/ResourceManagerTest4";
1424
1425 const std::string& success1_message = CreateMessage(kDoneMsg, "Success1");
1426 const std::string& success2_message = CreateMessage(kDoneMsg, "Success2");
1427 const std::string& success3_message = CreateMessage(kDoneMsg, "Success3");
1428 const std::string& success4_message = CreateMessage(kDoneMsg, "Success4");
1429 const std::string& not_handled_message = CreateMessage(kDoneMsg, kNotHandled);
1430
1431 ResourceManagerTestHandler::State state;
1432 state.urls_.push_back(kUrl1);
1433 state.urls_.push_back(kUrl2);
1434 state.urls_.push_back(kUrl3);
1435 state.urls_.push_back(kUrl4);
1436
1437 TestProvider::State provider_state1;
1438 TestProvider::State provider_state2;
1439 TestProvider::State provider_state3;
1440 TestProvider::State provider_state4;
1441
1442 ProviderDestructHelper destruct_helper(4);
1443 provider_state1.destruct_callback_ = destruct_helper.callback();
1444 provider_state2.destruct_callback_ = destruct_helper.callback();
1445 provider_state3.destruct_callback_ = destruct_helper.callback();
1446 provider_state4.destruct_callback_ = destruct_helper.callback();
1447
1448 // Resulting order should be sequential; success1 .. success4.
1449 state.manager_->AddProvider(
1450 new OneShotRemovalProvider(&provider_state2,
1451 CreateContents(success2_message),
1452 state.manager_.get(), std::string(), true),
1453 0, std::string());
1454 state.manager_->AddProvider(
1455 new OneShotRemovalProvider(&provider_state1,
1456 CreateContents(success1_message),
1457 state.manager_.get(), std::string(), true),
1458 -100, std::string());
1459 state.manager_->AddProvider(
1460 new OneShotRemovalProvider(&provider_state4,
1461 CreateContents(success4_message),
1462 state.manager_.get(), std::string(), true),
1463 100, std::string());
1464 // Will be removed at the same time as #2 and therefore never called.
1465 state.manager_->AddProvider(
1466 new OneShotRemovalProvider(&provider_state3,
1467 CreateContents(success3_message),
1468 state.manager_.get(), std::string(), true),
1469 0, std::string());
1470
1471 CefRefPtr<ResourceManagerTestHandler> handler =
1472 new ResourceManagerTestHandler(&state);
1473 handler->ExecuteTest();
1474
1475 ReleaseAndWaitForDestructor(handler);
1476
1477 state.manager_ = nullptr;
1478
1479 // Wait for the manager to be deleted.
1480 destruct_helper.Wait();
1481
1482 // No providers should complete.
1483 EXPECT_EQ(state.messages_.size(), 4U);
1484 EXPECT_EQ(not_handled_message, state.messages_[0]);
1485 EXPECT_EQ(not_handled_message, state.messages_[1]);
1486 EXPECT_EQ(not_handled_message, state.messages_[2]);
1487 EXPECT_EQ(not_handled_message, state.messages_[3]);
1488
1489 // 1st provider should also be canceled.
1490 EXPECT_TRUE(provider_state1.got_on_request_);
1491 EXPECT_TRUE(provider_state1.got_on_request_canceled_);
1492 EXPECT_TRUE(provider_state1.got_destruct_);
1493
1494 EXPECT_FALSE(provider_state2.got_on_request_);
1495 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
1496 EXPECT_TRUE(provider_state2.got_destruct_);
1497
1498 EXPECT_FALSE(provider_state3.got_on_request_);
1499 EXPECT_FALSE(provider_state3.got_on_request_canceled_);
1500 EXPECT_TRUE(provider_state3.got_destruct_);
1501
1502 EXPECT_FALSE(provider_state4.got_on_request_);
1503 EXPECT_FALSE(provider_state4.got_on_request_canceled_);
1504 EXPECT_TRUE(provider_state4.got_destruct_);
1505 }
1506
1507 namespace {
1508
1509 // Test the URL filter capability.
1510 class UrlFilterTestProvider : public TestProvider {
1511 public:
UrlFilterTestProvider(State * state,const std::string & expected_url,const std::string & expected_url_after_filter)1512 UrlFilterTestProvider(State* state,
1513 const std::string& expected_url,
1514 const std::string& expected_url_after_filter)
1515 : TestProvider(state),
1516 expected_url_(expected_url),
1517 expected_url_after_filter_(expected_url_after_filter) {}
1518
OnRequest(scoped_refptr<CefResourceManager::Request> request)1519 bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
1520 TestProvider::OnRequest(request);
1521
1522 // Request::url is already filtered.
1523 EXPECT_EQ(expected_url_, request->url());
1524
1525 // Explicitly filter the URL again.
1526 const std::string& filtered_url =
1527 request->url_filter().Run(request->request()->GetURL());
1528 EXPECT_EQ(expected_url_after_filter_, filtered_url);
1529
1530 request->Continue(nullptr);
1531 return true;
1532 }
1533
1534 private:
1535 std::string expected_url_;
1536 std::string expected_url_after_filter_;
1537 DISALLOW_COPY_AND_ASSIGN(UrlFilterTestProvider);
1538 };
1539
TestUrlFilter(const std::string & url)1540 std::string TestUrlFilter(const std::string& url) {
1541 return url + "Rewrite";
1542 }
1543
1544 // Add to the URL but keep the query component.
TestUrlFilterWithQuery(const std::string & url)1545 std::string TestUrlFilterWithQuery(const std::string& url) {
1546 size_t pos = url.find('?');
1547 if (pos == std::string::npos)
1548 return url;
1549 return url.substr(0, pos) + "Rewrite" + url.substr(pos);
1550 }
1551
1552 // Add to the URL but keep the fragment component.
TestUrlFilterWithFragment(const std::string & url)1553 std::string TestUrlFilterWithFragment(const std::string& url) {
1554 size_t pos = url.find('#');
1555 if (pos == std::string::npos)
1556 return url;
1557 return url.substr(0, pos) + "Rewrite" + url.substr(pos);
1558 }
1559
1560 } // namespace
1561
1562 // Test the URL filter capability.
TEST(ResourceManagerTest,UrlFilter)1563 TEST(ResourceManagerTest, UrlFilter) {
1564 const char kUrl[] = "http://test.com/ResourceManagerTest";
1565 const char kExpectedUrl[] = "http://test.com/ResourceManagerTestRewrite";
1566
1567 ResourceManagerTestHandler::State state;
1568 state.urls_.push_back(kUrl);
1569
1570 // Set the URL filter.
1571 state.manager_->SetUrlFilter(base::BindRepeating(TestUrlFilter));
1572
1573 TestProvider::State provider_state1;
1574 TestProvider::State provider_state2;
1575
1576 ProviderDestructHelper destruct_helper(2);
1577 provider_state1.destruct_callback_ = destruct_helper.callback();
1578 provider_state2.destruct_callback_ = destruct_helper.callback();
1579
1580 state.manager_->AddProvider(
1581 new UrlFilterTestProvider(&provider_state1, kExpectedUrl, kExpectedUrl),
1582 0, std::string());
1583 state.manager_->AddProvider(
1584 new UrlFilterTestProvider(&provider_state2, kExpectedUrl, kExpectedUrl),
1585 0, std::string());
1586
1587 CefRefPtr<ResourceManagerTestHandler> handler =
1588 new ResourceManagerTestHandler(&state);
1589 handler->ExecuteTest();
1590
1591 ReleaseAndWaitForDestructor(handler);
1592
1593 state.manager_ = nullptr;
1594
1595 // Wait for the manager to be deleted.
1596 destruct_helper.Wait();
1597
1598 // All providers are called.
1599 EXPECT_TRUE(provider_state1.got_on_request_);
1600 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
1601 EXPECT_TRUE(provider_state1.got_destruct_);
1602
1603 EXPECT_TRUE(provider_state2.got_on_request_);
1604 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
1605 EXPECT_TRUE(provider_state2.got_destruct_);
1606
1607 EXPECT_EQ(state.messages_.size(), 1U);
1608 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
1609 }
1610
1611 // Test the URL filter capability with a query component.
TEST(ResourceManagerTest,UrlFilterWithQuery)1612 TEST(ResourceManagerTest, UrlFilterWithQuery) {
1613 const char kUrl[] = "http://test.com/ResourceManagerTest?foo=bar";
1614 const char kExpectedUrl[] = "http://test.com/ResourceManagerTestRewrite";
1615 const char kExpectedUrlAfterFilter[] =
1616 "http://test.com/ResourceManagerTestRewrite?foo=bar";
1617
1618 ResourceManagerTestHandler::State state;
1619 state.urls_.push_back(kUrl);
1620
1621 // Set the URL filter.
1622 state.manager_->SetUrlFilter(base::BindRepeating(TestUrlFilterWithQuery));
1623
1624 TestProvider::State provider_state1;
1625 TestProvider::State provider_state2;
1626
1627 ProviderDestructHelper destruct_helper(2);
1628 provider_state1.destruct_callback_ = destruct_helper.callback();
1629 provider_state2.destruct_callback_ = destruct_helper.callback();
1630
1631 state.manager_->AddProvider(
1632 new UrlFilterTestProvider(&provider_state1, kExpectedUrl,
1633 kExpectedUrlAfterFilter),
1634 0, std::string());
1635 state.manager_->AddProvider(
1636 new UrlFilterTestProvider(&provider_state2, kExpectedUrl,
1637 kExpectedUrlAfterFilter),
1638 0, std::string());
1639
1640 CefRefPtr<ResourceManagerTestHandler> handler =
1641 new ResourceManagerTestHandler(&state);
1642 handler->ExecuteTest();
1643
1644 ReleaseAndWaitForDestructor(handler);
1645
1646 state.manager_ = nullptr;
1647
1648 // Wait for the manager to be deleted.
1649 destruct_helper.Wait();
1650
1651 // All providers are called.
1652 EXPECT_TRUE(provider_state1.got_on_request_);
1653 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
1654 EXPECT_TRUE(provider_state1.got_destruct_);
1655
1656 EXPECT_TRUE(provider_state2.got_on_request_);
1657 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
1658 EXPECT_TRUE(provider_state2.got_destruct_);
1659
1660 EXPECT_EQ(state.messages_.size(), 1U);
1661 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
1662 }
1663
1664 // Test the URL filter capability with a fragment component.
TEST(ResourceManagerTest,UrlFilterWithFragment)1665 TEST(ResourceManagerTest, UrlFilterWithFragment) {
1666 // Fragment components will not be passed with the request.
1667 const char kUrl[] = "http://test.com/ResourceManagerTest#fragment";
1668 const char kExpectedUrl[] = "http://test.com/ResourceManagerTestRewrite";
1669 const char kExpectedUrlAfterFilter[] =
1670 "http://test.com/ResourceManagerTestRewrite#fragment";
1671
1672 ResourceManagerTestHandler::State state;
1673 state.urls_.push_back(kUrl);
1674
1675 // Set the URL filter.
1676 state.manager_->SetUrlFilter(base::BindRepeating(TestUrlFilterWithFragment));
1677
1678 TestProvider::State provider_state1;
1679 TestProvider::State provider_state2;
1680
1681 ProviderDestructHelper destruct_helper(2);
1682 provider_state1.destruct_callback_ = destruct_helper.callback();
1683 provider_state2.destruct_callback_ = destruct_helper.callback();
1684
1685 state.manager_->AddProvider(
1686 new UrlFilterTestProvider(&provider_state1, kExpectedUrl,
1687 kExpectedUrlAfterFilter),
1688 0, std::string());
1689 state.manager_->AddProvider(
1690 new UrlFilterTestProvider(&provider_state2, kExpectedUrl,
1691 kExpectedUrlAfterFilter),
1692 0, std::string());
1693
1694 CefRefPtr<ResourceManagerTestHandler> handler =
1695 new ResourceManagerTestHandler(&state);
1696 handler->ExecuteTest();
1697
1698 ReleaseAndWaitForDestructor(handler);
1699
1700 state.manager_ = nullptr;
1701
1702 // Wait for the manager to be deleted.
1703 destruct_helper.Wait();
1704
1705 // All providers are called.
1706 EXPECT_TRUE(provider_state1.got_on_request_);
1707 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
1708 EXPECT_TRUE(provider_state1.got_destruct_);
1709
1710 EXPECT_TRUE(provider_state2.got_on_request_);
1711 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
1712 EXPECT_TRUE(provider_state2.got_destruct_);
1713
1714 EXPECT_EQ(state.messages_.size(), 1U);
1715 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
1716 }
1717
1718 namespace {
1719
1720 // Test the mime type resolver capability.
1721 class MimeTypeTestProvider : public TestProvider {
1722 public:
MimeTypeTestProvider(State * state,const std::string & expected_mime_type)1723 MimeTypeTestProvider(State* state, const std::string& expected_mime_type)
1724 : TestProvider(state), expected_mime_type_(expected_mime_type) {}
1725
OnRequest(scoped_refptr<CefResourceManager::Request> request)1726 bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
1727 TestProvider::OnRequest(request);
1728
1729 const std::string& mime_type =
1730 request->mime_type_resolver().Run(request->url());
1731 EXPECT_EQ(expected_mime_type_, mime_type);
1732
1733 request->Continue(nullptr);
1734 return true;
1735 }
1736
1737 private:
1738 std::string expected_mime_type_;
1739 DISALLOW_COPY_AND_ASSIGN(MimeTypeTestProvider);
1740 };
1741
1742 const char kExpectedMimeType[] = "foo/bar";
1743
TestMimeTypeResolver(const std::string & url)1744 std::string TestMimeTypeResolver(const std::string& url) {
1745 return kExpectedMimeType;
1746 }
1747
1748 } // namespace
1749
1750 // Test the mime type resolver capability.
TEST(ResourceManagerTest,MimeTypeResolver)1751 TEST(ResourceManagerTest, MimeTypeResolver) {
1752 const char kUrl[] = "http://test.com/ResourceManagerTest";
1753
1754 ResourceManagerTestHandler::State state;
1755 state.urls_.push_back(kUrl);
1756
1757 // Set the mime type resolver.
1758 state.manager_->SetMimeTypeResolver(
1759 base::BindRepeating(TestMimeTypeResolver));
1760
1761 TestProvider::State provider_state1;
1762 TestProvider::State provider_state2;
1763
1764 ProviderDestructHelper destruct_helper(2);
1765 provider_state1.destruct_callback_ = destruct_helper.callback();
1766 provider_state2.destruct_callback_ = destruct_helper.callback();
1767
1768 state.manager_->AddProvider(
1769 new MimeTypeTestProvider(&provider_state1, kExpectedMimeType), 0,
1770 std::string());
1771 state.manager_->AddProvider(
1772 new MimeTypeTestProvider(&provider_state2, kExpectedMimeType), 0,
1773 std::string());
1774
1775 CefRefPtr<ResourceManagerTestHandler> handler =
1776 new ResourceManagerTestHandler(&state);
1777 handler->ExecuteTest();
1778
1779 ReleaseAndWaitForDestructor(handler);
1780
1781 state.manager_ = nullptr;
1782
1783 // Wait for the manager to be deleted.
1784 destruct_helper.Wait();
1785
1786 // All providers are called.
1787 EXPECT_TRUE(provider_state1.got_on_request_);
1788 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
1789 EXPECT_TRUE(provider_state1.got_destruct_);
1790
1791 EXPECT_TRUE(provider_state2.got_on_request_);
1792 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
1793 EXPECT_TRUE(provider_state2.got_destruct_);
1794
1795 EXPECT_EQ(state.messages_.size(), 1U);
1796 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
1797 }
1798
1799 namespace {
1800
1801 // Content provider that adds another provider before or after the current
1802 // provider.
1803 class AddingTestProvider : public TestProvider {
1804 public:
AddingTestProvider(State * state,State * new_state,CefResourceManager * manager,bool before)1805 AddingTestProvider(State* state,
1806 State* new_state,
1807 CefResourceManager* manager,
1808 bool before)
1809 : TestProvider(state),
1810 new_state_(new_state),
1811 manager_(manager),
1812 before_(before) {}
1813
OnRequest(scoped_refptr<CefResourceManager::Request> request)1814 bool OnRequest(scoped_refptr<CefResourceManager::Request> request) override {
1815 TestProvider::OnRequest(request);
1816
1817 manager_->AddProvider(
1818 new SimpleTestProvider(new_state_, SimpleTestProvider::CONTINUE,
1819 nullptr),
1820 before_ ? -1 : 1, std::string());
1821
1822 request->Continue(nullptr);
1823 return true;
1824 }
1825
1826 private:
1827 State* new_state_;
1828 CefResourceManager* manager_; // Weak reference.
1829 bool before_;
1830
1831 DISALLOW_COPY_AND_ASSIGN(AddingTestProvider);
1832 };
1833
1834 } // namespace
1835
1836 // Test adding a new provider after the current provider.
TEST(ResourceManagerTest,AddProviderAfter)1837 TEST(ResourceManagerTest, AddProviderAfter) {
1838 const char kUrl[] = "http://test.com/ResourceManagerTest";
1839
1840 ResourceManagerTestHandler::State state;
1841 state.urls_.push_back(kUrl);
1842
1843 TestProvider::State provider_state1;
1844 TestProvider::State provider_state2;
1845
1846 ProviderDestructHelper destruct_helper(2);
1847 provider_state1.destruct_callback_ = destruct_helper.callback();
1848 provider_state2.destruct_callback_ = destruct_helper.callback();
1849
1850 state.manager_->AddProvider(
1851 new AddingTestProvider(&provider_state1, &provider_state2,
1852 state.manager_.get(), false),
1853 0, std::string());
1854
1855 CefRefPtr<ResourceManagerTestHandler> handler =
1856 new ResourceManagerTestHandler(&state);
1857 handler->ExecuteTest();
1858
1859 ReleaseAndWaitForDestructor(handler);
1860
1861 state.manager_ = nullptr;
1862
1863 // Wait for the manager to be deleted.
1864 destruct_helper.Wait();
1865
1866 // All providers are called.
1867 EXPECT_TRUE(provider_state1.got_on_request_);
1868 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
1869 EXPECT_TRUE(provider_state1.got_destruct_);
1870
1871 EXPECT_TRUE(provider_state2.got_on_request_);
1872 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
1873 EXPECT_TRUE(provider_state2.got_destruct_);
1874
1875 EXPECT_EQ(state.messages_.size(), 1U);
1876 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
1877 }
1878
1879 // Test adding a new provider before the current provider.
TEST(ResourceManagerTest,AddProviderBefore)1880 TEST(ResourceManagerTest, AddProviderBefore) {
1881 const char kUrl[] = "http://test.com/ResourceManagerTest";
1882
1883 ResourceManagerTestHandler::State state;
1884 state.urls_.push_back(kUrl);
1885
1886 TestProvider::State provider_state1;
1887 TestProvider::State provider_state2;
1888
1889 ProviderDestructHelper destruct_helper(2);
1890 provider_state1.destruct_callback_ = destruct_helper.callback();
1891 provider_state2.destruct_callback_ = destruct_helper.callback();
1892
1893 state.manager_->AddProvider(
1894 new AddingTestProvider(&provider_state1, &provider_state2,
1895 state.manager_.get(), true),
1896 0, std::string());
1897
1898 CefRefPtr<ResourceManagerTestHandler> handler =
1899 new ResourceManagerTestHandler(&state);
1900 handler->ExecuteTest();
1901
1902 ReleaseAndWaitForDestructor(handler);
1903
1904 state.manager_ = nullptr;
1905
1906 // Wait for the manager to be deleted.
1907 destruct_helper.Wait();
1908
1909 // 1st provider is called.
1910 EXPECT_TRUE(provider_state1.got_on_request_);
1911 EXPECT_FALSE(provider_state1.got_on_request_canceled_);
1912 EXPECT_TRUE(provider_state1.got_destruct_);
1913
1914 // 2nd provider is not called because it was added before the 1st provider.
1915 EXPECT_FALSE(provider_state2.got_on_request_);
1916 EXPECT_FALSE(provider_state2.got_on_request_canceled_);
1917 EXPECT_TRUE(provider_state2.got_destruct_);
1918
1919 EXPECT_EQ(state.messages_.size(), 1U);
1920 EXPECT_EQ(CreateMessage(kDoneMsg, kNotHandled), state.messages_[0]);
1921 }
1922