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 "chrome/common/extensions/api/extension_action/action_info.h" 6 #include "chrome/common/extensions/extension.h" 7 #include "chrome/common/extensions/extension_manifest_constants.h" 8 #include "chrome/common/extensions/manifest_tests/extension_manifest_test.h" 9 #include "extensions/common/error_utils.h" 10 #include "testing/gtest/include/gtest/gtest.h" 11 12 namespace errors = extension_manifest_errors; 13 namespace keys = extension_manifest_keys; 14 15 namespace extensions { 16 17 class PageActionManifestTest : public ExtensionManifestTest { 18 protected: 19 virtual const char* test_data_dir() OVERRIDE { 20 return "page_action"; 21 } 22 23 scoped_ptr<ActionInfo> LoadAction(const std::string& manifest_filename); 24 }; 25 26 scoped_ptr<ActionInfo> PageActionManifestTest::LoadAction( 27 const std::string& manifest_filename) { 28 scoped_refptr<Extension> extension = LoadAndExpectSuccess( 29 manifest_filename.c_str()); 30 const ActionInfo* page_action_info = 31 ActionInfo::GetPageActionInfo(extension.get()); 32 EXPECT_TRUE(page_action_info); 33 if (page_action_info) { 34 return make_scoped_ptr(new ActionInfo(*page_action_info)); 35 } 36 ADD_FAILURE() << "Expected manifest in " << manifest_filename 37 << " to include a page_action section."; 38 return scoped_ptr<ActionInfo>(); 39 } 40 41 TEST_F(PageActionManifestTest, ManifestVersion2) { 42 scoped_refptr<Extension> extension( 43 LoadAndExpectSuccess("page_action_manifest_version_2.json")); 44 ASSERT_TRUE(extension.get()); 45 const ActionInfo* page_action_info = 46 ActionInfo::GetPageActionInfo(extension.get()); 47 ASSERT_TRUE(page_action_info); 48 49 EXPECT_EQ("", page_action_info->id); 50 EXPECT_TRUE(page_action_info->default_icon.empty()); 51 EXPECT_EQ("", page_action_info->default_title); 52 EXPECT_TRUE(page_action_info->default_popup_url.is_empty()); 53 54 LoadAndExpectError("page_action_manifest_version_2b.json", 55 errors::kInvalidPageActionPopup); 56 } 57 58 TEST_F(PageActionManifestTest, LoadPageActionHelper) { 59 scoped_ptr<ActionInfo> action; 60 61 // First try with an empty dictionary. 62 action = LoadAction("page_action_empty.json"); 63 ASSERT_TRUE(action); 64 65 // Now setup some values to use in the action. 66 const std::string id("MyExtensionActionId"); 67 const std::string name("MyExtensionActionName"); 68 std::string img1("image1.png"); 69 70 action = LoadAction("page_action.json"); 71 ASSERT_TRUE(action); 72 ASSERT_EQ(id, action->id); 73 74 // No title, so fall back to name. 75 ASSERT_EQ(name, action->default_title); 76 ASSERT_EQ(img1, 77 action->default_icon.Get(extension_misc::EXTENSION_ICON_ACTION, 78 ExtensionIconSet::MATCH_EXACTLY)); 79 80 // Same test with explicitly set type. 81 action = LoadAction("page_action_type.json"); 82 ASSERT_TRUE(action); 83 84 // Try an action without id key. 85 action = LoadAction("page_action_no_id.json"); 86 ASSERT_TRUE(action); 87 88 // Then try without the name key. It's optional, so no error. 89 action = LoadAction("page_action_no_name.json"); 90 ASSERT_TRUE(action); 91 ASSERT_TRUE(action->default_title.empty()); 92 93 // Then try without the icon paths key. 94 action = LoadAction("page_action_no_icon.json"); 95 ASSERT_TRUE(action); 96 97 // Now test that we can parse the new format for page actions. 98 const std::string kTitle("MyExtensionActionTitle"); 99 const std::string kIcon("image1.png"); 100 const std::string kPopupHtmlFile("a_popup.html"); 101 102 action = LoadAction("page_action_new_format.json"); 103 ASSERT_TRUE(action); 104 ASSERT_EQ(kTitle, action->default_title); 105 ASSERT_FALSE(action->default_icon.empty()); 106 107 // Invalid title should give an error even with a valid name. 108 LoadAndExpectError("page_action_invalid_title.json", 109 errors::kInvalidPageActionDefaultTitle); 110 111 // Invalid name should give an error only with no title. 112 action = LoadAction("page_action_invalid_name.json"); 113 ASSERT_TRUE(action); 114 ASSERT_EQ(kTitle, action->default_title); 115 116 LoadAndExpectError("page_action_invalid_name_no_title.json", 117 errors::kInvalidPageActionName); 118 119 // Test that keys "popup" and "default_popup" both work, but can not 120 // be used at the same time. 121 // These tests require an extension_url, so we also load the manifest. 122 123 // Only use "popup", expect success. 124 scoped_refptr<Extension> extension = 125 LoadAndExpectSuccess("page_action_popup.json"); 126 const ActionInfo* extension_action = 127 ActionInfo::GetPageActionInfo(extension.get()); 128 ASSERT_TRUE(extension_action); 129 ASSERT_STREQ( 130 extension->url().Resolve(kPopupHtmlFile).spec().c_str(), 131 extension_action->default_popup_url.spec().c_str()); 132 133 // Use both "popup" and "default_popup", expect failure. 134 LoadAndExpectError("page_action_popup_and_default_popup.json", 135 ErrorUtils::FormatErrorMessage( 136 errors::kInvalidPageActionOldAndNewKeys, 137 keys::kPageActionDefaultPopup, 138 keys::kPageActionPopup)); 139 140 // Use only "default_popup", expect success. 141 extension = LoadAndExpectSuccess("page_action_popup.json"); 142 extension_action = ActionInfo::GetPageActionInfo(extension.get()); 143 ASSERT_TRUE(extension_action); 144 ASSERT_STREQ( 145 extension->url().Resolve(kPopupHtmlFile).spec().c_str(), 146 extension_action->default_popup_url.spec().c_str()); 147 148 // Setting default_popup to "" is the same as having no popup. 149 action = LoadAction("page_action_empty_default_popup.json"); 150 ASSERT_TRUE(action); 151 EXPECT_TRUE(action->default_popup_url.is_empty()); 152 ASSERT_STREQ( 153 "", 154 action->default_popup_url.spec().c_str()); 155 156 // Setting popup to "" is the same as having no popup. 157 action = LoadAction("page_action_empty_popup.json"); 158 159 ASSERT_TRUE(action); 160 EXPECT_TRUE(action->default_popup_url.is_empty()); 161 ASSERT_STREQ( 162 "", 163 action->default_popup_url.spec().c_str()); 164 } 165 166 } // namespace extensions 167