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
MakeThemeExtension(const FilePath & extension_path,const std::string & name,const std::string & update_url)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
TEST_F(ThemeUtilTest,AreThemeSpecificsEqualHelper)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
TEST_F(ThemeUtilTest,SetCurrentThemeDefaultTheme)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
TEST_F(ThemeUtilTest,SetCurrentThemeSystemTheme)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
TEST_F(ThemeUtilTest,GetThemeSpecificsHelperNoCustomTheme)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
TEST_F(ThemeUtilTest,GetThemeSpecificsHelperNoCustomThemeDistinct)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
TEST_F(ThemeUtilTest,GetThemeSpecificsHelperCustomTheme)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
TEST_F(ThemeUtilTest,GetThemeSpecificsHelperCustomThemeDistinct)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
TEST_F(ThemeUtilTest,SetCurrentThemeIfNecessaryDefaultThemeNotNecessary)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