Home | History | Annotate | Download | only in media
      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 
     19 using ::testing::_;
     20 using ::testing::DoAll;
     21 using ::testing::InSequence;
     22 using ::testing::Invoke;
     23 using ::testing::NiceMock;
     24 using ::testing::NotNull;
     25 using ::testing::Return;
     26 using ::testing::SetArgumentPointee;
     27 using ::testing::StrictMock;
     28 using ::testing::WithArgs;
     29 
     30 using WebKit::WebURLError;
     31 using WebKit::WebURLLoader;
     32 using WebKit::WebURLRequest;
     33 using WebKit::WebURLResponse;
     34 
     35 namespace webkit_glue {
     36 
     37 static const int kDataSize = 1024;
     38 static const char kHttpUrl[] = "http://test";
     39 static const char kHttpsUrl[] = "https://test";
     40 static const char kFileUrl[] = "file://test";
     41 static const char kDataUrl[] =
     42     "data:text/plain;base64,YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoK";
     43 static const char kDataUrlDecoded[] = "abcdefghijklmnopqrstuvwxyz";
     44 static const char kInvalidUrl[] = "whatever://test";
     45 static const char kHttpRedirectToSameDomainUrl1[] = "http://test/ing";
     46 static const char kHttpRedirectToSameDomainUrl2[] = "http://test/ing2";
     47 static const char kHttpRedirectToDifferentDomainUrl1[] = "http://test2";
     48 static const char kHttpRedirectToDifferentDomainUrl2[] = "http://test2/ing";
     49 
     50 class 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::MockStatusCallback* 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, 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 
    107     WebURLError error;
    108     error.reason = net::ERR_FAILED;
    109     data_source_->didFail(NULL, error);
    110 
    111     // Let the tasks to be executed.
    112     MessageLoop::current()->RunAllPending();
    113   }
    114 
    115   void Redirect(const char* url) {
    116     GURL redirectUrl(url);
    117     WebKit::WebURLRequest newRequest(redirectUrl);
    118     WebKit::WebURLResponse redirectResponse(gurl_);
    119 
    120     data_source_->willSendRequest(url_loader_, newRequest, redirectResponse);
    121 
    122     MessageLoop::current()->RunAllPending();
    123   }
    124 
    125   void DestroyDataSource() {
    126     data_source_->Stop(media::NewExpectedCallback());
    127     MessageLoop::current()->RunAllPending();
    128 
    129     data_source_ = NULL;
    130   }
    131 
    132   void AsyncRead() {
    133     for (int i = 0; i < kDataSize; ++i) {
    134       uint8 buffer[1];
    135 
    136       EXPECT_CALL(*this, ReadCallback(1));
    137       data_source_->Read(
    138           i, 1, buffer,
    139           NewCallback(this, &SimpleDataSourceTest::ReadCallback));
    140       EXPECT_EQ(static_cast<uint8>(data_[i]), buffer[0]);
    141     }
    142   }
    143 
    144   MOCK_METHOD1(ReadCallback, void(size_t size));
    145 
    146  protected:
    147   GURL gurl_;
    148   scoped_ptr<MessageLoop> message_loop_;
    149   NiceMock<MockWebURLLoader>* url_loader_;
    150   scoped_refptr<SimpleDataSource> data_source_;
    151   StrictMock<media::MockFilterHost> host_;
    152   scoped_ptr<NiceMock<MockWebFrame> > frame_;
    153 
    154   char data_[kDataSize];
    155 
    156   DISALLOW_COPY_AND_ASSIGN(SimpleDataSourceTest);
    157 };
    158 
    159 TEST_F(SimpleDataSourceTest, InitializeHTTP) {
    160   InitializeDataSource(kHttpUrl,
    161                        media::NewExpectedStatusCallback(media::PIPELINE_OK));
    162   RequestSucceeded(false);
    163   DestroyDataSource();
    164 }
    165 
    166 TEST_F(SimpleDataSourceTest, InitializeHTTPS) {
    167   InitializeDataSource(kHttpsUrl,
    168                        media::NewExpectedStatusCallback(media::PIPELINE_OK));
    169   RequestSucceeded(false);
    170   DestroyDataSource();
    171 }
    172 
    173 TEST_F(SimpleDataSourceTest, InitializeFile) {
    174   InitializeDataSource(kFileUrl,
    175                        media::NewExpectedStatusCallback(media::PIPELINE_OK));
    176   RequestSucceeded(true);
    177   DestroyDataSource();
    178 }
    179 
    180 TEST_F(SimpleDataSourceTest, InitializeData) {
    181   frame_.reset(new NiceMock<MockWebFrame>());
    182   url_loader_ = new NiceMock<MockWebURLLoader>();
    183 
    184   data_source_ = new SimpleDataSource(MessageLoop::current(),
    185                                       frame_.get());
    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,
    195       media::NewExpectedStatusCallback(media::PIPELINE_OK));
    196   MessageLoop::current()->RunAllPending();
    197 
    198   DestroyDataSource();
    199 }
    200 
    201 TEST_F(SimpleDataSourceTest, RequestFailed) {
    202   InitializeDataSource(kHttpUrl,
    203       media::NewExpectedStatusCallback(media::PIPELINE_ERROR_NETWORK));
    204   RequestFailed();
    205   DestroyDataSource();
    206 }
    207 
    208 TEST_F(SimpleDataSourceTest, StopWhenDownloading) {
    209   // The callback should be deleted, but not executed.
    210   // TODO(scherkus): should this really be the behaviour?  Seems strange...
    211   StrictMock<media::MockStatusCallback>* callback =
    212       new StrictMock<media::MockStatusCallback>();
    213   EXPECT_CALL(*callback, Destructor());
    214 
    215   InitializeDataSource(kHttpUrl, callback);
    216 
    217   EXPECT_CALL(*url_loader_, cancel());
    218   DestroyDataSource();
    219 }
    220 
    221 TEST_F(SimpleDataSourceTest, AsyncRead) {
    222   InitializeDataSource(kFileUrl,
    223                        media::NewExpectedStatusCallback(media::PIPELINE_OK));
    224   RequestSucceeded(true);
    225   AsyncRead();
    226   DestroyDataSource();
    227 }
    228 
    229 // NOTE: This test will need to be reworked a little once
    230 // http://code.google.com/p/chromium/issues/detail?id=72578
    231 // is fixed.
    232 TEST_F(SimpleDataSourceTest, HasSingleOrigin) {
    233   // Make sure no redirect case works as expected.
    234   InitializeDataSource(kHttpUrl,
    235                        media::NewExpectedStatusCallback(media::PIPELINE_OK));
    236   RequestSucceeded(false);
    237   EXPECT_TRUE(data_source_->HasSingleOrigin());
    238   DestroyDataSource();
    239 
    240   // Test redirect to the same domain.
    241   InitializeDataSource(kHttpUrl,
    242                        media::NewExpectedStatusCallback(media::PIPELINE_OK));
    243   Redirect(kHttpRedirectToSameDomainUrl1);
    244   RequestSucceeded(false);
    245   EXPECT_TRUE(data_source_->HasSingleOrigin());
    246   DestroyDataSource();
    247 
    248   // Test redirect twice to the same domain.
    249   InitializeDataSource(kHttpUrl,
    250                        media::NewExpectedStatusCallback(media::PIPELINE_OK));
    251   Redirect(kHttpRedirectToSameDomainUrl1);
    252   Redirect(kHttpRedirectToSameDomainUrl2);
    253   RequestSucceeded(false);
    254   EXPECT_TRUE(data_source_->HasSingleOrigin());
    255   DestroyDataSource();
    256 
    257   // Test redirect to a different domain.
    258   InitializeDataSource(kHttpUrl,
    259                        media::NewExpectedStatusCallback(media::PIPELINE_OK));
    260   Redirect(kHttpRedirectToDifferentDomainUrl1);
    261   RequestSucceeded(false);
    262   EXPECT_FALSE(data_source_->HasSingleOrigin());
    263   DestroyDataSource();
    264 
    265   // Test redirect to the same domain and then to a different domain.
    266   InitializeDataSource(kHttpUrl,
    267                        media::NewExpectedStatusCallback(media::PIPELINE_OK));
    268   Redirect(kHttpRedirectToSameDomainUrl1);
    269   Redirect(kHttpRedirectToDifferentDomainUrl1);
    270   RequestSucceeded(false);
    271   EXPECT_FALSE(data_source_->HasSingleOrigin());
    272   DestroyDataSource();
    273 }
    274 
    275 }  // namespace webkit_glue
    276