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/theme_util.h" 6 7 #include "base/file_path.h" 8 #include "base/values.h" 9 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/sync/protocol/theme_specifics.pb.h" 11 #include "chrome/browser/themes/theme_service.h" 12 #include "chrome/browser/themes/theme_service_factory.h" 13 #include "chrome/common/extensions/extension.h" 14 #include "chrome/common/extensions/extension_constants.h" 15 #include "chrome/test/testing_profile.h" 16 #include "testing/gmock/include/gmock/gmock.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 19 namespace browser_sync { 20 21 namespace { 22 23 using ::testing::Return; 24 25 class ThemeUtilTest : public testing::Test { 26 }; 27 28 scoped_refptr<Extension> MakeThemeExtension(const FilePath& extension_path, 29 const std::string& name, 30 const std::string& update_url) { 31 DictionaryValue source; 32 source.SetString(extension_manifest_keys::kName, name); 33 source.Set(extension_manifest_keys::kTheme, new DictionaryValue()); 34 source.SetString(extension_manifest_keys::kUpdateURL, update_url); 35 source.SetString(extension_manifest_keys::kVersion, "0.0.0.0"); 36 std::string error; 37 scoped_refptr<Extension> extension = Extension::Create( 38 extension_path, Extension::INTERNAL, source, 39 Extension::STRICT_ERROR_CHECKS, &error); 40 EXPECT_TRUE(extension); 41 EXPECT_EQ("", error); 42 return extension; 43 } 44 45 TEST_F(ThemeUtilTest, AreThemeSpecificsEqualHelper) { 46 sync_pb::ThemeSpecifics a, b; 47 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, false)); 48 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, true)); 49 50 // Custom vs. non-custom. 51 52 a.set_use_custom_theme(true); 53 EXPECT_FALSE(AreThemeSpecificsEqualHelper(a, b, false)); 54 EXPECT_FALSE(AreThemeSpecificsEqualHelper(a, b, true)); 55 56 // Custom theme equality. 57 58 b.set_use_custom_theme(true); 59 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, false)); 60 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, true)); 61 62 a.set_custom_theme_id("id"); 63 EXPECT_FALSE(AreThemeSpecificsEqualHelper(a, b, false)); 64 EXPECT_FALSE(AreThemeSpecificsEqualHelper(a, b, true)); 65 66 b.set_custom_theme_id("id"); 67 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, false)); 68 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, true)); 69 70 a.set_custom_theme_update_url("http://update.url"); 71 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, false)); 72 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, true)); 73 74 a.set_custom_theme_name("name"); 75 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, false)); 76 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, true)); 77 78 // Non-custom theme equality. 79 80 a.set_use_custom_theme(false); 81 b.set_use_custom_theme(false); 82 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, false)); 83 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, true)); 84 85 a.set_use_system_theme_by_default(true); 86 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, false)); 87 EXPECT_FALSE(AreThemeSpecificsEqualHelper(a, b, true)); 88 89 b.set_use_system_theme_by_default(true); 90 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, false)); 91 EXPECT_TRUE(AreThemeSpecificsEqualHelper(a, b, true)); 92 } 93 94 class MockThemeService : public ThemeService { 95 public: 96 MOCK_METHOD0(SetNativeTheme, void()); 97 MOCK_METHOD0(UseDefaultTheme, void()); 98 MOCK_CONST_METHOD0(GetThemeID, std::string()); 99 }; 100 101 TEST_F(ThemeUtilTest, SetCurrentThemeDefaultTheme) { 102 sync_pb::ThemeSpecifics theme_specifics; 103 TestingProfile profile; 104 MockThemeService* mock_theme_service = new MockThemeService; 105 ThemeServiceFactory::GetInstance()->ForceAssociationBetween(&profile, 106 mock_theme_service); 107 108 EXPECT_CALL(*mock_theme_service, UseDefaultTheme()).Times(1); 109 110 SetCurrentThemeFromThemeSpecifics(theme_specifics, &profile); 111 } 112 113 TEST_F(ThemeUtilTest, SetCurrentThemeSystemTheme) { 114 sync_pb::ThemeSpecifics theme_specifics; 115 theme_specifics.set_use_system_theme_by_default(true); 116 117 TestingProfile profile; 118 MockThemeService* mock_theme_service = new MockThemeService; 119 ThemeServiceFactory::GetInstance()->ForceAssociationBetween(&profile, 120 mock_theme_service); 121 122 EXPECT_CALL(*mock_theme_service, SetNativeTheme()).Times(1); 123 124 SetCurrentThemeFromThemeSpecifics(theme_specifics, &profile); 125 } 126 127 // TODO(akalin): Make ExtensionService/ExtensionUpdater testable 128 // enough to be able to write a unittest for SetCurrentTheme for a 129 // custom theme. 130 131 TEST_F(ThemeUtilTest, GetThemeSpecificsHelperNoCustomTheme) { 132 sync_pb::ThemeSpecifics theme_specifics; 133 theme_specifics.set_use_custom_theme(true); 134 theme_specifics.set_use_system_theme_by_default(true); 135 theme_specifics.set_custom_theme_name("name"); 136 theme_specifics.set_custom_theme_id("id"); 137 theme_specifics.set_custom_theme_update_url("updateurl"); 138 GetThemeSpecificsFromCurrentThemeHelper(NULL, false, false, 139 &theme_specifics); 140 141 EXPECT_TRUE(theme_specifics.has_use_custom_theme()); 142 EXPECT_FALSE(theme_specifics.use_custom_theme()); 143 // Should be preserved since we passed in false for 144 // is_system_theme_distinct_from_current_theme. 145 EXPECT_TRUE(theme_specifics.use_system_theme_by_default()); 146 EXPECT_FALSE(theme_specifics.has_custom_theme_name()); 147 EXPECT_FALSE(theme_specifics.has_custom_theme_id()); 148 EXPECT_FALSE(theme_specifics.has_custom_theme_update_url()); 149 } 150 151 TEST_F(ThemeUtilTest, GetThemeSpecificsHelperNoCustomThemeDistinct) { 152 sync_pb::ThemeSpecifics theme_specifics; 153 theme_specifics.set_use_custom_theme(true); 154 theme_specifics.set_custom_theme_name("name"); 155 theme_specifics.set_custom_theme_id("id"); 156 theme_specifics.set_custom_theme_update_url("updateurl"); 157 GetThemeSpecificsFromCurrentThemeHelper(NULL, true, false, 158 &theme_specifics); 159 160 EXPECT_TRUE(theme_specifics.has_use_custom_theme()); 161 EXPECT_FALSE(theme_specifics.use_custom_theme()); 162 // Should be set since we passed in true for 163 // is_system_theme_distinct_from_current_theme. 164 EXPECT_TRUE(theme_specifics.has_use_system_theme_by_default()); 165 EXPECT_FALSE(theme_specifics.use_system_theme_by_default()); 166 EXPECT_FALSE(theme_specifics.has_custom_theme_name()); 167 EXPECT_FALSE(theme_specifics.has_custom_theme_id()); 168 EXPECT_FALSE(theme_specifics.has_custom_theme_update_url()); 169 } 170 171 namespace { 172 #if defined(OS_WIN) 173 const FilePath::CharType kExtensionFilePath[] = FILE_PATH_LITERAL("c:\\foo"); 174 #elif defined(OS_POSIX) 175 const FilePath::CharType kExtensionFilePath[] = FILE_PATH_LITERAL("/oo"); 176 #endif 177 } // namespace 178 179 TEST_F(ThemeUtilTest, GetThemeSpecificsHelperCustomTheme) { 180 sync_pb::ThemeSpecifics theme_specifics; 181 theme_specifics.set_use_custom_theme(false); 182 theme_specifics.set_use_system_theme_by_default(true); 183 FilePath file_path(kExtensionFilePath); 184 const std::string kThemeName("name"); 185 const std::string kThemeUpdateUrl("http://update.url/foo"); 186 scoped_refptr<Extension> extension( 187 MakeThemeExtension(file_path, kThemeName, kThemeUpdateUrl)); 188 GetThemeSpecificsFromCurrentThemeHelper(extension.get(), false, false, 189 &theme_specifics); 190 191 EXPECT_TRUE(theme_specifics.use_custom_theme()); 192 EXPECT_TRUE(theme_specifics.use_system_theme_by_default()); 193 EXPECT_EQ(kThemeName, theme_specifics.custom_theme_name()); 194 EXPECT_EQ(extension->id(), theme_specifics.custom_theme_id()); 195 EXPECT_EQ(kThemeUpdateUrl, theme_specifics.custom_theme_update_url()); 196 } 197 198 TEST_F(ThemeUtilTest, GetThemeSpecificsHelperCustomThemeDistinct) { 199 sync_pb::ThemeSpecifics theme_specifics; 200 theme_specifics.set_use_custom_theme(false); 201 FilePath file_path(kExtensionFilePath); 202 const std::string kThemeName("name"); 203 const std::string kThemeUpdateUrl("http://update.url/foo"); 204 scoped_refptr<Extension> extension( 205 MakeThemeExtension(file_path, kThemeName, kThemeUpdateUrl)); 206 GetThemeSpecificsFromCurrentThemeHelper(extension.get(), true, false, 207 &theme_specifics); 208 209 EXPECT_TRUE(theme_specifics.use_custom_theme()); 210 EXPECT_TRUE(theme_specifics.has_use_system_theme_by_default()); 211 EXPECT_FALSE(theme_specifics.use_system_theme_by_default()); 212 EXPECT_EQ(kThemeName, theme_specifics.custom_theme_name()); 213 EXPECT_EQ(extension->id(), theme_specifics.custom_theme_id()); 214 EXPECT_EQ(kThemeUpdateUrl, theme_specifics.custom_theme_update_url()); 215 } 216 217 TEST_F(ThemeUtilTest, SetCurrentThemeIfNecessaryDefaultThemeNotNecessary) { 218 TestingProfile profile; 219 MockThemeService* mock_theme_service = new MockThemeService; 220 ThemeServiceFactory::GetInstance()->ForceAssociationBetween(&profile, 221 mock_theme_service); 222 223 EXPECT_CALL(*mock_theme_service, GetThemeID()).WillRepeatedly(Return( 224 ThemeService::kDefaultThemeID)); 225 226 // TODO(akalin): Mock out call to GetPrefs() under TOOLKIT_USES_GTK. 227 228 sync_pb::ThemeSpecifics theme_specifics; 229 SetCurrentThemeFromThemeSpecificsIfNecessary(theme_specifics, 230 &profile); 231 } 232 233 } // namespace 234 235 } // namespace browser_sync 236