• 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 <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