| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" | 5 #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 : public extensions::ExtensionServiceTestBase { | 120 : public extensions::ExtensionServiceTestBase { |
| 121 public: | 121 public: |
| 122 ToolbarActionsModelUnitTest() {} | 122 ToolbarActionsModelUnitTest() {} |
| 123 ~ToolbarActionsModelUnitTest() override {} | 123 ~ToolbarActionsModelUnitTest() override {} |
| 124 | 124 |
| 125 protected: | 125 protected: |
| 126 // Initialize the ExtensionService, ToolbarActionsModel, and | 126 // Initialize the ExtensionService, ToolbarActionsModel, and |
| 127 // ExtensionSystem. | 127 // ExtensionSystem. |
| 128 void Init(); | 128 void Init(); |
| 129 | 129 |
| 130 enum class MigrationStatus { | |
| 131 // The feature is enabled without any extension to migrate. | |
| 132 FEATURE_ENABLED_NO_EXTENSION, | |
| 133 // The feature is enabled and the user has installed an extension. | |
| 134 FEATURE_ENABLED_EXTENSION_INSTALLED, | |
| 135 // Feature is enabled with extension and a pref of false. | |
| 136 FEATURE_ENABLED_WITH_PREF_FALSE, | |
| 137 // Feature is enabled with extension and a pref of true. | |
| 138 FEATURE_ENABLED_WITH_PREF_TRUE, | |
| 139 // The feature is now disabled after previously being enabled, and the user | |
| 140 // has a pref reflecting a previous migration. | |
| 141 FEATURE_DISABLED_WITH_PREF_TRUE, | |
| 142 }; | |
| 143 | |
| 144 // Initialize the ExtensionService, ToolbarActionsModel, and ExtensionSystem, | |
| 145 // and an action extension to migrate to a component. |migration_status| | |
| 146 // is used to configure the user's initial migration status. | |
| 147 void InitForMigrationTest(MigrationStatus migration_status); | |
| 148 | |
| 149 void TearDown() override; | 130 void TearDown() override; |
| 150 | 131 |
| 151 // Adds or removes the given |extension| and verify success. | 132 // Adds or removes the given |extension| and verify success. |
| 152 testing::AssertionResult AddExtension( | 133 testing::AssertionResult AddExtension( |
| 153 const scoped_refptr<const extensions::Extension>& extension) | 134 const scoped_refptr<const extensions::Extension>& extension) |
| 154 WARN_UNUSED_RESULT; | 135 WARN_UNUSED_RESULT; |
| 155 testing::AssertionResult RemoveExtension( | 136 testing::AssertionResult RemoveExtension( |
| 156 const scoped_refptr<const extensions::Extension>& extension) | 137 const scoped_refptr<const extensions::Extension>& extension) |
| 157 WARN_UNUSED_RESULT; | 138 WARN_UNUSED_RESULT; |
| 158 | 139 |
| 159 // Adds three extensions, all with browser actions. | 140 // Adds three extensions, all with browser actions. |
| 160 testing::AssertionResult AddBrowserActionExtensions() WARN_UNUSED_RESULT; | 141 testing::AssertionResult AddBrowserActionExtensions() WARN_UNUSED_RESULT; |
| 161 | 142 |
| 162 // Adds three extensions, one each for browser action, page action, and no | 143 // Adds three extensions, one each for browser action, page action, and no |
| 163 // action, and are added in that order. | 144 // action, and are added in that order. |
| 164 testing::AssertionResult AddActionExtensions() WARN_UNUSED_RESULT; | 145 testing::AssertionResult AddActionExtensions() WARN_UNUSED_RESULT; |
| 165 | 146 |
| 166 // Creates an extension that is to be migrated to a component action. | |
| 167 void CreateMigratedActionExtension(); | |
| 168 | |
| 169 // Returns the action's id at the given index in the toolbar model, or empty | 147 // Returns the action's id at the given index in the toolbar model, or empty |
| 170 // if one does not exist. | 148 // if one does not exist. |
| 171 // If |model| is specified, it is used. Otherwise, this defaults to | 149 // If |model| is specified, it is used. Otherwise, this defaults to |
| 172 // |toolbar_model_|. | 150 // |toolbar_model_|. |
| 173 const std::string GetActionIdAtIndex(size_t index, | 151 const std::string GetActionIdAtIndex(size_t index, |
| 174 const ToolbarActionsModel* model) const; | 152 const ToolbarActionsModel* model) const; |
| 175 const std::string GetActionIdAtIndex(size_t index) const; | 153 const std::string GetActionIdAtIndex(size_t index) const; |
| 176 | 154 |
| 177 // Returns true if the |toobar_model_| has an action with the given |id|. | 155 // Returns true if the |toobar_model_| has an action with the given |id|. |
| 178 bool ModelHasActionForId(const std::string& id) const; | 156 bool ModelHasActionForId(const std::string& id) const; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 192 } | 170 } |
| 193 const extensions::Extension* browser_action_b() const { | 171 const extensions::Extension* browser_action_b() const { |
| 194 return browser_action_b_.get(); | 172 return browser_action_b_.get(); |
| 195 } | 173 } |
| 196 const extensions::Extension* browser_action_c() const { | 174 const extensions::Extension* browser_action_c() const { |
| 197 return browser_action_c_.get(); | 175 return browser_action_c_.get(); |
| 198 } | 176 } |
| 199 const extensions::Extension* browser_action() const { | 177 const extensions::Extension* browser_action() const { |
| 200 return browser_action_extension_.get(); | 178 return browser_action_extension_.get(); |
| 201 } | 179 } |
| 202 const extensions::Extension* browser_action_migrated() const { | |
| 203 return browser_action_migrated_.get(); | |
| 204 } | |
| 205 const extensions::Extension* page_action() const { | 180 const extensions::Extension* page_action() const { |
| 206 return page_action_extension_.get(); | 181 return page_action_extension_.get(); |
| 207 } | 182 } |
| 208 const extensions::Extension* no_action() const { | 183 const extensions::Extension* no_action() const { |
| 209 return no_action_extension_.get(); | 184 return no_action_extension_.get(); |
| 210 } | 185 } |
| 211 | 186 |
| 212 // The mock component action will be referred to as "MCA" below. | 187 // The mock component action will be referred to as "MCA" below. |
| 213 const char* component_action_id() { | 188 const char* component_action_id() { |
| 214 return MockComponentToolbarActionsFactory::kActionIdForTesting; | 189 return MockComponentToolbarActionsFactory::kActionIdForTesting; |
| 215 } | 190 } |
| 216 | 191 |
| 217 private: | 192 private: |
| 218 // Verifies that all extensions in |extensions| are added successfully. | 193 // Verifies that all extensions in |extensions| are added successfully. |
| 219 testing::AssertionResult AddAndVerifyExtensions( | 194 testing::AssertionResult AddAndVerifyExtensions( |
| 220 const extensions::ExtensionList& extensions); | 195 const extensions::ExtensionList& extensions); |
| 221 | 196 |
| 222 // The toolbar model associated with the testing profile. | 197 // The toolbar model associated with the testing profile. |
| 223 ToolbarActionsModel* toolbar_model_; | 198 ToolbarActionsModel* toolbar_model_; |
| 224 | 199 |
| 225 // The test observer to track events. Must come after toolbar_model_ so that | 200 // The test observer to track events. Must come after toolbar_model_ so that |
| 226 // it is destroyed and removes itself as an observer first. | 201 // it is destroyed and removes itself as an observer first. |
| 227 std::unique_ptr<ToolbarActionsModelTestObserver> model_observer_; | 202 std::unique_ptr<ToolbarActionsModelTestObserver> model_observer_; |
| 228 | 203 |
| 229 // Sample extensions with only browser actions. | 204 // Sample extensions with only browser actions. |
| 230 scoped_refptr<const extensions::Extension> browser_action_a_; | 205 scoped_refptr<const extensions::Extension> browser_action_a_; |
| 231 scoped_refptr<const extensions::Extension> browser_action_b_; | 206 scoped_refptr<const extensions::Extension> browser_action_b_; |
| 232 scoped_refptr<const extensions::Extension> browser_action_c_; | 207 scoped_refptr<const extensions::Extension> browser_action_c_; |
| 233 scoped_refptr<const extensions::Extension> browser_action_migrated_; | |
| 234 | 208 |
| 235 // Sample extensions with different kinds of actions. | 209 // Sample extensions with different kinds of actions. |
| 236 scoped_refptr<const extensions::Extension> browser_action_extension_; | 210 scoped_refptr<const extensions::Extension> browser_action_extension_; |
| 237 scoped_refptr<const extensions::Extension> page_action_extension_; | 211 scoped_refptr<const extensions::Extension> page_action_extension_; |
| 238 scoped_refptr<const extensions::Extension> no_action_extension_; | 212 scoped_refptr<const extensions::Extension> no_action_extension_; |
| 239 | 213 |
| 240 std::unique_ptr<MockComponentToolbarActionsFactory> mock_actions_factory_; | 214 std::unique_ptr<MockComponentToolbarActionsFactory> mock_actions_factory_; |
| 241 | 215 |
| 242 DISALLOW_COPY_AND_ASSIGN(ToolbarActionsModelUnitTest); | 216 DISALLOW_COPY_AND_ASSIGN(ToolbarActionsModelUnitTest); |
| 243 }; | 217 }; |
| 244 | 218 |
| 245 void ToolbarActionsModelUnitTest::Init() { | 219 void ToolbarActionsModelUnitTest::Init() { |
| 246 InitializeEmptyExtensionService(); | 220 InitializeEmptyExtensionService(); |
| 247 toolbar_model_ = | 221 toolbar_model_ = |
| 248 extensions::extension_action_test_util::CreateToolbarModelForProfile( | 222 extensions::extension_action_test_util::CreateToolbarModelForProfile( |
| 249 profile()); | 223 profile()); |
| 250 model_observer_.reset(new ToolbarActionsModelTestObserver(toolbar_model_)); | 224 model_observer_.reset(new ToolbarActionsModelTestObserver(toolbar_model_)); |
| 251 } | 225 } |
| 252 | 226 |
| 253 void ToolbarActionsModelUnitTest::InitForMigrationTest( | |
| 254 MigrationStatus migration_status) { | |
| 255 InitializeEmptyExtensionService(); | |
| 256 SetMockActionsFactory(new MockComponentToolbarActionsFactory(nullptr)); | |
| 257 CreateMigratedActionExtension(); | |
| 258 | |
| 259 { | |
| 260 DictionaryPrefUpdate update(profile()->GetPrefs(), | |
| 261 ::prefs::kToolbarMigratedComponentActionStatus); | |
| 262 switch (migration_status) { | |
| 263 case MigrationStatus::FEATURE_ENABLED_EXTENSION_INSTALLED: | |
| 264 mock_actions_factory_->set_migrated_feature_enabled(true); | |
| 265 ASSERT_TRUE(AddExtension(browser_action_migrated())); | |
| 266 break; | |
| 267 case MigrationStatus::FEATURE_ENABLED_NO_EXTENSION: | |
| 268 mock_actions_factory_->set_migrated_feature_enabled(true); | |
| 269 break; | |
| 270 case MigrationStatus::FEATURE_ENABLED_WITH_PREF_TRUE: | |
| 271 mock_actions_factory_->set_migrated_feature_enabled(true); | |
| 272 ASSERT_TRUE(AddExtension(browser_action_migrated())); | |
| 273 update->SetBoolean(component_action_id(), true); | |
| 274 break; | |
| 275 case MigrationStatus::FEATURE_ENABLED_WITH_PREF_FALSE: | |
| 276 mock_actions_factory_->set_migrated_feature_enabled(true); | |
| 277 ASSERT_TRUE(AddExtension(browser_action_migrated())); | |
| 278 update->SetBoolean(component_action_id(), false); | |
| 279 break; | |
| 280 case MigrationStatus::FEATURE_DISABLED_WITH_PREF_TRUE: | |
| 281 mock_actions_factory_->set_migrated_feature_enabled(false); | |
| 282 ASSERT_TRUE(AddExtension(browser_action_migrated())); | |
| 283 update->SetBoolean(component_action_id(), true); | |
| 284 break; | |
| 285 } | |
| 286 } | |
| 287 | |
| 288 toolbar_model_ = | |
| 289 extensions::extension_action_test_util::CreateToolbarModelForProfile( | |
| 290 profile()); | |
| 291 model_observer_.reset(new ToolbarActionsModelTestObserver(toolbar_model_)); | |
| 292 } | |
| 293 | |
| 294 void ToolbarActionsModelUnitTest::TearDown() { | 227 void ToolbarActionsModelUnitTest::TearDown() { |
| 295 model_observer_.reset(); | 228 model_observer_.reset(); |
| 296 extensions::ExtensionServiceTestBase::TearDown(); | 229 extensions::ExtensionServiceTestBase::TearDown(); |
| 297 } | 230 } |
| 298 | 231 |
| 299 testing::AssertionResult ToolbarActionsModelUnitTest::AddExtension( | 232 testing::AssertionResult ToolbarActionsModelUnitTest::AddExtension( |
| 300 const scoped_refptr<const extensions::Extension>& extension) { | 233 const scoped_refptr<const extensions::Extension>& extension) { |
| 301 if (registry()->enabled_extensions().GetByID(extension->id())) { | 234 if (registry()->enabled_extensions().GetByID(extension->id())) { |
| 302 return testing::AssertionFailure() << "Extension " << extension->name() | 235 return testing::AssertionFailure() << "Extension " << extension->name() |
| 303 << " already installed!"; | 236 << " already installed!"; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 extensions::extension_action_test_util::BROWSER_ACTION); | 294 extensions::extension_action_test_util::BROWSER_ACTION); |
| 362 | 295 |
| 363 extensions::ExtensionList extensions; | 296 extensions::ExtensionList extensions; |
| 364 extensions.push_back(browser_action_a_); | 297 extensions.push_back(browser_action_a_); |
| 365 extensions.push_back(browser_action_b_); | 298 extensions.push_back(browser_action_b_); |
| 366 extensions.push_back(browser_action_c_); | 299 extensions.push_back(browser_action_c_); |
| 367 | 300 |
| 368 return AddAndVerifyExtensions(extensions); | 301 return AddAndVerifyExtensions(extensions); |
| 369 } | 302 } |
| 370 | 303 |
| 371 void ToolbarActionsModelUnitTest::CreateMigratedActionExtension() { | |
| 372 browser_action_migrated_ = | |
| 373 extensions::extension_action_test_util::CreateActionExtension( | |
| 374 "browser_actionMigrated", | |
| 375 extensions::extension_action_test_util::BROWSER_ACTION); | |
| 376 mock_actions_factory_->set_migrated_extension_id( | |
| 377 browser_action_migrated_->id()); | |
| 378 } | |
| 379 | |
| 380 const std::string ToolbarActionsModelUnitTest::GetActionIdAtIndex( | 304 const std::string ToolbarActionsModelUnitTest::GetActionIdAtIndex( |
| 381 size_t index, | 305 size_t index, |
| 382 const ToolbarActionsModel* model) const { | 306 const ToolbarActionsModel* model) const { |
| 383 return index < model->toolbar_items().size() | 307 return index < model->toolbar_items().size() |
| 384 ? model->toolbar_items()[index].id | 308 ? model->toolbar_items()[index].id |
| 385 : std::string(); | 309 : std::string(); |
| 386 } | 310 } |
| 387 | 311 |
| 388 const std::string ToolbarActionsModelUnitTest::GetActionIdAtIndex( | 312 const std::string ToolbarActionsModelUnitTest::GetActionIdAtIndex( |
| 389 size_t index) const { | 313 size_t index) const { |
| (...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1528 InitializeEmptyExtensionService(); | 1452 InitializeEmptyExtensionService(); |
| 1529 ToolbarActionsModel* toolbar_model = extensions::extension_action_test_util:: | 1453 ToolbarActionsModel* toolbar_model = extensions::extension_action_test_util:: |
| 1530 CreateToolbarModelForProfileWithoutWaitingForReady(profile()); | 1454 CreateToolbarModelForProfileWithoutWaitingForReady(profile()); |
| 1531 ASSERT_FALSE(toolbar_model->actions_initialized()); | 1455 ASSERT_FALSE(toolbar_model->actions_initialized()); |
| 1532 | 1456 |
| 1533 // AddComponentAction() should be a no-op if actions_initialized() is false. | 1457 // AddComponentAction() should be a no-op if actions_initialized() is false. |
| 1534 toolbar_model->AddComponentAction(component_action_id()); | 1458 toolbar_model->AddComponentAction(component_action_id()); |
| 1535 EXPECT_EQ(0u, toolbar_model->toolbar_items().size()); | 1459 EXPECT_EQ(0u, toolbar_model->toolbar_items().size()); |
| 1536 EXPECT_FALSE(toolbar_model->HasComponentAction(component_action_id())); | 1460 EXPECT_FALSE(toolbar_model->HasComponentAction(component_action_id())); |
| 1537 } | 1461 } |
| 1538 | |
| 1539 TEST_F(ToolbarActionsModelUnitTest, | |
| 1540 NoMigrationToComponentActionWithoutExtension) { | |
| 1541 extensions::FeatureSwitch::ScopedOverride enable_redesign( | |
| 1542 extensions::FeatureSwitch::extension_action_redesign(), true); | |
| 1543 InitForMigrationTest(MigrationStatus::FEATURE_ENABLED_NO_EXTENSION); | |
| 1544 | |
| 1545 EXPECT_EQ(0u, num_toolbar_items()); | |
| 1546 } | |
| 1547 | |
| 1548 TEST_F(ToolbarActionsModelUnitTest, MigrationFromExtensionToComponentAction) { | |
| 1549 extensions::FeatureSwitch::ScopedOverride enable_redesign( | |
| 1550 extensions::FeatureSwitch::extension_action_redesign(), true); | |
| 1551 InitForMigrationTest(MigrationStatus::FEATURE_ENABLED_EXTENSION_INSTALLED); | |
| 1552 | |
| 1553 // Initialization disables the extension and adds the migrated component | |
| 1554 // action. | |
| 1555 EXPECT_EQ(1u, num_toolbar_items()); | |
| 1556 EXPECT_EQ(component_action_id(), GetActionIdAtIndex(0u)); | |
| 1557 } | |
| 1558 | |
| 1559 TEST_F(ToolbarActionsModelUnitTest, MigratedComponentActionAddedWithPrefTrue) { | |
| 1560 extensions::FeatureSwitch::ScopedOverride enable_redesign( | |
| 1561 extensions::FeatureSwitch::extension_action_redesign(), true); | |
| 1562 InitForMigrationTest(MigrationStatus::FEATURE_ENABLED_WITH_PREF_TRUE); | |
| 1563 | |
| 1564 EXPECT_EQ(1u, num_toolbar_items()); | |
| 1565 EXPECT_EQ(component_action_id(), GetActionIdAtIndex(0u)); | |
| 1566 } | |
| 1567 | |
| 1568 TEST_F(ToolbarActionsModelUnitTest, NoMigratedComponentActionWithPrefFalse) { | |
| 1569 extensions::FeatureSwitch::ScopedOverride enable_redesign( | |
| 1570 extensions::FeatureSwitch::extension_action_redesign(), true); | |
| 1571 InitForMigrationTest(MigrationStatus::FEATURE_ENABLED_WITH_PREF_FALSE); | |
| 1572 | |
| 1573 EXPECT_EQ(0u, num_toolbar_items()); | |
| 1574 } | |
| 1575 | |
| 1576 TEST_F(ToolbarActionsModelUnitTest, MigrationFromComponentActionToExtension) { | |
| 1577 extensions::FeatureSwitch::ScopedOverride enable_redesign( | |
| 1578 extensions::FeatureSwitch::extension_action_redesign(), true); | |
| 1579 InitForMigrationTest(MigrationStatus::FEATURE_DISABLED_WITH_PREF_TRUE); | |
| 1580 | |
| 1581 // Initialization re-enables the extension and removes the migrated component | |
| 1582 // action. | |
| 1583 EXPECT_EQ(1u, num_toolbar_items()); | |
| 1584 EXPECT_EQ(browser_action_migrated()->id(), GetActionIdAtIndex(0u)); | |
| 1585 } | |
| 1586 | |
| 1587 TEST_F(ToolbarActionsModelUnitTest, | |
| 1588 MigrationToExtensionWithoutExtensionActionRedesign) { | |
| 1589 InitForMigrationTest(MigrationStatus::FEATURE_DISABLED_WITH_PREF_TRUE); | |
| 1590 | |
| 1591 // Initialization re-enables the extension. | |
| 1592 EXPECT_EQ(1u, num_toolbar_items()); | |
| 1593 EXPECT_EQ(browser_action_migrated()->id(), GetActionIdAtIndex(0u)); | |
| 1594 } | |
| OLD | NEW |