Home | History | Annotate | Download | only in glue
      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 "chrome/browser/sync/glue/extension_util.h"
      6 
      7 #include "base/file_path.h"
      8 #include "base/values.h"
      9 #include "chrome/browser/extensions/mock_extension_service.h"
     10 #include "chrome/browser/sync/protocol/extension_specifics.pb.h"
     11 #include "chrome/common/extensions/extension.h"
     12 #include "chrome/common/extensions/extension_constants.h"
     13 #include "testing/gmock/include/gmock/gmock.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 namespace browser_sync {
     17 
     18 namespace {
     19 
     20 using ::testing::_;
     21 using ::testing::Return;
     22 using ::testing::StrictMock;
     23 
     24 #if defined(OS_WIN)
     25 const FilePath::CharType kExtensionFilePath[] = FILE_PATH_LITERAL("c:\\foo");
     26 #elif defined(OS_POSIX)
     27 const FilePath::CharType kExtensionFilePath[] = FILE_PATH_LITERAL("/foo");
     28 #endif
     29 
     30 const char kValidId[] = "abcdefghijklmnopabcdefghijklmnop";
     31 const char kValidVersion[] = "0.0.0.0";
     32 const char kVersion1[] = "1.0.0.1";
     33 const char kVersion2[] = "1.0.1.0";
     34 const char kVersion3[] = "1.1.0.0";
     35 const char kValidUpdateUrl1[] =
     36     "http://clients2.google.com/service/update2/crx";
     37 const char kValidUpdateUrl2[] =
     38     "https://clients2.google.com/service/update2/crx";
     39 const char kName[] = "MyExtension";
     40 const char kName2[] = "MyExtension2";
     41 
     42 class ExtensionUtilTest : public testing::Test {
     43 };
     44 
     45 scoped_refptr<Extension> MakeExtension(
     46     bool is_theme, const GURL& update_url,
     47     const GURL& launch_url,
     48     bool converted_from_user_script,
     49     Extension::Location location, int num_plugins,
     50     const FilePath& extension_path) {
     51   DictionaryValue source;
     52   source.SetString(extension_manifest_keys::kName,
     53                    "PossiblySyncableExtension");
     54   source.SetString(extension_manifest_keys::kVersion, "0.0.0.0");
     55   if (is_theme) {
     56     source.Set(extension_manifest_keys::kTheme, new DictionaryValue());
     57   }
     58   if (!update_url.is_empty()) {
     59     source.SetString(extension_manifest_keys::kUpdateURL,
     60                      update_url.spec());
     61   }
     62   if (!launch_url.is_empty()) {
     63     source.SetString(extension_manifest_keys::kLaunchWebURL,
     64                      launch_url.spec());
     65   }
     66   if (!is_theme) {
     67     source.SetBoolean(extension_manifest_keys::kConvertedFromUserScript,
     68                       converted_from_user_script);
     69     ListValue* plugins = new ListValue();
     70     for (int i = 0; i < num_plugins; ++i) {
     71       DictionaryValue* plugin = new DictionaryValue();
     72       plugin->SetString(extension_manifest_keys::kPluginsPath, "");
     73       plugins->Set(i, plugin);
     74     }
     75     source.Set(extension_manifest_keys::kPlugins, plugins);
     76   }
     77 
     78   std::string error;
     79   scoped_refptr<Extension> extension = Extension::Create(
     80       extension_path, location, source, Extension::STRICT_ERROR_CHECKS, &error);
     81   EXPECT_TRUE(extension);
     82   EXPECT_EQ("", error);
     83   return extension;
     84 }
     85 
     86 TEST_F(ExtensionUtilTest, IsExtensionValid) {
     87   {
     88     FilePath file_path(kExtensionFilePath);
     89     scoped_refptr<Extension> extension(
     90         MakeExtension(false, GURL(), GURL(), false,
     91                       Extension::INTERNAL, 0, file_path));
     92     EXPECT_TRUE(IsExtensionValid(*extension));
     93   }
     94   {
     95     FilePath file_path(kExtensionFilePath);
     96     scoped_refptr<Extension> extension(
     97         MakeExtension(false, GURL(kValidUpdateUrl1), GURL(),
     98                       true, Extension::INTERNAL, 0, file_path));
     99     EXPECT_TRUE(IsExtensionValid(*extension));
    100   }
    101   {
    102     FilePath file_path(kExtensionFilePath);
    103     scoped_refptr<Extension> extension(
    104         MakeExtension(false, GURL(), GURL(), true,
    105                       Extension::INTERNAL, 0, file_path));
    106     EXPECT_TRUE(IsExtensionValid(*extension));
    107   }
    108   {
    109     FilePath file_path(kExtensionFilePath);
    110     scoped_refptr<Extension> extension(
    111         MakeExtension(true, GURL(), GURL(), false,
    112                       Extension::INTERNAL, 0, file_path));
    113     EXPECT_TRUE(IsExtensionValid(*extension));
    114   }
    115   {
    116     FilePath file_path(kExtensionFilePath);
    117     scoped_refptr<Extension> extension(
    118         MakeExtension(false, GURL(),
    119                       GURL("http://www.google.com"), false,
    120                       Extension::INTERNAL, 0, file_path));
    121     EXPECT_TRUE(IsExtensionValid(*extension));
    122   }
    123   {
    124     FilePath file_path(kExtensionFilePath);
    125     scoped_refptr<Extension> extension(
    126         MakeExtension(false, GURL(), GURL(), false,
    127                       Extension::EXTERNAL_PREF, 0, file_path));
    128     EXPECT_FALSE(IsExtensionValid(*extension));
    129   }
    130   {
    131     FilePath file_path(kExtensionFilePath);
    132     scoped_refptr<Extension> extension(
    133         MakeExtension(
    134             false, GURL("http://third-party.update_url.com"), GURL(), true,
    135             Extension::INTERNAL, 0, file_path));
    136     EXPECT_FALSE(IsExtensionValid(*extension));
    137   }
    138   // These last 2 tests don't make sense on Chrome OS, where extension plugins
    139   // are not allowed.
    140 #if !defined(OS_CHROMEOS)
    141   {
    142     FilePath file_path(kExtensionFilePath);
    143     scoped_refptr<Extension> extension(
    144         MakeExtension(false, GURL(), GURL(), true,
    145                       Extension::INTERNAL, 1, file_path));
    146     EXPECT_FALSE(extension && IsExtensionValid(*extension));
    147   }
    148   {
    149     FilePath file_path(kExtensionFilePath);
    150     scoped_refptr<Extension> extension(
    151         MakeExtension(false, GURL(), GURL(), true,
    152                       Extension::INTERNAL, 2, file_path));
    153     EXPECT_FALSE(extension && IsExtensionValid(*extension));
    154   }
    155 #endif
    156 }
    157 
    158 TEST_F(ExtensionUtilTest, IsExtensionSpecificsUnset) {
    159   {
    160     sync_pb::ExtensionSpecifics specifics;
    161     EXPECT_TRUE(IsExtensionSpecificsUnset(specifics));
    162   }
    163 
    164   {
    165     sync_pb::ExtensionSpecifics specifics;
    166     specifics.set_id("a");
    167     EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
    168   }
    169 
    170   {
    171     sync_pb::ExtensionSpecifics specifics;
    172     specifics.set_version("a");
    173     EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
    174   }
    175 
    176   {
    177     sync_pb::ExtensionSpecifics specifics;
    178     specifics.set_update_url("a");
    179     EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
    180   }
    181 
    182   {
    183     sync_pb::ExtensionSpecifics specifics;
    184     specifics.set_enabled(true);
    185     EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
    186   }
    187 
    188   {
    189     sync_pb::ExtensionSpecifics specifics;
    190     specifics.set_incognito_enabled(true);
    191     EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
    192   }
    193 
    194   {
    195     sync_pb::ExtensionSpecifics specifics;
    196     specifics.set_name("a");
    197     EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
    198   }
    199 }
    200 
    201 TEST_F(ExtensionUtilTest, IsExtensionSpecificsValid) {
    202   sync_pb::ExtensionSpecifics specifics;
    203   EXPECT_FALSE(IsExtensionSpecificsValid(specifics));
    204   specifics.set_id(kValidId);
    205   EXPECT_FALSE(IsExtensionSpecificsValid(specifics));
    206   specifics.set_version(kValidVersion);
    207   EXPECT_TRUE(IsExtensionSpecificsValid(specifics));
    208   EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
    209   specifics.set_update_url(kValidUpdateUrl1);
    210   EXPECT_TRUE(IsExtensionSpecificsValid(specifics));
    211   EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
    212 
    213   {
    214     sync_pb::ExtensionSpecifics specifics_copy(specifics);
    215     specifics_copy.set_id("invalid");
    216     EXPECT_FALSE(IsExtensionSpecificsValid(specifics_copy));
    217   }
    218 
    219   {
    220     sync_pb::ExtensionSpecifics specifics_copy(specifics);
    221     specifics_copy.set_version("invalid");
    222     EXPECT_FALSE(IsExtensionSpecificsValid(specifics_copy));
    223   }
    224 
    225   {
    226     sync_pb::ExtensionSpecifics specifics_copy(specifics);
    227     specifics_copy.set_update_url("http:invalid.com:invalid");
    228     EXPECT_FALSE(IsExtensionSpecificsValid(specifics_copy));
    229   }
    230 }
    231 
    232 TEST_F(ExtensionUtilTest, AreExtensionSpecificsEqual) {
    233   sync_pb::ExtensionSpecifics a, b;
    234   EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
    235 
    236   a.set_id("a");
    237   EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
    238   b.set_id("a");
    239   EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
    240 
    241   a.set_version("1.5");
    242   EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
    243   b.set_version("1.5");
    244   EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
    245 
    246   a.set_update_url("http://www.foo.com");
    247   EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
    248   b.set_update_url("http://www.foo.com");
    249   EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
    250 
    251   a.set_enabled(true);
    252   EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
    253   b.set_enabled(true);
    254   EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
    255 
    256   a.set_incognito_enabled(true);
    257   EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
    258   b.set_incognito_enabled(true);
    259   EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
    260 
    261   a.set_name("name");
    262   EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
    263   b.set_name("name");
    264   EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
    265 }
    266 
    267 TEST_F(ExtensionUtilTest, CopyUserProperties) {
    268   sync_pb::ExtensionSpecifics dest_specifics;
    269   dest_specifics.set_version(kVersion2);
    270   dest_specifics.set_update_url(kValidUpdateUrl1);
    271   dest_specifics.set_enabled(true);
    272   dest_specifics.set_incognito_enabled(false);
    273   dest_specifics.set_name(kName);
    274 
    275   sync_pb::ExtensionSpecifics specifics;
    276   specifics.set_id(kValidId);
    277   specifics.set_version(kVersion3);
    278   specifics.set_update_url(kValidUpdateUrl2);
    279   specifics.set_enabled(false);
    280   specifics.set_incognito_enabled(true);
    281   specifics.set_name(kName2);
    282 
    283   CopyUserProperties(specifics, &dest_specifics);
    284   EXPECT_EQ("", dest_specifics.id());
    285   EXPECT_EQ(kVersion2, dest_specifics.version());
    286   EXPECT_EQ(kValidUpdateUrl1, dest_specifics.update_url());
    287   EXPECT_FALSE(dest_specifics.enabled());
    288   EXPECT_TRUE(dest_specifics.incognito_enabled());
    289   EXPECT_EQ(kName, dest_specifics.name());
    290 }
    291 
    292 TEST_F(ExtensionUtilTest, CopyNonUserProperties) {
    293   sync_pb::ExtensionSpecifics dest_specifics;
    294   dest_specifics.set_id(kValidId);
    295   dest_specifics.set_version(kVersion2);
    296   dest_specifics.set_update_url(kValidUpdateUrl1);
    297   dest_specifics.set_enabled(true);
    298   dest_specifics.set_incognito_enabled(false);
    299   dest_specifics.set_name(kName);
    300 
    301   sync_pb::ExtensionSpecifics specifics;
    302   specifics.set_id("");
    303   specifics.set_version(kVersion3);
    304   specifics.set_update_url(kValidUpdateUrl2);
    305   specifics.set_enabled(false);
    306   specifics.set_incognito_enabled(true);
    307   specifics.set_name(kName2);
    308 
    309   CopyNonUserProperties(specifics, &dest_specifics);
    310   EXPECT_EQ("", dest_specifics.id());
    311   EXPECT_EQ(kVersion3, dest_specifics.version());
    312   EXPECT_EQ(kValidUpdateUrl2, dest_specifics.update_url());
    313   EXPECT_TRUE(dest_specifics.enabled());
    314   EXPECT_FALSE(dest_specifics.incognito_enabled());
    315   EXPECT_EQ(kName2, dest_specifics.name());
    316 }
    317 
    318 TEST_F(ExtensionUtilTest, AreExtensionSpecificsUserPropertiesEqual) {
    319   sync_pb::ExtensionSpecifics a, b;
    320   EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
    321 
    322   a.set_id("a");
    323   b.set_id("b");
    324   EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
    325 
    326   a.set_version("1.5");
    327   b.set_version("1.6");
    328   EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
    329 
    330   a.set_name("name");
    331   b.set_name("name2");
    332   EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
    333 
    334   a.set_update_url("http://www.foo.com");
    335   b.set_update_url("http://www.foo2.com");
    336   EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
    337 
    338   a.set_enabled(true);
    339   EXPECT_FALSE(AreExtensionSpecificsUserPropertiesEqual(a, b));
    340   b.set_enabled(true);
    341   EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
    342 
    343   a.set_incognito_enabled(true);
    344   EXPECT_FALSE(AreExtensionSpecificsUserPropertiesEqual(a, b));
    345   b.set_incognito_enabled(true);
    346   EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
    347 }
    348 
    349 TEST_F(ExtensionUtilTest, AreExtensionSpecificsNonUserPropertiesEqual) {
    350   sync_pb::ExtensionSpecifics a, b;
    351   EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    352 
    353   a.set_enabled(true);
    354   b.set_enabled(false);
    355   EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    356 
    357   a.set_incognito_enabled(true);
    358   b.set_incognito_enabled(false);
    359   EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    360 
    361   a.set_id("a");
    362   EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    363   b.set_id("a");
    364   EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    365 
    366   a.set_version("1.5");
    367   EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    368   b.set_version("1.5");
    369   EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    370 
    371   a.set_update_url("http://www.foo.com");
    372   EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    373   b.set_update_url("http://www.foo.com");
    374   EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    375 
    376   a.set_name("name");
    377   EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    378   b.set_name("name");
    379   EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
    380 }
    381 
    382 scoped_refptr<Extension> MakeSyncableExtension(
    383     const std::string& version_string,
    384     const std::string& update_url_spec,
    385     const std::string& name,
    386     const FilePath& extension_path) {
    387   DictionaryValue source;
    388   source.SetString(extension_manifest_keys::kVersion, version_string);
    389   source.SetString(extension_manifest_keys::kUpdateURL, update_url_spec);
    390   source.SetString(extension_manifest_keys::kName, name);
    391   std::string error;
    392   scoped_refptr<Extension> extension = Extension::Create(
    393       extension_path, Extension::INTERNAL, source,
    394       Extension::STRICT_ERROR_CHECKS, &error);
    395   EXPECT_TRUE(extension);
    396   EXPECT_EQ("", error);
    397   return extension;
    398 }
    399 
    400 TEST_F(ExtensionUtilTest, GetExtensionSpecifics) {
    401   FilePath file_path(kExtensionFilePath);
    402   StrictMock<MockExtensionService> mock_extension_service;
    403   EXPECT_CALL(mock_extension_service, IsExtensionEnabled(_))
    404       .WillOnce(Return(true));
    405   EXPECT_CALL(mock_extension_service, IsIncognitoEnabled(_))
    406       .WillOnce(Return(false));
    407 
    408   scoped_refptr<Extension> extension(
    409       MakeSyncableExtension(
    410           kValidVersion, kValidUpdateUrl1, kName, file_path));
    411   sync_pb::ExtensionSpecifics specifics;
    412   GetExtensionSpecifics(*extension, mock_extension_service, &specifics);
    413   EXPECT_EQ(extension->id(), specifics.id());
    414   EXPECT_EQ(extension->VersionString(), kValidVersion);
    415   EXPECT_EQ(extension->update_url().spec(), kValidUpdateUrl1);
    416   EXPECT_TRUE(specifics.enabled());
    417   EXPECT_FALSE(specifics.incognito_enabled());
    418   EXPECT_EQ(kName, specifics.name());
    419 }
    420 
    421 // TODO(akalin): Make ExtensionService/ExtensionUpdater testable
    422 // enough to be able to write a unittest for SetExtensionProperties().
    423 
    424 TEST_F(ExtensionUtilTest, MergeExtensionSpecificsWithUserProperties) {
    425   sync_pb::ExtensionSpecifics merged_specifics;
    426   merged_specifics.set_id(kValidId);
    427   merged_specifics.set_update_url(kValidUpdateUrl1);
    428   merged_specifics.set_enabled(true);
    429   merged_specifics.set_incognito_enabled(false);
    430   merged_specifics.set_version(kVersion2);
    431 
    432   sync_pb::ExtensionSpecifics specifics;
    433   specifics.set_id(kValidId);
    434   specifics.set_update_url(kValidUpdateUrl2);
    435   merged_specifics.set_enabled(false);
    436   merged_specifics.set_incognito_enabled(true);
    437 
    438   specifics.set_version(kVersion1);
    439   {
    440     sync_pb::ExtensionSpecifics result = merged_specifics;
    441     MergeExtensionSpecifics(specifics, false, &result);
    442     EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(
    443         result, merged_specifics));
    444     EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(
    445         result, merged_specifics));
    446   }
    447   {
    448     sync_pb::ExtensionSpecifics result = merged_specifics;
    449     MergeExtensionSpecifics(specifics, true, &result);
    450     EXPECT_TRUE(AreExtensionSpecificsEqual(result, merged_specifics));
    451   }
    452 
    453   specifics.set_version(kVersion2);
    454   {
    455     sync_pb::ExtensionSpecifics result = merged_specifics;
    456     MergeExtensionSpecifics(specifics, false, &result);
    457     EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(
    458         result, merged_specifics));
    459     EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(
    460         result, specifics));
    461   }
    462   {
    463     sync_pb::ExtensionSpecifics result = merged_specifics;
    464     MergeExtensionSpecifics(specifics, true, &result);
    465     EXPECT_TRUE(AreExtensionSpecificsEqual(result, specifics));
    466   }
    467 
    468   specifics.set_version(kVersion3);
    469   {
    470     sync_pb::ExtensionSpecifics result = merged_specifics;
    471     MergeExtensionSpecifics(specifics, false, &result);
    472     EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(
    473         result, merged_specifics));
    474     EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(
    475         result, specifics));
    476   }
    477   {
    478     sync_pb::ExtensionSpecifics result = merged_specifics;
    479     MergeExtensionSpecifics(specifics, true, &result);
    480     EXPECT_TRUE(AreExtensionSpecificsEqual(result, specifics));
    481   }
    482 }
    483 
    484 }  // namespace
    485 
    486 }  // namespace browser_sync
    487