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 "base/memory/scoped_temp_dir.h"
6#include "base/message_loop.h"
7#include "base/path_service.h"
8#include "base/stl_util-inl.h"
9#include "base/string_number_conversions.h"
10#include "base/stringprintf.h"
11#include "chrome/browser/extensions/extension_prefs.h"
12#include "chrome/browser/extensions/test_extension_prefs.h"
13#include "chrome/browser/prefs/pref_change_registrar.h"
14#include "chrome/browser/prefs/scoped_user_pref_update.h"
15#include "chrome/common/chrome_paths.h"
16#include "chrome/common/extensions/extension_constants.h"
17#include "content/common/notification_details.h"
18#include "content/common/notification_observer_mock.h"
19#include "content/common/notification_source.h"
20#include "content/browser/browser_thread.h"
21#include "testing/gtest/include/gtest/gtest.h"
22
23using base::Time;
24using base::TimeDelta;
25
26namespace {
27
28const char kPref1[] = "path1.subpath";
29const char kPref2[] = "path2";
30const char kPref3[] = "path3";
31const char kPref4[] = "path4";
32
33// Default values in case an extension pref value is not overridden.
34const char kDefaultPref1[] = "default pref 1";
35const char kDefaultPref2[] = "default pref 2";
36const char kDefaultPref3[] = "default pref 3";
37const char kDefaultPref4[] = "default pref 4";
38
39}  // namespace
40
41static void AddPattern(ExtensionExtent* extent, const std::string& pattern) {
42  int schemes = URLPattern::SCHEME_ALL;
43  extent->AddPattern(URLPattern(schemes, pattern));
44}
45
46static void AssertEqualExtents(ExtensionExtent* extent1,
47                               ExtensionExtent* extent2) {
48  std::vector<URLPattern> patterns1 = extent1->patterns();
49  std::vector<URLPattern> patterns2 = extent2->patterns();
50  std::set<std::string> strings1;
51  EXPECT_EQ(patterns1.size(), patterns2.size());
52
53  for (size_t i = 0; i < patterns1.size(); ++i)
54    strings1.insert(patterns1.at(i).GetAsString());
55
56  std::set<std::string> strings2;
57  for (size_t i = 0; i < patterns2.size(); ++i)
58    strings2.insert(patterns2.at(i).GetAsString());
59
60  EXPECT_EQ(strings1, strings2);
61}
62
63// Base class for tests.
64class ExtensionPrefsTest : public testing::Test {
65 public:
66  ExtensionPrefsTest()
67      : ui_thread_(BrowserThread::UI, &message_loop_),
68        file_thread_(BrowserThread::FILE, &message_loop_) {
69  }
70
71  // This function will get called once, and is the right place to do operations
72  // on ExtensionPrefs that write data.
73  virtual void Initialize() = 0;
74
75  // This function will be called twice - once while the original ExtensionPrefs
76  // object is still alive, and once after recreation. Thus, it tests that
77  // things don't break after any ExtensionPrefs startup work.
78  virtual void Verify() = 0;
79
80  // This function is called to Register preference default values.
81  virtual void RegisterPreferences() {}
82
83  virtual void SetUp() {
84    RegisterPreferences();
85    Initialize();
86  }
87
88  virtual void TearDown() {
89    Verify();
90
91    // Reset ExtensionPrefs, and re-verify.
92    prefs_.RecreateExtensionPrefs();
93    RegisterPreferences();
94    Verify();
95  }
96
97 protected:
98  ExtensionPrefs* prefs() { return prefs_.prefs(); }
99
100  MessageLoop message_loop_;
101  BrowserThread ui_thread_;
102  BrowserThread file_thread_;
103
104  TestExtensionPrefs prefs_;
105
106 private:
107  DISALLOW_COPY_AND_ASSIGN(ExtensionPrefsTest);
108};
109
110// Tests the LastPingDay/SetLastPingDay functions.
111class ExtensionPrefsLastPingDay : public ExtensionPrefsTest {
112 public:
113  ExtensionPrefsLastPingDay()
114      : extension_time_(Time::Now() - TimeDelta::FromHours(4)),
115        blacklist_time_(Time::Now() - TimeDelta::FromHours(2)) {}
116
117  virtual void Initialize() {
118    extension_id_ = prefs_.AddExtensionAndReturnId("last_ping_day");
119    EXPECT_TRUE(prefs()->LastPingDay(extension_id_).is_null());
120    prefs()->SetLastPingDay(extension_id_, extension_time_);
121    prefs()->SetBlacklistLastPingDay(blacklist_time_);
122  }
123
124  virtual void Verify() {
125    Time result = prefs()->LastPingDay(extension_id_);
126    EXPECT_FALSE(result.is_null());
127    EXPECT_TRUE(result == extension_time_);
128    result = prefs()->BlacklistLastPingDay();
129    EXPECT_FALSE(result.is_null());
130    EXPECT_TRUE(result == blacklist_time_);
131  }
132
133 private:
134  Time extension_time_;
135  Time blacklist_time_;
136  std::string extension_id_;
137};
138TEST_F(ExtensionPrefsLastPingDay, LastPingDay) {}
139
140
141// Tests the GetToolbarOrder/SetToolbarOrder functions.
142class ExtensionPrefsToolbarOrder : public ExtensionPrefsTest {
143 public:
144  virtual void Initialize() {
145    list_.push_back(prefs_.AddExtensionAndReturnId("1"));
146    list_.push_back(prefs_.AddExtensionAndReturnId("2"));
147    list_.push_back(prefs_.AddExtensionAndReturnId("3"));
148    std::vector<std::string> before_list = prefs()->GetToolbarOrder();
149    EXPECT_TRUE(before_list.empty());
150    prefs()->SetToolbarOrder(list_);
151  }
152
153  virtual void Verify() {
154    std::vector<std::string> result = prefs()->GetToolbarOrder();
155    ASSERT_EQ(list_.size(), result.size());
156    for (size_t i = 0; i < list_.size(); i++) {
157      EXPECT_EQ(list_[i], result[i]);
158    }
159  }
160
161 private:
162  std::vector<std::string> list_;
163};
164TEST_F(ExtensionPrefsToolbarOrder, ToolbarOrder) {}
165
166
167// Tests the GetExtensionState/SetExtensionState functions.
168class ExtensionPrefsExtensionState : public ExtensionPrefsTest {
169 public:
170  virtual void Initialize() {
171    extension = prefs_.AddExtension("test");
172    prefs()->SetExtensionState(extension.get(), Extension::DISABLED);
173  }
174
175  virtual void Verify() {
176    EXPECT_EQ(Extension::DISABLED, prefs()->GetExtensionState(extension->id()));
177  }
178
179 private:
180  scoped_refptr<Extension> extension;
181};
182TEST_F(ExtensionPrefsExtensionState, ExtensionState) {}
183
184
185class ExtensionPrefsEscalatePermissions : public ExtensionPrefsTest {
186 public:
187  virtual void Initialize() {
188    extension = prefs_.AddExtension("test");
189    prefs()->SetDidExtensionEscalatePermissions(extension.get(), true);
190  }
191
192  virtual void Verify() {
193    EXPECT_TRUE(prefs()->DidExtensionEscalatePermissions(extension->id()));
194  }
195
196 private:
197  scoped_refptr<Extension> extension;
198};
199TEST_F(ExtensionPrefsEscalatePermissions, EscalatePermissions) {}
200
201// Tests the AddGrantedPermissions / GetGrantedPermissions functions.
202class ExtensionPrefsGrantedPermissions : public ExtensionPrefsTest {
203 public:
204  virtual void Initialize() {
205    extension_id_ = prefs_.AddExtensionAndReturnId("test");
206
207    api_perm_set1_.insert("tabs");
208    api_perm_set1_.insert("bookmarks");
209    api_perm_set1_.insert("something_random");
210
211    api_perm_set2_.insert("history");
212    api_perm_set2_.insert("unknown2");
213
214    AddPattern(&host_perm_set1_, "http://*.google.com/*");
215    AddPattern(&host_perm_set1_, "http://example.com/*");
216    AddPattern(&host_perm_set1_, "chrome://favicon/*");
217
218    AddPattern(&host_perm_set2_, "https://*.google.com/*");
219    // with duplicate:
220    AddPattern(&host_perm_set2_, "http://*.google.com/*");
221
222    std::set_union(api_perm_set1_.begin(), api_perm_set1_.end(),
223                   api_perm_set2_.begin(), api_perm_set2_.end(),
224                   std::inserter(api_permissions_, api_permissions_.begin()));
225
226    AddPattern(&host_permissions_, "http://*.google.com/*");
227    AddPattern(&host_permissions_, "http://example.com/*");
228    AddPattern(&host_permissions_, "chrome://favicon/*");
229    AddPattern(&host_permissions_, "https://*.google.com/*");
230
231    std::set<std::string> empty_set;
232    std::set<std::string> api_perms;
233    bool full_access = false;
234    ExtensionExtent host_perms;
235    ExtensionExtent empty_extent;
236
237    // Make sure both granted api and host permissions start empty.
238    EXPECT_FALSE(prefs()->GetGrantedPermissions(
239        extension_id_, &full_access, &api_perms, &host_perms));
240
241    EXPECT_TRUE(api_perms.empty());
242    EXPECT_TRUE(host_perms.is_empty());
243
244    // Add part of the api permissions.
245    prefs()->AddGrantedPermissions(
246        extension_id_, false, api_perm_set1_, empty_extent);
247    EXPECT_TRUE(prefs()->GetGrantedPermissions(
248        extension_id_, &full_access, &api_perms, &host_perms));
249    EXPECT_EQ(api_perm_set1_, api_perms);
250    EXPECT_TRUE(host_perms.is_empty());
251    EXPECT_FALSE(full_access);
252    host_perms.ClearPaths();
253    api_perms.clear();
254
255    // Add part of the host permissions.
256    prefs()->AddGrantedPermissions(
257        extension_id_, false, empty_set, host_perm_set1_);
258    EXPECT_TRUE(prefs()->GetGrantedPermissions(
259        extension_id_, &full_access, &api_perms, &host_perms));
260    EXPECT_FALSE(full_access);
261    EXPECT_EQ(api_perm_set1_, api_perms);
262    AssertEqualExtents(&host_perm_set1_, &host_perms);
263    host_perms.ClearPaths();
264    api_perms.clear();
265
266    // Add the rest of both the api and host permissions.
267    prefs()->AddGrantedPermissions(extension_id_,
268                                   true,
269                                   api_perm_set2_,
270                                   host_perm_set2_);
271
272    EXPECT_TRUE(prefs()->GetGrantedPermissions(
273        extension_id_, &full_access, &api_perms, &host_perms));
274    EXPECT_TRUE(full_access);
275    EXPECT_EQ(api_permissions_, api_perms);
276    AssertEqualExtents(&host_permissions_, &host_perms);
277  }
278
279  virtual void Verify() {
280    std::set<std::string> api_perms;
281    ExtensionExtent host_perms;
282    bool full_access;
283
284    EXPECT_TRUE(prefs()->GetGrantedPermissions(
285        extension_id_, &full_access, &api_perms, &host_perms));
286    EXPECT_EQ(api_permissions_, api_perms);
287    EXPECT_TRUE(full_access);
288    AssertEqualExtents(&host_permissions_, &host_perms);
289  }
290
291 private:
292  std::string extension_id_;
293  std::set<std::string> api_perm_set1_;
294  std::set<std::string> api_perm_set2_;
295  ExtensionExtent host_perm_set1_;
296  ExtensionExtent host_perm_set2_;
297
298
299  std::set<std::string> api_permissions_;
300  ExtensionExtent host_permissions_;
301};
302TEST_F(ExtensionPrefsGrantedPermissions, GrantedPermissions) {}
303
304// Tests the GetVersionString function.
305class ExtensionPrefsVersionString : public ExtensionPrefsTest {
306 public:
307  virtual void Initialize() {
308    extension = prefs_.AddExtension("test");
309    EXPECT_EQ("0.1", prefs()->GetVersionString(extension->id()));
310    prefs()->OnExtensionUninstalled(extension->id(),
311                                    Extension::INTERNAL, false);
312  }
313
314  virtual void Verify() {
315    EXPECT_EQ("", prefs()->GetVersionString(extension->id()));
316  }
317
318 private:
319  scoped_refptr<Extension> extension;
320};
321TEST_F(ExtensionPrefsVersionString, VersionString) {}
322
323// Tests various areas of blacklist functionality.
324class ExtensionPrefsBlacklist : public ExtensionPrefsTest {
325 public:
326  virtual void Initialize() {
327    not_installed_id_ = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
328
329    // Install 5 extensions.
330    for (int i = 0; i < 5; i++) {
331      std::string name = "test" + base::IntToString(i);
332      extensions_.push_back(prefs_.AddExtension(name));
333    }
334    EXPECT_EQ(NULL, prefs()->GetInstalledExtensionInfo(not_installed_id_));
335
336    ExtensionList::const_iterator iter;
337    for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
338      EXPECT_FALSE(prefs()->IsExtensionBlacklisted((*iter)->id()));
339    }
340    // Blacklist one installed and one not-installed extension id.
341    std::set<std::string> blacklisted_ids;
342    blacklisted_ids.insert(extensions_[0]->id());
343    blacklisted_ids.insert(not_installed_id_);
344    prefs()->UpdateBlacklist(blacklisted_ids);
345  }
346
347  virtual void Verify() {
348    // Make sure the two id's we expect to be blacklisted are.
349    EXPECT_TRUE(prefs()->IsExtensionBlacklisted(extensions_[0]->id()));
350    EXPECT_TRUE(prefs()->IsExtensionBlacklisted(not_installed_id_));
351
352    // Make sure the other id's are not blacklisted.
353    ExtensionList::const_iterator iter;
354    for (iter = extensions_.begin() + 1; iter != extensions_.end(); ++iter) {
355      EXPECT_FALSE(prefs()->IsExtensionBlacklisted((*iter)->id()));
356    }
357
358    // Make sure GetInstalledExtensionsInfo returns only the non-blacklisted
359    // extensions data.
360    scoped_ptr<ExtensionPrefs::ExtensionsInfo> info(
361        prefs()->GetInstalledExtensionsInfo());
362    EXPECT_EQ(4u, info->size());
363    ExtensionPrefs::ExtensionsInfo::iterator info_iter;
364    for (info_iter = info->begin(); info_iter != info->end(); ++info_iter) {
365      ExtensionInfo* extension_info = info_iter->get();
366      EXPECT_NE(extensions_[0]->id(), extension_info->extension_id);
367    }
368  }
369
370 private:
371  ExtensionList extensions_;
372
373  // An id we'll make up that doesn't match any installed extension id.
374  std::string not_installed_id_;
375};
376TEST_F(ExtensionPrefsBlacklist, Blacklist) {}
377
378// Tests force hiding browser actions.
379class ExtensionPrefsHidingBrowserActions : public ExtensionPrefsTest {
380 public:
381  virtual void Initialize() {
382    // Install 5 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
388    ExtensionList::const_iterator iter;
389    for (iter = extensions_.begin(); iter != extensions_.end(); ++iter)
390      EXPECT_TRUE(prefs()->GetBrowserActionVisibility(*iter));
391
392    prefs()->SetBrowserActionVisibility(extensions_[0], false);
393    prefs()->SetBrowserActionVisibility(extensions_[1], true);
394  }
395
396  virtual void Verify() {
397    // Make sure the one we hid is hidden.
398    EXPECT_FALSE(prefs()->GetBrowserActionVisibility(extensions_[0]));
399
400    // Make sure the other id's are not hidden.
401    ExtensionList::const_iterator iter = extensions_.begin() + 1;
402    for (; iter != extensions_.end(); ++iter) {
403      SCOPED_TRACE(base::StringPrintf("Loop %d ",
404                       static_cast<int>(iter - extensions_.begin())));
405      EXPECT_TRUE(prefs()->GetBrowserActionVisibility(*iter));
406    }
407  }
408
409 private:
410  ExtensionList extensions_;
411};
412TEST_F(ExtensionPrefsHidingBrowserActions, ForceHide) {}
413
414// Tests the idle install information functions.
415class ExtensionPrefsIdleInstallInfo : public ExtensionPrefsTest {
416 public:
417  // Sets idle install information for one test extension.
418  void SetIdleInfo(std::string id, int num) {
419    prefs()->SetIdleInstallInfo(id,
420                                basedir_.AppendASCII(base::IntToString(num)),
421                                "1." + base::IntToString(num),
422                                now_ + TimeDelta::FromSeconds(num));
423  }
424
425  // Verifies that we get back expected idle install information previously
426  // set by SetIdleInfo.
427  void VerifyIdleInfo(std::string id, int num) {
428    FilePath crx_path;
429    std::string version;
430    base::Time fetch_time;
431    ASSERT_TRUE(prefs()->GetIdleInstallInfo(id, &crx_path, &version,
432                                            &fetch_time));
433    ASSERT_EQ(crx_path.value(),
434              basedir_.AppendASCII(base::IntToString(num)).value());
435    ASSERT_EQ("1." + base::IntToString(num), version);
436    ASSERT_TRUE(fetch_time == now_ + TimeDelta::FromSeconds(num));
437  }
438
439  virtual void Initialize() {
440    PathService::Get(chrome::DIR_TEST_DATA, &basedir_);
441    now_ = Time::Now();
442    id1_ = prefs_.AddExtensionAndReturnId("1");
443    id2_ = prefs_.AddExtensionAndReturnId("2");
444    id3_ = prefs_.AddExtensionAndReturnId("3");
445    id4_ = prefs_.AddExtensionAndReturnId("4");
446
447    // Set info for two extensions, then remove it.
448    SetIdleInfo(id1_, 1);
449    SetIdleInfo(id2_, 2);
450    VerifyIdleInfo(id1_, 1);
451    VerifyIdleInfo(id2_, 2);
452    std::set<std::string> ids = prefs()->GetIdleInstallInfoIds();
453    EXPECT_EQ(2u, ids.size());
454    EXPECT_TRUE(ContainsKey(ids, id1_));
455    EXPECT_TRUE(ContainsKey(ids, id2_));
456    prefs()->RemoveIdleInstallInfo(id1_);
457    prefs()->RemoveIdleInstallInfo(id2_);
458    ids = prefs()->GetIdleInstallInfoIds();
459    EXPECT_TRUE(ids.empty());
460
461    // Try getting/removing info for an id that used to have info set.
462    EXPECT_FALSE(prefs()->GetIdleInstallInfo(id1_, NULL, NULL, NULL));
463    EXPECT_FALSE(prefs()->RemoveIdleInstallInfo(id1_));
464
465    // Try getting/removing info for an id that has not yet had any info set.
466    EXPECT_FALSE(prefs()->GetIdleInstallInfo(id3_, NULL, NULL, NULL));
467    EXPECT_FALSE(prefs()->RemoveIdleInstallInfo(id3_));
468
469    // Set info for 4 extensions, then remove for one of them.
470    SetIdleInfo(id1_, 1);
471    SetIdleInfo(id2_, 2);
472    SetIdleInfo(id3_, 3);
473    SetIdleInfo(id4_, 4);
474    VerifyIdleInfo(id1_, 1);
475    VerifyIdleInfo(id2_, 2);
476    VerifyIdleInfo(id3_, 3);
477    VerifyIdleInfo(id4_, 4);
478    prefs()->RemoveIdleInstallInfo(id3_);
479  }
480
481  virtual void Verify() {
482    // Make sure the info for the 3 extensions we expect is present.
483    std::set<std::string> ids = prefs()->GetIdleInstallInfoIds();
484    EXPECT_EQ(3u, ids.size());
485    EXPECT_TRUE(ContainsKey(ids, id1_));
486    EXPECT_TRUE(ContainsKey(ids, id2_));
487    EXPECT_TRUE(ContainsKey(ids, id4_));
488    VerifyIdleInfo(id1_, 1);
489    VerifyIdleInfo(id2_, 2);
490    VerifyIdleInfo(id4_, 4);
491
492    // Make sure there isn't info the for the one extension id we removed.
493    EXPECT_FALSE(prefs()->GetIdleInstallInfo(id3_, NULL, NULL, NULL));
494  }
495
496 protected:
497  Time now_;
498  FilePath basedir_;
499  std::string id1_;
500  std::string id2_;
501  std::string id3_;
502  std::string id4_;
503};
504TEST_F(ExtensionPrefsIdleInstallInfo, IdleInstallInfo) {}
505
506class ExtensionPrefsOnExtensionInstalled : public ExtensionPrefsTest {
507 public:
508  virtual void Initialize() {
509    extension_ = prefs_.AddExtension("on_extension_installed");
510    EXPECT_EQ(Extension::ENABLED,
511              prefs()->GetExtensionState(extension_->id()));
512    EXPECT_FALSE(prefs()->IsIncognitoEnabled(extension_->id()));
513    prefs()->OnExtensionInstalled(extension_.get(),
514                                  Extension::DISABLED, true);
515  }
516
517  virtual void Verify() {
518    EXPECT_EQ(Extension::DISABLED,
519              prefs()->GetExtensionState(extension_->id()));
520    EXPECT_TRUE(prefs()->IsIncognitoEnabled(extension_->id()));
521  }
522
523 private:
524  scoped_refptr<Extension> extension_;
525};
526TEST_F(ExtensionPrefsOnExtensionInstalled,
527       ExtensionPrefsOnExtensionInstalled) {}
528
529class ExtensionPrefsAppLaunchIndex : public ExtensionPrefsTest {
530 public:
531  virtual void Initialize() {
532    // No extensions yet.
533    EXPECT_EQ(0, prefs()->GetNextAppLaunchIndex());
534
535    extension_ = prefs_.AddExtension("on_extension_installed");
536    EXPECT_EQ(Extension::ENABLED,
537        prefs()->GetExtensionState(extension_->id()));
538    prefs()->OnExtensionInstalled(extension_.get(),
539        Extension::ENABLED, false);
540  }
541
542  virtual void Verify() {
543    int launch_index = prefs()->GetAppLaunchIndex(extension_->id());
544    // Extension should have been assigned a launch index > 0.
545    EXPECT_GT(launch_index, 0);
546    EXPECT_EQ(launch_index + 1, prefs()->GetNextAppLaunchIndex());
547    // Set a new launch index of one higher and verify.
548    prefs()->SetAppLaunchIndex(extension_->id(),
549        prefs()->GetNextAppLaunchIndex());
550    int new_launch_index = prefs()->GetAppLaunchIndex(extension_->id());
551    EXPECT_EQ(launch_index + 1, new_launch_index);
552
553    // This extension doesn't exist, so it should return -1.
554    EXPECT_EQ(-1, prefs()->GetAppLaunchIndex("foo"));
555  }
556
557 private:
558  scoped_refptr<Extension> extension_;
559};
560TEST_F(ExtensionPrefsAppLaunchIndex, ExtensionPrefsAppLaunchIndex) {}
561
562class ExtensionPrefsPageIndex : public ExtensionPrefsTest {
563 public:
564  virtual void Initialize() {
565    extension_id_ = prefs_.AddExtensionAndReturnId("page_index");
566
567    int page_index = prefs()->GetPageIndex(extension_id_);
568    // Extension should not have been assigned a page
569    EXPECT_EQ(page_index, -1);
570
571    // Set the page index
572    prefs()->SetPageIndex(extension_id_, 2);
573  }
574
575  virtual void Verify() {
576    // Verify the page index.
577    int page_index = prefs()->GetPageIndex(extension_id_);
578    EXPECT_EQ(page_index, 2);
579
580    // This extension doesn't exist, so it should return -1.
581    EXPECT_EQ(-1, prefs()->GetPageIndex("foo"));
582  }
583
584 private:
585  std::string extension_id_;
586};
587TEST_F(ExtensionPrefsPageIndex, ExtensionPrefsPageIndex) {}
588
589class ExtensionPrefsAppDraggedByUser : public ExtensionPrefsTest {
590 public:
591  virtual void Initialize() {
592    extension_ = prefs_.AddExtension("on_extension_installed");
593    EXPECT_FALSE(prefs()->WasAppDraggedByUser(extension_->id()));
594    prefs()->OnExtensionInstalled(extension_.get(),
595        Extension::ENABLED, false);
596  }
597
598  virtual void Verify() {
599    // Set the flag and see if it persisted.
600    prefs()->SetAppDraggedByUser(extension_->id());
601    EXPECT_TRUE(prefs()->WasAppDraggedByUser(extension_->id()));
602
603    // Make sure it doesn't change on consecutive calls.
604    prefs()->SetAppDraggedByUser(extension_->id());
605    EXPECT_TRUE(prefs()->WasAppDraggedByUser(extension_->id()));
606  }
607
608 private:
609  scoped_refptr<Extension> extension_;
610};
611TEST_F(ExtensionPrefsAppDraggedByUser, ExtensionPrefsAppDraggedByUser) {}
612
613namespace keys = extension_manifest_keys;
614
615// Tests that we gracefully handle changes in the ID generation function for
616// unpacked extensions.
617class ExtensionPrefsIdChange : public ExtensionPrefsTest {
618 public:
619  virtual void Initialize() {
620    DictionaryValue manifest;
621    manifest.SetString(keys::kVersion, "1.0.0.0");
622    manifest.SetString(keys::kName, "unused");
623
624    extension_ = prefs_.AddExtensionWithManifest(
625        manifest, Extension::LOAD);
626    extension_id_ = extension_->id();
627
628    DictionaryPrefUpdate extensions_dict_update(
629        prefs()->pref_service(), ExtensionPrefs::kExtensionsPref);
630
631    Value* extension_prefs;
632    ASSERT_TRUE(extensions_dict_update->RemoveWithoutPathExpansion(
633        extension_id_, &extension_prefs));
634    extensions_dict_update->SetWithoutPathExpansion(
635        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", extension_prefs);
636  }
637
638  virtual void Verify() {
639    prefs_.RecreateExtensionPrefs();
640    prefs()->SetExtensionState(extension_.get(), Extension::DISABLED);
641    ExtensionPrefs::ExtensionIdSet extension_ids;
642    prefs()->GetExtensions(&extension_ids);
643    EXPECT_EQ(1U, extension_ids.size());
644    EXPECT_EQ(extension_id_, extension_ids[0]);
645  }
646
647 private:
648  scoped_refptr<Extension> extension_;
649  std::string extension_id_;
650};
651TEST_F(ExtensionPrefsIdChange, IdChange) {}
652
653class ExtensionPrefsPreferencesBase : public ExtensionPrefsTest {
654 public:
655  ExtensionPrefsPreferencesBase()
656      : ExtensionPrefsTest(),
657        ext1_(NULL),
658        ext2_(NULL),
659        ext3_(NULL),
660        installed() {
661    DictionaryValue simple_dict;
662    std::string error;
663
664    simple_dict.SetString(keys::kVersion, "1.0.0.0");
665    simple_dict.SetString(keys::kName, "unused");
666
667    ext1_scoped_ = Extension::Create(
668        prefs_.temp_dir().AppendASCII("ext1_"), Extension::EXTERNAL_PREF,
669        simple_dict, Extension::STRICT_ERROR_CHECKS, &error);
670    ext2_scoped_ = Extension::Create(
671        prefs_.temp_dir().AppendASCII("ext2_"), Extension::EXTERNAL_PREF,
672        simple_dict, Extension::STRICT_ERROR_CHECKS, &error);
673    ext3_scoped_ = Extension::Create(
674        prefs_.temp_dir().AppendASCII("ext3_"), Extension::EXTERNAL_PREF,
675        simple_dict, Extension::STRICT_ERROR_CHECKS, &error);
676
677    ext1_ = ext1_scoped_.get();
678    ext2_ = ext2_scoped_.get();
679    ext3_ = ext3_scoped_.get();
680
681    for (size_t i = 0; i < arraysize(installed); ++i)
682      installed[i] = false;
683  }
684
685  void RegisterPreferences() {
686    prefs()->pref_service()->RegisterStringPref(kPref1, kDefaultPref1);
687    prefs()->pref_service()->RegisterStringPref(kPref2, kDefaultPref2);
688    prefs()->pref_service()->RegisterStringPref(kPref3, kDefaultPref3);
689    prefs()->pref_service()->RegisterStringPref(kPref4, kDefaultPref4);
690  }
691
692  void InstallExtControlledPref(Extension *ext,
693                                const std::string& key,
694                                Value* val) {
695    EnsureExtensionInstalled(ext);
696    prefs()->SetExtensionControlledPref(ext->id(), key, false, val);
697  }
698
699  void InstallExtControlledPrefIncognito(Extension *ext,
700                                         const std::string& key,
701                                         Value* val) {
702    EnsureExtensionInstalled(ext);
703    prefs()->SetExtensionControlledPref(ext->id(), key, true, val);
704  }
705
706  void InstallExtension(Extension *ext) {
707    EnsureExtensionInstalled(ext);
708  }
709
710  void UninstallExtension(const std::string& extension_id) {
711    EnsureExtensionUninstalled(extension_id);
712  }
713
714  // Weak references, for convenience.
715  Extension* ext1_;
716  Extension* ext2_;
717  Extension* ext3_;
718
719  // Flags indicating whether each of the extensions has been installed, yet.
720  bool installed[3];
721
722 private:
723  void EnsureExtensionInstalled(Extension *ext) {
724    // Install extension the first time a preference is set for it.
725    Extension* extensions[] = {ext1_, ext2_, ext3_};
726    for (int i = 0; i < 3; ++i) {
727      if (ext == extensions[i] && !installed[i]) {
728        prefs()->OnExtensionInstalled(ext, Extension::ENABLED, true);
729        installed[i] = true;
730        break;
731      }
732    }
733  }
734
735  void EnsureExtensionUninstalled(const std::string& extension_id) {
736    Extension* extensions[] = {ext1_, ext2_, ext3_};
737    for (int i = 0; i < 3; ++i) {
738      if (extensions[i]->id() == extension_id) {
739        installed[i] = false;
740        break;
741      }
742    }
743    prefs()->OnExtensionUninstalled(extension_id, Extension::INTERNAL, false);
744  }
745
746  scoped_refptr<Extension> ext1_scoped_;
747  scoped_refptr<Extension> ext2_scoped_;
748  scoped_refptr<Extension> ext3_scoped_;
749};
750
751class ExtensionPrefsInstallOneExtension
752    : public ExtensionPrefsPreferencesBase {
753  virtual void Initialize() {
754    InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
755  }
756  virtual void Verify() {
757    std::string actual = prefs()->pref_service()->GetString(kPref1);
758    EXPECT_EQ("val1", actual);
759  }
760};
761TEST_F(ExtensionPrefsInstallOneExtension, ExtensionPrefsInstallOneExtension) {}
762
763// Check that we forget incognito values after a reload.
764class ExtensionPrefsInstallIncognito
765    : public ExtensionPrefsPreferencesBase {
766 public:
767  ExtensionPrefsInstallIncognito() : iteration_(0) {}
768
769  virtual void Initialize() {
770    InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
771    InstallExtControlledPrefIncognito(ext1_, kPref1,
772                                      Value::CreateStringValue("val2"));
773    scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
774    std::string actual = incog_prefs->GetString(kPref1);
775    EXPECT_EQ("val2", actual);
776  }
777  virtual void Verify() {
778    // Main pref service shall see only non-incognito settings.
779    std::string actual = prefs()->pref_service()->GetString(kPref1);
780    EXPECT_EQ("val1", actual);
781    // Incognito pref service shall see incognito values only during first run.
782    // Once the pref service was reloaded, all values shall be discarded.
783    scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
784    actual = incog_prefs->GetString(kPref1);
785    if (iteration_ == 0) {
786      EXPECT_EQ("val2", actual);
787    } else {
788      EXPECT_EQ("val1", actual);
789    }
790    ++iteration_;
791  }
792  int iteration_;
793};
794TEST_F(ExtensionPrefsInstallIncognito, ExtensionPrefsInstallOneExtension) {}
795
796class ExtensionPrefsUninstallExtension
797    : public ExtensionPrefsPreferencesBase {
798  virtual void Initialize() {
799    InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
800    InstallExtControlledPref(ext1_, kPref2, Value::CreateStringValue("val2"));
801
802    UninstallExtension(ext1_->id());
803  }
804  virtual void Verify() {
805    std::string actual;
806    actual = prefs()->pref_service()->GetString(kPref1);
807    EXPECT_EQ(kDefaultPref1, actual);
808    actual = prefs()->pref_service()->GetString(kPref2);
809    EXPECT_EQ(kDefaultPref2, actual);
810  }
811};
812TEST_F(ExtensionPrefsUninstallExtension,
813    ExtensionPrefsUninstallExtension) {}
814
815// Tests triggering of notifications to registered observers.
816class ExtensionPrefsNotifyWhenNeeded
817    : public ExtensionPrefsPreferencesBase {
818  virtual void Initialize() {
819    using testing::_;
820    using testing::Mock;
821    using testing::StrEq;
822
823    NotificationObserverMock observer;
824    PrefChangeRegistrar registrar;
825    registrar.Init(prefs()->pref_service());
826    registrar.Add(kPref1, &observer);
827
828    NotificationObserverMock incognito_observer;
829    scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
830    PrefChangeRegistrar incognito_registrar;
831    incognito_registrar.Init(incog_prefs.get());
832    incognito_registrar.Add(kPref1, &incognito_observer);
833
834    // Write value and check notification.
835    EXPECT_CALL(observer, Observe(_, _, _));
836    EXPECT_CALL(incognito_observer, Observe(_, _, _));
837    InstallExtControlledPref(ext1_, kPref1,
838        Value::CreateStringValue("https://www.chromium.org"));
839    Mock::VerifyAndClearExpectations(&observer);
840    Mock::VerifyAndClearExpectations(&incognito_observer);
841
842    // Write same value.
843    EXPECT_CALL(observer, Observe(_, _, _)).Times(0);
844    EXPECT_CALL(incognito_observer, Observe(_, _, _)).Times(0);
845    InstallExtControlledPref(ext1_, kPref1,
846        Value::CreateStringValue("https://www.chromium.org"));
847    Mock::VerifyAndClearExpectations(&observer);
848    Mock::VerifyAndClearExpectations(&incognito_observer);
849
850    // Change value.
851    EXPECT_CALL(observer, Observe(_, _, _));
852    EXPECT_CALL(incognito_observer, Observe(_, _, _));
853    InstallExtControlledPref(ext1_, kPref1,
854        Value::CreateStringValue("chrome://newtab"));
855    Mock::VerifyAndClearExpectations(&observer);
856    Mock::VerifyAndClearExpectations(&incognito_observer);
857
858    // Change only incognito value.
859    EXPECT_CALL(observer, Observe(_, _, _)).Times(0);
860    EXPECT_CALL(incognito_observer, Observe(_, _, _));
861    InstallExtControlledPrefIncognito(ext1_, kPref1,
862        Value::CreateStringValue("chrome://newtab2"));
863    Mock::VerifyAndClearExpectations(&observer);
864    Mock::VerifyAndClearExpectations(&incognito_observer);
865
866    // Uninstall.
867    EXPECT_CALL(observer, Observe(_, _, _));
868    EXPECT_CALL(incognito_observer, Observe(_, _, _));
869    UninstallExtension(ext1_->id());
870    Mock::VerifyAndClearExpectations(&observer);
871    Mock::VerifyAndClearExpectations(&incognito_observer);
872
873    registrar.Remove(kPref1, &observer);
874    incognito_registrar.Remove(kPref1, &incognito_observer);
875  }
876  virtual void Verify() {
877    std::string actual = prefs()->pref_service()->GetString(kPref1);
878    EXPECT_EQ(kDefaultPref1, actual);
879  }
880};
881TEST_F(ExtensionPrefsNotifyWhenNeeded,
882    ExtensionPrefsNotifyWhenNeeded) {}
883
884// Tests disabling an extension.
885class ExtensionPrefsDisableExt
886    : public ExtensionPrefsPreferencesBase {
887  virtual void Initialize() {
888    InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
889    std::string actual = prefs()->pref_service()->GetString(kPref1);
890    EXPECT_EQ("val1", actual);
891    prefs()->SetExtensionState(ext1_, Extension::DISABLED);
892  }
893  virtual void Verify() {
894    std::string actual = prefs()->pref_service()->GetString(kPref1);
895    EXPECT_EQ(kDefaultPref1, actual);
896  }
897};
898TEST_F(ExtensionPrefsDisableExt,  ExtensionPrefsDisableExt) {}
899
900// Tests disabling and reenabling an extension.
901class ExtensionPrefsReenableExt
902    : public ExtensionPrefsPreferencesBase {
903  virtual void Initialize() {
904    InstallExtControlledPref(ext1_, kPref1, Value::CreateStringValue("val1"));
905    prefs()->SetExtensionState(ext1_, Extension::DISABLED);
906    prefs()->SetExtensionState(ext1_, Extension::ENABLED);
907  }
908  virtual void Verify() {
909    std::string actual = prefs()->pref_service()->GetString(kPref1);
910    EXPECT_EQ("val1", actual);
911  }
912};
913TEST_F(ExtensionPrefsDisableExt,  ExtensionPrefsReenableExt) {}
914
915// Mock class to test whether objects are deleted correctly.
916class MockStringValue : public StringValue {
917 public:
918  explicit MockStringValue(const std::string& in_value)
919      : StringValue(in_value) {
920  }
921  virtual ~MockStringValue() {
922    Die();
923  }
924  MOCK_METHOD0(Die, void());
925};
926
927class ExtensionPrefsSetExtensionControlledPref
928    : public ExtensionPrefsPreferencesBase {
929 public:
930  virtual void Initialize() {
931    MockStringValue* v1 = new MockStringValue("https://www.chromium.org");
932    MockStringValue* v2 = new MockStringValue("https://www.chromium.org");
933    MockStringValue* v1i = new MockStringValue("https://www.chromium.org");
934    MockStringValue* v2i = new MockStringValue("https://www.chromium.org");
935    // Ownership is taken, value shall not be deleted.
936    EXPECT_CALL(*v1, Die()).Times(0);
937    EXPECT_CALL(*v1i, Die()).Times(0);
938    InstallExtControlledPref(ext1_, kPref1, v1);
939    InstallExtControlledPrefIncognito(ext1_, kPref1, v1i);
940    testing::Mock::VerifyAndClearExpectations(v1);
941    testing::Mock::VerifyAndClearExpectations(v1i);
942    // Make sure there is no memory leak and both values are deleted.
943    EXPECT_CALL(*v1, Die()).Times(1);
944    EXPECT_CALL(*v1i, Die()).Times(1);
945    EXPECT_CALL(*v2, Die()).Times(1);
946    EXPECT_CALL(*v2i, Die()).Times(1);
947    InstallExtControlledPref(ext1_, kPref1, v2);
948    InstallExtControlledPrefIncognito(ext1_, kPref1, v2i);
949    prefs_.RecreateExtensionPrefs();
950    testing::Mock::VerifyAndClearExpectations(v1);
951    testing::Mock::VerifyAndClearExpectations(v1i);
952    testing::Mock::VerifyAndClearExpectations(v2);
953    testing::Mock::VerifyAndClearExpectations(v2i);
954  }
955
956  virtual void Verify() {
957  }
958};
959TEST_F(ExtensionPrefsSetExtensionControlledPref,
960    ExtensionPrefsSetExtensionControlledPref) {}
961