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