simple_data_source_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2011 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 "media/base/filters.h"
6#include "media/base/mock_callback.h"
7#include "media/base/mock_filter_host.h"
8#include "media/base/mock_filters.h"
9#include "net/base/net_errors.h"
10#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
11#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h"
12#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoader.h"
13#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h"
14#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
15#include "webkit/glue/media/simple_data_source.h"
16#include "webkit/mocks/mock_webframe.h"
17#include "webkit/mocks/mock_weburlloader.h"
18
19using ::testing::_;
20using ::testing::DoAll;
21using ::testing::InSequence;
22using ::testing::Invoke;
23using ::testing::NiceMock;
24using ::testing::NotNull;
25using ::testing::Return;
26using ::testing::SetArgumentPointee;
27using ::testing::StrictMock;
28using ::testing::WithArgs;
29
30using WebKit::WebURLError;
31using WebKit::WebURLLoader;
32using WebKit::WebURLRequest;
33using WebKit::WebURLResponse;
34
35namespace webkit_glue {
36
37static const int kDataSize = 1024;
38static const char kHttpUrl[] = "http://test";
39static const char kHttpsUrl[] = "https://test";
40static const char kFileUrl[] = "file://test";
41static const char kDataUrl[] =
42    "data:text/plain;base64,YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoK";
43static const char kDataUrlDecoded[] = "abcdefghijklmnopqrstuvwxyz";
44static const char kInvalidUrl[] = "whatever://test";
45static const char kHttpRedirectToSameDomainUrl1[] = "http://test/ing";
46static const char kHttpRedirectToSameDomainUrl2[] = "http://test/ing2";
47static const char kHttpRedirectToDifferentDomainUrl1[] = "http://test2";
48static const char kHttpRedirectToDifferentDomainUrl2[] = "http://test2/ing";
49
50class SimpleDataSourceTest : public testing::Test {
51 public:
52  SimpleDataSourceTest() {
53    for (int i = 0; i < kDataSize; ++i) {
54      data_[i] = i;
55    }
56  }
57
58  virtual ~SimpleDataSourceTest() {
59  }
60
61  void InitializeDataSource(const char* url,
62                            media::MockCallback* callback) {
63    gurl_ = GURL(url);
64
65    frame_.reset(new NiceMock<MockWebFrame>());
66    url_loader_ = new NiceMock<MockWebURLLoader>();
67
68    data_source_ = new SimpleDataSource(MessageLoop::current(),
69                                        frame_.get());
70
71    // There is no need to provide a message loop to data source.
72    data_source_->set_host(&host_);
73    data_source_->SetURLLoaderForTest(url_loader_);
74
75    data_source_->Initialize(url, callback);
76    MessageLoop::current()->RunAllPending();
77  }
78
79  void RequestSucceeded(bool is_loaded) {
80    WebURLResponse response(gurl_);
81    response.setExpectedContentLength(kDataSize);
82
83    data_source_->didReceiveResponse(NULL, response);
84    int64 size;
85    EXPECT_TRUE(data_source_->GetSize(&size));
86    EXPECT_EQ(kDataSize, size);
87
88    for (int i = 0; i < kDataSize; ++i) {
89      data_source_->didReceiveData(NULL, data_ + i, 1);
90    }
91
92    EXPECT_CALL(host_, SetLoaded(is_loaded));
93
94    InSequence s;
95    EXPECT_CALL(host_, SetTotalBytes(kDataSize));
96    EXPECT_CALL(host_, SetBufferedBytes(kDataSize));
97
98    data_source_->didFinishLoading(NULL, 0);
99
100    // Let the tasks to be executed.
101    MessageLoop::current()->RunAllPending();
102  }
103
104  void RequestFailed() {
105    InSequence s;
106    EXPECT_CALL(host_, SetError(media::PIPELINE_ERROR_NETWORK));
107
108    WebURLError error;
109    error.reason = net::ERR_FAILED;
110    data_source_->didFail(NULL, error);
111
112    // Let the tasks to be executed.
113    MessageLoop::current()->RunAllPending();
114  }
115
116  void Redirect(const char* url) {
117    GURL redirectUrl(url);
118    WebKit::WebURLRequest newRequest(redirectUrl);
119    WebKit::WebURLResponse redirectResponse(gurl_);
120
121    data_source_->willSendRequest(url_loader_, newRequest, redirectResponse);
122
123    MessageLoop::current()->RunAllPending();
124  }
125
126  void DestroyDataSource() {
127    data_source_->Stop(media::NewExpectedCallback());
128    MessageLoop::current()->RunAllPending();
129
130    data_source_ = NULL;
131  }
132
133  void AsyncRead() {
134    for (int i = 0; i < kDataSize; ++i) {
135      uint8 buffer[1];
136
137      EXPECT_CALL(*this, ReadCallback(1));
138      data_source_->Read(
139          i, 1, buffer,
140          NewCallback(this, &SimpleDataSourceTest::ReadCallback));
141      EXPECT_EQ(static_cast<uint8>(data_[i]), buffer[0]);
142    }
143  }
144
145  MOCK_METHOD1(ReadCallback, void(size_t size));
146
147 protected:
148  GURL gurl_;
149  scoped_ptr<MessageLoop> message_loop_;
150  NiceMock<MockWebURLLoader>* url_loader_;
151  scoped_refptr<SimpleDataSource> data_source_;
152  StrictMock<media::MockFilterHost> host_;
153  scoped_ptr<NiceMock<MockWebFrame> > frame_;
154
155  char data_[kDataSize];
156
157  DISALLOW_COPY_AND_ASSIGN(SimpleDataSourceTest);
158};
159
160TEST_F(SimpleDataSourceTest, InitializeHTTP) {
161  InitializeDataSource(kHttpUrl, media::NewExpectedCallback());
162  RequestSucceeded(false);
163  DestroyDataSource();
164}
165
166TEST_F(SimpleDataSourceTest, InitializeHTTPS) {
167  InitializeDataSource(kHttpsUrl, media::NewExpectedCallback());
168  RequestSucceeded(false);
169  DestroyDataSource();
170}
171
172TEST_F(SimpleDataSourceTest, InitializeFile) {
173  InitializeDataSource(kFileUrl, media::NewExpectedCallback());
174  RequestSucceeded(true);
175  DestroyDataSource();
176}
177
178TEST_F(SimpleDataSourceTest, InitializeData) {
179  frame_.reset(new NiceMock<MockWebFrame>());
180  url_loader_ = new NiceMock<MockWebURLLoader>();
181
182  data_source_ = new SimpleDataSource(MessageLoop::current(),
183                                      frame_.get());
184  EXPECT_TRUE(data_source_->IsUrlSupported(kDataUrl));
185
186  // There is no need to provide a message loop to data source.
187  data_source_->set_host(&host_);
188  data_source_->SetURLLoaderForTest(url_loader_);
189
190  EXPECT_CALL(host_, SetLoaded(true));
191  EXPECT_CALL(host_, SetTotalBytes(sizeof(kDataUrlDecoded)));
192  EXPECT_CALL(host_, SetBufferedBytes(sizeof(kDataUrlDecoded)));
193
194  data_source_->Initialize(kDataUrl, media::NewExpectedCallback());
195  MessageLoop::current()->RunAllPending();
196
197  DestroyDataSource();
198}
199
200TEST_F(SimpleDataSourceTest, RequestFailed) {
201  InitializeDataSource(kHttpUrl, media::NewExpectedCallback());
202  RequestFailed();
203  DestroyDataSource();
204}
205
206TEST_F(SimpleDataSourceTest, StopWhenDownloading) {
207  // The callback should be deleted, but not executed.
208  // TODO(scherkus): should this really be the behaviour?  Seems strange...
209  StrictMock<media::MockCallback>* callback =
210      new StrictMock<media::MockCallback>();
211  EXPECT_CALL(*callback, Destructor());
212
213  InitializeDataSource(kHttpUrl, callback);
214
215  EXPECT_CALL(*url_loader_, cancel());
216  DestroyDataSource();
217}
218
219TEST_F(SimpleDataSourceTest, AsyncRead) {
220  InitializeDataSource(kFileUrl, media::NewExpectedCallback());
221  RequestSucceeded(true);
222  AsyncRead();
223  DestroyDataSource();
224}
225
226// NOTE: This test will need to be reworked a little once
227// http://code.google.com/p/chromium/issues/detail?id=72578
228// is fixed.
229TEST_F(SimpleDataSourceTest, HasSingleOrigin) {
230  // Make sure no redirect case works as expected.
231  InitializeDataSource(kHttpUrl, media::NewExpectedCallback());
232  RequestSucceeded(false);
233  EXPECT_TRUE(data_source_->HasSingleOrigin());
234  DestroyDataSource();
235
236  // Test redirect to the same domain.
237  InitializeDataSource(kHttpUrl, media::NewExpectedCallback());
238  Redirect(kHttpRedirectToSameDomainUrl1);
239  RequestSucceeded(false);
240  EXPECT_TRUE(data_source_->HasSingleOrigin());
241  DestroyDataSource();
242
243  // Test redirect twice to the same domain.
244  InitializeDataSource(kHttpUrl, media::NewExpectedCallback());
245  Redirect(kHttpRedirectToSameDomainUrl1);
246  Redirect(kHttpRedirectToSameDomainUrl2);
247  RequestSucceeded(false);
248  EXPECT_TRUE(data_source_->HasSingleOrigin());
249  DestroyDataSource();
250
251  // Test redirect to a different domain.
252  InitializeDataSource(kHttpUrl, media::NewExpectedCallback());
253  Redirect(kHttpRedirectToDifferentDomainUrl1);
254  RequestSucceeded(false);
255  EXPECT_FALSE(data_source_->HasSingleOrigin());
256  DestroyDataSource();
257
258  // Test redirect to the same domain and then to a different domain.
259  InitializeDataSource(kHttpUrl, media::NewExpectedCallback());
260  Redirect(kHttpRedirectToSameDomainUrl1);
261  Redirect(kHttpRedirectToDifferentDomainUrl1);
262  RequestSucceeded(false);
263  EXPECT_FALSE(data_source_->HasSingleOrigin());
264  DestroyDataSource();
265}
266
267}  // namespace webkit_glue
268