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