Chromium Code Reviews| Index: chrome/browser/extensions/extension_action_manager_unittest.cc |
| diff --git a/chrome/browser/extensions/extension_action_manager_unittest.cc b/chrome/browser/extensions/extension_action_manager_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2ac1319d644c65d74c3d29f750a7e92c29aefe36 |
| --- /dev/null |
| +++ b/chrome/browser/extensions/extension_action_manager_unittest.cc |
| @@ -0,0 +1,223 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/extensions/extension_action_manager.h" |
| + |
| +#include "base/strings/string_number_conversions.h" |
| +#include "chrome/browser/extensions/extension_action.h" |
| +#include "chrome/test/base/testing_profile.h" |
| +#include "extensions/common/extension_builder.h" |
| +#include "extensions/common/manifest_handlers/icons_handler.h" |
| +#include "extensions/common/value_builder.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace extensions { |
| + |
| +namespace { |
| + |
| +const char kBrowserAction[] = "browser_action"; |
| +const char kPageAction[] = "page_action"; |
| + |
| +} // namespace |
| + |
| +class ExtensionActionManagerTest : public testing::Test { |
| + public: |
| + ExtensionActionManagerTest(); |
| + |
| + protected: |
| + // Build an extension, populating |action_type| key with |action|, and |
| + // "icons" key with |extension_icons|. |
| + scoped_refptr<Extension> BuildExtension(DictionaryBuilder& extension_icons, |
| + DictionaryBuilder& action, |
| + const char* action_type); |
| + |
| + // Returns true if |action|'s title matches |extension|'s name. |
| + bool TitlesMatch(const Extension& extension, const ExtensionAction& action); |
| + |
| + // Returns true if |action|'s icon for size |action_key| matches |
| + // |extension|'s icon for size |extension_key|; |
| + bool IconsMatch(const Extension& extension, |
| + int extension_key, |
| + const ExtensionAction& action, |
| + int action_key); |
| + |
| + // Returns the appropriate action for |extension| according to |action_type|. |
| + ExtensionAction* GetAction(const char* action_type, |
| + const Extension& extension); |
| + |
| + // Tests that values that are missing from the |action_type| key are properly |
| + // populated with values from the other keys in the manifest (e.g. |
| + // "default_icon" key of |action_type| is populated with "icons" key). |
| + void TestPopulateMissingValues(const char* action_type); |
| + |
| + ExtensionActionManager* manager() { return manager_; } |
| + |
| + private: |
| + int curr_id_; |
| + ExtensionActionManager* manager_; |
| + scoped_ptr<TestingProfile> profile_; |
| +}; |
| + |
| +ExtensionActionManagerTest::ExtensionActionManagerTest() |
| + : curr_id_(0), |
| + profile_(new TestingProfile) { |
| + manager_ = ExtensionActionManager::Get(profile_.get()); |
| +} |
| + |
| +scoped_refptr<Extension> ExtensionActionManagerTest::BuildExtension( |
| + DictionaryBuilder& extension_icons, |
| + DictionaryBuilder& action, |
| + const char* action_type) { |
| + std::string id = base::IntToString(curr_id_++); |
| + return ExtensionBuilder() |
| + .SetManifest(DictionaryBuilder().Set("version", "1") |
| + .Set("manifest_version", 2) |
| + .Set("icons", extension_icons) |
| + .Set(action_type, action) |
| + .Set("name", |
| + std::string("Test Extension").append(id))) |
| + .SetID(id) |
| + .Build(); |
| +} |
| + |
| +bool ExtensionActionManagerTest::TitlesMatch(const Extension& extension, |
| + const ExtensionAction& action) { |
| + return action.GetTitle(ExtensionAction::kDefaultTabId) == extension.name(); |
| +} |
| + |
| +bool ExtensionActionManagerTest::IconsMatch(const Extension& extension, |
| + int extension_key, |
| + const ExtensionAction& action, |
| + int action_key) { |
| + return action.default_icon()->Get(action_key, |
| + ExtensionIconSet::MATCH_EXACTLY) == |
| + IconsInfo::GetIcons(&extension).Get(extension_key, |
| + ExtensionIconSet::MATCH_EXACTLY); |
| +} |
| + |
| +ExtensionAction* ExtensionActionManagerTest::GetAction( |
| + const char* action_type, |
| + const Extension& extension) { |
| + return (action_type == kBrowserAction) ? |
| + manager_->GetBrowserAction(extension) : |
| + manager_->GetPageAction(extension); |
| +} |
| + |
| +void ExtensionActionManagerTest::TestPopulateMissingValues( |
| + const char* action_type) { |
| + // Test that the largest icon from the extension's "icons" key is chosen as a |
| + // replacement for missing action default_icons keys. |
| + scoped_refptr<Extension> extension = BuildExtension( |
| + DictionaryBuilder().Set("48", "icon48.png") |
| + .Set("128", "icon128.png"), |
| + DictionaryBuilder().Pass(), |
| + action_type); |
| + |
| + ASSERT_TRUE(extension.get()); |
| + const ExtensionAction* action = GetAction(action_type, *extension); |
| + ASSERT_TRUE(action); |
| + |
| + ASSERT_TRUE(TitlesMatch(*extension, *action)); |
| + ASSERT_TRUE(IconsMatch(*extension, 128, *action, 19)); |
| + ASSERT_TRUE(IconsMatch(*extension, 128, *action, 38)); |
| + |
| + // Test that the action's missing default_icons are not replaced with smaller |
| + // icons. |
| + extension = BuildExtension( |
| + DictionaryBuilder().Set("16", "icon16.png"), |
| + DictionaryBuilder().Pass(), |
| + action_type); |
| + |
| + ASSERT_TRUE(extension.get()); |
| + action = GetAction(action_type, *extension); |
| + ASSERT_TRUE(action); |
| + |
| + ASSERT_FALSE(IconsMatch(*extension, 16, *action, 19)); |
| + ASSERT_FALSE(IconsMatch(*extension, 16, *action, 38)); |
| + |
| + // Test that an action's 19px icon is not replaced if a 38px action icon |
| + // exists. |
| + extension = BuildExtension( |
| + DictionaryBuilder().Set("128", "icon128.png"), |
| + DictionaryBuilder().Set("default_icon", DictionaryBuilder() |
| + .Set("38", "action38.png")), |
| + action_type); |
| + |
| + ASSERT_TRUE(extension.get()); |
| + action = GetAction(action_type, *extension); |
| + ASSERT_TRUE(action); |
| + |
| + ASSERT_FALSE(IconsMatch(*extension, 128, *action, 19)); |
| + |
| + // Test that existing default_icons and default_title are not replaced. |
| + extension = BuildExtension( |
| + DictionaryBuilder().Set("128", "icon128.png"), |
| + DictionaryBuilder().Set("default_title", "Action!") |
| + .Set("default_icon", DictionaryBuilder() |
| + .Set("19", "action19.png") |
| + .Set("38", "action38.png")), |
| + action_type); |
| + |
| + ASSERT_TRUE(extension.get()); |
| + action = GetAction(action_type, *extension); |
| + ASSERT_TRUE(action); |
| + |
| + ASSERT_FALSE(TitlesMatch(*extension, *action)); |
| + ASSERT_FALSE(IconsMatch(*extension, 128, *action, 19)); |
| + ASSERT_FALSE(IconsMatch(*extension, 128, *action, 38)); |
| +} |
| + |
| +namespace { |
| + |
| +TEST_F(ExtensionActionManagerTest, PopulateBrowserAction) { |
| + TestPopulateMissingValues(kBrowserAction); |
| +} |
| + |
| +TEST_F(ExtensionActionManagerTest, PopulatePageAction) { |
| + TestPopulateMissingValues(kPageAction); |
| +} |
| + |
| +TEST_F(ExtensionActionManagerTest, GetBestFitActionTest) { |
| + // Create an extension with page action defaults. |
| + scoped_ptr<DictionaryBuilder> extension_icons(new DictionaryBuilder()); |
| + extension_icons->Set("48", "icon48.png"); |
|
not at google - send to devlin
2014/08/07 22:15:09
inline extension_icons as well.
gpdavis
2014/08/07 23:48:35
Done.
|
| + scoped_ptr<DictionaryBuilder> action_manifest(new DictionaryBuilder()); |
| + action_manifest->Set("default_title", "Action!") |
| + .Set("default_icon", DictionaryBuilder() |
| + .Set("38", "action38.png")); |
| + scoped_refptr<Extension> extension = BuildExtension(extension_icons->Pass(), |
| + action_manifest->Pass(), |
| + kPageAction); |
| + ASSERT_TRUE(extension.get()); |
| + |
| + // Get a "best fit" browser action for |extension|. |
| + scoped_ptr<ExtensionAction> action = |
| + manager()->GetBestFitAction(*extension, ActionInfo::TYPE_BROWSER); |
| + ASSERT_TRUE(action.get()); |
| + |
| + // |action|'s title and default icon should match |extension|'s page action's. |
| + ASSERT_EQ(action->GetTitle(ExtensionAction::kDefaultTabId), "Action!"); |
| + ASSERT_EQ(action->default_icon()->Get(38, ExtensionIconSet::MATCH_EXACTLY), |
| + "action38.png"); |
|
not at google - send to devlin
2014/08/07 22:15:10
also assert that action is TYPE_BROWSER.
gpdavis
2014/08/07 23:48:35
Done.
|
| + |
| + // Create a new extension without page action defaults. |
| + extension_icons.reset(new DictionaryBuilder()); |
|
not at google - send to devlin
2014/08/07 22:15:09
ditto
gpdavis
2014/08/07 23:48:35
Done.
|
| + extension_icons->Set("48", "icon48.png"); |
| + extension = BuildExtension( |
| + extension_icons->Pass(), |
| + DictionaryBuilder().Pass(), |
| + kPageAction); |
| + ASSERT_TRUE(extension.get()); |
| + |
| + action = manager()->GetBestFitAction(*extension, ActionInfo::TYPE_BROWSER); |
| + |
| + // Now these values match because |extension| does not have page action |
| + // defaults. |
| + ASSERT_TRUE(TitlesMatch(*extension, *action)); |
| + ASSERT_TRUE(IconsMatch(*extension, 48, *action, 19)); |
| + ASSERT_TRUE(IconsMatch(*extension, 48, *action, 38)); |
| +} |
| + |
| +} // namespace |
| +} // namespace extensions |