extension_util_unittest.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
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
39void MakeExtension(bool is_theme, const GURL& update_url,
40                   const GURL& launch_url, bool converted_from_user_script,
41                   Extension::Location location, int num_plugins,
42                   Extension* extension) {
43  DictionaryValue source;
44  source.SetString(extension_manifest_keys::kName,
45                   "PossiblySyncableExtension");
46  source.SetString(extension_manifest_keys::kVersion, "0.0.0.0");
47  if (is_theme) {
48    source.Set(extension_manifest_keys::kTheme, new DictionaryValue());
49  }
50  if (!update_url.is_empty()) {
51    source.SetString(extension_manifest_keys::kUpdateURL,
52                     update_url.spec());
53  }
54  if (!launch_url.is_empty()) {
55    source.SetString(extension_manifest_keys::kLaunchWebURL,
56                     launch_url.spec());
57  }
58  if (!is_theme) {
59    source.SetBoolean(extension_manifest_keys::kConvertedFromUserScript,
60                      converted_from_user_script);
61    ListValue* plugins = new ListValue();
62    for (int i = 0; i < num_plugins; ++i) {
63      DictionaryValue* plugin = new DictionaryValue();
64      plugin->SetString(extension_manifest_keys::kPluginsPath, "");
65      plugins->Set(i, plugin);
66    }
67    source.Set(extension_manifest_keys::kPlugins, plugins);
68  }
69
70  std::string error;
71#if defined(OS_CHROMEOS)
72  if (num_plugins > 0) {  // plugins are illegal in extensions on chrome os.
73    EXPECT_FALSE(extension->InitFromValue(source, false, &error));
74    return;
75  }
76#endif
77  EXPECT_TRUE(extension->InitFromValue(source, false, &error));
78  EXPECT_EQ("", error);
79  extension->set_location(location);
80}
81
82TEST_F(ExtensionUtilTest, GetExtensionType) {
83  {
84    FilePath file_path(kExtensionFilePath);
85    Extension extension(file_path);
86    MakeExtension(false, GURL(), GURL(), false,
87                  Extension::INTERNAL, 0, &extension);
88    EXPECT_EQ(EXTENSION, GetExtensionType(extension));
89  }
90  {
91    FilePath file_path(kExtensionFilePath);
92    Extension extension(file_path);
93    MakeExtension(true, GURL(), GURL(), false,
94                  Extension::INTERNAL, 0, &extension);
95    EXPECT_EQ(THEME, GetExtensionType(extension));
96  }
97  {
98    FilePath file_path(kExtensionFilePath);
99    Extension extension(file_path);
100    MakeExtension(false, GURL(), GURL(), true,
101                  Extension::INTERNAL, 0, &extension);
102    EXPECT_EQ(LOCAL_USER_SCRIPT, GetExtensionType(extension));
103  }
104  {
105    FilePath file_path(kExtensionFilePath);
106    Extension extension(file_path);
107    MakeExtension(false, GURL("http://www.google.com"), GURL(), true,
108                  Extension::INTERNAL, 0, &extension);
109    EXPECT_EQ(UPDATEABLE_USER_SCRIPT, GetExtensionType(extension));
110  }
111  {
112    FilePath file_path(kExtensionFilePath);
113    Extension extension(file_path);
114    MakeExtension(false, GURL(),
115                  GURL("http://www.google.com"), false,
116                  Extension::INTERNAL, 0, &extension);
117    EXPECT_EQ(APP, GetExtensionType(extension));
118  }
119}
120
121TEST_F(ExtensionUtilTest, IsExtensionValid) {
122  {
123    FilePath file_path(kExtensionFilePath);
124    Extension extension(file_path);
125    MakeExtension(false, GURL(), GURL(), false,
126                  Extension::INTERNAL, 0, &extension);
127    EXPECT_TRUE(IsExtensionValid(extension));
128  }
129  {
130    FilePath file_path(kExtensionFilePath);
131    Extension extension(file_path);
132    MakeExtension(false, GURL(kValidUpdateUrl1), GURL(),
133                  true, Extension::INTERNAL, 0, &extension);
134    EXPECT_TRUE(IsExtensionValid(extension));
135  }
136  {
137    FilePath file_path(kExtensionFilePath);
138    Extension extension(file_path);
139    MakeExtension(false, GURL(), GURL(), true,
140                  Extension::INTERNAL, 0, &extension);
141    EXPECT_TRUE(IsExtensionValid(extension));
142  }
143  {
144    FilePath file_path(kExtensionFilePath);
145    Extension extension(file_path);
146    MakeExtension(true, GURL(), GURL(), false,
147                  Extension::INTERNAL, 0, &extension);
148    EXPECT_TRUE(IsExtensionValid(extension));
149  }
150  {
151    FilePath file_path(kExtensionFilePath);
152    Extension extension(file_path);
153    MakeExtension(false, GURL(),
154                  GURL("http://www.google.com"), false,
155                  Extension::INTERNAL, 0, &extension);
156    EXPECT_TRUE(IsExtensionValid(extension));
157  }
158  {
159    FilePath file_path(kExtensionFilePath);
160    Extension extension(file_path);
161    MakeExtension(false, GURL(), GURL(), false,
162                  Extension::EXTERNAL_PREF, 0, &extension);
163    EXPECT_FALSE(IsExtensionValid(extension));
164  }
165  {
166    FilePath file_path(kExtensionFilePath);
167    Extension extension(file_path);
168    MakeExtension(
169        false, GURL("http://third-party.update_url.com"), GURL(), true,
170        Extension::INTERNAL, 0, &extension);
171    EXPECT_FALSE(IsExtensionValid(extension));
172  }
173  {
174    FilePath file_path(kExtensionFilePath);
175    Extension extension(file_path);
176    MakeExtension(false, GURL(), GURL(), true,
177                  Extension::INTERNAL, 1, &extension);
178    EXPECT_FALSE(IsExtensionValid(extension));
179  }
180  {
181    FilePath file_path(kExtensionFilePath);
182    Extension extension(file_path);
183    MakeExtension(false, GURL(), GURL(), true,
184                  Extension::INTERNAL, 2, &extension);
185    EXPECT_FALSE(IsExtensionValid(extension));
186  }
187}
188
189TEST_F(ExtensionUtilTest, IsExtensionValidAndSyncable) {
190  ExtensionTypeSet allowed_extension_types;
191  allowed_extension_types.insert(EXTENSION);
192  allowed_extension_types.insert(APP);
193  {
194    FilePath file_path(kExtensionFilePath);
195    Extension extension(file_path);
196    MakeExtension(false, GURL(), GURL(), false,
197                  Extension::INTERNAL, 0, &extension);
198    EXPECT_TRUE(IsExtensionValidAndSyncable(
199        extension, allowed_extension_types));
200  }
201  {
202    FilePath file_path(kExtensionFilePath);
203    Extension extension(file_path);
204    MakeExtension(false, GURL(),
205                  GURL("http://www.google.com"), false,
206                  Extension::INTERNAL, 0, &extension);
207    EXPECT_TRUE(IsExtensionValidAndSyncable(
208        extension, allowed_extension_types));
209  }
210  {
211    FilePath file_path(kExtensionFilePath);
212    Extension extension(file_path);
213    MakeExtension(false, GURL(), GURL(), true,
214                  Extension::INTERNAL, 0, &extension);
215    EXPECT_FALSE(IsExtensionValidAndSyncable(
216        extension, allowed_extension_types));
217  }
218  {
219    FilePath file_path(kExtensionFilePath);
220    Extension extension(file_path);
221    MakeExtension(false, GURL(), GURL(), false,
222                  Extension::EXTERNAL_PREF, 0, &extension);
223    EXPECT_FALSE(IsExtensionValidAndSyncable(
224        extension, allowed_extension_types));
225  }
226}
227
228
229TEST_F(ExtensionUtilTest, IsExtensionSpecificsUnset) {
230  {
231    sync_pb::ExtensionSpecifics specifics;
232    EXPECT_TRUE(IsExtensionSpecificsUnset(specifics));
233  }
234
235  {
236    sync_pb::ExtensionSpecifics specifics;
237    specifics.set_id("a");
238    EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
239  }
240
241  {
242    sync_pb::ExtensionSpecifics specifics;
243    specifics.set_version("a");
244    EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
245  }
246
247  {
248    sync_pb::ExtensionSpecifics specifics;
249    specifics.set_update_url("a");
250    EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
251  }
252
253  {
254    sync_pb::ExtensionSpecifics specifics;
255    specifics.set_enabled(true);
256    EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
257  }
258
259  {
260    sync_pb::ExtensionSpecifics specifics;
261    specifics.set_incognito_enabled(true);
262    EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
263  }
264
265  {
266    sync_pb::ExtensionSpecifics specifics;
267    specifics.set_name("a");
268    EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
269  }
270}
271
272TEST_F(ExtensionUtilTest, IsExtensionSpecificsValid) {
273  sync_pb::ExtensionSpecifics specifics;
274  EXPECT_FALSE(IsExtensionSpecificsValid(specifics));
275  specifics.set_id(kValidId);
276  EXPECT_FALSE(IsExtensionSpecificsValid(specifics));
277  specifics.set_version(kValidVersion);
278  EXPECT_TRUE(IsExtensionSpecificsValid(specifics));
279  EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
280  specifics.set_update_url(kValidUpdateUrl1);
281  EXPECT_TRUE(IsExtensionSpecificsValid(specifics));
282  EXPECT_FALSE(IsExtensionSpecificsUnset(specifics));
283
284  {
285    sync_pb::ExtensionSpecifics specifics_copy(specifics);
286    specifics_copy.set_id("invalid");
287    EXPECT_FALSE(IsExtensionSpecificsValid(specifics_copy));
288  }
289
290  {
291    sync_pb::ExtensionSpecifics specifics_copy(specifics);
292    specifics_copy.set_version("invalid");
293    EXPECT_FALSE(IsExtensionSpecificsValid(specifics_copy));
294  }
295
296  {
297    sync_pb::ExtensionSpecifics specifics_copy(specifics);
298    specifics_copy.set_update_url("http:invalid.com:invalid");
299    EXPECT_FALSE(IsExtensionSpecificsValid(specifics_copy));
300  }
301}
302
303TEST_F(ExtensionUtilTest, AreExtensionSpecificsEqual) {
304  sync_pb::ExtensionSpecifics a, b;
305  EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
306
307  a.set_id("a");
308  EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
309  b.set_id("a");
310  EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
311
312  a.set_version("1.5");
313  EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
314  b.set_version("1.5");
315  EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
316
317  a.set_update_url("http://www.foo.com");
318  EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
319  b.set_update_url("http://www.foo.com");
320  EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
321
322  a.set_enabled(true);
323  EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
324  b.set_enabled(true);
325  EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
326
327  a.set_incognito_enabled(true);
328  EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
329  b.set_incognito_enabled(true);
330  EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
331
332  a.set_name("name");
333  EXPECT_FALSE(AreExtensionSpecificsEqual(a, b));
334  b.set_name("name");
335  EXPECT_TRUE(AreExtensionSpecificsEqual(a, b));
336}
337
338TEST_F(ExtensionUtilTest, CopyUserProperties) {
339  sync_pb::ExtensionSpecifics dest_specifics;
340  dest_specifics.set_version(kVersion2);
341  dest_specifics.set_update_url(kValidUpdateUrl1);
342  dest_specifics.set_enabled(true);
343  dest_specifics.set_incognito_enabled(false);
344  dest_specifics.set_name(kName);
345
346  sync_pb::ExtensionSpecifics specifics;
347  specifics.set_id(kValidId);
348  specifics.set_version(kVersion3);
349  specifics.set_update_url(kValidUpdateUrl2);
350  specifics.set_enabled(false);
351  specifics.set_incognito_enabled(true);
352  specifics.set_name(kName2);
353
354  CopyUserProperties(specifics, &dest_specifics);
355  EXPECT_EQ("", dest_specifics.id());
356  EXPECT_EQ(kVersion2, dest_specifics.version());
357  EXPECT_EQ(kValidUpdateUrl1, dest_specifics.update_url());
358  EXPECT_FALSE(dest_specifics.enabled());
359  EXPECT_TRUE(dest_specifics.incognito_enabled());
360  EXPECT_EQ(kName, dest_specifics.name());
361}
362
363TEST_F(ExtensionUtilTest, CopyNonUserProperties) {
364  sync_pb::ExtensionSpecifics dest_specifics;
365  dest_specifics.set_id(kValidId);
366  dest_specifics.set_version(kVersion2);
367  dest_specifics.set_update_url(kValidUpdateUrl1);
368  dest_specifics.set_enabled(true);
369  dest_specifics.set_incognito_enabled(false);
370  dest_specifics.set_name(kName);
371
372  sync_pb::ExtensionSpecifics specifics;
373  specifics.set_id("");
374  specifics.set_version(kVersion3);
375  specifics.set_update_url(kValidUpdateUrl2);
376  specifics.set_enabled(false);
377  specifics.set_incognito_enabled(true);
378  specifics.set_name(kName2);
379
380  CopyNonUserProperties(specifics, &dest_specifics);
381  EXPECT_EQ("", dest_specifics.id());
382  EXPECT_EQ(kVersion3, dest_specifics.version());
383  EXPECT_EQ(kValidUpdateUrl2, dest_specifics.update_url());
384  EXPECT_TRUE(dest_specifics.enabled());
385  EXPECT_FALSE(dest_specifics.incognito_enabled());
386  EXPECT_EQ(kName2, dest_specifics.name());
387}
388
389TEST_F(ExtensionUtilTest, AreExtensionSpecificsUserPropertiesEqual) {
390  sync_pb::ExtensionSpecifics a, b;
391  EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
392
393  a.set_id("a");
394  b.set_id("b");
395  EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
396
397  a.set_version("1.5");
398  b.set_version("1.6");
399  EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
400
401  a.set_name("name");
402  b.set_name("name2");
403  EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
404
405  a.set_update_url("http://www.foo.com");
406  b.set_update_url("http://www.foo2.com");
407  EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
408
409  a.set_enabled(true);
410  EXPECT_FALSE(AreExtensionSpecificsUserPropertiesEqual(a, b));
411  b.set_enabled(true);
412  EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
413
414  a.set_incognito_enabled(true);
415  EXPECT_FALSE(AreExtensionSpecificsUserPropertiesEqual(a, b));
416  b.set_incognito_enabled(true);
417  EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(a, b));
418}
419
420TEST_F(ExtensionUtilTest, AreExtensionSpecificsNonUserPropertiesEqual) {
421  sync_pb::ExtensionSpecifics a, b;
422  EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
423
424  a.set_enabled(true);
425  b.set_enabled(false);
426  EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
427
428  a.set_incognito_enabled(true);
429  b.set_incognito_enabled(false);
430  EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
431
432  a.set_id("a");
433  EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
434  b.set_id("a");
435  EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
436
437  a.set_version("1.5");
438  EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
439  b.set_version("1.5");
440  EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
441
442  a.set_update_url("http://www.foo.com");
443  EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
444  b.set_update_url("http://www.foo.com");
445  EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
446
447  a.set_name("name");
448  EXPECT_FALSE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
449  b.set_name("name");
450  EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(a, b));
451}
452
453void MakeSyncableExtension(const std::string& version_string,
454                           const std::string& update_url_spec,
455                           const std::string& name,
456                           Extension* extension) {
457  DictionaryValue source;
458  source.SetString(extension_manifest_keys::kVersion, version_string);
459  source.SetString(extension_manifest_keys::kUpdateURL, update_url_spec);
460  source.SetString(extension_manifest_keys::kName, name);
461  std::string error;
462  EXPECT_TRUE(extension->InitFromValue(source, false, &error));
463  EXPECT_EQ("", error);
464  extension->set_location(Extension::INTERNAL);
465}
466
467TEST_F(ExtensionUtilTest, GetExtensionSpecificsHelper) {
468  FilePath file_path(kExtensionFilePath);
469  Extension extension(file_path);
470  MakeSyncableExtension(kValidVersion, kValidUpdateUrl1, kName,
471                        &extension);
472  sync_pb::ExtensionSpecifics specifics;
473  GetExtensionSpecificsHelper(extension, true, false, &specifics);
474  EXPECT_EQ(extension.id(), specifics.id());
475  EXPECT_EQ(extension.VersionString(), kValidVersion);
476  EXPECT_EQ(extension.update_url().spec(), kValidUpdateUrl1);
477  EXPECT_TRUE(specifics.enabled());
478  EXPECT_FALSE(specifics.incognito_enabled());
479  EXPECT_EQ(kName, specifics.name());
480}
481
482TEST_F(ExtensionUtilTest, IsExtensionOutdated) {
483  FilePath file_path(kExtensionFilePath);
484  Extension extension(file_path);
485  MakeSyncableExtension(kVersion2, kValidUpdateUrl1, kName,
486                        &extension);
487  sync_pb::ExtensionSpecifics specifics;
488  specifics.set_id(kValidId);
489  specifics.set_update_url(kValidUpdateUrl1);
490
491  specifics.set_version(kVersion1);
492  EXPECT_FALSE(IsExtensionOutdated(extension, specifics));
493  specifics.set_version(kVersion2);
494  EXPECT_FALSE(IsExtensionOutdated(extension, specifics));
495  specifics.set_version(kVersion3);
496  EXPECT_TRUE(IsExtensionOutdated(extension, specifics));
497}
498
499// TODO(akalin): Make ExtensionsService/ExtensionUpdater testable
500// enough to be able to write a unittest for SetExtensionProperties().
501
502TEST_F(ExtensionUtilTest, MergeExtensionSpecificsWithUserProperties) {
503  sync_pb::ExtensionSpecifics merged_specifics;
504  merged_specifics.set_id(kValidId);
505  merged_specifics.set_update_url(kValidUpdateUrl1);
506  merged_specifics.set_enabled(true);
507  merged_specifics.set_incognito_enabled(false);
508  merged_specifics.set_version(kVersion2);
509
510  sync_pb::ExtensionSpecifics specifics;
511  specifics.set_id(kValidId);
512  specifics.set_update_url(kValidUpdateUrl2);
513  merged_specifics.set_enabled(false);
514  merged_specifics.set_incognito_enabled(true);
515
516  specifics.set_version(kVersion1);
517  {
518    sync_pb::ExtensionSpecifics result = merged_specifics;
519    MergeExtensionSpecifics(specifics, false, &result);
520    EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(
521        result, merged_specifics));
522    EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(
523        result, merged_specifics));
524  }
525  {
526    sync_pb::ExtensionSpecifics result = merged_specifics;
527    MergeExtensionSpecifics(specifics, true, &result);
528    EXPECT_TRUE(AreExtensionSpecificsEqual(result, merged_specifics));
529  }
530
531  specifics.set_version(kVersion2);
532  {
533    sync_pb::ExtensionSpecifics result = merged_specifics;
534    MergeExtensionSpecifics(specifics, false, &result);
535    EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(
536        result, merged_specifics));
537    EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(
538        result, specifics));
539  }
540  {
541    sync_pb::ExtensionSpecifics result = merged_specifics;
542    MergeExtensionSpecifics(specifics, true, &result);
543    EXPECT_TRUE(AreExtensionSpecificsEqual(result, specifics));
544  }
545
546  specifics.set_version(kVersion3);
547  {
548    sync_pb::ExtensionSpecifics result = merged_specifics;
549    MergeExtensionSpecifics(specifics, false, &result);
550    EXPECT_TRUE(AreExtensionSpecificsUserPropertiesEqual(
551        result, merged_specifics));
552    EXPECT_TRUE(AreExtensionSpecificsNonUserPropertiesEqual(
553        result, specifics));
554  }
555  {
556    sync_pb::ExtensionSpecifics result = merged_specifics;
557    MergeExtensionSpecifics(specifics, true, &result);
558    EXPECT_TRUE(AreExtensionSpecificsEqual(result, specifics));
559  }
560}
561
562}  // namespace
563
564}  // namespace browser_sync
565