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