Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / android_webview / browser / net / android_stream_reader_url_request_job_unittest.cc
blob651d01d1e924529026426ca53718a3ec3fe93dba
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/run_loop.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "net/base/request_priority.h"
16 #include "net/http/http_byte_range.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/url_request/url_request.h"
19 #include "net/url_request/url_request_job_factory_impl.h"
20 #include "net/url_request/url_request_test_util.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 using android_webview::InputStream;
26 using android_webview::InputStreamReader;
27 using net::TestDelegate;
28 using net::TestJobInterceptor;
29 using net::TestNetworkDelegate;
30 using net::TestURLRequestContext;
31 using net::URLRequest;
32 using testing::DoAll;
33 using testing::Ge;
34 using testing::Gt;
35 using testing::InSequence;
36 using testing::Invoke;
37 using testing::InvokeWithoutArgs;
38 using testing::NotNull;
39 using testing::Return;
40 using testing::SaveArg;
41 using testing::SetArgPointee;
42 using testing::StrictMock;
43 using testing::Test;
44 using testing::WithArg;
45 using testing::WithArgs;
46 using testing::_;
48 // Some of the classes will DCHECK on a null InputStream (which is desirable).
49 // The workaround is to use this class. None of the methods need to be
50 // implemented as the mock InputStreamReader should never forward calls to the
51 // InputStream.
52 class NotImplInputStream : public InputStream {
53 public:
54 NotImplInputStream() {}
55 ~NotImplInputStream() override {}
56 bool BytesAvailable(int* bytes_available) const override {
57 NOTIMPLEMENTED();
58 return false;
60 bool Skip(int64_t n, int64_t* bytes_skipped) override {
61 NOTIMPLEMENTED();
62 return false;
64 bool Read(net::IOBuffer* dest, int length, int* bytes_read) override {
65 NOTIMPLEMENTED();
66 return false;
70 // Required in order to create an instance of AndroidStreamReaderURLRequestJob.
71 class StreamReaderDelegate :
72 public AndroidStreamReaderURLRequestJob::Delegate {
73 public:
74 StreamReaderDelegate() {}
76 scoped_ptr<InputStream> OpenInputStream(JNIEnv* env,
77 const GURL& url) override {
78 return make_scoped_ptr<InputStream>(new NotImplInputStream());
81 void OnInputStreamOpenFailed(net::URLRequest* request,
82 bool* restart) override {
83 *restart = false;
86 bool GetMimeType(JNIEnv* env,
87 net::URLRequest* request,
88 android_webview::InputStream* stream,
89 std::string* mime_type) override {
90 return false;
93 bool GetCharset(JNIEnv* env,
94 net::URLRequest* request,
95 android_webview::InputStream* stream,
96 std::string* charset) override {
97 return false;
100 void AppendResponseHeaders(JNIEnv* env,
101 net::HttpResponseHeaders* headers) override {
102 // no-op
106 class NullStreamReaderDelegate : public StreamReaderDelegate {
107 public:
108 NullStreamReaderDelegate() {}
110 scoped_ptr<InputStream> OpenInputStream(JNIEnv* env,
111 const GURL& url) override {
112 return make_scoped_ptr<InputStream>(NULL);
116 class HeaderAlteringStreamReaderDelegate : public NullStreamReaderDelegate {
117 public:
118 HeaderAlteringStreamReaderDelegate() {}
120 void AppendResponseHeaders(JNIEnv* env,
121 net::HttpResponseHeaders* headers) override {
122 headers->ReplaceStatusLine(kStatusLine);
123 std::string headerLine(kCustomHeaderName);
124 headerLine.append(": ");
125 headerLine.append(kCustomHeaderValue);
126 headers->AddHeader(headerLine);
129 static const int kResponseCode;
130 static const char* kStatusLine;
131 static const char* kCustomHeaderName;
132 static const char* kCustomHeaderValue;
135 const int HeaderAlteringStreamReaderDelegate::kResponseCode = 401;
136 const char* HeaderAlteringStreamReaderDelegate::kStatusLine =
137 "HTTP/1.1 401 Gone";
138 const char* HeaderAlteringStreamReaderDelegate::kCustomHeaderName =
139 "X-Test-Header";
140 const char* HeaderAlteringStreamReaderDelegate::kCustomHeaderValue =
141 "TestHeaderValue";
143 class MockInputStreamReader : public InputStreamReader {
144 public:
145 MockInputStreamReader() : InputStreamReader(new NotImplInputStream()) {}
146 ~MockInputStreamReader() {}
148 MOCK_METHOD1(Seek, int(const net::HttpByteRange& byte_range));
149 MOCK_METHOD2(ReadRawData, int(net::IOBuffer* buffer, int buffer_size));
153 class TestStreamReaderJob : public AndroidStreamReaderURLRequestJob {
154 public:
155 TestStreamReaderJob(
156 net::URLRequest* request,
157 net::NetworkDelegate* network_delegate,
158 scoped_ptr<Delegate> delegate,
159 scoped_ptr<InputStreamReader> stream_reader)
160 : AndroidStreamReaderURLRequestJob(request,
161 network_delegate,
162 delegate.Pass()),
163 stream_reader_(stream_reader.Pass()) {
164 task_runner_ = base::ThreadTaskRunnerHandle::Get();
167 scoped_ptr<InputStreamReader> CreateStreamReader(
168 InputStream* stream) override {
169 return stream_reader_.Pass();
171 protected:
172 ~TestStreamReaderJob() override {}
174 base::TaskRunner* GetWorkerThreadRunner() override {
175 return task_runner_.get();
178 scoped_ptr<InputStreamReader> stream_reader_;
179 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
182 class AndroidStreamReaderURLRequestJobTest : public Test {
183 public:
184 AndroidStreamReaderURLRequestJobTest() {}
186 protected:
187 void SetUp() override {
188 context_.set_job_factory(&factory_);
189 context_.set_network_delegate(&network_delegate_);
190 req_ = context_.CreateRequest(GURL("content://foo"),
191 net::DEFAULT_PRIORITY,
192 &url_request_delegate_);
193 req_->set_method("GET");
196 void SetRange(net::URLRequest* req, int first_byte, int last_byte) {
197 net::HttpRequestHeaders headers;
198 headers.SetHeader(net::HttpRequestHeaders::kRange,
199 net::HttpByteRange::Bounded(
200 first_byte, last_byte).GetHeaderValue());
201 req->SetExtraRequestHeaders(headers);
204 void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader) {
205 SetUpTestJob(stream_reader.Pass(),
206 make_scoped_ptr(new StreamReaderDelegate()));
209 void SetUpTestJob(scoped_ptr<InputStreamReader> stream_reader,
210 scoped_ptr<AndroidStreamReaderURLRequestJob::Delegate>
211 stream_reader_delegate) {
212 TestStreamReaderJob* test_stream_reader_job =
213 new TestStreamReaderJob(
214 req_.get(),
215 &network_delegate_,
216 stream_reader_delegate.Pass(),
217 stream_reader.Pass());
218 // The Interceptor is owned by the |factory_|.
219 TestJobInterceptor* protocol_handler = new TestJobInterceptor;
220 protocol_handler->set_main_intercept_job(test_stream_reader_job);
221 bool set_protocol =
222 factory_.SetProtocolHandler("http", make_scoped_ptr(protocol_handler));
223 DCHECK(set_protocol);
225 protocol_handler = new TestJobInterceptor;
226 protocol_handler->set_main_intercept_job(test_stream_reader_job);
227 set_protocol = factory_.SetProtocolHandler(
228 "content", make_scoped_ptr(protocol_handler));
229 DCHECK(set_protocol);
232 base::MessageLoopForIO loop_;
233 TestURLRequestContext context_;
234 android_webview::AwURLRequestJobFactory factory_;
235 TestDelegate url_request_delegate_;
236 TestNetworkDelegate network_delegate_;
237 scoped_ptr<URLRequest> req_;
240 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadEmptyStream) {
241 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
242 new StrictMock<MockInputStreamReader>());
244 InSequence s;
245 EXPECT_CALL(*stream_reader, Seek(_))
246 .WillOnce(Return(0));
247 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Gt(0)))
248 .WillOnce(Return(0));
251 SetUpTestJob(stream_reader.Pass());
253 req_->Start();
255 // The TestDelegate will quit the message loop on request completion.
256 base::MessageLoop::current()->Run();
258 EXPECT_FALSE(url_request_delegate_.request_failed());
259 EXPECT_EQ(1, network_delegate_.completed_requests());
260 EXPECT_EQ(0, network_delegate_.error_count());
261 EXPECT_EQ(200, req_->GetResponseCode());
264 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadWithNullStream) {
265 SetUpTestJob(nullptr, make_scoped_ptr(new NullStreamReaderDelegate()));
266 req_->Start();
268 // The TestDelegate will quit the message loop on request completion.
269 base::MessageLoop::current()->Run();
271 // The request_failed() method is named confusingly but all it checks is
272 // whether the request got as far as calling NotifyHeadersComplete.
273 EXPECT_FALSE(url_request_delegate_.request_failed());
274 EXPECT_EQ(1, network_delegate_.completed_requests());
275 // A null input stream shouldn't result in an error. See crbug.com/180950.
276 EXPECT_EQ(0, network_delegate_.error_count());
277 EXPECT_EQ(404, req_->GetResponseCode());
280 TEST_F(AndroidStreamReaderURLRequestJobTest, ModifyHeadersAndStatus) {
281 SetUpTestJob(nullptr,
282 make_scoped_ptr(new HeaderAlteringStreamReaderDelegate()));
283 req_->Start();
285 // The TestDelegate will quit the message loop on request completion.
286 base::MessageLoop::current()->Run();
288 // The request_failed() method is named confusingly but all it checks is
289 // whether the request got as far as calling NotifyHeadersComplete.
290 EXPECT_FALSE(url_request_delegate_.request_failed());
291 EXPECT_EQ(1, network_delegate_.completed_requests());
292 // A null input stream shouldn't result in an error. See crbug.com/180950.
293 EXPECT_EQ(0, network_delegate_.error_count());
294 EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kResponseCode,
295 req_->GetResponseCode());
296 EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kStatusLine,
297 req_->response_headers()->GetStatusLine());
298 EXPECT_TRUE(req_->response_headers()->HasHeader(
299 HeaderAlteringStreamReaderDelegate::kCustomHeaderName));
300 std::string header_value;
301 EXPECT_TRUE(req_->response_headers()->EnumerateHeader(
302 NULL, HeaderAlteringStreamReaderDelegate::kCustomHeaderName,
303 &header_value));
304 EXPECT_EQ(HeaderAlteringStreamReaderDelegate::kCustomHeaderValue,
305 header_value);
308 TEST_F(AndroidStreamReaderURLRequestJobTest, ReadPartOfStream) {
309 const int bytes_available = 128;
310 const int offset = 32;
311 const int bytes_to_read = bytes_available - offset;
312 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
313 new StrictMock<MockInputStreamReader>());
315 InSequence s;
316 EXPECT_CALL(*stream_reader, Seek(_))
317 .WillOnce(Return(bytes_available));
318 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
319 .WillOnce(Return(bytes_to_read/2));
320 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
321 .WillOnce(Return(bytes_to_read/2));
322 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
323 .WillOnce(Return(0));
326 SetUpTestJob(stream_reader.Pass());
328 SetRange(req_.get(), offset, bytes_available);
329 req_->Start();
331 base::MessageLoop::current()->Run();
333 EXPECT_FALSE(url_request_delegate_.request_failed());
334 EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received());
335 EXPECT_EQ(1, network_delegate_.completed_requests());
336 EXPECT_EQ(0, network_delegate_.error_count());
339 TEST_F(AndroidStreamReaderURLRequestJobTest,
340 ReadStreamWithMoreAvailableThanActual) {
341 const int bytes_available_reported = 190;
342 const int bytes_available = 128;
343 const int offset = 0;
344 const int bytes_to_read = bytes_available - offset;
345 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
346 new StrictMock<MockInputStreamReader>());
348 InSequence s;
349 EXPECT_CALL(*stream_reader, Seek(_))
350 .WillOnce(Return(bytes_available_reported));
351 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
352 .WillOnce(Return(bytes_available));
353 EXPECT_CALL(*stream_reader, ReadRawData(NotNull(), Ge(bytes_to_read)))
354 .WillOnce(Return(0));
357 SetUpTestJob(stream_reader.Pass());
359 SetRange(req_.get(), offset, bytes_available_reported);
360 req_->Start();
362 base::MessageLoop::current()->Run();
364 EXPECT_FALSE(url_request_delegate_.request_failed());
365 EXPECT_EQ(bytes_to_read, url_request_delegate_.bytes_received());
366 EXPECT_EQ(1, network_delegate_.completed_requests());
367 EXPECT_EQ(0, network_delegate_.error_count());
370 TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWaySeek) {
371 const int offset = 20;
372 const int bytes_available = 128;
373 base::RunLoop loop;
374 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
375 new StrictMock<MockInputStreamReader>());
376 EXPECT_CALL(*stream_reader, Seek(_))
377 .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit),
378 Return(bytes_available)));
379 ON_CALL(*stream_reader, ReadRawData(_, _))
380 .WillByDefault(Return(0));
382 SetUpTestJob(stream_reader.Pass());
384 SetRange(req_.get(), offset, bytes_available);
385 req_->Start();
387 loop.Run();
389 EXPECT_EQ(0, network_delegate_.completed_requests());
390 req_->Cancel();
391 EXPECT_EQ(1, network_delegate_.completed_requests());
394 TEST_F(AndroidStreamReaderURLRequestJobTest, DeleteJobMidWayRead) {
395 const int offset = 20;
396 const int bytes_available = 128;
397 base::RunLoop loop;
398 scoped_ptr<StrictMock<MockInputStreamReader> > stream_reader(
399 new StrictMock<MockInputStreamReader>());
400 net::CompletionCallback read_completion_callback;
401 EXPECT_CALL(*stream_reader, Seek(_))
402 .WillOnce(Return(bytes_available));
403 EXPECT_CALL(*stream_reader, ReadRawData(_, _))
404 .WillOnce(DoAll(InvokeWithoutArgs(&loop, &base::RunLoop::Quit),
405 Return(bytes_available)));
407 SetUpTestJob(stream_reader.Pass());
409 SetRange(req_.get(), offset, bytes_available);
410 req_->Start();
412 loop.Run();
414 EXPECT_EQ(0, network_delegate_.completed_requests());
415 req_->Cancel();
416 EXPECT_EQ(1, network_delegate_.completed_requests());