Home | History | Annotate | Download | only in test
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/test/weburl_loader_mock_factory.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/logging.h"
      9 #include "base/run_loop.h"
     10 #include "content/test/webkit_support.h"
     11 #include "content/test/weburl_loader_mock.h"
     12 #include "third_party/WebKit/public/platform/WebString.h"
     13 #include "third_party/WebKit/public/platform/WebURLError.h"
     14 #include "third_party/WebKit/public/platform/WebURLRequest.h"
     15 #include "third_party/WebKit/public/platform/WebURLResponse.h"
     16 #include "third_party/WebKit/public/web/WebCache.h"
     17 
     18 using blink::WebCache;
     19 using blink::WebData;
     20 using blink::WebString;
     21 using blink::WebURL;
     22 using blink::WebURLError;
     23 using blink::WebURLLoader;
     24 using blink::WebURLRequest;
     25 using blink::WebURLResponse;
     26 
     27 WebURLLoaderMockFactory::WebURLLoaderMockFactory() {}
     28 
     29 WebURLLoaderMockFactory::~WebURLLoaderMockFactory() {}
     30 
     31 void WebURLLoaderMockFactory::RegisterURL(const WebURL& url,
     32                                           const WebURLResponse& response,
     33                                           const WebString& file_path) {
     34   ResponseInfo response_info;
     35   response_info.response = response;
     36   if (!file_path.isNull() && !file_path.isEmpty()) {
     37 #if defined(OS_POSIX)
     38     // TODO(jcivelli): On Linux, UTF8 might not be correct.
     39     response_info.file_path =
     40         base::FilePath(static_cast<std::string>(file_path.utf8()));
     41 #elif defined(OS_WIN)
     42     base::string16 file_path_16 = file_path;
     43     response_info.file_path = base::FilePath(std::wstring(
     44         file_path_16.data(), file_path_16.length()));
     45 #endif
     46     DCHECK(base::PathExists(response_info.file_path))
     47         << response_info.file_path.MaybeAsASCII() << " does not exist.";
     48   }
     49 
     50   DCHECK(url_to_reponse_info_.find(url) == url_to_reponse_info_.end());
     51   url_to_reponse_info_[url] = response_info;
     52 }
     53 
     54 
     55 void WebURLLoaderMockFactory::RegisterErrorURL(const WebURL& url,
     56                                                const WebURLResponse& response,
     57                                                const WebURLError& error) {
     58   DCHECK(url_to_reponse_info_.find(url) == url_to_reponse_info_.end());
     59   RegisterURL(url, response, WebString());
     60   url_to_error_info_[url] = error;
     61 }
     62 
     63 void WebURLLoaderMockFactory::UnregisterURL(const blink::WebURL& url) {
     64   URLToResponseMap::iterator iter = url_to_reponse_info_.find(url);
     65   DCHECK(iter != url_to_reponse_info_.end());
     66   url_to_reponse_info_.erase(iter);
     67 
     68   URLToErrorMap::iterator error_iter = url_to_error_info_.find(url);
     69   if (error_iter != url_to_error_info_.end())
     70     url_to_error_info_.erase(error_iter);
     71 }
     72 
     73 void WebURLLoaderMockFactory::UnregisterAllURLs() {
     74   url_to_reponse_info_.clear();
     75   url_to_error_info_.clear();
     76   WebCache::clear();
     77 }
     78 
     79 void WebURLLoaderMockFactory::ServeAsynchronousRequests() {
     80   last_handled_asynchronous_request_.reset();
     81   // Serving a request might trigger more requests, so we cannot iterate on
     82   // pending_loaders_ as it might get modified.
     83   while (!pending_loaders_.empty()) {
     84     LoaderToRequestMap::iterator iter = pending_loaders_.begin();
     85     WebURLLoaderMock* loader = iter->first;
     86     const WebURLRequest& request = iter->second;
     87     WebURLResponse response;
     88     WebURLError error;
     89     WebData data;
     90     last_handled_asynchronous_request_ = request;
     91     LoadRequest(request, &response, &error, &data);
     92     // Follow any redirects while the loader is still active.
     93     while (response.httpStatusCode() >= 300 &&
     94            response.httpStatusCode() < 400) {
     95       WebURLRequest newRequest = loader->ServeRedirect(response);
     96       if (!IsPending(loader) || loader->isDeferred())
     97         break;
     98       last_handled_asynchronous_request_ = newRequest;
     99       LoadRequest(newRequest, &response, &error, &data);
    100     }
    101     // Serve the request if the loader is still active.
    102     if (IsPending(loader) && !loader->isDeferred())
    103       loader->ServeAsynchronousRequest(response, data, error);
    104     // The loader might have already been removed.
    105     pending_loaders_.erase(loader);
    106   }
    107   base::RunLoop().RunUntilIdle();
    108 }
    109 
    110 blink::WebURLRequest
    111 WebURLLoaderMockFactory::GetLastHandledAsynchronousRequest() {
    112   return last_handled_asynchronous_request_;
    113 }
    114 
    115 bool WebURLLoaderMockFactory::IsMockedURL(const blink::WebURL& url) {
    116   return url_to_reponse_info_.find(url) != url_to_reponse_info_.end();
    117 }
    118 
    119 void WebURLLoaderMockFactory::CancelLoad(WebURLLoaderMock* loader) {
    120   LoaderToRequestMap::iterator iter = pending_loaders_.find(loader);
    121   DCHECK(iter != pending_loaders_.end());
    122   pending_loaders_.erase(iter);
    123 }
    124 
    125 WebURLLoader* WebURLLoaderMockFactory::CreateURLLoader(
    126     WebURLLoader* default_loader) {
    127   DCHECK(default_loader);
    128   return new WebURLLoaderMock(this, default_loader);
    129 }
    130 
    131 void WebURLLoaderMockFactory::LoadSynchronously(const WebURLRequest& request,
    132                                                 WebURLResponse* response,
    133                                                 WebURLError* error,
    134                                                 WebData* data) {
    135   LoadRequest(request, response, error, data);
    136 }
    137 
    138 void WebURLLoaderMockFactory::LoadAsynchronouly(const WebURLRequest& request,
    139                                                 WebURLLoaderMock* loader) {
    140   LoaderToRequestMap::iterator iter = pending_loaders_.find(loader);
    141   DCHECK(iter == pending_loaders_.end());
    142   pending_loaders_[loader] = request;
    143 }
    144 
    145 void WebURLLoaderMockFactory::LoadRequest(const WebURLRequest& request,
    146                                           WebURLResponse* response,
    147                                           WebURLError* error,
    148                                           WebData* data) {
    149   URLToErrorMap::const_iterator error_iter =
    150       url_to_error_info_.find(request.url());
    151   if (error_iter != url_to_error_info_.end())
    152     *error = error_iter->second;
    153 
    154   URLToResponseMap::const_iterator iter =
    155       url_to_reponse_info_.find(request.url());
    156   if (iter == url_to_reponse_info_.end()) {
    157     // Non mocked URLs should not have been passed to the default URLLoader.
    158     NOTREACHED();
    159     return;
    160   }
    161 
    162   if (!error->reason && !ReadFile(iter->second.file_path, data)) {
    163     NOTREACHED();
    164     return;
    165   }
    166 
    167   *response = iter->second.response;
    168 }
    169 
    170 bool WebURLLoaderMockFactory::IsPending(WebURLLoaderMock* loader) {
    171   LoaderToRequestMap::iterator iter = pending_loaders_.find(loader);
    172   return iter != pending_loaders_.end();
    173 }
    174 
    175 // static
    176 bool WebURLLoaderMockFactory::ReadFile(const base::FilePath& file_path,
    177                                        WebData* data) {
    178   int64 file_size = 0;
    179   if (!base::GetFileSize(file_path, &file_size))
    180     return false;
    181 
    182   int size = static_cast<int>(file_size);
    183   scoped_ptr<char[]> buffer(new char[size]);
    184   data->reset();
    185   int read_count = base::ReadFile(file_path, buffer.get(), size);
    186   if (read_count == -1)
    187     return false;
    188   DCHECK(read_count == size);
    189   data->assign(buffer.get(), size);
    190 
    191   return true;
    192 }
    193