1 // Copyright (c) 2011 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/path_service.h" 6 #include "base/string_util.h" 7 #include "chrome/browser/extensions/extensions_ui.h" 8 #include "chrome/common/chrome_paths.h" 9 #include "chrome/common/extensions/extension.h" 10 #include "content/common/json_value_serializer.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 namespace { 14 static DictionaryValue* DeserializeJSONTestData(const FilePath& path, 15 std::string *error) { 16 Value* value; 17 18 JSONFileValueSerializer serializer(path); 19 value = serializer.Deserialize(NULL, error); 20 21 return static_cast<DictionaryValue*>(value); 22 } 23 24 static DictionaryValue* CreateExtensionDetailViewFromPath( 25 const FilePath& extension_path, 26 const std::vector<ExtensionPage>& pages, 27 Extension::Location location) { 28 std::string error; 29 30 FilePath manifest_path = extension_path.Append( 31 Extension::kManifestFilename); 32 scoped_ptr<DictionaryValue> extension_data(DeserializeJSONTestData( 33 manifest_path, &error)); 34 EXPECT_EQ("", error); 35 36 scoped_refptr<Extension> extension(Extension::Create( 37 extension_path, location, *extension_data, 38 Extension::REQUIRE_KEY | Extension::STRICT_ERROR_CHECKS, &error)); 39 EXPECT_TRUE(extension.get()); 40 EXPECT_EQ("", error); 41 42 return ExtensionsDOMHandler::CreateExtensionDetailValue( 43 NULL, extension.get(), pages, true, false); 44 } 45 46 47 static void CompareExpectedAndActualOutput( 48 const FilePath& extension_path, 49 const std::vector<ExtensionPage>& pages, 50 const FilePath& expected_output_path) { 51 std::string error; 52 53 scoped_ptr<DictionaryValue> expected_output_data(DeserializeJSONTestData( 54 expected_output_path, &error)); 55 EXPECT_EQ("", error); 56 57 // Produce test output. 58 scoped_ptr<DictionaryValue> actual_output_data( 59 CreateExtensionDetailViewFromPath( 60 extension_path, pages, Extension::INVALID)); 61 62 // Compare the outputs. 63 // Ignore unknown fields in the actual output data. 64 std::string paths_details = " - expected (" + 65 expected_output_path.MaybeAsASCII() + ") vs. actual (" + 66 extension_path.MaybeAsASCII() + ")"; 67 for (DictionaryValue::key_iterator key = expected_output_data->begin_keys(); 68 key != expected_output_data->end_keys(); 69 ++key) { 70 Value* expected_value = NULL; 71 Value* actual_value = NULL; 72 EXPECT_TRUE(expected_output_data->Get(*key, &expected_value)) << 73 *key + " is missing" + paths_details; 74 EXPECT_TRUE(actual_output_data->Get(*key, &actual_value)) << 75 *key + " is missing" + paths_details; 76 if (expected_value == NULL) { 77 EXPECT_EQ(NULL, actual_value) << *key + paths_details; 78 } else { 79 EXPECT_TRUE(expected_value->Equals(actual_value)) << *key + 80 paths_details; 81 } 82 } 83 } 84 } // namespace 85 86 TEST(ExtensionUITest, GenerateExtensionsJSONData) { 87 FilePath data_test_dir_path, extension_path, expected_output_path; 88 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_test_dir_path)); 89 90 // Test Extension1 91 extension_path = data_test_dir_path.AppendASCII("extensions") 92 .AppendASCII("good") 93 .AppendASCII("Extensions") 94 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 95 .AppendASCII("1.0.0.0"); 96 97 std::vector<ExtensionPage> pages; 98 pages.push_back(ExtensionPage( 99 GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/bar.html"), 100 42, 88, false)); 101 pages.push_back(ExtensionPage( 102 GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/dog.html"), 103 0, 0, false)); 104 105 expected_output_path = data_test_dir_path.AppendASCII("extensions") 106 .AppendASCII("ui") 107 .AppendASCII("create_extension_detail_value_expected_output") 108 .AppendASCII("good-extension1.json"); 109 110 CompareExpectedAndActualOutput(extension_path, pages, expected_output_path); 111 112 #if !defined(OS_CHROMEOS) 113 // Test Extension2 114 extension_path = data_test_dir_path.AppendASCII("extensions") 115 .AppendASCII("good") 116 .AppendASCII("Extensions") 117 .AppendASCII("hpiknbiabeeppbpihjehijgoemciehgk") 118 .AppendASCII("2"); 119 120 expected_output_path = data_test_dir_path.AppendASCII("extensions") 121 .AppendASCII("ui") 122 .AppendASCII("create_extension_detail_value_expected_output") 123 .AppendASCII("good-extension2.json"); 124 125 // It's OK to have duplicate URLs, so long as the IDs are different. 126 pages[1].url = pages[0].url; 127 128 CompareExpectedAndActualOutput(extension_path, pages, expected_output_path); 129 #endif 130 131 // Test Extension3 132 extension_path = data_test_dir_path.AppendASCII("extensions") 133 .AppendASCII("good") 134 .AppendASCII("Extensions") 135 .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa") 136 .AppendASCII("1.0"); 137 138 expected_output_path = data_test_dir_path.AppendASCII("extensions") 139 .AppendASCII("ui") 140 .AppendASCII("create_extension_detail_value_expected_output") 141 .AppendASCII("good-extension3.json"); 142 143 pages.clear(); 144 145 CompareExpectedAndActualOutput(extension_path, pages, expected_output_path); 146 } 147 148 // Test that using Extension::LOAD for the extension location triggers the 149 // correct values in the details, including location, order, and allow_reload. 150 TEST(ExtensionUITest, LocationLoadPropagation) { 151 FilePath data_test_dir_path, extension_path; 152 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_test_dir_path)); 153 154 extension_path = data_test_dir_path.AppendASCII("extensions") 155 .AppendASCII("good") 156 .AppendASCII("Extensions") 157 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 158 .AppendASCII("1.0.0.0"); 159 160 std::vector<ExtensionPage> pages; 161 162 scoped_ptr<DictionaryValue> extension_details( 163 CreateExtensionDetailViewFromPath( 164 extension_path, pages, Extension::LOAD)); 165 166 bool ui_allow_reload = false; 167 bool ui_is_unpacked = false; 168 FilePath::StringType ui_path; 169 170 EXPECT_TRUE(extension_details->GetBoolean("allow_reload", &ui_allow_reload)); 171 EXPECT_TRUE(extension_details->GetBoolean("isUnpacked", &ui_is_unpacked)); 172 EXPECT_TRUE(extension_details->GetString("path", &ui_path)); 173 EXPECT_EQ(true, ui_allow_reload); 174 EXPECT_EQ(true, ui_is_unpacked); 175 EXPECT_EQ(extension_path, FilePath(ui_path)); 176 } 177 178 // Test that using Extension::EXTERNAL_PREF for the extension location triggers 179 // the correct values in the details, including location, order, and 180 // allow_reload. Contrast to Extension::LOAD, which has somewhat different 181 // values. 182 TEST(ExtensionUITest, LocationExternalPrefPropagation) { 183 FilePath data_test_dir_path, extension_path; 184 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_test_dir_path)); 185 186 extension_path = data_test_dir_path.AppendASCII("extensions") 187 .AppendASCII("good") 188 .AppendASCII("Extensions") 189 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 190 .AppendASCII("1.0.0.0"); 191 192 std::vector<ExtensionPage> pages; 193 194 scoped_ptr<DictionaryValue> extension_details( 195 CreateExtensionDetailViewFromPath( 196 extension_path, pages, Extension::EXTERNAL_PREF)); 197 198 bool ui_allow_reload = true; 199 bool ui_is_unpacked = true; 200 FilePath::StringType ui_path; 201 202 EXPECT_TRUE(extension_details->GetBoolean("allow_reload", &ui_allow_reload)); 203 EXPECT_TRUE(extension_details->GetBoolean("isUnpacked", &ui_is_unpacked)); 204 EXPECT_FALSE(extension_details->GetString("path", &ui_path)); 205 EXPECT_FALSE(ui_allow_reload); 206 EXPECT_FALSE(ui_is_unpacked); 207 } 208 209 // Test that the extension path is correctly propagated into the extension 210 // details. 211 TEST(ExtensionUITest, PathPropagation) { 212 FilePath data_test_dir_path, extension_path; 213 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &data_test_dir_path)); 214 215 extension_path = data_test_dir_path.AppendASCII("extensions") 216 .AppendASCII("good") 217 .AppendASCII("Extensions") 218 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 219 .AppendASCII("1.0.0.0"); 220 221 std::vector<ExtensionPage> pages; 222 223 scoped_ptr<DictionaryValue> extension_details( 224 CreateExtensionDetailViewFromPath( 225 extension_path, pages, Extension::LOAD)); 226 227 FilePath::StringType ui_path; 228 229 EXPECT_TRUE(extension_details->GetString("path", &ui_path)); 230 EXPECT_EQ(extension_path, FilePath(ui_path)); 231 } 232 233