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/command_line.h" 6#include "base/i18n/rtl.h" 7#include "base/path_service.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/common/chrome_paths.h" 10#include "chrome/common/extensions/manifest_tests/chrome_manifest_test.h" 11#include "components/crx_file/id_util.h" 12#include "extensions/common/extension.h" 13#include "extensions/common/manifest_constants.h" 14#include "extensions/common/manifest_handlers/options_page_info.h" 15#include "extensions/common/switches.h" 16#include "testing/gtest/include/gtest/gtest.h" 17#include "ui/base/l10n/l10n_util.h" 18 19namespace extensions { 20 21namespace { 22 23// The ID of test manifests requiring whitelisting. 24const char kWhitelistID[] = "lmadimbbgapmngbiclpjjngmdickadpl"; 25 26} // namespace 27 28namespace errors = manifest_errors; 29namespace keys = manifest_keys; 30 31class InitValueManifestTest : public ChromeManifestTest { 32}; 33 34TEST_F(InitValueManifestTest, InitFromValueInvalid) { 35 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 36 extensions::switches::kWhitelistedExtensionID, kWhitelistID); 37 Testcase testcases[] = { 38 Testcase("init_invalid_version_missing.json", errors::kInvalidVersion), 39 Testcase("init_invalid_version_invalid.json", errors::kInvalidVersion), 40 Testcase("init_invalid_name_missing.json", errors::kInvalidName), 41 Testcase("init_invalid_name_invalid.json", errors::kInvalidName), 42 Testcase("init_invalid_description_invalid.json", 43 errors::kInvalidDescription), 44 Testcase("init_invalid_icons_invalid.json", errors::kInvalidIcons), 45 Testcase("init_invalid_icons_path_invalid.json", errors::kInvalidIconPath), 46 Testcase("init_invalid_launcher_page_invalid.json", 47 errors::kInvalidLauncherPage), 48 Testcase("init_invalid_launcher_page_page_missing.json", 49 errors::kLauncherPagePageRequired), 50 Testcase("init_invalid_launcher_page_page_invalid.json", 51 errors::kInvalidLauncherPagePage), 52 Testcase("init_invalid_script_invalid.json", 53 errors::kInvalidContentScriptsList), 54 Testcase("init_invalid_script_item_invalid.json", 55 errors::kInvalidContentScript), 56 Testcase("init_invalid_script_matches_missing.json", 57 errors::kInvalidMatches), 58 Testcase("init_invalid_script_matches_invalid.json", 59 errors::kInvalidMatches), 60 Testcase("init_invalid_script_matches_empty.json", 61 errors::kInvalidMatchCount), 62 Testcase("init_invalid_script_match_item_invalid.json", 63 errors::kInvalidMatch), 64 Testcase("init_invalid_script_match_item_invalid_2.json", 65 errors::kInvalidMatch), 66 Testcase("init_invalid_script_files_missing.json", errors::kMissingFile), 67 Testcase("init_invalid_files_js_invalid.json", errors::kInvalidJsList), 68 Testcase("init_invalid_files_empty.json", errors::kMissingFile), 69 Testcase("init_invalid_files_js_empty_css_missing.json", 70 errors::kMissingFile), 71 Testcase("init_invalid_files_js_item_invalid.json", errors::kInvalidJs), 72 Testcase("init_invalid_files_css_invalid.json", errors::kInvalidCssList), 73 Testcase("init_invalid_files_css_item_invalid.json", errors::kInvalidCss), 74 Testcase("init_invalid_permissions_invalid.json", 75 errors::kInvalidPermissions), 76 Testcase("init_invalid_permissions_item_invalid.json", 77 errors::kInvalidPermission), 78 Testcase("init_invalid_page_actions_multi.json", 79 errors::kInvalidPageActionsListSize), 80 Testcase("init_invalid_options_url_invalid.json", 81 errors::kInvalidOptionsPage), 82 Testcase("init_invalid_locale_invalid.json", errors::kInvalidDefaultLocale), 83 Testcase("init_invalid_locale_empty.json", errors::kInvalidDefaultLocale), 84 Testcase("init_invalid_min_chrome_invalid.json", 85 errors::kInvalidMinimumChromeVersion), 86 Testcase("init_invalid_chrome_version_too_low.json", 87 errors::kChromeVersionTooLow), 88 Testcase("init_invalid_short_name_empty.json", 89 errors::kInvalidShortName), 90 Testcase("init_invalid_short_name_type.json", 91 errors::kInvalidShortName), 92 }; 93 94 RunTestcases(testcases, arraysize(testcases), 95 EXPECT_TYPE_ERROR); 96} 97 98TEST_F(InitValueManifestTest, InitFromValueValid) { 99 scoped_refptr<Extension> extension(LoadAndExpectSuccess( 100 "init_valid_minimal.json")); 101 102 base::FilePath path; 103 PathService::Get(chrome::DIR_TEST_DATA, &path); 104 path = path.AppendASCII("extensions"); 105 106 EXPECT_TRUE(crx_file::id_util::IdIsValid(extension->id())); 107 EXPECT_EQ("1.0.0.0", extension->VersionString()); 108 EXPECT_EQ("my extension", extension->name()); 109 EXPECT_EQ(extension->name(), extension->short_name()); 110 EXPECT_EQ(extension->id(), extension->url().host()); 111 EXPECT_EQ(extension->path(), path); 112 EXPECT_EQ(path, extension->path()); 113 114 // Test permissions scheme. 115 // We allow unknown API permissions, so this will be valid until we better 116 // distinguish between API and host permissions. 117 LoadAndExpectSuccess("init_valid_permissions.json"); 118 119 // Test with an options page. 120 extension = LoadAndExpectSuccess("init_valid_options.json"); 121 EXPECT_EQ("chrome-extension", 122 OptionsPageInfo::GetOptionsPage(extension.get()).scheme()); 123 EXPECT_EQ("/options.html", 124 OptionsPageInfo::GetOptionsPage(extension.get()).path()); 125 126 // Test optional short_name field. 127 extension = LoadAndExpectSuccess("init_valid_short_name.json"); 128 EXPECT_EQ("a very descriptive extension name", extension->name()); 129 EXPECT_EQ("concise name", extension->short_name()); 130 131 Testcase testcases[] = { 132 // Test that an empty list of page actions does not stop a browser action 133 // from being loaded. 134 Testcase("init_valid_empty_page_actions.json"), 135 136 // Test with a minimum_chrome_version. 137 Testcase("init_valid_minimum_chrome.json"), 138 139 // Test a hosted app with a minimum_chrome_version. 140 Testcase("init_valid_app_minimum_chrome.json"), 141 142 // Test a hosted app with a requirements section. 143 Testcase("init_valid_app_requirements.json"), 144 145 // Verify empty permission settings are considered valid. 146 Testcase("init_valid_permissions_empty.json"), 147 148 // We allow unknown API permissions, so this will be valid until we better 149 // distinguish between API and host permissions. 150 Testcase("init_valid_permissions_unknown.json") 151 }; 152 153 RunTestcases(testcases, arraysize(testcases), 154 EXPECT_TYPE_SUCCESS); 155} 156 157TEST_F(InitValueManifestTest, InitFromValueValidNameInRTL) { 158 std::string locale = l10n_util::GetApplicationLocale(""); 159 base::i18n::SetICUDefaultLocale("he"); 160 161 // No strong RTL characters in name. 162 scoped_refptr<Extension> extension(LoadAndExpectSuccess( 163 "init_valid_name_no_rtl.json")); 164 165 base::string16 localized_name(base::ASCIIToUTF16("Dictionary (by Google)")); 166 base::i18n::AdjustStringForLocaleDirection(&localized_name); 167 EXPECT_EQ(localized_name, base::UTF8ToUTF16(extension->name())); 168 169 // Strong RTL characters in name. 170 extension = LoadAndExpectSuccess("init_valid_name_strong_rtl.json"); 171 172 localized_name = base::WideToUTF16(L"Dictionary (\x05D1\x05D2" L" Google)"); 173 base::i18n::AdjustStringForLocaleDirection(&localized_name); 174 EXPECT_EQ(localized_name, base::UTF8ToUTF16(extension->name())); 175 176 // Reset locale. 177 base::i18n::SetICUDefaultLocale(locale); 178} 179 180} // namespace extensions 181