Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / android_webview / browser / net / android_stream_reader_url_request_job_unittest.cc
blobf2ed786db4b21be515c5d2446c498e4c1b7d3bc4
1 // Copyright (c) 2012 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 "android_webview/browser/input_stream.h"
6 #include "android_webview/browser/net/android_stream_reader_url_request_job.h"
7 #include "android_webview/browser/net/aw_url_request_job_factory.h"
8 #include "android_webview/browser/net/input_stream_reader.h"
9 #include "base/format_macros.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h"
14 #include "net/base/request_priority.h"
15 #include "net/http/http_byte_range.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/url_request/url_request.h"
18 #include "net/url_request/url_request_job_factory_impl.h"
19 #include "net/url_request/url_request_test_util.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 using android_webview::InputStream;
25 using android_webview::InputStreamReader;
26 using net::TestDelegate;
27 using net::TestJobInterceptor;
28 using net::TestNetworkDelegate;
29 using net::TestURLRequestContext;
30 using net::URLRequest;
31 using testing::DoAll;
32 using testing::Ge;
33 using testing::Gt;
34 using testing::InSequence;
35 using testing::Invoke;
36 using testing::InvokeWithoutArgs;
37 using testing::NotNull;
38 using testing::Return;
39 using testing::SaveArg;
40 using testing::SetArgPointee;
41 using testing::StrictMock;
42 using testing::Test;
43 using testing::WithArg;
44 using testing::WithArgs;
45 using testing::_;
47 // Some of the classes will DCHECK on a null InputStream (which is desirable).
48 // The workaround is to use this class. None of the methods need to be
49 // implemented as the mock InputStreamReader should never forward calls to the
50 // InputStream.
51 class NotImplInputStream : public InputStream {
52 public:
53 NotImplInputStream() {}
54 ~NotImplInputStream() override {}
55 bool BytesAvailable(int* bytes_available) const override {
56 NOTIMPLEMENTED();
57 return false;
59 bool Skip(int64_t n, int64_t* bytes_skipped) override {
60 NOTIMPLEMENTED();
61 return false;
63 bool Read(net::IOBuffer* dest, int length, int* bytes_read) override {
64 NOTIMPLEMENTED();
65 return false;
69 // Required in order to create an instance of AndroidStreamReaderURLRequestJob.
70 class StreamReaderDelegate :
71 public AndroidStreamReaderURLRequestJob::Delegate {
72 public:
73 StreamReaderDelegate() {}
75 scoped_ptr<InputStream> OpenInputStream(JNIEnv* env,
76 const GURL& url) override {
77 return make_scoped_ptr<InputStream>(new NotImplInputStream());
80 void OnInputStreamOpenFailed(net::URLRequest* request,
81 bool* restart) override {
82 *restart = false;
85 bool GetMimeType(JNIEnv* env,
86 net::URLRequest* request,
87 android_webview::InputStream* stream,
88 std::string* mime_type) override {
89 return false;
92 bool GetCharset(JNIEnv* env,
93 net::URLRequest* request,
94 android_webview::InputStream* stream,
95 std::string* charset) override {
96 return false;
99 void AppendResponseHeaders(JNIEnv* env,
100 net::HttpResponseHeaders* headers) override {
101 // no-op
105 class NullStreamReaderDelegate : public StreamReaderDelegate {
106 public:
107 NullStreamReaderDelegate() {}
109 scoped_ptr<InputStream> OpenInputStream(JNIEnv* env,
110 const GURL& url) override {
111 return make_scoped_ptr<InputStream>(NULL);
115 class HeaderAlteringStreamReaderDelegate : public NullStreamReaderDelegate {
116 public:
117 HeaderAlteringStreamReaderDelegate() {}
119 void AppendResponseHeaders(JNIEnv* env,
120 net::HttpResponseHeaders* headers) override {
121 headers->ReplaceStatusLine(kStatusLine);
122 std::string headerLine(kCustomHeaderName);
123 headerLine.append(": ");
124 headerLine.append(kCustomHeaderValue);
125 headers->AddHeader(headerLine);
128 static const int kResponseCode;
129 static const char* kStatusLine;
130 static const char* kCustomHeaderName;
131 static const char* kCustomHeaderValue;
134 const int HeaderAlteringStreamReaderDelegate::kResponseCode = 401;
135 const char* HeaderAlteringStreamReaderDelegate::kStatusLine =
136 "HTTP/1.1 401 Gone";
137 const char* HeaderAlteringStreamReaderDelegate::kCustomHeaderName =
138 "X-Test-Header";
139 const char* HeaderAlteringStreamReaderDelegate::kCustomHeaderValue =
140 "TestHeaderValue";
142 class MockInputStreamReader : public InputStreamReader {
143 public:
144 MockInputStreamReader() : InputStreamReader(new NotImplInputStream()) {}
145 ~MockInputStreamReader() {}
147 MOCK_METHOD1(Seek, int(const net::HttpByteRange& byte_range));
148 MOCK_METHOD2(ReadRawData, int(net::IOBuffer* buffer, int buffer_size));
152 class TestStreamReaderJob : public AndroidStreamReaderURLRequestJob {
153 public:
154 TestStreamReaderJob(
155 net::URLRequest* request,
156 net::NetworkDelegate* network_delegate,
157 scoped_ptr<Delegate> delegate,
158 scoped_ptr<InputStreamReader> stream_reader)
159 : AndroidStreamReaderURLRequestJob(request,
160 network_delegate,
161 delegate.Pass()),
162 stream_reader_(stream_reader.Pass()) {
163 message_loop_proxy_ = base::MessageLoopProxy::current();
166 scoped_ptr<InputStreamReader> CreateStreamReader(
167 InputStream* stream) override {
168 return stream_reader_.Pass();
170 protected:
171 ~TestStreamReaderJob() override {}
173 base::TaskRunner* GetWorkerThreadRunner() override {
174 return message_loop_proxy_.get();
177 scoped_ptr<InputStreamReader> stream_reader_;
178 scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
181 class AndroidStreamReaderURLRequestJobTest : public Test {
182 public:
183 AndroidStreamReaderURLRequestJobTest() {}
185 protected:
186 void SetUp() override {
187 context_.set_job_factory(&factory_);
188 context_.set_network_delegate(&network_delegate_);
189 req_ = context_.CreateRequest(GURL("content://foo"),
190 net::DEFAULT_PRIORITY,
191 &url_request_delegate_);
192 req_->set_method("GET");
195 void SetRange(net::URLRequest* req, int first_byte, int last_byte) {
196 net::HttpRequestHeaders headers;
197 headers.SetHeader(net::HttpRequestHeaders::kRange,
198 net::HttpByteRange::Bounded(
199 first_byte, last_byte).GetHeaderValue());
200 req->SetExtraRequestHeaders(headers);
203 void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader) {
204 SetUpTestJob(stream_reader.Pass(),
205 make_scoped_ptr(new StreamReaderDelegate()));
208 void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader,
209 scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate>
210 stream_reader_delegate) {
211 TestStreamReaderJob* test_stream_reader_job =
212 new TestStreamReaderJob(
213 req_.get(),
214 &network_delegate_,
215 stream_reader_delegate.Pass(),
216 stream_reader.Pass());
217 // The Interceptor is owned by the |factory_|.
218 TestJobInterceptor* protocol_handler = new TestJobInterceptor;
219 protocol_handler->set_main_intercept_job(test_stream_reader_job);
220 bool set_protocol = factory_.SetProtocolHandler("http", protocol_handler);
221 DCHECK(set_protocol);
223 protocol_handler = new TestJobInterceptor;
224 protocol_handler->set_main_intercept_job(test_stream_reader_job);
225 set_protocol = factory_.SetProtocolHandler("content", protocol_handler);
226 DCHECK(set_protocol);
229 base::MessageLoopForIO loop_;
230 TestURLRequestContext context_;
231 android_webview::AwURLRequestJobFactory factory_;
232 TestDelegate url_request_delegate_;
233 TestNetworkDelegate network_delegate_;
234 scoped_ptr<URLRequest> req_;
237 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadEmptyStream) {
238 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
239 new StrictMock<MockInputStreamReader>());
241 InSequence s;
242 EXPECT_CALL(*stream_reader, Seek(_))
243 .WillOnce(Return(0));
244 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Gt(0)))
245 .WillOnce(Return(0));
248 SetUpTestJob(stream_reader.Pass());
250 req_->Start();
252 // The TestDelegate will quit the message loop on request completion.
253 base::MessageLoop::current()->Run();
255 EXPECT_FALSE(url_request_delegate_.request_failed());
256 EXPECT_EQ(1, network_delegate_.completed_requests());
257 EXPECT_EQ(0, network_delegate_.error_count());
258 EXPECT_EQ(200, req_->GetResponseCode());
261 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadWithNullStream) {
262 SetUpTestJob(nullptr, make_scoped_ptr(new NullStreamReaderDelegate()));
263 req_->Start();
265 // The TestDelegate will quit the message loop on request completion.
266 base::MessageLoop::current()->Run();
268 // The request_failed() method is named confusingly but all it checks is
269 // whether the request got as far as calling NotifyHeadersComplete.
270 EXPECT_FALSE(url_request_delegate_.request_failed());
271 EXPECT_EQ(1, network_delegate_.completed_requests());
272 // A null input stream shouldn't result in an error. See crbug.com/180950.
273 EXPECT_EQ(0, network_delegate_.error_count());
274 EXPECT_EQ(404, req_->GetResponseCode());
277 TEST_F(AndroidStreamReaderURLRequestJobTest, ModifyHeadersAndStatus) {
278 SetUpTestJob(nullptr,
279 make_scoped_ptr(new HeaderAlteringStreamReaderDelegate()));
280 req_->Start();
282 // The TestDelegate will quit the message loop on request completion.
283 base::MessageLoop::current()->Run();
285 // The request_failed() method is named confusingly but all it checks is
286 // whether the request got as far as calling NotifyHeadersComplete.
287 EXPECT_FALSE(url_request_delegate_.request_failed());
288 EXPECT_EQ(1, network_delegate_.completed_requests());
289 // A null input stream shouldn't result in an error. See crbug.com/180950.
290 EXPECT_EQ(0, network_delegate_.error_count());
291 EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kResponseCode,
292 req_->GetResponseCode());
293 EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kStatusLine,
294 req_->response_headers()->GetStatusLine());
295 EXPECT_TRUE(req_->response_headers()->HasHeader(
296 HeaderAlteringStreamReaderDelegate::kCustomHeaderName));
297 std::string header_value;
298 EXPECT_TRUE(req_->response_headers()->EnumerateHeader(
299 NULL, HeaderAlteringStreamReaderDelegate::kCustomHeaderName,
300 &header_value));
301 EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kCustomHeaderValue,
302 header_value);
305 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadPartOfStream) {
306 const int bytes_available = 128;
307 const int offset = 32;
308 const int bytes_to_read = bytes_available - offset;
309 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
310 new StrictMock<MockInputStreamReader>());
312 InSequence s;
313 EXPECT_CALL(*stream_reader, Seek(_))
314 .WillOnce(Return(bytes_available));
315 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
316 .WillOnce(Return(bytes_to_read/2));
317 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
318 .WillOnce(Return(bytes_to_read/2));
319 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
320 .WillOnce(Return(0));
323 SetUpTestJob(stream_reader.Pass());
325 SetRange(req_.get(), offset, bytes_available);
326 req_->Start();
328 base::MessageLoop::current()->Run();
330 EXPECT_FALSE(url_request_delegate_.request_failed());
331 EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received());
332 EXPECT_EQ(1, network_delegate_.completed_requests());
333 EXPECT_EQ(0, network_delegate_.error_count());
336 TEST_F(AndroidStreamReaderURLRequestJobTest,
337 ReadStreamWithMoreAvailableThanActual) {
338 const int bytes_available_reported = 190;
339 const int bytes_available = 128;
340 const int offset = 0;
341 const int bytes_to_read = bytes_available - offset;
342 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
343 new StrictMock<MockInputStreamReader>());
345 InSequence s;
346 EXPECT_CALL(*stream_reader, Seek(_))
347 .WillOnce(Return(bytes_available_reported));
348 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
349 .WillOnce(Return(bytes_available));
350 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
351 .WillOnce(Return(0));
354 SetUpTestJob(stream_reader.Pass());
356 SetRange(req_.get(), offset, bytes_available_reported);
357 req_->Start();
359 base::MessageLoop::current()->Run();
361 EXPECT_FALSE(url_request_delegate_.request_failed());
362 EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received());
363 EXPECT_EQ(1, network_delegate_.completed_requests());
364 EXPECT_EQ(0, network_delegate_.error_count());
367 TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWaySeek) {
368 const int offset = 20;
369 const int bytes_available = 128;
370 base::RunLoop loop;
371 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
372 new StrictMock<MockInputStreamReader>());
373 EXPECT_CALL(*stream_reader, Seek(_))
374 .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit),
375 Return(bytes_available)));
376 ON_CALL(*stream_reader, ReadRawData(_, _))
377 .WillByDefault(Return(0));
379 SetUpTestJob(stream_reader.Pass());
381 SetRange(req_.get(), offset, bytes_available);
382 req_->Start();
384 loop.Run();
386 EXPECT_EQ(0, network_delegate_.completed_requests());
387 req_->Cancel();
388 EXPECT_EQ(1, network_delegate_.completed_requests());
391 TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWayRead) {
392 const int offset = 20;
393 const int bytes_available = 128;
394 base::RunLoop loop;
395 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
396 new StrictMock<MockInputStreamReader>());
397 net::CompletionCallback read_completion_callback;
398 EXPECT_CALL(*stream_reader, Seek(_))
399 .WillOnce(Return(bytes_available));
400 EXPECT_CALL(*stream_reader, ReadRawData(_, _))
401 .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit),
402 Return(bytes_available)));
404 SetUpTestJob(stream_reader.Pass());
406 SetRange(req_.get(), offset, bytes_available);
407 req_->Start();
409 loop.Run();
411 EXPECT_EQ(0, network_delegate_.completed_requests());
412 req_->Cancel();
413 EXPECT_EQ(1, network_delegate_.completed_requests());