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