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.
5 #include "content/test/weburl_loader_mock_factory.h"
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"
18 using blink::WebCache
;
20 using blink::WebString
;
22 using blink::WebURLError
;
23 using blink::WebURLLoader
;
24 using blink::WebURLRequest
;
25 using blink::WebURLResponse
;
27 WebURLLoaderMockFactory::WebURLLoaderMockFactory() {}
29 WebURLLoaderMockFactory::~WebURLLoaderMockFactory() {}
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()) {
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()));
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()));
46 DCHECK(base::PathExists(response_info
.file_path
))
47 << response_info
.file_path
.MaybeAsASCII() << " does not exist.";
50 DCHECK(url_to_reponse_info_
.find(url
) == url_to_reponse_info_
.end());
51 url_to_reponse_info_
[url
] = response_info
;
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
;
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
);
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
);
73 void WebURLLoaderMockFactory::UnregisterAllURLs() {
74 url_to_reponse_info_
.clear();
75 url_to_error_info_
.clear();
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
;
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())
98 last_handled_asynchronous_request_
= newRequest
;
99 LoadRequest(newRequest
, &response
, &error
, &data
);
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
);
107 base::RunLoop().RunUntilIdle();
111 WebURLLoaderMockFactory::GetLastHandledAsynchronousRequest() {
112 return last_handled_asynchronous_request_
;
115 bool WebURLLoaderMockFactory::IsMockedURL(const blink::WebURL
& url
) {
116 return url_to_reponse_info_
.find(url
) != url_to_reponse_info_
.end();
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
);
125 WebURLLoader
* WebURLLoaderMockFactory::CreateURLLoader(
126 WebURLLoader
* default_loader
) {
127 DCHECK(default_loader
);
128 return new WebURLLoaderMock(this, default_loader
);
131 void WebURLLoaderMockFactory::LoadSynchronously(const WebURLRequest
& request
,
132 WebURLResponse
* response
,
135 LoadRequest(request
, response
, error
, data
);
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
;
145 void WebURLLoaderMockFactory::LoadRequest(const WebURLRequest
& request
,
146 WebURLResponse
* response
,
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
;
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.
162 if (!error
->reason
&& !ReadFile(iter
->second
.file_path
, data
)) {
167 *response
= iter
->second
.response
;
170 bool WebURLLoaderMockFactory::IsPending(WebURLLoaderMock
* loader
) {
171 LoaderToRequestMap::iterator iter
= pending_loaders_
.find(loader
);
172 return iter
!= pending_loaders_
.end();
176 bool WebURLLoaderMockFactory::ReadFile(const base::FilePath
& file_path
,
179 if (!base::GetFileSize(file_path
, &file_size
))
182 int size
= static_cast<int>(file_size
);
183 scoped_ptr
<char[]> buffer(new char[size
]);
185 int read_count
= base::ReadFile(file_path
, buffer
.get(), size
);
186 if (read_count
== -1)
188 DCHECK(read_count
== size
);
189 data
->assign(buffer
.get(), size
);