| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/sync/glue/extension_util.h" |
| |
| #include "base/file_path.h" |
| #include "base/values.h" |
| #include "chrome/browser/extensions/mock_extension_service.h" |
| #include "chrome/browser/sync/protocol/extension_specifics.pb.h" |
| #include "chrome/common/extensions/extension.h" |
| #include "chrome/common/extensions/extension_constants.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace browser_sync { |
| |
| namespace { |
| |
| using ::testing::_; |
| using ::testing::Return; |
| using ::testing::StrictMock; |
| |
| #if defined(OS_WIN) |
| const FilePath::CharType kExtensionFilePath[] = FILE_PATH_LITERAL("c:\\foo"); |
| #elif defined(OS_POSIX) |
| const FilePath::CharType kExtensionFilePath[] = FILE_PATH_LITERAL("/foo"); |
| #endif |
| |
| const char kValidId[] = "abcdefghijklmnopabcdefghijklmnop"; |
| const char kValidVersion[] = "0.0.0.0"; |
| const char kVersion1[] = "1.0.0.1"; |
| const char kVersion2[] = "1.0.1.0"; |
| const char kVersion3[] = "1.1.0.0"; |
| const char kValidUpdateUrl1[] = |
| "http://clients2.google.com/service/update2/crx"; |
| const char kValidUpdateUrl2[] = |
| "https://clients2.google.com/service/update2/crx"; |
| const char kName[] = "MyExtension"; |
| const char kName2[] = "MyExtension2"; |
| |
| class ExtensionUtilTest : public testing::Test { |
| }; |
| |
| scoped_refptr<Extension> MakeExtension( |
| bool is_theme, const GURL& update_url, |
| const GURL& launch_url, |
| bool converted_from_user_script, |
| Extension::Location location, int num_plugins, |
| const FilePath& extension_path) { |
| DictionaryValue source; |
| source.SetString(extension_manifest_keys::kName, |
| "PossiblySyncableExtension"); |
| source.SetString(extension_manifest_keys::kVersion, "0.0.0.0"); |
| if (is_theme) { |
| source.Set(extension_manifest_keys::kTheme, new DictionaryValue()); |
| } |
| if (!update_url.is_empty()) { |
| source.SetString(extension_manifest_keys::kUpdateURL, |
| update_url.spec()); |
| } |
| if (!launch_url.is_empty()) { |
| source.SetString(extension_manifest_keys::kLaunchWebURL, |
| launch_url.spec()); |
| } |
| if (!is_theme) { |
| source.SetBoolean(extension_manifest_keys::kConvertedFromUserScript, |
| converted_from_user_script); |
| ListValue* plugins = new ListValue(); |
| for (int i = 0; i < num_plugins; ++i) { |
| DictionaryValue* plugin = new DictionaryValue(); |
| plugin->SetString(extension_manifest_keys::kPluginsPath, ""); |
| plugins->Set(i, plugin); |
| } |
| source.Set(extension_manifest_keys::kPlugins, plugins); |
| } |
| |
| std::string error; |
| scoped_refptr<Extension> extension = Extension::Create( |
| extension_path, location, source, Extension::STRICT_ERROR_CHECKS, &error); |
| EXPECT_TRUE(extension); |
| EXPECT_EQ("", error); |
| return extension; |
| } |
| |
| TEST_F(ExtensionUtilTest, IsExtensionValid) { |
| { |
| FilePath file_path(kExtensionFilePath); |
| scoped_refptr<Extension> extension( |
| MakeExtension(false, GURL(), GURL(), false, |
| Extension::INTERNAL, 0, file_path)); |
| EXPECT_TRUE(IsExtensionValid(*extension)); |
| } |
| { |
| FilePath file_path(kExtensionFilePath); |
| scoped_refptr<Extension> extension( |
| MakeExtension(false, GURL(kValidUpdateUrl1), GURL(), |
| true, Extension::INTERNAL, 0, file_path)); |
| EXPECT_TRUE(IsExtensionValid(*extension)); |
| } |
| { |
| FilePath file_path(kExtensionFilePath); |
| scoped_refptr<Extension> extension( |
| MakeExtension(false, GURL(), GURL(), true, |
| Extension::INTERNAL, 0, file_path)); |
| EXPECT_TRUE(IsExtensionValid(*extension)); |
| } |
| { |
| FilePath file_path(kExtensionFilePath); |
| scoped_refptr<Extension> extension( |
| MakeExtension(true, GURL(), GURL(), false, |
| Extension::INTERNAL, 0, file_path)); |
| EXPECT_TRUE(IsExtensionValid(*extension)); |
| } |
| { |
| FilePath file_path(kExtensionFilePath); |
| scoped_refptr<Extension> extension( |
| MakeExtension(false, GURL(), |
| GURL("http://www.google.com"), false, |
| Extension::INTERNAL, 0, file_path)); |
| EXPECT_TRUE(IsExtensionValid(*extension)); |
| } |
| { |
| FilePath file_path(kExtensionFilePath); |
| scoped_refptr<Extension> extension( |
| MakeExtension(false, GURL(), GURL(), false, |
| Extension::EXTERNAL_PREF, 0, file_path)); |
| EXPECT_FALSE(IsExtensionValid(*extension)); |
| } |
| { |
| FilePath file_path(kExtensionFilePath); |
| scoped_refptr<Extension> extension( |
| MakeExtension( |
| false, GURL("http://third-party.update_url.com"), GURL(), true, |
| Extension::INTERNAL, 0, file_path)); |
| EXPECT_FALSE(IsExtensionValid(*extension)); |
| } |
| // These last 2 tests don't make sense on Chrome OS, where extension plugins |
| // are not allowed. |
| #if !defined(OS_CHROMEOS) |
| { |
| FilePath file_path(kExtensionFilePath); |
| scoped_refptr<Extension> extension( |
| MakeExtension(false, GURL(), GURL(), true, |
| Extension::INTERNAL, 1, file_path)); |
| EXPECT_FALSE(extension && IsExtensionValid(*extension)); |
| } |
| { |
| FilePath file_path(kExtensionFilePath); |
| scoped_refptr<Extension> extension( |
| MakeExtension(false, GURL(), GURL(), true, |
| Extension::INTERNAL, 2, file_path)); |
| EXPECT_FALSE(extension && IsExtensionValid(*extension)); |
| } |
| #endif |
| } |
| |
| TEST_F(ExtensionUtilTest, IsExtensionSpecificsUnset) { |
| { |
| sync_pb::ExtensionSpecifics specifics; |
| EXPECT_TRUE(IsExtensionSpecificsUnset(specifics)); |
| } |
| |
| { |
| sync_pb::ExtensionSpecifics specifics; |
| specifics.set_id("a"); |
| EXPECT_FALSE(IsExtensionSpecificsUnset(specifics)); |
| } |
| |
| { |
| sync_pb::ExtensionSpecifics specifics; |
| specifics.set_version("a"); |
| EXPECT_FALSE(IsExtensionSpecificsUnset(specifics)); |
| } |
| |
| { |
| sync_pb::ExtensionSpecifics specifics; |
| specifics.set_update_url("a"); |
| EXPECT_FALSE(IsExtensionSpecificsUnset(specifics)); |
| } |
| |
| { |
| sync_pb::ExtensionSpecifics specifics; |
| specifics.set_enabled(true); |
| EXPECT_FALSE(IsExtensionSpecificsUnset(specifics)); |
| } |
| |
| { |
| sync_pb::ExtensionSpecifics specifics; |
| specifics.set_incognito_enabled(true); |
| EXPECT_FALSE(IsExtensionSpecificsUnset(specifics)); |
| } |
| |
| { |
| sync_pb::ExtensionSpecifics specifics; |
| specifics.set_name("a"); |
| EXPECT_FALSE(IsExtensionSpecificsUnset(specifics)); |
| } |
| } |
| |
| TEST_F(ExtensionUtilTest, IsExtensionSpecificsValid) { |
| sync_pb::ExtensionSpecifics specifics; |
| EXPECT_FALSE(IsExtensionSpecificsValid(specifics)); |
| specifics.set_id(kValidId); |
| EXPECT_FALSE(IsExtensionSpecificsValid(specifics)); |
| specifics.set_version(kValidVersion); |
| EXPECT_TRUE(IsExtensionSpecificsValid(specifics)); |
| EXPECT_FALSE(IsExtensionSpecificsUnset(specifics)); |
| specifics.set_update_url(kValidUpdateUrl1); |
| EXPECT_TRUE(IsExtensionSpecificsValid(specifics)); |
| EXPECT_FALSE(IsExtensionSpecificsUnset(specifics)); |
| |
| { |
| sync_pb::ExtensionSpecifics specifics_copy(specifics); |
| specifics_copy.set_id("invalid"); |
| EXPECT_FALSE(IsExtensionSpecificsValid(specifics_copy)); |
| } |
| |
| { |
| sync_pb::ExtensionSpecifics specifics_copy(specifics); |
| specifics_copy.set_version("invalid"); |
| EXPECT_FALSE(IsExtensionSpecificsValid(specifics_copy)); |
| } |
| |
| { |
| sync_pb::ExtensionSpecifics specifics_copy(specifics); |
| specifics_copy.set_update_url("http:invalid.com:invalid"); |
| EXPECT_FALSE(IsExtensionSpecificsValid(specifics_copy)); |
| } |
| } |
| |
| TEST_F(ExtensionUtilTest, AreExtensionSpecificsEqual) { |
| sync_pb::ExtensionSpecifics a, b; |
| EXPECT_TRUE(AreExtensionSpecificsEqual(a, b)); |
| |
| a.set_id("a"); |
| EXPECT_FALSE(AreExtensionSpecificsEqual(a, b)); |
| b.set_id("a"); |
| EXPECT_TRUE(AreExtensionSpecificsEqual(a, b)); |
| |
| a.set_version("1.5"); |
| EXPECT_FALSE(AreExtensionSpecificsEqual(a, b)); |
| b.set_version("1.5"); |
| EXPECT_TRUE(AreExtensionSpecificsEqual(a, b)); |
| |
| a.set_update_url("http://www.foo.com"); |
| EXPECT_FALSE(AreExtensionSpecificsEqual(a, b)); |
| b.set_update_url("http://www.foo.com"); |
| EXPECT_TRUE(AreExtensionSpecificsEqual(a, b)); |
| |
| a.set_enabled(true); |
| EXPECT_FALSE(AreExtensionSpecificsEqual(a, b)); |
| b.set_enabled(true); |
| EXPECT_TRUE(AreExtensionSpecificsEqual(a, b)); |
| |
| a.set_incognito_enabled(true); |
| EXPECT_FALSE(AreExtensionSpecificsEqual(a, b)); |
| b.set_incognito_enabled(true); |
| EXPECT_TRUE(AreExtensionSpecificsEqual(a, b)); |
| |
| a.set_name("name"); |
| EXPECT_FALSE(AreExtensionSpecificsEqual(a, b)); |
| b.set_name("name"); |
| EXPECT_TRUE(AreExtensionSpecificsEqual(a, b)); |
| } |
| |
| TEST_F(ExtensionUtilTest, CopyUserProperties) { |
| sync_pb::ExtensionSpecifics dest_specifics; |
| dest_specifics.set_version(kVersion2); |
| dest_specifics.set_update_url(kValidUpdateUrl1); |
| dest_specifics.set_enabled(true); |
| dest_specifics.set_incognito_enabled(false); |
| dest_specifics.set_name(kName); |
| |
| sync_pb::ExtensionSpecifics specifics; |
| specifics.set_id(kValidId); |
| specifics.set_version(kVersion3); |
| specifics.set_update_url(kValidUpdateUrl2); |
| specifics.set_enabled(false); |
| specifics.set_incognito_enabled(true); |
| specifics.set_name(kName2); |
| |
| CopyUserProperties(specifics, &dest_specifics); |
| EXPECT_EQ("", dest_specifics.id()); |
| EXPECT_EQ(kVersion2, dest_specifics.version()); |
| EXPECT_EQ(kValidUpdateUrl1, dest_specifics.update_url()); |
| EXPECT_FALSE(dest_specifics.enabled()); |
| EXPECT_TRUE(dest_specifics.incognito_enabled()); |
| EXPECT_EQ(kName, dest_specifics.name()); |
| } |
| |
| TEST_F(ExtensionUtilTest, CopyNonUserProperties) { |
| sync_pb::ExtensionSpecifics dest_specifics; |
| dest_specifics.set_id(kValidId); |
| dest_specifics.set_version(kVersion2); |
| dest_specifics.set_update_url(kValidUpdateUrl1); |
| dest_specifics.set_enabled(true); |
| dest_specifics.set_incognito_enabled(false); |
| dest_specifics.set_name(kName); |
| |
| sync_pb::ExtensionSpecifics specifics; |
| specifics.set_id(""); |
| specifics.set_version(kVersion3); |
| specifics.set_update_url(kValidUpdateUrl2); |
| specifics.set_enabled(false); |
| specifics.set_incognito_enabled(true); |
| specifics.set_name(kName2); |
| |
| CopyNonUserProperties(specifics, &dest_specifics); |
| EXPECT_EQ("", dest_specifics.id()); |
| EXPECT_EQ(kVersion3, dest_specifics.version()); |
| EXPECT_EQ(kValidUpdateUrl2, dest_specifics.update_url()); |
| EXPECT_TRUE(dest_specifics.enabled()); |
| EXPECT_FALSE(dest_specifics.incognito_enabled()); |
| EXPECT_EQ(kName2, dest_specifics.name()); |
| } |
| |
| TEST_F(ExtensionUtilTest, AreExtensionSpecificsUserPropertiesEqual) { |
| sync_pb::ExtensionSpecifics a, b; |
| EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b)); |
| |
| a.set_id("a"); |
| b.set_id("b"); |
| EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b)); |
| |
| a.set_version("1.5"); |
| b.set_version("1.6"); |
| EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b)); |
| |
| a.set_name("name"); |
| b.set_name("name2"); |
| EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b)); |
| |
| a.set_update_url("http://www.foo.com"); |
| b.set_update_url("http://www.foo2.com"); |
| EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b)); |
| |
| a.set_enabled(true); |
| EXPECT_FALSE(AreExtensionSpecificsUserPropertiesEqual(a, b)); |
| b.set_enabled(true); |
| EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b)); |
| |
| a.set_incognito_enabled(true); |
| EXPECT_FALSE(AreExtensionSpecificsUserPropertiesEqual(a, b)); |
| b.set_incognito_enabled(true); |
| EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b)); |
| } |
| |
| TEST_F(ExtensionUtilTest, AreExtensionSpecificsNonUserPropertiesEqual) { |
| sync_pb::ExtensionSpecifics a, b; |
| EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| |
| a.set_enabled(true); |
| b.set_enabled(false); |
| EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| |
| a.set_incognito_enabled(true); |
| b.set_incognito_enabled(false); |
| EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| |
| a.set_id("a"); |
| EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| b.set_id("a"); |
| EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| |
| a.set_version("1.5"); |
| EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| b.set_version("1.5"); |
| EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| |
| a.set_update_url("http://www.foo.com"); |
| EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| b.set_update_url("http://www.foo.com"); |
| EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| |
| a.set_name("name"); |
| EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| b.set_name("name"); |
| EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b)); |
| } |
| |
| scoped_refptr<Extension> MakeSyncableExtension( |
| const std::string& version_string, |
| const std::string& update_url_spec, |
| const std::string& name, |
| const FilePath& extension_path) { |
| DictionaryValue source; |
| source.SetString(extension_manifest_keys::kVersion, version_string); |
| source.SetString(extension_manifest_keys::kUpdateURL, update_url_spec); |
| source.SetString(extension_manifest_keys::kName, name); |
| std::string error; |
| scoped_refptr<Extension> extension = Extension::Create( |
| extension_path, Extension::INTERNAL, source, |
| Extension::STRICT_ERROR_CHECKS, &error); |
| EXPECT_TRUE(extension); |
| EXPECT_EQ("", error); |
| return extension; |
| } |
| |
| TEST_F(ExtensionUtilTest, GetExtensionSpecifics) { |
| FilePath file_path(kExtensionFilePath); |
| StrictMock<MockExtensionService> mock_extension_service; |
| EXPECT_CALL(mock_extension_service, IsExtensionEnabled(_)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_extension_service, IsIncognitoEnabled(_)) |
| .WillOnce(Return(false)); |
| |
| scoped_refptr<Extension> extension( |
| MakeSyncableExtension( |
| kValidVersion, kValidUpdateUrl1, kName, file_path)); |
| sync_pb::ExtensionSpecifics specifics; |
| GetExtensionSpecifics(*extension, mock_extension_service, &specifics); |
| EXPECT_EQ(extension->id(), specifics.id()); |
| EXPECT_EQ(extension->VersionString(), kValidVersion); |
| EXPECT_EQ(extension->update_url().spec(), kValidUpdateUrl1); |
| EXPECT_TRUE(specifics.enabled()); |
| EXPECT_FALSE(specifics.incognito_enabled()); |
| EXPECT_EQ(kName, specifics.name()); |
| } |
| |
| // TODO(akalin): Make ExtensionService/ExtensionUpdater testable |
| // enough to be able to write a unittest for SetExtensionProperties(). |
| |
| TEST_F(ExtensionUtilTest, MergeExtensionSpecificsWithUserProperties) { |
| sync_pb::ExtensionSpecifics merged_specifics; |
| merged_specifics.set_id(kValidId); |
| merged_specifics.set_update_url(kValidUpdateUrl1); |
| merged_specifics.set_enabled(true); |
| merged_specifics.set_incognito_enabled(false); |
| merged_specifics.set_version(kVersion2); |
| |
| sync_pb::ExtensionSpecifics specifics; |
| specifics.set_id(kValidId); |
| specifics.set_update_url(kValidUpdateUrl2); |
| merged_specifics.set_enabled(false); |
| merged_specifics.set_incognito_enabled(true); |
| |
| specifics.set_version(kVersion1); |
| { |
| sync_pb::ExtensionSpecifics result = merged_specifics; |
| MergeExtensionSpecifics(specifics, false, &result); |
| EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual( |
| result, merged_specifics)); |
| EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual( |
| result, merged_specifics)); |
| } |
| { |
| sync_pb::ExtensionSpecifics result = merged_specifics; |
| MergeExtensionSpecifics(specifics, true, &result); |
| EXPECT_TRUE(AreExtensionSpecificsEqual(result, merged_specifics)); |
| } |
| |
| specifics.set_version(kVersion2); |
| { |
| sync_pb::ExtensionSpecifics result = merged_specifics; |
| MergeExtensionSpecifics(specifics, false, &result); |
| EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual( |
| result, merged_specifics)); |
| EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual( |
| result, specifics)); |
| } |
| { |
| sync_pb::ExtensionSpecifics result = merged_specifics; |
| MergeExtensionSpecifics(specifics, true, &result); |
| EXPECT_TRUE(AreExtensionSpecificsEqual(result, specifics)); |
| } |
| |
| specifics.set_version(kVersion3); |
| { |
| sync_pb::ExtensionSpecifics result = merged_specifics; |
| MergeExtensionSpecifics(specifics, false, &result); |
| EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual( |
| result, merged_specifics)); |
| EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual( |
| result, specifics)); |
| } |
| { |
| sync_pb::ExtensionSpecifics result = merged_specifics; |
| MergeExtensionSpecifics(specifics, true, &result); |
| EXPECT_TRUE(AreExtensionSpecificsEqual(result, specifics)); |
| } |
| } |
| |
| } // namespace |
| |
| } // namespace browser_sync |