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. 4 5 #include "base/bind.h" 6 #include "base/message_loop/message_loop.h" 7 #include "content/renderer/media/android/media_info_loader.h" 8 #include "third_party/WebKit/public/platform/WebURLError.h" 9 #include "third_party/WebKit/public/platform/WebURLRequest.h" 10 #include "third_party/WebKit/public/platform/WebURLResponse.h" 11 #include "third_party/WebKit/public/web/WebMediaPlayer.h" 12 #include "third_party/WebKit/public/web/WebView.h" 13 #include "webkit/mocks/mock_webframeclient.h" 14 #include "webkit/mocks/mock_weburlloader.h" 15 16 using ::testing::_; 17 using ::testing::InSequence; 18 using ::testing::NiceMock; 19 20 using WebKit::WebString; 21 using WebKit::WebURLError; 22 using WebKit::WebURLResponse; 23 using WebKit::WebView; 24 25 using webkit_glue::MockWebFrameClient; 26 using webkit_glue::MockWebURLLoader; 27 28 namespace content { 29 30 static const char* kHttpUrl = "http://test"; 31 static const char kHttpRedirectToSameDomainUrl1[] = "http://test/ing"; 32 static const char kHttpRedirectToSameDomainUrl2[] = "http://test/ing2"; 33 static const char kHttpRedirectToDifferentDomainUrl1[] = "http://test2"; 34 35 static const int kHttpOK = 200; 36 static const int kHttpNotFound = 404; 37 38 class MediaInfoLoaderTest : public testing::Test { 39 public: 40 MediaInfoLoaderTest() 41 : view_(WebView::create(NULL)) { 42 view_->initializeMainFrame(&client_); 43 } 44 45 virtual ~MediaInfoLoaderTest() { 46 view_->close(); 47 } 48 49 void Initialize( 50 const char* url, 51 WebKit::WebMediaPlayer::CORSMode cors_mode) { 52 gurl_ = GURL(url); 53 54 loader_.reset(new MediaInfoLoader( 55 gurl_, cors_mode, 56 base::Bind(&MediaInfoLoaderTest::ReadyCallback, 57 base::Unretained(this)))); 58 59 // |test_loader_| will be used when Start() is called. 60 url_loader_ = new NiceMock<MockWebURLLoader>(); 61 loader_->test_loader_ = scoped_ptr<WebKit::WebURLLoader>(url_loader_); 62 } 63 64 void Start() { 65 InSequence s; 66 EXPECT_CALL(*url_loader_, loadAsynchronously(_, _)); 67 loader_->Start(view_->mainFrame()); 68 } 69 70 void Stop() { 71 InSequence s; 72 EXPECT_CALL(*url_loader_, cancel()); 73 loader_.reset(); 74 } 75 76 void Redirect(const char* url) { 77 GURL redirect_url(url); 78 WebKit::WebURLRequest new_request(redirect_url); 79 WebKit::WebURLResponse redirect_response(gurl_); 80 81 loader_->willSendRequest(url_loader_, new_request, redirect_response); 82 83 base::MessageLoop::current()->RunUntilIdle(); 84 } 85 86 void SendResponse( 87 int http_status, MediaInfoLoader::Status expected_status) { 88 EXPECT_CALL(*this, ReadyCallback(expected_status)); 89 EXPECT_CALL(*url_loader_, cancel()); 90 91 WebURLResponse response(gurl_); 92 response.setHTTPHeaderField(WebString::fromUTF8("Content-Length"), 93 WebString::fromUTF8("0")); 94 response.setExpectedContentLength(0); 95 response.setHTTPStatusCode(http_status); 96 loader_->didReceiveResponse(url_loader_, response); 97 } 98 99 void FailLoad() { 100 EXPECT_CALL(*this, ReadyCallback(MediaInfoLoader::kFailed)); 101 loader_->didFail(url_loader_, WebURLError()); 102 } 103 104 MOCK_METHOD1(ReadyCallback, void(MediaInfoLoader::Status)); 105 106 protected: 107 GURL gurl_; 108 109 scoped_ptr<MediaInfoLoader> loader_; 110 NiceMock<MockWebURLLoader>* url_loader_; 111 112 MockWebFrameClient client_; 113 WebView* view_; 114 115 base::MessageLoop message_loop_; 116 117 private: 118 DISALLOW_COPY_AND_ASSIGN(MediaInfoLoaderTest); 119 }; 120 121 TEST_F(MediaInfoLoaderTest, StartStop) { 122 Initialize(kHttpUrl, WebKit::WebMediaPlayer::CORSModeUnspecified); 123 Start(); 124 Stop(); 125 } 126 127 TEST_F(MediaInfoLoaderTest, LoadFailure) { 128 Initialize(kHttpUrl, WebKit::WebMediaPlayer::CORSModeUnspecified); 129 Start(); 130 FailLoad(); 131 } 132 133 TEST_F(MediaInfoLoaderTest, HasSingleOriginNoRedirect) { 134 // Make sure no redirect case works as expected. 135 Initialize(kHttpUrl, WebKit::WebMediaPlayer::CORSModeUnspecified); 136 Start(); 137 SendResponse(kHttpOK, MediaInfoLoader::kOk); 138 EXPECT_TRUE(loader_->HasSingleOrigin()); 139 } 140 141 TEST_F(MediaInfoLoaderTest, HasSingleOriginSingleRedirect) { 142 // Test redirect to the same domain. 143 Initialize(kHttpUrl, WebKit::WebMediaPlayer::CORSModeUnspecified); 144 Start(); 145 Redirect(kHttpRedirectToSameDomainUrl1); 146 SendResponse(kHttpOK, MediaInfoLoader::kOk); 147 EXPECT_TRUE(loader_->HasSingleOrigin()); 148 } 149 150 TEST_F(MediaInfoLoaderTest, HasSingleOriginDoubleRedirect) { 151 // Test redirect twice to the same domain. 152 Initialize(kHttpUrl, WebKit::WebMediaPlayer::CORSModeUnspecified); 153 Start(); 154 Redirect(kHttpRedirectToSameDomainUrl1); 155 Redirect(kHttpRedirectToSameDomainUrl2); 156 SendResponse(kHttpOK, MediaInfoLoader::kOk); 157 EXPECT_TRUE(loader_->HasSingleOrigin()); 158 } 159 160 TEST_F(MediaInfoLoaderTest, HasSingleOriginDifferentDomain) { 161 // Test redirect to a different domain. 162 Initialize(kHttpUrl, WebKit::WebMediaPlayer::CORSModeUnspecified); 163 Start(); 164 Redirect(kHttpRedirectToDifferentDomainUrl1); 165 SendResponse(kHttpOK, MediaInfoLoader::kOk); 166 EXPECT_FALSE(loader_->HasSingleOrigin()); 167 } 168 169 TEST_F(MediaInfoLoaderTest, HasSingleOriginMultipleDomains) { 170 // Test redirect to the same domain and then to a different domain. 171 Initialize(kHttpUrl, WebKit::WebMediaPlayer::CORSModeUnspecified); 172 Start(); 173 Redirect(kHttpRedirectToSameDomainUrl1); 174 Redirect(kHttpRedirectToDifferentDomainUrl1); 175 SendResponse(kHttpOK, MediaInfoLoader::kOk); 176 EXPECT_FALSE(loader_->HasSingleOrigin()); 177 } 178 179 TEST_F(MediaInfoLoaderTest, CORSAccessCheckPassed) { 180 Initialize(kHttpUrl, WebKit::WebMediaPlayer::CORSModeUseCredentials); 181 Start(); 182 SendResponse(kHttpOK, MediaInfoLoader::kOk); 183 EXPECT_TRUE(loader_->DidPassCORSAccessCheck()); 184 } 185 186 TEST_F(MediaInfoLoaderTest, CORSAccessCheckFailed) { 187 Initialize(kHttpUrl, WebKit::WebMediaPlayer::CORSModeUseCredentials); 188 Start(); 189 SendResponse(kHttpNotFound, MediaInfoLoader::kFailed); 190 EXPECT_FALSE(loader_->DidPassCORSAccessCheck()); 191 } 192 193 } // namespace content 194