Home | History | Annotate | Download | only in profile_resetter
      1 // Copyright (c) 2013 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/profile_resetter/profile_resetter.h"
      6 
      7 #include "base/json/json_string_value_serializer.h"
      8 #include "base/prefs/pref_service.h"
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "chrome/browser/content_settings/host_content_settings_map.h"
     11 #include "chrome/browser/extensions/extension_service_unittest.h"
     12 #include "chrome/browser/extensions/tab_helper.h"
     13 #include "chrome/browser/notifications/desktop_notification_service.h"
     14 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
     15 #include "chrome/browser/prefs/session_startup_pref.h"
     16 #include "chrome/browser/profile_resetter/brandcode_config_fetcher.h"
     17 #include "chrome/browser/profile_resetter/profile_resetter_test_base.h"
     18 #include "chrome/browser/profile_resetter/resettable_settings_snapshot.h"
     19 #include "chrome/browser/search_engines/template_url_service.h"
     20 #include "chrome/browser/search_engines/template_url_service_factory.h"
     21 #include "chrome/browser/themes/theme_service.h"
     22 #include "chrome/browser/themes/theme_service_factory.h"
     23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     24 #include "chrome/common/extensions/extension.h"
     25 #include "chrome/common/extensions/extension_manifest_constants.h"
     26 #include "chrome/common/pref_names.h"
     27 #include "chrome/test/base/browser_with_test_window_test.h"
     28 #include "content/public/browser/web_contents.h"
     29 #include "content/public/test/test_browser_thread.h"
     30 #include "net/http/http_response_headers.h"
     31 #include "net/url_request/test_url_fetcher_factory.h"
     32 
     33 
     34 namespace {
     35 
     36 const char kDistributionConfig[] = "{"
     37     " \"homepage\" : \"http://www.foo.com\","
     38     " \"homepage_is_newtabpage\" : false,"
     39     " \"browser\" : {"
     40     "   \"show_home_button\" : true"
     41     "  },"
     42     " \"session\" : {"
     43     "   \"restore_on_startup\" : 4,"
     44     "   \"urls_to_restore_on_startup\" : [\"http://goo.gl\", \"http://foo.de\"]"
     45     "  },"
     46     " \"search_provider_overrides\" : ["
     47     "    {"
     48     "      \"name\" : \"first\","
     49     "      \"keyword\" : \"firstkey\","
     50     "      \"search_url\" : \"http://www.foo.com/s?q={searchTerms}\","
     51     "      \"favicon_url\" : \"http://www.foo.com/favicon.ico\","
     52     "      \"suggest_url\" : \"http://www.foo.com/s?q={searchTerms}\","
     53     "      \"encoding\" : \"UTF-8\","
     54     "      \"id\" : 1001"
     55     "    }"
     56     "  ],"
     57     " \"extensions\" : {"
     58     "   \"settings\" : {"
     59     "     \"placeholder_for_id\": {"
     60     "      }"
     61     "    }"
     62     "  }"
     63     "}";
     64 
     65 const char kXmlConfig[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
     66     "<response protocol=\"3.0\" server=\"prod\">"
     67       "<app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
     68         "<data index=\"skipfirstrunui-importsearch-defaultbrowser\" "
     69           "name=\"install\" status=\"ok\">"
     70           "placeholder_for_data"
     71         "</data>"
     72       "</app>"
     73     "</response>";
     74 
     75 using extensions::Extension;
     76 using extensions::Manifest;
     77 
     78 
     79 // ProfileResetterTest --------------------------------------------------------
     80 
     81 // ProfileResetterTest sets up the extension, WebData and TemplateURL services.
     82 class ProfileResetterTest : public ExtensionServiceTestBase,
     83                             public ProfileResetterTestBase {
     84  protected:
     85   virtual void SetUp() OVERRIDE;
     86 
     87   TestingProfile* profile() { return profile_.get(); }
     88 
     89   static BrowserContextKeyedService* CreateTemplateURLService(
     90       content::BrowserContext* context);
     91 };
     92 
     93 void ProfileResetterTest::SetUp() {
     94   ExtensionServiceTestBase::SetUp();
     95   InitializeEmptyExtensionService();
     96 
     97   profile()->CreateWebDataService();
     98   TemplateURLServiceFactory::GetInstance()->SetTestingFactory(
     99       profile(),
    100       &ProfileResetterTest::CreateTemplateURLService);
    101   resetter_.reset(new ProfileResetter(profile()));
    102 }
    103 
    104 // static
    105 BrowserContextKeyedService* ProfileResetterTest::CreateTemplateURLService(
    106     content::BrowserContext* context) {
    107   return new TemplateURLService(static_cast<Profile*>(context));
    108 }
    109 
    110 
    111 // PinnedTabsResetTest --------------------------------------------------------
    112 
    113 class PinnedTabsResetTest : public BrowserWithTestWindowTest,
    114                             public ProfileResetterTestBase {
    115  protected:
    116   virtual void SetUp() OVERRIDE;
    117 
    118   content::WebContents* CreateWebContents();
    119 };
    120 
    121 void PinnedTabsResetTest::SetUp() {
    122   BrowserWithTestWindowTest::SetUp();
    123   resetter_.reset(new ProfileResetter(profile()));
    124 }
    125 
    126 content::WebContents* PinnedTabsResetTest::CreateWebContents() {
    127   return content::WebContents::Create(
    128       content::WebContents::CreateParams(profile()));
    129 }
    130 
    131 
    132 // ConfigParserTest -----------------------------------------------------------
    133 
    134 // URLFetcher delegate that simply records the upload data.
    135 struct URLFetcherRequestListener : net::URLFetcherDelegate {
    136   URLFetcherRequestListener();
    137   virtual ~URLFetcherRequestListener();
    138 
    139   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
    140 
    141   std::string upload_data;
    142   net::URLFetcherDelegate* real_delegate;
    143 };
    144 
    145 URLFetcherRequestListener::URLFetcherRequestListener()
    146     : real_delegate(NULL) {
    147 }
    148 
    149 URLFetcherRequestListener::~URLFetcherRequestListener() {
    150 }
    151 
    152 void URLFetcherRequestListener::OnURLFetchComplete(
    153     const net::URLFetcher* source) {
    154   const net::TestURLFetcher* test_fetcher =
    155       static_cast<const net::TestURLFetcher*>(source);
    156   upload_data = test_fetcher->upload_data();
    157   DCHECK(real_delegate);
    158   real_delegate->OnURLFetchComplete(source);
    159 }
    160 
    161 class ConfigParserTest : public testing::Test {
    162  protected:
    163   ConfigParserTest();
    164   virtual ~ConfigParserTest();
    165 
    166   scoped_ptr<BrandcodeConfigFetcher> WaitForRequest(const GURL& url);
    167 
    168   net::FakeURLFetcherFactory& factory() { return factory_; }
    169 
    170  private:
    171   scoped_ptr<net::FakeURLFetcher> CreateFakeURLFetcher(
    172       const GURL& url,
    173       net::URLFetcherDelegate* fetcher_delegate,
    174       const std::string& response_data,
    175       bool success);
    176 
    177   MOCK_METHOD0(Callback, void(void));
    178 
    179   base::MessageLoop loop_;
    180   content::TestBrowserThread ui_thread_;
    181   content::TestBrowserThread io_thread_;
    182   URLFetcherRequestListener request_listener_;
    183   net::FakeURLFetcherFactory factory_;
    184 };
    185 
    186 ConfigParserTest::ConfigParserTest()
    187     : loop_(base::MessageLoop::TYPE_IO),
    188       ui_thread_(content::BrowserThread::UI, &loop_),
    189       io_thread_(content::BrowserThread::IO, &loop_),
    190       factory_(NULL, base::Bind(&ConfigParserTest::CreateFakeURLFetcher,
    191                                 base::Unretained(this))) {
    192 }
    193 
    194 ConfigParserTest::~ConfigParserTest() {}
    195 
    196 scoped_ptr<BrandcodeConfigFetcher> ConfigParserTest::WaitForRequest(
    197     const GURL& url) {
    198   EXPECT_CALL(*this, Callback());
    199   scoped_ptr<BrandcodeConfigFetcher> fetcher(
    200       new BrandcodeConfigFetcher(base::Bind(&ConfigParserTest::Callback,
    201                                             base::Unretained(this)),
    202                                  url,
    203                                  "ABCD"));
    204   base::MessageLoop::current()->RunUntilIdle();
    205   EXPECT_FALSE(fetcher->IsActive());
    206   // Look for the brand code in the request.
    207   EXPECT_NE(std::string::npos, request_listener_.upload_data.find("ABCD"));
    208   return fetcher.Pass();
    209 }
    210 
    211 scoped_ptr<net::FakeURLFetcher> ConfigParserTest::CreateFakeURLFetcher(
    212     const GURL& url,
    213     net::URLFetcherDelegate* fetcher_delegate,
    214     const std::string& response_data,
    215     bool success) {
    216   request_listener_.real_delegate = fetcher_delegate;
    217   scoped_ptr<net::FakeURLFetcher> fetcher(
    218       new net::FakeURLFetcher(url, &request_listener_, response_data, success));
    219   scoped_refptr<net::HttpResponseHeaders> download_headers =
    220       new net::HttpResponseHeaders("");
    221   download_headers->AddHeader("Content-Type: text/xml");
    222   fetcher->set_response_headers(download_headers);
    223   return fetcher.Pass();
    224 }
    225 
    226 
    227 // helper functions -----------------------------------------------------------
    228 
    229 scoped_refptr<Extension> CreateExtension(const std::string& name,
    230                                          const base::FilePath& path,
    231                                          Manifest::Location location,
    232                                          extensions::Manifest::Type type,
    233                                          bool installed_by_default) {
    234   DictionaryValue manifest;
    235   manifest.SetString(extension_manifest_keys::kVersion, "1.0.0.0");
    236   manifest.SetString(extension_manifest_keys::kName, name);
    237   switch (type) {
    238     case extensions::Manifest::TYPE_THEME:
    239       manifest.Set(extension_manifest_keys::kTheme, new DictionaryValue);
    240       break;
    241     case extensions::Manifest::TYPE_HOSTED_APP:
    242       manifest.SetString(extension_manifest_keys::kLaunchWebURL,
    243                          "http://www.google.com");
    244       manifest.SetString(extension_manifest_keys::kUpdateURL,
    245                          "http://clients2.google.com/service/update2/crx");
    246       break;
    247     case extensions::Manifest::TYPE_EXTENSION:
    248       // do nothing
    249       break;
    250     default:
    251       NOTREACHED();
    252   }
    253   manifest.SetString(extension_manifest_keys::kOmniboxKeyword, name);
    254   std::string error;
    255   scoped_refptr<Extension> extension = Extension::Create(
    256       path,
    257       location,
    258       manifest,
    259       installed_by_default ? Extension::WAS_INSTALLED_BY_DEFAULT
    260                            : Extension::NO_FLAGS,
    261       &error);
    262   EXPECT_TRUE(extension.get() != NULL) << error;
    263   return extension;
    264 }
    265 
    266 void ReplaceString(std::string* str,
    267                    const std::string& placeholder,
    268                    const std::string& substitution) {
    269   ASSERT_NE(static_cast<std::string*>(NULL), str);
    270   size_t placeholder_pos = str->find(placeholder);
    271   ASSERT_NE(std::string::npos, placeholder_pos);
    272   str->replace(placeholder_pos, placeholder.size(), substitution);
    273 }
    274 
    275 
    276 /********************* Tests *********************/
    277 
    278 TEST_F(ProfileResetterTest, ResetDefaultSearchEngine) {
    279   // Search engine's logic is tested by
    280   // TemplateURLServiceTest.ResetURLs.
    281   PrefService* prefs = profile()->GetPrefs();
    282   DCHECK(prefs);
    283   prefs->SetString(prefs::kLastPromptedGoogleURL, "http://www.foo.com/");
    284 
    285   scoped_refptr<Extension> extension = CreateExtension(
    286       "xxx",
    287       base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
    288       Manifest::COMPONENT,
    289       extensions::Manifest::TYPE_EXTENSION,
    290       false);
    291   service_->AddExtension(extension.get());
    292 
    293   ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE);
    294 
    295   // TemplateURLService should reset extension search engines.
    296   TemplateURLService* model =
    297       TemplateURLServiceFactory::GetForProfile(profile());
    298   TemplateURL* ext_url = model->GetTemplateURLForKeyword(ASCIIToUTF16("xxx"));
    299   ASSERT_TRUE(ext_url);
    300   EXPECT_TRUE(ext_url->IsExtensionKeyword());
    301   EXPECT_EQ(ASCIIToUTF16("xxx"), ext_url->keyword());
    302   EXPECT_EQ(ASCIIToUTF16("xxx"), ext_url->short_name());
    303   EXPECT_EQ("", prefs->GetString(prefs::kLastPromptedGoogleURL));
    304 }
    305 
    306 TEST_F(ProfileResetterTest, ResetDefaultSearchEngineNonOrganic) {
    307   PrefService* prefs = profile()->GetPrefs();
    308   DCHECK(prefs);
    309   prefs->SetString(prefs::kLastPromptedGoogleURL, "http://www.foo.com/");
    310 
    311   ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE, kDistributionConfig);
    312 
    313   TemplateURLService* model =
    314       TemplateURLServiceFactory::GetForProfile(profile());
    315   EXPECT_EQ(1u, model->GetTemplateURLs().size());
    316   TemplateURL* default_engine = model->GetDefaultSearchProvider();
    317   ASSERT_NE(static_cast<TemplateURL*>(NULL), default_engine);
    318   EXPECT_EQ(ASCIIToUTF16("first"), default_engine->short_name());
    319   EXPECT_EQ(ASCIIToUTF16("firstkey"), default_engine->keyword());
    320   EXPECT_EQ("http://www.foo.com/s?q={searchTerms}", default_engine->url());
    321 
    322   EXPECT_EQ("", prefs->GetString(prefs::kLastPromptedGoogleURL));
    323 }
    324 
    325 TEST_F(ProfileResetterTest, ResetHomepage) {
    326   PrefService* prefs = profile()->GetPrefs();
    327   DCHECK(prefs);
    328   prefs->SetBoolean(prefs::kHomePageIsNewTabPage, false);
    329   prefs->SetString(prefs::kHomePage, "http://google.com");
    330   prefs->SetBoolean(prefs::kShowHomeButton, true);
    331 
    332   ResetAndWait(ProfileResetter::HOMEPAGE);
    333 
    334   EXPECT_TRUE(prefs->GetBoolean(prefs::kHomePageIsNewTabPage));
    335   EXPECT_EQ(std::string(), prefs->GetString(prefs::kHomePage));
    336   EXPECT_FALSE(prefs->GetBoolean(prefs::kShowHomeButton));
    337 }
    338 
    339 TEST_F(ProfileResetterTest, ResetHomepageNonOrganic) {
    340   PrefService* prefs = profile()->GetPrefs();
    341   DCHECK(prefs);
    342   prefs->SetBoolean(prefs::kHomePageIsNewTabPage, true);
    343   prefs->SetString(prefs::kHomePage, "http://google.com");
    344   prefs->SetBoolean(prefs::kShowHomeButton, false);
    345 
    346   ResetAndWait(ProfileResetter::HOMEPAGE, kDistributionConfig);
    347 
    348   EXPECT_FALSE(prefs->GetBoolean(prefs::kHomePageIsNewTabPage));
    349   EXPECT_EQ("http://www.foo.com", prefs->GetString(prefs::kHomePage));
    350   EXPECT_TRUE(prefs->GetBoolean(prefs::kShowHomeButton));
    351 }
    352 
    353 TEST_F(ProfileResetterTest, ResetContentSettings) {
    354   HostContentSettingsMap* host_content_settings_map =
    355       profile()->GetHostContentSettingsMap();
    356   DesktopNotificationService* notification_service =
    357       DesktopNotificationServiceFactory::GetForProfile(profile());
    358   ContentSettingsPattern pattern =
    359       ContentSettingsPattern::FromString("[*.]example.org");
    360   std::map<ContentSettingsType, ContentSetting> default_settings;
    361 
    362   for (int type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
    363     if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
    364       notification_service->SetDefaultContentSetting(CONTENT_SETTING_BLOCK);
    365       notification_service->GrantPermission(GURL("http://foo.de"));
    366     } else if (type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE ||
    367                type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT ||
    368                type == CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS) {
    369       // These types are excluded because one can't call
    370       // GetDefaultContentSetting() for them.
    371     } else {
    372       ContentSettingsType content_type = static_cast<ContentSettingsType>(type);
    373       ContentSetting default_setting =
    374           host_content_settings_map->GetDefaultContentSetting(content_type,
    375                                                               NULL);
    376       default_settings[content_type] = default_setting;
    377       ContentSetting wildcard_setting =
    378           default_setting == CONTENT_SETTING_BLOCK ? CONTENT_SETTING_ALLOW
    379                                                    : CONTENT_SETTING_BLOCK;
    380       ContentSetting site_setting =
    381           default_setting == CONTENT_SETTING_ALLOW ? CONTENT_SETTING_ALLOW
    382                                                    : CONTENT_SETTING_BLOCK;
    383       if (HostContentSettingsMap::IsSettingAllowedForType(
    384               profile()->GetPrefs(),
    385               wildcard_setting,
    386               content_type)) {
    387         host_content_settings_map->SetDefaultContentSetting(
    388             content_type,
    389             wildcard_setting);
    390       }
    391       if (!HostContentSettingsMap::ContentTypeHasCompoundValue(content_type) &&
    392           HostContentSettingsMap::IsSettingAllowedForType(
    393               profile()->GetPrefs(),
    394               site_setting,
    395               content_type)) {
    396         host_content_settings_map->SetContentSetting(
    397             pattern,
    398             ContentSettingsPattern::Wildcard(),
    399             content_type,
    400             std::string(),
    401             site_setting);
    402         ContentSettingsForOneType host_settings;
    403         host_content_settings_map->GetSettingsForOneType(
    404             content_type, std::string(), &host_settings);
    405         EXPECT_EQ(2U, host_settings.size());
    406       }
    407     }
    408   }
    409 
    410   ResetAndWait(ProfileResetter::CONTENT_SETTINGS);
    411 
    412   for (int type = 0; type < CONTENT_SETTINGS_NUM_TYPES; ++type) {
    413     if (type == CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
    414       EXPECT_EQ(CONTENT_SETTING_ASK,
    415                 notification_service->GetDefaultContentSetting(NULL));
    416       EXPECT_EQ(CONTENT_SETTING_ASK,
    417                 notification_service->GetContentSetting(GURL("http://foo.de")));
    418     } else {
    419       ContentSettingsType content_type = static_cast<ContentSettingsType>(type);
    420       if (HostContentSettingsMap::ContentTypeHasCompoundValue(content_type) ||
    421           type == CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE ||
    422           content_type == CONTENT_SETTINGS_TYPE_MIXEDSCRIPT ||
    423           content_type == CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS)
    424         continue;
    425       ContentSetting default_setting =
    426           host_content_settings_map->GetDefaultContentSetting(content_type,
    427                                                               NULL);
    428       EXPECT_TRUE(default_settings.count(content_type));
    429       EXPECT_EQ(default_settings[content_type], default_setting);
    430       if (!HostContentSettingsMap::ContentTypeHasCompoundValue(content_type)) {
    431         ContentSetting site_setting =
    432             host_content_settings_map->GetContentSetting(
    433                 GURL("example.org"),
    434                 GURL(),
    435                 content_type,
    436                 std::string());
    437         EXPECT_EQ(default_setting, site_setting);
    438       }
    439 
    440       ContentSettingsForOneType host_settings;
    441       host_content_settings_map->GetSettingsForOneType(
    442           content_type, std::string(), &host_settings);
    443       EXPECT_EQ(1U, host_settings.size());
    444     }
    445   }
    446 }
    447 
    448 TEST_F(ProfileResetterTest, ResetExtensionsByDisabling) {
    449   base::ScopedTempDir temp_dir;
    450   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    451 
    452   scoped_refptr<Extension> theme =
    453       CreateExtension("example1",
    454                       temp_dir.path(),
    455                       Manifest::INVALID_LOCATION,
    456                       extensions::Manifest::TYPE_THEME,
    457                       false);
    458   service_->FinishInstallationForTest(theme.get());
    459   // Let ThemeService finish creating the theme pack.
    460   base::MessageLoop::current()->RunUntilIdle();
    461 
    462   ThemeService* theme_service =
    463       ThemeServiceFactory::GetForProfile(profile());
    464   EXPECT_FALSE(theme_service->UsingDefaultTheme());
    465 
    466   scoped_refptr<Extension> ext2 = CreateExtension(
    467       "example2",
    468       base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
    469       Manifest::INVALID_LOCATION,
    470       extensions::Manifest::TYPE_EXTENSION,
    471       false);
    472   service_->AddExtension(ext2.get());
    473   // Components and external policy extensions shouldn't be deleted.
    474   scoped_refptr<Extension> ext3 = CreateExtension(
    475       "example3",
    476       base::FilePath(FILE_PATH_LITERAL("//nonexistent2")),
    477       Manifest::COMPONENT,
    478       extensions::Manifest::TYPE_EXTENSION,
    479       false);
    480   service_->AddExtension(ext3.get());
    481   scoped_refptr<Extension> ext4 =
    482       CreateExtension("example4",
    483                       base::FilePath(FILE_PATH_LITERAL("//nonexistent3")),
    484                       Manifest::EXTERNAL_POLICY_DOWNLOAD,
    485                       extensions::Manifest::TYPE_EXTENSION,
    486                       false);
    487   service_->AddExtension(ext4.get());
    488   EXPECT_EQ(4u, service_->extensions()->size());
    489 
    490   ResetAndWait(ProfileResetter::EXTENSIONS);
    491   EXPECT_EQ(2u, service_->extensions()->size());
    492   EXPECT_FALSE(service_->extensions()->Contains(theme->id()));
    493   EXPECT_FALSE(service_->extensions()->Contains(ext2->id()));
    494   EXPECT_TRUE(service_->extensions()->Contains(ext3->id()));
    495   EXPECT_TRUE(service_->extensions()->Contains(ext4->id()));
    496   EXPECT_TRUE(theme_service->UsingDefaultTheme());
    497 }
    498 
    499 TEST_F(ProfileResetterTest, ResetExtensionsByDisablingNonOrganic) {
    500   scoped_refptr<Extension> ext2 = CreateExtension(
    501       "example2",
    502       base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
    503       Manifest::INVALID_LOCATION,
    504       extensions::Manifest::TYPE_EXTENSION,
    505       false);
    506   service_->AddExtension(ext2.get());
    507   // Components and external policy extensions shouldn't be deleted.
    508   scoped_refptr<Extension> ext3 = CreateExtension(
    509       "example3",
    510       base::FilePath(FILE_PATH_LITERAL("//nonexistent2")),
    511       Manifest::INVALID_LOCATION,
    512       extensions::Manifest::TYPE_EXTENSION,
    513       false);
    514   service_->AddExtension(ext3.get());
    515   EXPECT_EQ(2u, service_->extensions()->size());
    516 
    517   std::string master_prefs(kDistributionConfig);
    518   ReplaceString(&master_prefs, "placeholder_for_id", ext3->id());
    519 
    520   ResetAndWait(ProfileResetter::EXTENSIONS, master_prefs);
    521 
    522   EXPECT_EQ(1u, service_->extensions()->size());
    523   EXPECT_TRUE(service_->extensions()->Contains(ext3->id()));
    524 }
    525 
    526 TEST_F(ProfileResetterTest, ResetExtensionsAndDefaultApps) {
    527   service_->Init();
    528 
    529   base::ScopedTempDir temp_dir;
    530   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    531 
    532   scoped_refptr<Extension> ext1 =
    533       CreateExtension("example1",
    534                       temp_dir.path(),
    535                       Manifest::INVALID_LOCATION,
    536                       extensions::Manifest::TYPE_THEME,
    537                       false);
    538   service_->FinishInstallationForTest(ext1.get());
    539   // Let ThemeService finish creating the theme pack.
    540   base::MessageLoop::current()->RunUntilIdle();
    541 
    542   ThemeService* theme_service =
    543       ThemeServiceFactory::GetForProfile(profile());
    544   EXPECT_FALSE(theme_service->UsingDefaultTheme());
    545 
    546   scoped_refptr<Extension> ext2 =
    547       CreateExtension("example2",
    548                       base::FilePath(FILE_PATH_LITERAL("//nonexistent2")),
    549                       Manifest::INVALID_LOCATION,
    550                       extensions::Manifest::TYPE_EXTENSION,
    551                       false);
    552   service_->AddExtension(ext2.get());
    553 
    554   scoped_refptr<Extension> ext3 =
    555       CreateExtension("example2",
    556                       base::FilePath(FILE_PATH_LITERAL("//nonexistent3")),
    557                       Manifest::INVALID_LOCATION,
    558                       extensions::Manifest::TYPE_HOSTED_APP,
    559                       true);
    560   service_->AddExtension(ext3.get());
    561   EXPECT_EQ(3u, service_->extensions()->size());
    562 
    563   ResetAndWait(ProfileResetter::EXTENSIONS);
    564 
    565   EXPECT_EQ(1u, service_->extensions()->size());
    566   EXPECT_FALSE(service_->extensions()->Contains(ext1->id()));
    567   EXPECT_FALSE(service_->extensions()->Contains(ext2->id()));
    568   EXPECT_TRUE(service_->extensions()->Contains(ext3->id()));
    569   EXPECT_TRUE(theme_service->UsingDefaultTheme());
    570 }
    571 
    572 TEST_F(ProfileResetterTest, ResetStartPage) {
    573   PrefService* prefs = profile()->GetPrefs();
    574   DCHECK(prefs);
    575 
    576   SessionStartupPref startup_pref(SessionStartupPref::URLS);
    577   startup_pref.urls.push_back(GURL("http://foo"));
    578   startup_pref.urls.push_back(GURL("http://bar"));
    579   SessionStartupPref::SetStartupPref(prefs, startup_pref);
    580 
    581   ResetAndWait(ProfileResetter::STARTUP_PAGES);
    582 
    583   startup_pref = SessionStartupPref::GetStartupPref(prefs);
    584   EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(), startup_pref.type);
    585   EXPECT_EQ(std::vector<GURL>(), startup_pref.urls);
    586 }
    587 
    588 TEST_F(ProfileResetterTest, ResetStartPageNonOrganic) {
    589   PrefService* prefs = profile()->GetPrefs();
    590   DCHECK(prefs);
    591 
    592   SessionStartupPref startup_pref(SessionStartupPref::LAST);
    593   SessionStartupPref::SetStartupPref(prefs, startup_pref);
    594 
    595   ResetAndWait(ProfileResetter::STARTUP_PAGES, kDistributionConfig);
    596 
    597   startup_pref = SessionStartupPref::GetStartupPref(prefs);
    598   EXPECT_EQ(SessionStartupPref::URLS, startup_pref.type);
    599   const GURL urls[] = {GURL("http://goo.gl"), GURL("http://foo.de")};
    600   EXPECT_EQ(std::vector<GURL>(urls, urls + arraysize(urls)), startup_pref.urls);
    601 }
    602 
    603 TEST_F(PinnedTabsResetTest, ResetPinnedTabs) {
    604   scoped_refptr<Extension> extension_app = CreateExtension(
    605       "hello!",
    606       base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
    607       Manifest::INVALID_LOCATION,
    608       extensions::Manifest::TYPE_HOSTED_APP,
    609       false);
    610   scoped_ptr<content::WebContents> contents1(CreateWebContents());
    611   extensions::TabHelper::CreateForWebContents(contents1.get());
    612   extensions::TabHelper::FromWebContents(contents1.get())->
    613       SetExtensionApp(extension_app.get());
    614   scoped_ptr<content::WebContents> contents2(CreateWebContents());
    615   scoped_ptr<content::WebContents> contents3(CreateWebContents());
    616   scoped_ptr<content::WebContents> contents4(CreateWebContents());
    617   TabStripModel* tab_strip_model = browser()->tab_strip_model();
    618 
    619   tab_strip_model->AppendWebContents(contents4.get(), true);
    620   tab_strip_model->AppendWebContents(contents3.get(), true);
    621   tab_strip_model->AppendWebContents(contents2.get(), true);
    622   tab_strip_model->SetTabPinned(2, true);
    623   tab_strip_model->AppendWebContents(contents1.get(), true);
    624   tab_strip_model->SetTabPinned(3, true);
    625 
    626   EXPECT_EQ(contents2, tab_strip_model->GetWebContentsAt(0));
    627   EXPECT_EQ(contents1, tab_strip_model->GetWebContentsAt(1));
    628   EXPECT_EQ(contents3, tab_strip_model->GetWebContentsAt(2));
    629   EXPECT_EQ(contents4, tab_strip_model->GetWebContentsAt(3));
    630   EXPECT_EQ(3, tab_strip_model->IndexOfFirstNonMiniTab());
    631 
    632   ResetAndWait(ProfileResetter::PINNED_TABS);
    633 
    634   EXPECT_EQ(contents1, tab_strip_model->GetWebContentsAt(0));
    635   EXPECT_EQ(contents2, tab_strip_model->GetWebContentsAt(1));
    636   EXPECT_EQ(contents3, tab_strip_model->GetWebContentsAt(2));
    637   EXPECT_EQ(contents4, tab_strip_model->GetWebContentsAt(3));
    638   EXPECT_EQ(1, tab_strip_model->IndexOfFirstNonMiniTab());
    639 }
    640 
    641 TEST_F(ProfileResetterTest, ResetFewFlags) {
    642   // mock_object_ is a StrictMock, so we verify that it is called only once.
    643   ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
    644                ProfileResetter::HOMEPAGE |
    645                ProfileResetter::CONTENT_SETTINGS);
    646 }
    647 
    648 // Tries to load unavailable config file.
    649 TEST_F(ConfigParserTest, NoConnectivity) {
    650   const std::string url("http://test");
    651   factory().SetFakeResponse(url, "", false);
    652 
    653   scoped_ptr<BrandcodeConfigFetcher> fetcher = WaitForRequest(GURL(url));
    654   EXPECT_FALSE(fetcher->GetSettings());
    655 }
    656 
    657 // Tries to load available config file.
    658 TEST_F(ConfigParserTest, ParseConfig) {
    659   const std::string url("http://test");
    660   std::string xml_config(kXmlConfig);
    661   ReplaceString(&xml_config, "placeholder_for_data", kDistributionConfig);
    662   ReplaceString(&xml_config,
    663                 "placeholder_for_id",
    664                 "abbaabbaabbaabbaabbaabbaabbaabba");
    665   factory().SetFakeResponse(url, xml_config, true);
    666 
    667   scoped_ptr<BrandcodeConfigFetcher> fetcher = WaitForRequest(GURL(url));
    668   scoped_ptr<BrandcodedDefaultSettings> settings = fetcher->GetSettings();
    669   ASSERT_TRUE(settings);
    670 
    671   std::vector<std::string> extension_ids;
    672   EXPECT_TRUE(settings->GetExtensions(&extension_ids));
    673   EXPECT_EQ(1u, extension_ids.size());
    674   EXPECT_EQ("abbaabbaabbaabbaabbaabbaabbaabba", extension_ids[0]);
    675 
    676   std::string homepage;
    677   EXPECT_TRUE(settings->GetHomepage(&homepage));
    678   EXPECT_EQ("http://www.foo.com", homepage);
    679 
    680   scoped_ptr<base::ListValue> startup_list(
    681       settings->GetUrlsToRestoreOnStartup());
    682   EXPECT_TRUE(startup_list);
    683   std::vector<std::string> startup_pages;
    684   for (base::ListValue::iterator i = startup_list->begin();
    685        i != startup_list->end(); ++i) {
    686     std::string url;
    687     EXPECT_TRUE((*i)->GetAsString(&url));
    688     startup_pages.push_back(url);
    689   }
    690   ASSERT_EQ(2u, startup_pages.size());
    691   EXPECT_EQ("http://goo.gl", startup_pages[0]);
    692   EXPECT_EQ("http://foo.de", startup_pages[1]);
    693 }
    694 
    695 TEST_F(ProfileResetterTest, CheckSnapshots) {
    696   ResettableSettingsSnapshot empty_snap(profile());
    697   EXPECT_EQ(0, empty_snap.FindDifferentFields(empty_snap));
    698 
    699   scoped_refptr<Extension> ext = CreateExtension(
    700       "example",
    701       base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
    702       Manifest::INVALID_LOCATION,
    703       extensions::Manifest::TYPE_EXTENSION,
    704       false);
    705   ASSERT_TRUE(ext);
    706   service_->AddExtension(ext.get());
    707 
    708   std::string master_prefs(kDistributionConfig);
    709   std::string ext_id = ext->id();
    710   ReplaceString(&master_prefs, "placeholder_for_id", ext_id);
    711 
    712   // Reset to non organic defaults.
    713   ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
    714                ProfileResetter::HOMEPAGE |
    715                ProfileResetter::STARTUP_PAGES, master_prefs);
    716 
    717   ResettableSettingsSnapshot nonorganic_snap(profile());
    718   EXPECT_EQ(ResettableSettingsSnapshot::ALL_FIELDS,
    719             empty_snap.FindDifferentFields(nonorganic_snap));
    720   empty_snap.Subtract(nonorganic_snap);
    721   EXPECT_TRUE(empty_snap.startup_urls().empty());
    722   EXPECT_EQ(SessionStartupPref::GetDefaultStartupType(),
    723             empty_snap.startup_type());
    724   EXPECT_TRUE(empty_snap.homepage().empty());
    725   EXPECT_TRUE(empty_snap.homepage_is_ntp());
    726   EXPECT_NE(std::string::npos, empty_snap.dse_url().find("{google:baseURL}"));
    727   EXPECT_EQ(std::vector<std::string>(), empty_snap.enabled_extensions());
    728 
    729   // Reset to organic defaults.
    730   ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
    731                ProfileResetter::HOMEPAGE |
    732                ProfileResetter::STARTUP_PAGES |
    733                ProfileResetter::EXTENSIONS);
    734 
    735   ResettableSettingsSnapshot organic_snap(profile());
    736   EXPECT_EQ(ResettableSettingsSnapshot::ALL_FIELDS,
    737             nonorganic_snap.FindDifferentFields(organic_snap));
    738   nonorganic_snap.Subtract(organic_snap);
    739   const GURL urls[] = {GURL("http://foo.de"), GURL("http://goo.gl")};
    740   EXPECT_EQ(std::vector<GURL>(urls, urls + arraysize(urls)),
    741             nonorganic_snap.startup_urls());
    742   EXPECT_EQ(SessionStartupPref::URLS, nonorganic_snap.startup_type());
    743   EXPECT_EQ("http://www.foo.com", nonorganic_snap.homepage());
    744   EXPECT_FALSE(nonorganic_snap.homepage_is_ntp());
    745   EXPECT_EQ("http://www.foo.com/s?q={searchTerms}", nonorganic_snap.dse_url());
    746   EXPECT_EQ(std::vector<std::string>(1, ext_id),
    747             nonorganic_snap.enabled_extensions());
    748 }
    749 
    750 TEST_F(ProfileResetterTest, FeedbackSerializtionTest) {
    751   // Reset to non organic defaults.
    752   ResetAndWait(ProfileResetter::DEFAULT_SEARCH_ENGINE |
    753                ProfileResetter::HOMEPAGE |
    754                ProfileResetter::STARTUP_PAGES, kDistributionConfig);
    755 
    756   scoped_refptr<Extension> ext = CreateExtension(
    757       "example",
    758       base::FilePath(FILE_PATH_LITERAL("//nonexistent")),
    759       Manifest::INVALID_LOCATION,
    760       extensions::Manifest::TYPE_EXTENSION,
    761       false);
    762   ASSERT_TRUE(ext);
    763   service_->AddExtension(ext.get());
    764 
    765   const ResettableSettingsSnapshot nonorganic_snap(profile());
    766 
    767   COMPILE_ASSERT(ResettableSettingsSnapshot::ALL_FIELDS == 63,
    768                  expand_this_test);
    769   for (int field_mask = 0; field_mask <= ResettableSettingsSnapshot::ALL_FIELDS;
    770        ++field_mask) {
    771     std::string report = SerializeSettingsReport(nonorganic_snap, field_mask);
    772     JSONStringValueSerializer json(report);
    773     std::string error;
    774     scoped_ptr<base::Value> root(json.Deserialize(NULL, &error));
    775     ASSERT_TRUE(root) << error;
    776     ASSERT_TRUE(root->IsType(base::Value::TYPE_DICTIONARY)) << error;
    777 
    778     base::DictionaryValue* dict =
    779         static_cast<base::DictionaryValue*>(root.get());
    780 
    781     ListValue* startup_urls = NULL;
    782     int startup_type = 0;
    783     std::string homepage;
    784     bool homepage_is_ntp = true;
    785     std::string default_search_engine;
    786     ListValue* extensions;
    787 
    788     EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_URLS),
    789               dict->GetList("startup_urls", &startup_urls));
    790     EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::STARTUP_TYPE),
    791               dict->GetInteger("startup_type", &startup_type));
    792     EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::HOMEPAGE),
    793               dict->GetString("homepage", &homepage));
    794     EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::HOMEPAGE_IS_NTP),
    795               dict->GetBoolean("homepage_is_ntp", &homepage_is_ntp));
    796     EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::DSE_URL),
    797               dict->GetString("default_search_engine", &default_search_engine));
    798     EXPECT_EQ(!!(field_mask & ResettableSettingsSnapshot::EXTENSIONS),
    799               dict->GetList("enabled_extensions", &extensions));
    800   }
    801 }
    802 
    803 }  // namespace
    804