Home | History | Annotate | Download | only in extensions
      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