1// Copyright (c) 2012 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/extensions/./extension_prefs_unittest.h"
6
7#include "base/basictypes.h"
8#include "base/files/scoped_temp_dir.h"
9#include "base/path_service.h"
10#include "base/prefs/mock_pref_change_callback.h"
11#include "base/prefs/pref_change_registrar.h"
12#include "base/prefs/scoped_user_pref_update.h"
13#include "base/stl_util.h"
14#include "base/strings/string_number_conversions.h"
15#include "base/strings/stringprintf.h"
16#include "base/values.h"
17#include "chrome/browser/prefs/pref_service_syncable.h"
18#include "chrome/common/chrome_paths.h"
19#include "components/pref_registry/pref_registry_syncable.h"
20#include "content/public/browser/notification_details.h"
21#include "content/public/browser/notification_source.h"
22#include "content/public/test/mock_notification_observer.h"
23#include "extensions/browser/extension_pref_value_map.h"
24#include "extensions/browser/extension_prefs.h"
25#include "extensions/browser/install_flag.h"
26#include "extensions/common/extension.h"
27#include "extensions/common/manifest_constants.h"
28#include "extensions/common/permissions/permission_set.h"
29#include "extensions/common/permissions/permissions_info.h"
30#include "sync/api/string_ordinal.h"
31
32using base::Time;
33using base::TimeDelta;
34using content::BrowserThread;
35
36namespace extensions {
37
38static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
39  int schemes = URLPattern::SCHEME_ALL;
40  extent->AddPattern(URLPattern(schemes, pattern));
41}
42
43ExtensionPrefsTest::ExtensionPrefsTest()
44    : ui_thread_(BrowserThread::UI, &message_loop_),
45      prefs_(message_loop_.message_loop_proxy().get()) {}
46
47ExtensionPrefsTest::~ExtensionPrefsTest() {
48}
49
50void ExtensionPrefsTest::RegisterPreferences(
51    user_prefs::PrefRegistrySyncable* registry) {}
52
53void ExtensionPrefsTest::SetUp() {
54  RegisterPreferences(prefs_.pref_registry().get());
55  Initialize();
56}
57
58void ExtensionPrefsTest::TearDown() {
59  Verify();
60
61  // Reset ExtensionPrefs, and re-verify.
62  prefs_.ResetPrefRegistry();
63  RegisterPreferences(prefs_.pref_registry().get());
64  prefs_.RecreateExtensionPrefs();
65  Verify();
66  prefs_.pref_service()->CommitPendingWrite();
67  message_loop_.RunUntilIdle();
68}
69
70// Tests the LastPingDay/SetLastPingDay functions.
71class ExtensionPrefsLastPingDay : public ExtensionPrefsTest {
72 public:
73  ExtensionPrefsLastPingDay()
74      : extension_time_(Time::Now() - TimeDelta::FromHours(4)),
75        blacklist_time_(Time::Now() - TimeDelta::FromHours(2)) {}
76
77  virtual void Initialize() OVERRIDE {
78    extension_id_ = prefs_.AddExtensionAndReturnId("last_ping_day");
79    EXPECT_TRUE(prefs()->LastPingDay(extension_id_).is_null());
80    prefs()->SetLastPingDay(extension_id_, extension_time_);
81    prefs()->SetBlacklistLastPingDay(blacklist_time_);
82  }
83
84  virtual void Verify() OVERRIDE {
85    Time result = prefs()->LastPingDay(extension_id_);
86    EXPECT_FALSE(result.is_null());
87    EXPECT_TRUE(result == extension_time_);
88    result = prefs()->BlacklistLastPingDay();
89    EXPECT_FALSE(result.is_null());
90    EXPECT_TRUE(result == blacklist_time_);
91  }
92
93 private:
94  Time extension_time_;
95  Time blacklist_time_;
96  std::string extension_id_;
97};
98TEST_F(ExtensionPrefsLastPingDay, LastPingDay) {}
99
100// Tests the GetToolbarOrder/SetToolbarOrder functions.
101class ExtensionPrefsToolbarOrder : public ExtensionPrefsTest {
102 public:
103  virtual void Initialize() OVERRIDE {
104    list_.push_back(prefs_.AddExtensionAndReturnId("1"));
105    list_.push_back(prefs_.AddExtensionAndReturnId("2"));
106    list_.push_back(prefs_.AddExtensionAndReturnId("3"));
107    ExtensionIdList before_list = prefs()->GetToolbarOrder();
108    EXPECT_TRUE(before_list.empty());
109    prefs()->SetToolbarOrder(list_);
110  }
111
112  virtual void Verify() OVERRIDE {
113    ExtensionIdList result = prefs()->GetToolbarOrder();
114    ASSERT_EQ(list_, result);
115  }
116
117 private:
118  ExtensionIdList list_;
119};
120TEST_F(ExtensionPrefsToolbarOrder, ToolbarOrder) {}
121
122// Tests the IsExtensionDisabled/SetExtensionState functions.
123class ExtensionPrefsExtensionState : public ExtensionPrefsTest {
124 public:
125  virtual void Initialize() OVERRIDE {
126    extension = prefs_.AddExtension("test");
127    prefs()->SetExtensionState(extension->id(), Extension::DISABLED);
128  }
129
130  virtual void Verify() OVERRIDE {
131    EXPECT_TRUE(prefs()->IsExtensionDisabled(extension->id()));
132  }
133
134 private:
135  scoped_refptr<Extension> extension;
136};
137TEST_F(ExtensionPrefsExtensionState, ExtensionState) {}
138
139class ExtensionPrefsEscalatePermissions : public ExtensionPrefsTest {
140 public:
141  virtual void Initialize() OVERRIDE {
142    extension = prefs_.AddExtension("test");
143    prefs()->SetDidExtensionEscalatePermissions(extension.get(), true);
144  }
145
146  virtual void Verify() OVERRIDE {
147    EXPECT_TRUE(prefs()->DidExtensionEscalatePermissions(extension->id()));
148  }
149
150 private:
151  scoped_refptr<Extension> extension;
152};
153TEST_F(ExtensionPrefsEscalatePermissions, EscalatePermissions) {}
154
155// Tests the AddGrantedPermissions / GetGrantedPermissions functions.
156class ExtensionPrefsGrantedPermissions : public ExtensionPrefsTest {
157 public:
158  virtual void Initialize() OVERRIDE {
159    const APIPermissionInfo* permission_info =
160      PermissionsInfo::GetInstance()->GetByID(APIPermission::kSocket);
161
162    extension_id_ = prefs_.AddExtensionAndReturnId("test");
163
164    api_perm_set1_.insert(APIPermission::kTab);
165    api_perm_set1_.insert(APIPermission::kBookmark);
166    scoped_ptr<APIPermission> permission(
167        permission_info->CreateAPIPermission());
168    {
169      scoped_ptr<base::ListValue> value(new base::ListValue());
170      value->Append(new base::StringValue("tcp-connect:*.example.com:80"));
171      value->Append(new base::StringValue("udp-bind::8080"));
172      value->Append(new base::StringValue("udp-send-to::8888"));
173      ASSERT_TRUE(permission->FromValue(value.get(), NULL, NULL));
174    }
175    api_perm_set1_.insert(permission.release());
176
177    api_perm_set2_.insert(APIPermission::kHistory);
178
179    AddPattern(&ehost_perm_set1_, "http://*.google.com/*");
180    AddPattern(&ehost_perm_set1_, "http://example.com/*");
181    AddPattern(&ehost_perm_set1_, "chrome://favicon/*");
182
183    AddPattern(&ehost_perm_set2_, "https://*.google.com/*");
184    // with duplicate:
185    AddPattern(&ehost_perm_set2_, "http://*.google.com/*");
186
187    AddPattern(&shost_perm_set1_, "http://reddit.com/r/test/*");
188    AddPattern(&shost_perm_set2_, "http://reddit.com/r/test/*");
189    AddPattern(&shost_perm_set2_, "http://somesite.com/*");
190    AddPattern(&shost_perm_set2_, "http://example.com/*");
191
192    APIPermissionSet expected_apis = api_perm_set1_;
193
194    AddPattern(&ehost_permissions_, "http://*.google.com/*");
195    AddPattern(&ehost_permissions_, "http://example.com/*");
196    AddPattern(&ehost_permissions_, "chrome://favicon/*");
197    AddPattern(&ehost_permissions_, "https://*.google.com/*");
198
199    AddPattern(&shost_permissions_, "http://reddit.com/r/test/*");
200    AddPattern(&shost_permissions_, "http://somesite.com/*");
201    AddPattern(&shost_permissions_, "http://example.com/*");
202
203    APIPermissionSet empty_set;
204    ManifestPermissionSet empty_manifest_permissions;
205    URLPatternSet empty_extent;
206    scoped_refptr<PermissionSet> permissions;
207    scoped_refptr<PermissionSet> granted_permissions;
208
209    // Make sure both granted api and host permissions start empty.
210    granted_permissions =
211        prefs()->GetGrantedPermissions(extension_id_);
212    EXPECT_TRUE(granted_permissions->IsEmpty());
213
214    permissions = new PermissionSet(
215        api_perm_set1_, empty_manifest_permissions, empty_extent, empty_extent);
216
217    // Add part of the api permissions.
218    prefs()->AddGrantedPermissions(extension_id_, permissions.get());
219    granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
220    EXPECT_TRUE(granted_permissions.get());
221    EXPECT_FALSE(granted_permissions->IsEmpty());
222    EXPECT_EQ(expected_apis, granted_permissions->apis());
223    EXPECT_TRUE(granted_permissions->effective_hosts().is_empty());
224    EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess());
225    granted_permissions = NULL;
226
227    // Add part of the explicit host permissions.
228    permissions = new PermissionSet(
229        empty_set, empty_manifest_permissions, ehost_perm_set1_, empty_extent);
230    prefs()->AddGrantedPermissions(extension_id_, permissions.get());
231    granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
232    EXPECT_FALSE(granted_permissions->IsEmpty());
233    EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess());
234    EXPECT_EQ(expected_apis, granted_permissions->apis());
235    EXPECT_EQ(ehost_perm_set1_,
236              granted_permissions->explicit_hosts());
237    EXPECT_EQ(ehost_perm_set1_,
238              granted_permissions->effective_hosts());
239
240    // Add part of the scriptable host permissions.
241    permissions = new PermissionSet(
242        empty_set, empty_manifest_permissions, empty_extent, shost_perm_set1_);
243    prefs()->AddGrantedPermissions(extension_id_, permissions.get());
244    granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
245    EXPECT_FALSE(granted_permissions->IsEmpty());
246    EXPECT_FALSE(granted_permissions->HasEffectiveFullAccess());
247    EXPECT_EQ(expected_apis, granted_permissions->apis());
248    EXPECT_EQ(ehost_perm_set1_,
249              granted_permissions->explicit_hosts());
250    EXPECT_EQ(shost_perm_set1_,
251              granted_permissions->scriptable_hosts());
252
253    URLPatternSet::CreateUnion(ehost_perm_set1_, shost_perm_set1_,
254                               &effective_permissions_);
255    EXPECT_EQ(effective_permissions_, granted_permissions->effective_hosts());
256
257    // Add the rest of the permissions.
258    permissions = new PermissionSet(
259        api_perm_set2_, empty_manifest_permissions,
260        ehost_perm_set2_, shost_perm_set2_);
261
262    APIPermissionSet::Union(expected_apis, api_perm_set2_, &api_permissions_);
263
264    prefs()->AddGrantedPermissions(extension_id_, permissions.get());
265    granted_permissions = prefs()->GetGrantedPermissions(extension_id_);
266    EXPECT_TRUE(granted_permissions.get());
267    EXPECT_FALSE(granted_permissions->IsEmpty());
268    EXPECT_EQ(api_permissions_, granted_permissions->apis());
269    EXPECT_EQ(ehost_permissions_,
270              granted_permissions->explicit_hosts());
271    EXPECT_EQ(shost_permissions_,
272              granted_permissions->scriptable_hosts());
273    effective_permissions_.ClearPatterns();
274    URLPatternSet::CreateUnion(ehost_permissions_, shost_permissions_,
275                               &effective_permissions_);
276    EXPECT_EQ(effective_permissions_, granted_permissions->effective_hosts());
277  }
278
279  virtual void Verify() OVERRIDE {
280    scoped_refptr<PermissionSet> permissions(
281        prefs()->GetGrantedPermissions(extension_id_));
282    EXPECT_TRUE(permissions.get());
283    EXPECT_FALSE(permissions->HasEffectiveFullAccess());
284    EXPECT_EQ(api_permissions_, permissions->apis());
285    EXPECT_EQ(ehost_permissions_,
286              permissions->explicit_hosts());
287    EXPECT_EQ(shost_permissions_,
288              permissions->scriptable_hosts());
289  }
290
291 private:
292  std::string extension_id_;
293  APIPermissionSet api_perm_set1_;
294  APIPermissionSet api_perm_set2_;
295  URLPatternSet ehost_perm_set1_;
296  URLPatternSet ehost_perm_set2_;
297  URLPatternSet shost_perm_set1_;
298  URLPatternSet shost_perm_set2_;
299
300  APIPermissionSet api_permissions_;
301  URLPatternSet ehost_permissions_;
302  URLPatternSet shost_permissions_;
303  URLPatternSet effective_permissions_;
304};
305TEST_F(ExtensionPrefsGrantedPermissions, GrantedPermissions) {}
306
307// Tests the SetActivePermissions / GetActivePermissions functions.
308class ExtensionPrefsActivePermissions : public ExtensionPrefsTest {
309 public:
310  virtual void Initialize() OVERRIDE {
311    extension_id_ = prefs_.AddExtensionAndReturnId("test");
312
313    APIPermissionSet api_perms;
314    api_perms.insert(APIPermission::kTab);
315    api_perms.insert(APIPermission::kBookmark);
316    api_perms.insert(APIPermission::kHistory);
317
318    ManifestPermissionSet empty_manifest_permissions;
319
320    URLPatternSet ehosts;
321    AddPattern(&ehosts, "http://*.google.com/*");
322    AddPattern(&ehosts, "http://example.com/*");
323    AddPattern(&ehosts, "chrome://favicon/*");
324
325    URLPatternSet shosts;
326    AddPattern(&shosts, "https://*.google.com/*");
327    AddPattern(&shosts, "http://reddit.com/r/test/*");
328
329    active_perms_ = new PermissionSet(
330        api_perms, empty_manifest_permissions, ehosts, shosts);
331
332    // Make sure the active permissions start empty.
333    scoped_refptr<PermissionSet> active(
334        prefs()->GetActivePermissions(extension_id_));
335    EXPECT_TRUE(active->IsEmpty());
336
337    // Set the active permissions.
338    prefs()->SetActivePermissions(extension_id_, active_perms_.get());
339    active = prefs()->GetActivePermissions(extension_id_);
340    EXPECT_EQ(active_perms_->apis(), active->apis());
341    EXPECT_EQ(active_perms_->explicit_hosts(), active->explicit_hosts());
342    EXPECT_EQ(active_perms_->scriptable_hosts(), active->scriptable_hosts());
343    EXPECT_EQ(*active_perms_.get(), *active.get());
344  }
345
346  virtual void Verify() OVERRIDE {
347    scoped_refptr<PermissionSet> permissions(
348        prefs()->GetActivePermissions(extension_id_));
349    EXPECT_EQ(*active_perms_.get(), *permissions.get());
350  }
351
352 private:
353  std::string extension_id_;
354  scoped_refptr<PermissionSet> active_perms_;
355};
356TEST_F(ExtensionPrefsActivePermissions, SetAndGetActivePermissions) {}
357
358// Tests the GetVersionString function.
359class ExtensionPrefsVersionString : public ExtensionPrefsTest {
360 public:
361  virtual void Initialize() OVERRIDE {
362    extension = prefs_.AddExtension("test");
363    EXPECT_EQ("0.1", prefs()->GetVersionString(extension->id()));
364    prefs()->OnExtensionUninstalled(extension->id(),
365                                    Manifest::INTERNAL, false);
366  }
367
368  virtual void Verify() OVERRIDE {
369    EXPECT_EQ("", prefs()->GetVersionString(extension->id()));
370  }
371
372 private:
373  scoped_refptr<Extension> extension;
374};
375TEST_F(ExtensionPrefsVersionString, VersionString) {}
376
377class ExtensionPrefsAcknowledgment : public ExtensionPrefsTest {
378 public:
379  virtual void Initialize() OVERRIDE {
380    not_installed_id_ = "pghjnghklobnfoidcldiidjjjhkeeaoi";
381
382    // Install some extensions.
383    for (int i = 0; i < 5; i++) {
384      std::string name = "test" + base::IntToString(i);
385      extensions_.push_back(prefs_.AddExtension(name));
386    }
387    EXPECT_EQ(NULL,
388              prefs()->GetInstalledExtensionInfo(not_installed_id_).get());
389
390    ExtensionList::const_iterator iter;
391    for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
392      std::string id = (*iter)->id();
393      EXPECT_FALSE(prefs()->IsExternalExtensionAcknowledged(id));
394      EXPECT_FALSE(prefs()->IsBlacklistedExtensionAcknowledged(id));
395      if (external_id_.empty()) {
396        external_id_ = id;
397        continue;
398      }
399      if (blacklisted_id_.empty()) {
400        blacklisted_id_ = id;
401        continue;
402      }
403    }
404    // For each type of acknowledgment, acknowledge one installed and one
405    // not-installed extension id.
406    prefs()->AcknowledgeExternalExtension(external_id_);
407    prefs()->AcknowledgeBlacklistedExtension(blacklisted_id_);
408    prefs()->AcknowledgeExternalExtension(not_installed_id_);
409    prefs()->AcknowledgeBlacklistedExtension(not_installed_id_);
410  }
411
412  virtual void Verify() OVERRIDE {
413    ExtensionList::const_iterator iter;
414    for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
415      std::string id = (*iter)->id();
416      if (id == external_id_) {
417        EXPECT_TRUE(prefs()->IsExternalExtensionAcknowledged(id));
418      } else {
419        EXPECT_FALSE(prefs()->IsExternalExtensionAcknowledged(id));
420      }
421      if (id == blacklisted_id_) {
422        EXPECT_TRUE(prefs()->IsBlacklistedExtensionAcknowledged(id));
423      } else {
424        EXPECT_FALSE(prefs()->IsBlacklistedExtensionAcknowledged(id));
425      }
426    }
427    EXPECT_TRUE(prefs()->IsExternalExtensionAcknowledged(not_installed_id_));
428    EXPECT_TRUE(prefs()->IsBlacklistedExtensionAcknowledged(not_installed_id_));
429  }
430
431 private:
432  ExtensionList extensions_;
433
434  std::string not_installed_id_;
435  std::string external_id_;
436  std::string blacklisted_id_;
437};
438TEST_F(ExtensionPrefsAcknowledgment, Acknowledgment) {}
439
440// Tests the idle install information functions.
441class ExtensionPrefsDelayedInstallInfo : public ExtensionPrefsTest {
442 public:
443  // Sets idle install information for one test extension.
444  void SetIdleInfo(const std::string& id, int num) {
445    base::DictionaryValue manifest;
446    manifest.SetString(manifest_keys::kName, "test");
447    manifest.SetString(manifest_keys::kVersion, "1." + base::IntToString(num));
448    base::FilePath path =
449        prefs_.extensions_dir().AppendASCII(base::IntToString(num));
450    std::string errors;
451    scoped_refptr<Extension> extension = Extension::Create(
452        path, Manifest::INTERNAL, manifest, Extension::NO_FLAGS, id, &errors);
453    ASSERT_TRUE(extension.get()) << errors;
454    ASSERT_EQ(id, extension->id());
455    prefs()->SetDelayedInstallInfo(extension.get(),
456                                   Extension::ENABLED,
457                                   kInstallFlagNone,
458                                   ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE,
459                                   syncer::StringOrdinal(),
460                                   std::string());
461  }
462
463  // Verifies that we get back expected idle install information previously
464  // set by SetIdleInfo.
465  void VerifyIdleInfo(const std::string& id, int num) {
466    scoped_ptr<ExtensionInfo> info(prefs()->GetDelayedInstallInfo(id));
467    ASSERT_TRUE(info);
468    std::string version;
469    ASSERT_TRUE(info->extension_manifest->GetString("version", &version));
470    ASSERT_EQ("1." + base::IntToString(num), version);
471    ASSERT_EQ(base::IntToString(num),
472              info->extension_path.BaseName().MaybeAsASCII());
473  }
474
475  bool HasInfoForId(ExtensionPrefs::ExtensionsInfo* info,
476                    const std::string& id) {
477    for (size_t i = 0; i < info->size(); ++i) {
478      if (info->at(i)->extension_id == id)
479        return true;
480    }
481    return false;
482  }
483
484  virtual void Initialize() OVERRIDE {
485    PathService::Get(chrome::DIR_TEST_DATA, &basedir_);
486    now_ = Time::Now();
487    id1_ = prefs_.AddExtensionAndReturnId("1");
488    id2_ = prefs_.AddExtensionAndReturnId("2");
489    id3_ = prefs_.AddExtensionAndReturnId("3");
490    id4_ = prefs_.AddExtensionAndReturnId("4");
491
492    // Set info for two extensions, then remove it.
493    SetIdleInfo(id1_, 1);
494    SetIdleInfo(id2_, 2);
495    VerifyIdleInfo(id1_, 1);
496    VerifyIdleInfo(id2_, 2);
497    scoped_ptr<ExtensionPrefs::ExtensionsInfo> info(
498        prefs()->GetAllDelayedInstallInfo());
499    EXPECT_EQ(2u, info->size());
500    EXPECT_TRUE(HasInfoForId(info.get(), id1_));
501    EXPECT_TRUE(HasInfoForId(info.get(), id2_));
502    prefs()->RemoveDelayedInstallInfo(id1_);
503    prefs()->RemoveDelayedInstallInfo(id2_);
504    info = prefs()->GetAllDelayedInstallInfo();
505    EXPECT_TRUE(info->empty());
506
507    // Try getting/removing info for an id that used to have info set.
508    EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id1_));
509    EXPECT_FALSE(prefs()->RemoveDelayedInstallInfo(id1_));
510
511    // Try getting/removing info for an id that has not yet had any info set.
512    EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id3_));
513    EXPECT_FALSE(prefs()->RemoveDelayedInstallInfo(id3_));
514
515    // Set info for 4 extensions, then remove for one of them.
516    SetIdleInfo(id1_, 1);
517    SetIdleInfo(id2_, 2);
518    SetIdleInfo(id3_, 3);
519    SetIdleInfo(id4_, 4);
520    VerifyIdleInfo(id1_, 1);
521    VerifyIdleInfo(id2_, 2);
522    VerifyIdleInfo(id3_, 3);
523    VerifyIdleInfo(id4_, 4);
524    prefs()->RemoveDelayedInstallInfo(id3_);
525  }
526
527  virtual void Verify() OVERRIDE {
528    // Make sure the info for the 3 extensions we expect is present.
529    scoped_ptr<ExtensionPrefs::ExtensionsInfo> info(
530        prefs()->GetAllDelayedInstallInfo());
531    EXPECT_EQ(3u, info->size());
532    EXPECT_TRUE(HasInfoForId(info.get(), id1_));
533    EXPECT_TRUE(HasInfoForId(info.get(), id2_));
534    EXPECT_TRUE(HasInfoForId(info.get(), id4_));
535    VerifyIdleInfo(id1_, 1);
536    VerifyIdleInfo(id2_, 2);
537    VerifyIdleInfo(id4_, 4);
538
539    // Make sure there isn't info the for the one extension id we removed.
540    EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id3_));
541  }
542
543 protected:
544  Time now_;
545  base::FilePath basedir_;
546  std::string id1_;
547  std::string id2_;
548  std::string id3_;
549  std::string id4_;
550};
551TEST_F(ExtensionPrefsDelayedInstallInfo, DelayedInstallInfo) {}
552
553// Tests the FinishDelayedInstallInfo function.
554class ExtensionPrefsFinishDelayedInstallInfo : public ExtensionPrefsTest {
555 public:
556  virtual void Initialize() OVERRIDE {
557    base::DictionaryValue dictionary;
558    dictionary.SetString(manifest_keys::kName, "test");
559    dictionary.SetString(manifest_keys::kVersion, "0.1");
560    dictionary.SetString(manifest_keys::kBackgroundPage, "background.html");
561    scoped_refptr<Extension> extension =
562        prefs_.AddExtensionWithManifest(dictionary, Manifest::INTERNAL);
563    id_ = extension->id();
564
565
566    // Set idle info
567    base::DictionaryValue manifest;
568    manifest.SetString(manifest_keys::kName, "test");
569    manifest.SetString(manifest_keys::kVersion, "0.2");
570    scoped_ptr<base::ListValue> scripts(new base::ListValue);
571    scripts->AppendString("test.js");
572    manifest.Set(manifest_keys::kBackgroundScripts, scripts.release());
573    base::FilePath path =
574        prefs_.extensions_dir().AppendASCII("test_0.2");
575    std::string errors;
576    scoped_refptr<Extension> new_extension = Extension::Create(
577        path, Manifest::INTERNAL, manifest, Extension::NO_FLAGS, id_, &errors);
578    ASSERT_TRUE(new_extension.get()) << errors;
579    ASSERT_EQ(id_, new_extension->id());
580    prefs()->SetDelayedInstallInfo(new_extension.get(),
581                                   Extension::ENABLED,
582                                   kInstallFlagNone,
583                                   ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE,
584                                   syncer::StringOrdinal(),
585                                   "Param");
586
587    // Finish idle installation
588    ASSERT_TRUE(prefs()->FinishDelayedInstallInfo(id_));
589  }
590
591  virtual void Verify() OVERRIDE {
592    EXPECT_FALSE(prefs()->GetDelayedInstallInfo(id_));
593    EXPECT_EQ(std::string("Param"), prefs()->GetInstallParam(id_));
594
595    const base::DictionaryValue* manifest;
596    ASSERT_TRUE(prefs()->ReadPrefAsDictionary(id_, "manifest", &manifest));
597    ASSERT_TRUE(manifest);
598    std::string value;
599    EXPECT_TRUE(manifest->GetString(manifest_keys::kName, &value));
600    EXPECT_EQ("test", value);
601    EXPECT_TRUE(manifest->GetString(manifest_keys::kVersion, &value));
602    EXPECT_EQ("0.2", value);
603    EXPECT_FALSE(manifest->GetString(manifest_keys::kBackgroundPage, &value));
604    const base::ListValue* scripts;
605    ASSERT_TRUE(manifest->GetList(manifest_keys::kBackgroundScripts, &scripts));
606    EXPECT_EQ(1u, scripts->GetSize());
607  }
608
609 protected:
610  std::string id_;
611};
612TEST_F(ExtensionPrefsFinishDelayedInstallInfo, FinishDelayedInstallInfo) {}
613
614class ExtensionPrefsOnExtensionInstalled : public ExtensionPrefsTest {
615 public:
616  virtual void Initialize() OVERRIDE {
617    extension_ = prefs_.AddExtension("on_extension_installed");
618    EXPECT_FALSE(prefs()->IsExtensionDisabled(extension_->id()));
619    prefs()->OnExtensionInstalled(extension_.get(),
620                                  Extension::DISABLED,
621                                  syncer::StringOrdinal(),
622                                  "Param");
623  }
624
625  virtual void Verify() OVERRIDE {
626    EXPECT_TRUE(prefs()->IsExtensionDisabled(extension_->id()));
627    EXPECT_EQ(std::string("Param"), prefs()->GetInstallParam(extension_->id()));
628  }
629
630 private:
631  scoped_refptr<Extension> extension_;
632};
633TEST_F(ExtensionPrefsOnExtensionInstalled,
634       ExtensionPrefsOnExtensionInstalled) {}
635
636class ExtensionPrefsAppDraggedByUser : public ExtensionPrefsTest {
637 public:
638  virtual void Initialize() OVERRIDE {
639    extension_ = prefs_.AddExtension("on_extension_installed");
640    EXPECT_FALSE(prefs()->WasAppDraggedByUser(extension_->id()));
641    prefs()->OnExtensionInstalled(extension_.get(),
642                                  Extension::ENABLED,
643                                  syncer::StringOrdinal(),
644                                  std::string());
645  }
646
647  virtual void Verify() OVERRIDE {
648    // Set the flag and see if it persisted.
649    prefs()->SetAppDraggedByUser(extension_->id());
650    EXPECT_TRUE(prefs()->WasAppDraggedByUser(extension_->id()));
651
652    // Make sure it doesn't change on consecutive calls.
653    prefs()->SetAppDraggedByUser(extension_->id());
654    EXPECT_TRUE(prefs()->WasAppDraggedByUser(extension_->id()));
655  }
656
657 private:
658  scoped_refptr<Extension> extension_;
659};
660TEST_F(ExtensionPrefsAppDraggedByUser, ExtensionPrefsAppDraggedByUser) {}
661
662class ExtensionPrefsFlags : public ExtensionPrefsTest {
663 public:
664  virtual void Initialize() OVERRIDE {
665    {
666      base::DictionaryValue dictionary;
667      dictionary.SetString(manifest_keys::kName, "from_webstore");
668      dictionary.SetString(manifest_keys::kVersion, "0.1");
669      webstore_extension_ = prefs_.AddExtensionWithManifestAndFlags(
670          dictionary, Manifest::INTERNAL, Extension::FROM_WEBSTORE);
671    }
672
673    {
674      base::DictionaryValue dictionary;
675      dictionary.SetString(manifest_keys::kName, "from_bookmark");
676      dictionary.SetString(manifest_keys::kVersion, "0.1");
677      bookmark_extension_ = prefs_.AddExtensionWithManifestAndFlags(
678          dictionary, Manifest::INTERNAL, Extension::FROM_BOOKMARK);
679    }
680
681    {
682      base::DictionaryValue dictionary;
683      dictionary.SetString(manifest_keys::kName, "was_installed_by_default");
684      dictionary.SetString(manifest_keys::kVersion, "0.1");
685      default_extension_ = prefs_.AddExtensionWithManifestAndFlags(
686          dictionary,
687          Manifest::INTERNAL,
688          Extension::WAS_INSTALLED_BY_DEFAULT);
689    }
690
691    {
692      base::DictionaryValue dictionary;
693      dictionary.SetString(manifest_keys::kName, "was_installed_by_oem");
694      dictionary.SetString(manifest_keys::kVersion, "0.1");
695      oem_extension_ = prefs_.AddExtensionWithManifestAndFlags(
696          dictionary, Manifest::INTERNAL, Extension::WAS_INSTALLED_BY_OEM);
697    }
698  }
699
700  virtual void Verify() OVERRIDE {
701    EXPECT_TRUE(prefs()->IsFromWebStore(webstore_extension_->id()));
702    EXPECT_FALSE(prefs()->IsFromBookmark(webstore_extension_->id()));
703
704    EXPECT_TRUE(prefs()->IsFromBookmark(bookmark_extension_->id()));
705    EXPECT_FALSE(prefs()->IsFromWebStore(bookmark_extension_->id()));
706
707    EXPECT_TRUE(prefs()->WasInstalledByDefault(default_extension_->id()));
708    EXPECT_TRUE(prefs()->WasInstalledByOem(oem_extension_->id()));
709  }
710
711 private:
712  scoped_refptr<Extension> webstore_extension_;
713  scoped_refptr<Extension> bookmark_extension_;
714  scoped_refptr<Extension> default_extension_;
715  scoped_refptr<Extension> oem_extension_;
716};
717TEST_F(ExtensionPrefsFlags, ExtensionPrefsFlags) {}
718
719PrefsPrepopulatedTestBase::PrefsPrepopulatedTestBase()
720    : ExtensionPrefsTest() {
721  base::DictionaryValue simple_dict;
722  std::string error;
723
724  simple_dict.SetString(manifest_keys::kVersion, "1.0.0.0");
725  simple_dict.SetString(manifest_keys::kName, "unused");
726
727  extension1_ = Extension::Create(
728      prefs_.temp_dir().AppendASCII("ext1_"),
729      Manifest::EXTERNAL_PREF,
730      simple_dict,
731      Extension::NO_FLAGS,
732      &error);
733  extension2_ = Extension::Create(
734      prefs_.temp_dir().AppendASCII("ext2_"),
735      Manifest::EXTERNAL_PREF,
736      simple_dict,
737      Extension::NO_FLAGS,
738      &error);
739  extension3_ = Extension::Create(
740      prefs_.temp_dir().AppendASCII("ext3_"),
741      Manifest::EXTERNAL_PREF,
742      simple_dict,
743      Extension::NO_FLAGS,
744      &error);
745  extension4_ = Extension::Create(
746      prefs_.temp_dir().AppendASCII("ext4_"),
747      Manifest::EXTERNAL_PREF,
748      simple_dict,
749      Extension::NO_FLAGS,
750      &error);
751
752  for (size_t i = 0; i < kNumInstalledExtensions; ++i)
753    installed_[i] = false;
754}
755
756PrefsPrepopulatedTestBase::~PrefsPrepopulatedTestBase() {
757}
758
759// Tests that blacklist state can be queried.
760class ExtensionPrefsBlacklistedExtensions : public ExtensionPrefsTest {
761 public:
762  virtual ~ExtensionPrefsBlacklistedExtensions() {}
763
764  virtual void Initialize() OVERRIDE {
765    extension_a_ = prefs_.AddExtension("a");
766    extension_b_ = prefs_.AddExtension("b");
767    extension_c_ = prefs_.AddExtension("c");
768  }
769
770  virtual void Verify() OVERRIDE {
771    {
772      ExtensionIdSet ids;
773      EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
774    }
775    prefs()->SetExtensionBlacklisted(extension_a_->id(), true);
776    {
777      ExtensionIdSet ids;
778      ids.insert(extension_a_->id());
779      EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
780    }
781    prefs()->SetExtensionBlacklisted(extension_b_->id(), true);
782    prefs()->SetExtensionBlacklisted(extension_c_->id(), true);
783    {
784      ExtensionIdSet ids;
785      ids.insert(extension_a_->id());
786      ids.insert(extension_b_->id());
787      ids.insert(extension_c_->id());
788      EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
789    }
790    prefs()->SetExtensionBlacklisted(extension_a_->id(), false);
791    {
792      ExtensionIdSet ids;
793      ids.insert(extension_b_->id());
794      ids.insert(extension_c_->id());
795      EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
796    }
797    prefs()->SetExtensionBlacklisted(extension_b_->id(), false);
798    prefs()->SetExtensionBlacklisted(extension_c_->id(), false);
799    {
800      ExtensionIdSet ids;
801      EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
802    }
803
804    // The interesting part: make sure that we're cleaning up after ourselves
805    // when we're storing *just* the fact that the extension is blacklisted.
806    std::string arbitrary_id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
807
808    prefs()->SetExtensionBlacklisted(arbitrary_id, true);
809    prefs()->SetExtensionBlacklisted(extension_a_->id(), true);
810
811    // (And make sure that the acknowledged bit is also cleared).
812    prefs()->AcknowledgeBlacklistedExtension(arbitrary_id);
813
814    EXPECT_TRUE(prefs()->GetExtensionPref(arbitrary_id));
815    {
816      ExtensionIdSet ids;
817      ids.insert(arbitrary_id);
818      ids.insert(extension_a_->id());
819      EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
820    }
821    prefs()->SetExtensionBlacklisted(arbitrary_id, false);
822    prefs()->SetExtensionBlacklisted(extension_a_->id(), false);
823    EXPECT_FALSE(prefs()->GetExtensionPref(arbitrary_id));
824    {
825      ExtensionIdSet ids;
826      EXPECT_EQ(ids, prefs()->GetBlacklistedExtensions());
827    }
828  }
829
830 private:
831  scoped_refptr<const Extension> extension_a_;
832  scoped_refptr<const Extension> extension_b_;
833  scoped_refptr<const Extension> extension_c_;
834};
835TEST_F(ExtensionPrefsBlacklistedExtensions,
836       ExtensionPrefsBlacklistedExtensions) {}
837
838// Tests the blacklist state. Old "blacklist" preference should take precedence
839// over new "blacklist_state".
840class ExtensionPrefsBlacklistState : public ExtensionPrefsTest {
841 public:
842  virtual ~ExtensionPrefsBlacklistState() {}
843
844  virtual void Initialize() OVERRIDE {
845    extension_a_ = prefs_.AddExtension("a");
846  }
847
848  virtual void Verify() OVERRIDE {
849    ExtensionIdSet empty_ids;
850    EXPECT_EQ(empty_ids, prefs()->GetBlacklistedExtensions());
851
852    prefs()->SetExtensionBlacklisted(extension_a_->id(), true);
853    EXPECT_EQ(BLACKLISTED_MALWARE,
854              prefs()->GetExtensionBlacklistState(extension_a_->id()));
855
856    prefs()->SetExtensionBlacklistState(extension_a_->id(),
857                                        BLACKLISTED_POTENTIALLY_UNWANTED);
858    EXPECT_EQ(BLACKLISTED_POTENTIALLY_UNWANTED,
859              prefs()->GetExtensionBlacklistState(extension_a_->id()));
860    EXPECT_FALSE(prefs()->IsExtensionBlacklisted(extension_a_->id()));
861    EXPECT_EQ(empty_ids, prefs()->GetBlacklistedExtensions());
862
863    prefs()->SetExtensionBlacklisted(extension_a_->id(), true);
864    EXPECT_TRUE(prefs()->IsExtensionBlacklisted(extension_a_->id()));
865    EXPECT_EQ(BLACKLISTED_MALWARE,
866              prefs()->GetExtensionBlacklistState(extension_a_->id()));
867    EXPECT_EQ(1u, prefs()->GetBlacklistedExtensions().size());
868
869    prefs()->SetExtensionBlacklistState(extension_a_->id(),
870                                        NOT_BLACKLISTED);
871    EXPECT_EQ(NOT_BLACKLISTED,
872              prefs()->GetExtensionBlacklistState(extension_a_->id()));
873    EXPECT_FALSE(prefs()->IsExtensionBlacklisted(extension_a_->id()));
874    EXPECT_EQ(empty_ids, prefs()->GetBlacklistedExtensions());
875  }
876
877 private:
878  scoped_refptr<const Extension> extension_a_;
879};
880TEST_F(ExtensionPrefsBlacklistState, ExtensionPrefsBlacklistState) {}
881
882}  // namespace extensions
883