| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "base/message_loop.h" | |
| 6 #include "chrome/browser/chromeos/extensions/file_browser_handler.h" | |
| 7 #include "chrome/browser/chromeos/extensions/file_browser_resource_throttle.h" | |
| 8 #include "chrome/browser/extensions/extension_info_map.h" | |
| 9 #include "chrome/common/extensions/extension.h" | |
| 10 #include "chrome/common/extensions/extension_builder.h" | |
| 11 #include "chrome/common/extensions/extension_constants.h" | |
| 12 #include "chrome/common/extensions/manifest_handler.h" | |
| 13 #include "chrome/common/extensions/value_builder.h" | |
| 14 #include "content/public/browser/resource_controller.h" | |
| 15 #include "content/public/test/test_browser_thread.h" | |
| 16 #include "testing/gmock/include/gmock/gmock.h" | |
| 17 #include "testing/gtest/include/gtest/gtest.h" | |
| 18 | |
| 19 using content::BrowserThread; | |
| 20 using extensions::DictionaryBuilder; | |
| 21 using extensions::Extension; | |
| 22 using extensions::ExtensionBuilder; | |
| 23 using extensions::ListBuilder; | |
| 24 using testing::_; | |
| 25 | |
| 26 namespace { | |
| 27 | |
| 28 // Mock file browser handler event router to be used in the test. | |
| 29 class MockFileBrowserHandlerEventRouter | |
| 30 : public FileBrowserResourceThrottle::FileBrowserHandlerEventRouter { | |
| 31 public: | |
| 32 virtual ~MockFileBrowserHandlerEventRouter() {} | |
| 33 | |
| 34 MOCK_METHOD5(DispatchMimeTypeHandlerEvent, | |
| 35 void(int render_process_id, | |
| 36 int render_process_view, | |
| 37 const std::string& mime_type, | |
| 38 const GURL& request_url, | |
| 39 const std::string& extension_id)); | |
| 40 }; | |
| 41 | |
| 42 // Resource controller to be used in the tests. | |
| 43 class MockResourceController : public content::ResourceController { | |
| 44 public: | |
| 45 virtual ~MockResourceController() {} | |
| 46 MOCK_METHOD0(Cancel, void()); | |
| 47 MOCK_METHOD0(CancelAndIgnore, void()); | |
| 48 MOCK_METHOD1(CancelWithError, void(int error_code)); | |
| 49 MOCK_METHOD0(Resume, void()); | |
| 50 }; | |
| 51 | |
| 52 class FileBrowserResourceThrottleTest : public testing::Test { | |
| 53 public: | |
| 54 typedef FileBrowserResourceThrottle::FileBrowserHandlerEventRouter | |
| 55 HandlerEventRouter; | |
| 56 | |
| 57 FileBrowserResourceThrottleTest() | |
| 58 : test_extension_id_("test_extension_id"), | |
| 59 test_render_process_id_(2), | |
| 60 test_render_view_id_(12), | |
| 61 test_request_url_("http://some_url/file.txt"), | |
| 62 ui_thread_(content::BrowserThread::UI, &message_loop_), | |
| 63 io_thread_(content::BrowserThread::IO, &message_loop_) { | |
| 64 } | |
| 65 | |
| 66 virtual ~FileBrowserResourceThrottleTest() {} | |
| 67 | |
| 68 virtual void SetUp() OVERRIDE { | |
| 69 (new FileBrowserHandlerParser)->Register(); | |
| 70 // Extension info map must be created before |CreateAndInstallTestExtension| | |
| 71 // is called (the method will add created extension to the info map). | |
| 72 extension_info_map_ = new ExtensionInfoMap(); | |
| 73 CreateAndInstallTestExtension(); | |
| 74 InitResourceController(); | |
| 75 } | |
| 76 | |
| 77 virtual void TearDown() OVERRIDE { | |
| 78 FileBrowserHandler::set_extension_whitelisted_for_test(NULL); | |
| 79 extensions::ManifestHandler::ClearRegistryForTesting(); | |
| 80 } | |
| 81 | |
| 82 protected: | |
| 83 // Creates the test extension, and adds it to the |extension_info_map_|. | |
| 84 // The extension has separate file browser handlers that can handle | |
| 85 // 'plain/html' and 'plain/text' MIME types. | |
| 86 void CreateAndInstallTestExtension() { | |
| 87 // The extension must be white-listed in order to be successfully created. | |
| 88 FileBrowserHandler::set_extension_whitelisted_for_test( | |
| 89 &test_extension_id_); | |
| 90 | |
| 91 extension_ = | |
| 92 ExtensionBuilder() | |
| 93 .SetManifest(DictionaryBuilder() | |
| 94 .Set("name", "file browser handler test") | |
| 95 .Set("version", "1.0.0") | |
| 96 .Set("manifest_version", 2) | |
| 97 .Set("file_browser_handlers", ListBuilder() | |
| 98 .Append(DictionaryBuilder() | |
| 99 // Handler that handles 'plain/html', among others. | |
| 100 .Set("id", "ID_handle_html") | |
| 101 .Set("default_title", "Default title") | |
| 102 .Set("default_icon", "icon.png") | |
| 103 // file_filters_field is mandatory, even though | |
| 104 // it's not used in the tests. | |
| 105 .Set("file_filters", ListBuilder() | |
| 106 .Append("filesystem:*.html")) | |
| 107 .Set("mime_types", ListBuilder() | |
| 108 .Append("random/mime1") | |
| 109 .Append("random/mime2") | |
| 110 .Append("plain/html"))) | |
| 111 .Append(DictionaryBuilder() | |
| 112 // Handler that handles only 'plain/text'. | |
| 113 .Set("id", "ID_handle_text") | |
| 114 .Set("default_title", "Default title") | |
| 115 .Set("default_icon", "icon.png") | |
| 116 // file_filters_field is mandatory, even though | |
| 117 // it's not used in the tests. | |
| 118 .Set("file_filters", ListBuilder() | |
| 119 .Append("filesystem:*.txt")) | |
| 120 .Set("mime_types", ListBuilder() | |
| 121 .Append("plain/text"))))) | |
| 122 .SetID(test_extension_id_) | |
| 123 .Build(); | |
| 124 | |
| 125 // 'Install' the extension. | |
| 126 extension_info_map_->AddExtension(extension_, | |
| 127 base::Time(), // install time | |
| 128 true); // enable_incognito | |
| 129 } | |
| 130 | |
| 131 // Initiates the default mock_resource_controller_ expectations. | |
| 132 // By the default, resource controller should not be called at all. | |
| 133 void InitResourceController() { | |
| 134 EXPECT_CALL(mock_resource_controller_, Cancel()).Times(0); | |
| 135 EXPECT_CALL(mock_resource_controller_, CancelAndIgnore()).Times(0); | |
| 136 EXPECT_CALL(mock_resource_controller_, CancelWithError(_)).Times(0); | |
| 137 EXPECT_CALL(mock_resource_controller_, Resume()).Times(0); | |
| 138 } | |
| 139 | |
| 140 // Removes the test extension to |extension_info_map_|'s disabled extensions. | |
| 141 void DisableTestExtension() { | |
| 142 extension_info_map_->RemoveExtension(test_extension_id_, | |
| 143 extension_misc::UNLOAD_REASON_DISABLE); | |
| 144 } | |
| 145 | |
| 146 void ReloadTestExtensionIncognitoDisabled() { | |
| 147 extension_info_map_->RemoveExtension( | |
| 148 test_extension_id_, extension_misc::UNLOAD_REASON_UNINSTALL); | |
| 149 extension_info_map_->AddExtension(extension_, | |
| 150 base::Time(), // install_time | |
| 151 false); // enable incognito | |
| 152 } | |
| 153 | |
| 154 // Creates the resource throttle that should be tested. | |
| 155 // It's setup with |mock_event_router| passed to the method and | |
| 156 // |mock_resource_throttle_|. | |
| 157 // |mock_event_router|'s expectations must be set before calling this method. | |
| 158 scoped_ptr<FileBrowserResourceThrottle> CreateThrottleToTest( | |
| 159 bool is_incognito, | |
| 160 scoped_ptr<MockFileBrowserHandlerEventRouter> mock_event_router, | |
| 161 const std::string& mime_type) { | |
| 162 scoped_ptr<HandlerEventRouter> event_router(mock_event_router.release()); | |
| 163 scoped_ptr<FileBrowserResourceThrottle> test_throttle( | |
| 164 FileBrowserResourceThrottle::CreateForTest(test_render_process_id_, | |
| 165 test_render_view_id_, | |
| 166 mime_type, | |
| 167 test_request_url_, | |
| 168 is_incognito, | |
| 169 extension_info_map_.get(), | |
| 170 event_router.Pass())); | |
| 171 | |
| 172 test_throttle->set_controller_for_testing(&mock_resource_controller_); | |
| 173 | |
| 174 return test_throttle.Pass(); | |
| 175 } | |
| 176 | |
| 177 // The test extension's id. | |
| 178 std::string test_extension_id_; | |
| 179 // The test extension. | |
| 180 scoped_refptr<const Extension> extension_; | |
| 181 | |
| 182 // The extension info map used in the test. The extensions are considered | |
| 183 // installed/disabled depending on the extension_info_map_ state. | |
| 184 scoped_refptr<ExtensionInfoMap> extension_info_map_; | |
| 185 | |
| 186 MockResourceController mock_resource_controller_; | |
| 187 | |
| 188 // Parameters used to create the test resource throttle. Unlike, mime_type | |
| 189 // these can be selected at random. | |
| 190 int test_render_process_id_; | |
| 191 int test_render_view_id_; | |
| 192 GURL test_request_url_; | |
| 193 | |
| 194 private: | |
| 195 // ExtensionInfoMap needs IO thread. | |
| 196 MessageLoop message_loop_; | |
| 197 content::TestBrowserThread ui_thread_; | |
| 198 content::TestBrowserThread io_thread_; | |
| 199 }; | |
| 200 | |
| 201 // Tests that the request gets canceled (mock_resource_controller_.Cancel() is | |
| 202 // called) and the event_router is invoked when a white-listed extension has a | |
| 203 // file browser handler that can handle the request's MIME type. | |
| 204 TEST_F(FileBrowserResourceThrottleTest, HandlerWhiteListed) { | |
| 205 EXPECT_CALL(mock_resource_controller_, CancelAndIgnore()).Times(1); | |
| 206 | |
| 207 scoped_ptr<MockFileBrowserHandlerEventRouter> mock_event_router( | |
| 208 new MockFileBrowserHandlerEventRouter()); | |
| 209 EXPECT_CALL(*mock_event_router, | |
| 210 DispatchMimeTypeHandlerEvent(test_render_process_id_, | |
| 211 test_render_view_id_, | |
| 212 "plain/html", | |
| 213 test_request_url_, | |
| 214 test_extension_id_)) | |
| 215 .Times(1); | |
| 216 | |
| 217 scoped_ptr<FileBrowserResourceThrottle> throttle( | |
| 218 CreateThrottleToTest(false, mock_event_router.Pass(), "plain/html")); | |
| 219 | |
| 220 bool defer = false; | |
| 221 throttle->WillProcessResponse(&defer); | |
| 222 EXPECT_FALSE(defer); | |
| 223 } | |
| 224 | |
| 225 // Tests that the request gets canceled (mock_resource_controller_.Cancel() is | |
| 226 // called) and the event_router is invoked when a white-listed extension has a | |
| 227 // file browser handler that can handle the request's MIME type, even when the | |
| 228 // file browser handler is not first in the extension's file browser handler | |
| 229 // list. | |
| 230 TEST_F(FileBrowserResourceThrottleTest, SecondHandlerWhiteListed) { | |
| 231 EXPECT_CALL(mock_resource_controller_, CancelAndIgnore()).Times(1); | |
| 232 | |
| 233 scoped_ptr<MockFileBrowserHandlerEventRouter> mock_event_router( | |
| 234 new MockFileBrowserHandlerEventRouter()); | |
| 235 EXPECT_CALL(*mock_event_router, | |
| 236 DispatchMimeTypeHandlerEvent(test_render_process_id_, | |
| 237 test_render_view_id_, | |
| 238 "plain/text", | |
| 239 test_request_url_, | |
| 240 test_extension_id_)) | |
| 241 .Times(1); | |
| 242 | |
| 243 scoped_ptr<FileBrowserResourceThrottle> throttle( | |
| 244 CreateThrottleToTest(false, mock_event_router.Pass(), "plain/text")); | |
| 245 | |
| 246 bool defer = false; | |
| 247 throttle->WillProcessResponse(&defer); | |
| 248 EXPECT_FALSE(defer); | |
| 249 } | |
| 250 | |
| 251 // Tests that the request is not canceled and the event router is not invoked | |
| 252 // if there is no file browser handlers registered for the request's MIME type. | |
| 253 TEST_F(FileBrowserResourceThrottleTest, NoWhiteListedHandler) { | |
| 254 scoped_ptr<MockFileBrowserHandlerEventRouter> mock_event_router( | |
| 255 new MockFileBrowserHandlerEventRouter()); | |
| 256 EXPECT_CALL(*mock_event_router, DispatchMimeTypeHandlerEvent(_, _, _, _, _)) | |
| 257 .Times(0); | |
| 258 | |
| 259 scoped_ptr<FileBrowserResourceThrottle> throttle( | |
| 260 CreateThrottleToTest(false, mock_event_router.Pass(), | |
| 261 "random_mime_type")); | |
| 262 | |
| 263 bool defer = false; | |
| 264 throttle->WillProcessResponse(&defer); | |
| 265 EXPECT_FALSE(defer); | |
| 266 } | |
| 267 | |
| 268 // Tests that the request is not canceled and the event router is not invoked | |
| 269 // if there is an extension with the file browser handler that can handle the | |
| 270 // request's MIME type, but the extension is disabled. | |
| 271 TEST_F(FileBrowserResourceThrottleTest, HandlerWhiteListedAndDisabled) { | |
| 272 DisableTestExtension(); | |
| 273 | |
| 274 scoped_ptr<MockFileBrowserHandlerEventRouter> mock_event_router( | |
| 275 new MockFileBrowserHandlerEventRouter()); | |
| 276 EXPECT_CALL(*mock_event_router, DispatchMimeTypeHandlerEvent(_, _, _, _, _)) | |
| 277 .Times(0); | |
| 278 | |
| 279 scoped_ptr<FileBrowserResourceThrottle> throttle( | |
| 280 CreateThrottleToTest(false, mock_event_router.Pass(), "plain/text")); | |
| 281 | |
| 282 bool defer = false; | |
| 283 throttle->WillProcessResponse(&defer); | |
| 284 EXPECT_FALSE(defer); | |
| 285 } | |
| 286 | |
| 287 // Tests that the request is not canceled and the event router is not invoked | |
| 288 // in incognito mode if the extension that handles the request's MIME type is | |
| 289 // not incognito enabled. | |
| 290 TEST_F(FileBrowserResourceThrottleTest, IncognitoExtensionNotEnabled) { | |
| 291 ReloadTestExtensionIncognitoDisabled(); | |
| 292 | |
| 293 scoped_ptr<MockFileBrowserHandlerEventRouter> mock_event_router( | |
| 294 new MockFileBrowserHandlerEventRouter()); | |
| 295 EXPECT_CALL(*mock_event_router, DispatchMimeTypeHandlerEvent(_, _, _, _, _)) | |
| 296 .Times(0); | |
| 297 | |
| 298 scoped_ptr<FileBrowserResourceThrottle> throttle( | |
| 299 CreateThrottleToTest(true, mock_event_router.Pass(), "plain/text")); | |
| 300 | |
| 301 bool defer = false; | |
| 302 throttle->WillProcessResponse(&defer); | |
| 303 EXPECT_FALSE(defer); | |
| 304 } | |
| 305 | |
| 306 // Tests that the request gets canceled (mock_resource_controller_.Cancel() is | |
| 307 // called) and the event_router is invoked in incognito when a white-listed | |
| 308 // extension that handles request's MIME type is incognito enabled. | |
| 309 TEST_F(FileBrowserResourceThrottleTest, IncognitoExtensionEnabled) { | |
| 310 EXPECT_CALL(mock_resource_controller_, CancelAndIgnore()).Times(1); | |
| 311 | |
| 312 scoped_ptr<MockFileBrowserHandlerEventRouter> mock_event_router( | |
| 313 new MockFileBrowserHandlerEventRouter()); | |
| 314 EXPECT_CALL(*mock_event_router, | |
| 315 DispatchMimeTypeHandlerEvent(test_render_process_id_, | |
| 316 test_render_view_id_, | |
| 317 "plain/html", | |
| 318 test_request_url_, | |
| 319 test_extension_id_)) | |
| 320 .Times(1); | |
| 321 | |
| 322 scoped_ptr<FileBrowserResourceThrottle> throttle( | |
| 323 CreateThrottleToTest(true, mock_event_router.Pass(), "plain/html")); | |
| 324 | |
| 325 bool defer = false; | |
| 326 throttle->WillProcessResponse(&defer); | |
| 327 EXPECT_FALSE(defer); | |
| 328 } | |
| 329 | |
| 330 } // namespace | |
| OLD | NEW |