Home | History | Annotate | Download | only in profile_resetter
      1 // Copyright 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/automatic_profile_resetter_delegate.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/bind.h"
     10 #include "base/bind_helpers.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/prefs/pref_service.h"
     14 #include "base/run_loop.h"
     15 #include "base/strings/string_number_conversions.h"
     16 #include "base/strings/string_split.h"
     17 #include "base/strings/string_util.h"
     18 #include "base/strings/utf_string_conversions.h"
     19 #include "base/test/values_test_util.h"
     20 #include "base/values.h"
     21 #include "chrome/app/chrome_command_ids.h"
     22 #include "chrome/browser/chrome_notification_types.h"
     23 #include "chrome/browser/extensions/extension_service.h"
     24 #include "chrome/browser/extensions/extension_service_test_base.h"
     25 #include "chrome/browser/google/google_brand.h"
     26 #include "chrome/browser/profile_resetter/brandcoded_default_settings.h"
     27 #include "chrome/browser/profile_resetter/profile_reset_global_error.h"
     28 #include "chrome/browser/search_engines/template_url_service_factory.h"
     29 #include "chrome/browser/search_engines/template_url_service_factory_test_util.h"
     30 #include "chrome/browser/ui/global_error/global_error.h"
     31 #include "chrome/browser/ui/global_error/global_error_service.h"
     32 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
     33 #include "chrome/common/pref_names.h"
     34 #include "chrome/test/base/testing_pref_service_syncable.h"
     35 #include "chrome/test/base/testing_profile.h"
     36 #include "components/search_engines/default_search_manager.h"
     37 #include "components/search_engines/template_url_prepopulate_data.h"
     38 #include "components/search_engines/template_url_service.h"
     39 #include "content/public/browser/notification_service.h"
     40 #include "net/http/http_response_headers.h"
     41 #include "net/url_request/test_url_fetcher_factory.h"
     42 #include "testing/gmock/include/gmock/gmock.h"
     43 #include "testing/gtest/include/gtest/gtest.h"
     44 
     45 #if defined(OS_WIN)
     46 #include "chrome/browser/enumerate_modules_model_win.h"
     47 #endif
     48 
     49 namespace {
     50 
     51 const char kTestBrandcode[] = "FOOBAR";
     52 
     53 const char kTestHomepage[] = "http://google.com";
     54 const char kTestBrandedHomepage[] = "http://example.com";
     55 
     56 const ProfileResetter::ResettableFlags kResettableAspectsForTest =
     57     ProfileResetter::ALL & ~ProfileResetter::COOKIES_AND_SITE_DATA;
     58 
     59 // Helpers -------------------------------------------------------------------
     60 
     61 // A testing version of the AutomaticProfileResetterDelegate that differs from
     62 // the real one only in that it has its feedback reporting mocked out, and it
     63 // will not reset COOKIES_AND_SITE_DATA, due to difficulties to set up some
     64 // required URLRequestContexts in unit tests.
     65 class AutomaticProfileResetterDelegateUnderTest
     66     : public AutomaticProfileResetterDelegateImpl {
     67  public:
     68   explicit AutomaticProfileResetterDelegateUnderTest(Profile* profile)
     69       : AutomaticProfileResetterDelegateImpl(
     70             profile, kResettableAspectsForTest) {}
     71   virtual ~AutomaticProfileResetterDelegateUnderTest() {}
     72 
     73   MOCK_CONST_METHOD1(SendFeedback, void(const std::string&));
     74 
     75  private:
     76   DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterDelegateUnderTest);
     77 };
     78 
     79 class MockCallbackTarget {
     80  public:
     81   MockCallbackTarget() {}
     82   ~MockCallbackTarget() {}
     83 
     84   MOCK_CONST_METHOD0(Run, void(void));
     85 
     86   base::Closure CreateClosure() {
     87     return base::Bind(&MockCallbackTarget::Run, base::Unretained(this));
     88   }
     89 
     90  private:
     91   DISALLOW_COPY_AND_ASSIGN(MockCallbackTarget);
     92 };
     93 
     94 // Returns the details of the default search provider from |prefs| in a format
     95 // suitable for usage as |expected_details| in ExpectDetailsMatch().
     96 const base::DictionaryValue* GetDefaultSearchProviderDetailsFromPrefs(
     97     const PrefService* prefs) {
     98   return prefs->GetDictionary(
     99       DefaultSearchManager::kDefaultSearchProviderDataPrefName);
    100 }
    101 
    102 // Verifies that the |details| of a search engine as provided by the delegate
    103 // are correct in comparison to the |expected_details| coming from the Prefs.
    104 void ExpectDetailsMatch(const base::DictionaryValue& expected_details,
    105                         const base::DictionaryValue& details) {
    106   for (base::DictionaryValue::Iterator it(expected_details); !it.IsAtEnd();
    107        it.Advance()) {
    108     SCOPED_TRACE(testing::Message("Key: ") << it.key());
    109     if (it.key() == "enabled" || it.key() == "synced_guid") {
    110       // These attributes should not be present.
    111       EXPECT_FALSE(details.HasKey(it.key()));
    112       continue;
    113     }
    114     const base::Value* expected_value = &it.value();
    115     const base::Value* actual_value = NULL;
    116     ASSERT_TRUE(details.Get(it.key(), &actual_value));
    117 
    118     // Ignore ID as it is dynamically assigned by the TemplateURLService.
    119     // last_modified may get updated during a run, so ignore value differences.
    120     if (it.key() != "id" && it.key() != "last_modified") {
    121       // Everything else is the same format.
    122       EXPECT_TRUE(actual_value->Equals(expected_value))
    123           << "Expected: " << *expected_value << ". Actual: " << *actual_value;
    124     }
    125   }
    126 }
    127 
    128 // If |simulate_failure| is false, then replies to the pending request on
    129 // |fetcher| with a brandcoded config that only specifies a home page URL.
    130 // If |simulate_failure| is true, replies with 404.
    131 void ServicePendingBrancodedConfigFetch(net::TestURLFetcher* fetcher,
    132                                         bool simulate_failure) {
    133   const char kBrandcodedXmlSettings[] =
    134       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    135       "<response protocol=\"3.0\" server=\"prod\">"
    136         "<app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
    137           "<data index=\"skipfirstrunui-importsearch-defaultbrowser\" "
    138           "name=\"install\" status=\"ok\">"
    139             "{\"homepage\" : \"$1\"}"
    140           "</data>"
    141         "</app>"
    142       "</response>";
    143 
    144   fetcher->set_response_code(simulate_failure ? 404 : 200);
    145   scoped_refptr<net::HttpResponseHeaders> response_headers(
    146       new net::HttpResponseHeaders(""));
    147   response_headers->AddHeader("Content-Type: text/xml");
    148   fetcher->set_response_headers(response_headers);
    149   if (!simulate_failure) {
    150     std::string response(kBrandcodedXmlSettings);
    151     size_t placeholder_index = response.find("$1");
    152     ASSERT_NE(std::string::npos, placeholder_index);
    153     response.replace(placeholder_index, 2, kTestBrandedHomepage);
    154     fetcher->SetResponseString(response);
    155   }
    156   fetcher->delegate()->OnURLFetchComplete(fetcher);
    157 }
    158 
    159 
    160 // Test fixture --------------------------------------------------------------
    161 
    162 // ExtensionServiceTestBase sets up a TestingProfile with the ExtensionService,
    163 // we then add the TemplateURLService, so the ProfileResetter can be exercised.
    164 class AutomaticProfileResetterDelegateTest
    165     : public extensions::ExtensionServiceTestBase {
    166  protected:
    167   AutomaticProfileResetterDelegateTest() {}
    168   virtual ~AutomaticProfileResetterDelegateTest() {}
    169 
    170   virtual void SetUp() OVERRIDE {
    171     extensions::ExtensionServiceTestBase::SetUp();
    172     ExtensionServiceInitParams params = CreateDefaultInitParams();
    173     params.pref_file.clear();  // Prescribes a TestingPrefService to be created.
    174     InitializeExtensionService(params);
    175     template_url_service_test_util_.reset(
    176         new TemplateURLServiceFactoryTestUtil(profile_.get()));
    177     resetter_delegate_.reset(
    178         new AutomaticProfileResetterDelegateUnderTest(profile()));
    179   }
    180 
    181   virtual void TearDown() OVERRIDE {
    182     resetter_delegate_.reset();
    183     template_url_service_test_util_.reset();
    184     extensions::ExtensionServiceTestBase::TearDown();
    185   }
    186 
    187   scoped_ptr<TemplateURL> CreateTestTemplateURL() {
    188     TemplateURLData data;
    189 
    190     data.SetURL("http://example.com/search?q={searchTerms}");
    191     data.suggestions_url = "http://example.com/suggest?q={searchTerms}";
    192     data.instant_url = "http://example.com/instant?q={searchTerms}";
    193     data.image_url = "http://example.com/image?q={searchTerms}";
    194     data.search_url_post_params = "search-post-params";
    195     data.suggestions_url_post_params = "suggest-post-params";
    196     data.instant_url_post_params = "instant-post-params";
    197     data.image_url_post_params = "image-post-params";
    198 
    199     data.favicon_url = GURL("http://example.com/favicon.ico");
    200     data.new_tab_url = "http://example.com/newtab.html";
    201     data.alternate_urls.push_back("http://example.com/s?q={searchTerms}");
    202 
    203     data.short_name = base::ASCIIToUTF16("name");
    204     data.SetKeyword(base::ASCIIToUTF16("keyword"));
    205     data.search_terms_replacement_key = "search-terms-replacment-key";
    206     data.prepopulate_id = 42;
    207     data.input_encodings.push_back("UTF-8");
    208     data.safe_for_autoreplace = true;
    209 
    210     return scoped_ptr<TemplateURL>(new TemplateURL(data));
    211   }
    212 
    213   void ExpectNoPendingBrandcodedConfigFetch() {
    214     EXPECT_FALSE(test_url_fetcher_factory_.GetFetcherByID(0));
    215   }
    216 
    217   void ExpectAndServicePendingBrandcodedConfigFetch(bool simulate_failure) {
    218     net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0);
    219     ASSERT_TRUE(fetcher);
    220     EXPECT_THAT(fetcher->upload_data(),
    221                 testing::HasSubstr(kTestBrandcode));
    222     ServicePendingBrancodedConfigFetch(fetcher, simulate_failure);
    223   }
    224 
    225   void ExpectResetPromptState(bool active) {
    226     GlobalErrorService* global_error_service =
    227         GlobalErrorServiceFactory::GetForProfile(profile());
    228     GlobalError* global_error = global_error_service->
    229         GetGlobalErrorByMenuItemCommandID(IDC_SHOW_SETTINGS_RESET_BUBBLE);
    230     EXPECT_EQ(active, !!global_error);
    231   }
    232 
    233   AutomaticProfileResetterDelegateUnderTest* resetter_delegate() {
    234     return resetter_delegate_.get();
    235   }
    236 
    237   TemplateURLServiceFactoryTestUtil* template_url_service_test_util() {
    238     return template_url_service_test_util_.get();
    239   }
    240 
    241  private:
    242   scoped_ptr<TemplateURLServiceFactoryTestUtil> template_url_service_test_util_;
    243   net::TestURLFetcherFactory test_url_fetcher_factory_;
    244   scoped_ptr<AutomaticProfileResetterDelegateUnderTest> resetter_delegate_;
    245 
    246   DISALLOW_COPY_AND_ASSIGN(AutomaticProfileResetterDelegateTest);
    247 };
    248 
    249 
    250 // Tests ---------------------------------------------------------------------
    251 
    252 TEST_F(AutomaticProfileResetterDelegateTest,
    253        TriggerAndWaitOnModuleEnumeration) {
    254   // Expect ready_callback to be called just after the modules have been
    255   // enumerated. Fail if it is not called. Note: as the EnumerateModulesModel is
    256   // a global singleton, the callback might be invoked immediately if another
    257   // test-case (e.g. the one below) has already performed module enumeration.
    258   testing::StrictMock<MockCallbackTarget> mock_target;
    259   EXPECT_CALL(mock_target, Run());
    260   resetter_delegate()->RequestCallbackWhenLoadedModulesAreEnumerated(
    261       mock_target.CreateClosure());
    262   resetter_delegate()->EnumerateLoadedModulesIfNeeded();
    263   base::RunLoop().RunUntilIdle();
    264 
    265   testing::Mock::VerifyAndClearExpectations(&mock_target);
    266 
    267   // Expect ready_callback to be posted immediately when the modules have
    268   // already been enumerated.
    269   EXPECT_CALL(mock_target, Run());
    270   resetter_delegate()->RequestCallbackWhenLoadedModulesAreEnumerated(
    271       mock_target.CreateClosure());
    272   base::RunLoop().RunUntilIdle();
    273 
    274 #if defined(OS_WIN)
    275   testing::Mock::VerifyAndClearExpectations(&mock_target);
    276 
    277   // Expect ready_callback to be posted immediately even when the modules had
    278   // already been enumerated when the delegate was constructed.
    279   scoped_ptr<AutomaticProfileResetterDelegate> late_resetter_delegate(
    280       new AutomaticProfileResetterDelegateImpl(profile(),
    281                                                ProfileResetter::ALL));
    282 
    283   EXPECT_CALL(mock_target, Run());
    284   late_resetter_delegate->RequestCallbackWhenLoadedModulesAreEnumerated(
    285       mock_target.CreateClosure());
    286   base::RunLoop().RunUntilIdle();
    287 #endif
    288 }
    289 
    290 TEST_F(AutomaticProfileResetterDelegateTest, GetLoadedModuleNameDigests) {
    291   resetter_delegate()->EnumerateLoadedModulesIfNeeded();
    292   base::RunLoop().RunUntilIdle();
    293   scoped_ptr<base::ListValue> module_name_digests(
    294       resetter_delegate()->GetLoadedModuleNameDigests());
    295 
    296   // Just verify that each element looks like an MD5 hash in hexadecimal, and
    297   // also that we have at least one element on Win.
    298   ASSERT_TRUE(module_name_digests);
    299   for (base::ListValue::const_iterator it = module_name_digests->begin();
    300        it != module_name_digests->end(); ++it) {
    301     std::string digest_hex;
    302     std::vector<uint8> digest_raw;
    303 
    304     ASSERT_TRUE((*it)->GetAsString(&digest_hex));
    305     ASSERT_TRUE(base::HexStringToBytes(digest_hex, &digest_raw));
    306     EXPECT_EQ(16u, digest_raw.size());
    307   }
    308 #if defined(OS_WIN)
    309   EXPECT_LE(1u, module_name_digests->GetSize());
    310 #endif
    311 }
    312 
    313 TEST_F(AutomaticProfileResetterDelegateTest, LoadAndWaitOnTemplateURLService) {
    314   // Expect ready_callback to be called just after the template URL service gets
    315   // initialized. Fail if it is not called, or called too early.
    316   testing::StrictMock<MockCallbackTarget> mock_target;
    317   resetter_delegate()->RequestCallbackWhenTemplateURLServiceIsLoaded(
    318       mock_target.CreateClosure());
    319   base::RunLoop().RunUntilIdle();
    320 
    321   EXPECT_CALL(mock_target, Run());
    322   resetter_delegate()->LoadTemplateURLServiceIfNeeded();
    323   base::RunLoop().RunUntilIdle();
    324 
    325   testing::Mock::VerifyAndClearExpectations(&mock_target);
    326 
    327   // Expect ready_callback to be posted immediately when the template URL
    328   // service is already initialized.
    329   EXPECT_CALL(mock_target, Run());
    330   resetter_delegate()->RequestCallbackWhenTemplateURLServiceIsLoaded(
    331       mock_target.CreateClosure());
    332   base::RunLoop().RunUntilIdle();
    333 
    334   testing::Mock::VerifyAndClearExpectations(&mock_target);
    335 
    336   // Expect ready_callback to be posted immediately even when the template URL
    337   // service had already been initialized when the delegate was constructed.
    338   scoped_ptr<AutomaticProfileResetterDelegate> late_resetter_delegate(
    339       new AutomaticProfileResetterDelegateImpl(profile(),
    340                                                ProfileResetter::ALL));
    341 
    342   EXPECT_CALL(mock_target, Run());
    343   late_resetter_delegate->RequestCallbackWhenTemplateURLServiceIsLoaded(
    344       mock_target.CreateClosure());
    345   base::RunLoop().RunUntilIdle();
    346 }
    347 
    348 TEST_F(AutomaticProfileResetterDelegateTest,
    349        DefaultSearchProviderDataWhenNotManaged) {
    350   TemplateURLService* template_url_service =
    351       TemplateURLServiceFactory::GetForProfile(profile());
    352   template_url_service_test_util()->VerifyLoad();
    353 
    354   // Check that the "managed state" and the details returned by the delegate are
    355   // correct. We verify the details against the data stored by
    356   // TemplateURLService into Prefs.
    357   scoped_ptr<TemplateURL> owned_custom_dsp(CreateTestTemplateURL());
    358   TemplateURL* custom_dsp = owned_custom_dsp.get();
    359   template_url_service->Add(owned_custom_dsp.release());
    360   template_url_service->SetUserSelectedDefaultSearchProvider(custom_dsp);
    361 
    362   PrefService* prefs = profile()->GetPrefs();
    363   ASSERT_TRUE(prefs);
    364   scoped_ptr<base::DictionaryValue> dsp_details(
    365       resetter_delegate()->GetDefaultSearchProviderDetails());
    366   const base::DictionaryValue* expected_dsp_details =
    367       GetDefaultSearchProviderDetailsFromPrefs(prefs);
    368 
    369   ExpectDetailsMatch(*expected_dsp_details, *dsp_details);
    370   EXPECT_FALSE(resetter_delegate()->IsDefaultSearchProviderManaged());
    371 }
    372 
    373 TEST_F(AutomaticProfileResetterDelegateTest,
    374        DefaultSearchProviderDataWhenManaged) {
    375   const char kTestSearchURL[] = "http://example.com/search?q={searchTerms}";
    376   const char kTestName[] = "name";
    377   const char kTestKeyword[] = "keyword";
    378 
    379   template_url_service_test_util()->VerifyLoad();
    380 
    381   EXPECT_FALSE(resetter_delegate()->IsDefaultSearchProviderManaged());
    382 
    383   // Set managed preferences to emulate a default search provider set by policy.
    384   template_url_service_test_util()->SetManagedDefaultSearchPreferences(
    385       true, kTestName, kTestKeyword, kTestSearchURL, std::string(),
    386       std::string(), std::string(), std::string(), std::string());
    387 
    388   EXPECT_TRUE(resetter_delegate()->IsDefaultSearchProviderManaged());
    389   scoped_ptr<base::DictionaryValue> dsp_details(
    390       resetter_delegate()->GetDefaultSearchProviderDetails());
    391   // Checking that all details are correct is already done by the above test.
    392   // Just make sure details are reported about the correct engine.
    393   base::ExpectDictStringValue(kTestSearchURL, *dsp_details, "search_url");
    394 
    395   // Set managed preferences to emulate that having a default search provider is
    396   // disabled by policy.
    397   template_url_service_test_util()->RemoveManagedDefaultSearchPreferences();
    398   template_url_service_test_util()->SetManagedDefaultSearchPreferences(
    399       false, std::string(), std::string(), std::string(), std::string(),
    400       std::string(), std::string(), std::string(), std::string());
    401 
    402   dsp_details = resetter_delegate()->GetDefaultSearchProviderDetails();
    403   EXPECT_TRUE(resetter_delegate()->IsDefaultSearchProviderManaged());
    404   EXPECT_TRUE(dsp_details->empty());
    405 }
    406 
    407 TEST_F(AutomaticProfileResetterDelegateTest,
    408        GetPrepopulatedSearchProvidersDetails) {
    409   TemplateURLService* template_url_service =
    410       TemplateURLServiceFactory::GetForProfile(profile());
    411   template_url_service_test_util()->VerifyLoad();
    412 
    413   scoped_ptr<base::ListValue> search_engines_details(
    414       resetter_delegate()->GetPrepopulatedSearchProvidersDetails());
    415 
    416   // Do the same kind of verification as for GetDefaultSearchEngineDetails:
    417   // subsequently set each pre-populated engine as the default, so we can verify
    418   // that the details returned by the delegate about one particular engine are
    419   // correct in comparison to what has been stored to the Prefs.
    420   std::vector<TemplateURL*> prepopulated_engines =
    421       template_url_service->GetTemplateURLs();
    422 
    423   ASSERT_EQ(prepopulated_engines.size(), search_engines_details->GetSize());
    424 
    425   for (size_t i = 0; i < search_engines_details->GetSize(); ++i) {
    426     const base::DictionaryValue* details = NULL;
    427     ASSERT_TRUE(search_engines_details->GetDictionary(i, &details));
    428 
    429     std::string keyword;
    430     ASSERT_TRUE(details->GetString("keyword", &keyword));
    431     TemplateURL* search_engine =
    432         template_url_service->GetTemplateURLForKeyword(
    433             base::ASCIIToUTF16(keyword));
    434     ASSERT_TRUE(search_engine);
    435     template_url_service->SetUserSelectedDefaultSearchProvider(
    436         prepopulated_engines[i]);
    437 
    438     PrefService* prefs = profile()->GetPrefs();
    439     ASSERT_TRUE(prefs);
    440     const base::DictionaryValue* expected_dsp_details =
    441         GetDefaultSearchProviderDetailsFromPrefs(prefs);
    442     ExpectDetailsMatch(*expected_dsp_details, *details);
    443   }
    444 }
    445 
    446 TEST_F(AutomaticProfileResetterDelegateTest,
    447        FetchAndWaitOnDefaultSettingsVanilla) {
    448   google_brand::BrandForTesting scoped_brand_for_testing((std::string()));
    449 
    450   // Expect ready_callback to be called just after empty brandcoded settings
    451   // are loaded, given this is a vanilla build. Fail if it is not called, or
    452   // called too early.
    453   testing::StrictMock<MockCallbackTarget> mock_target;
    454   resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
    455       mock_target.CreateClosure());
    456   base::RunLoop().RunUntilIdle();
    457   EXPECT_FALSE(resetter_delegate()->brandcoded_defaults());
    458 
    459   EXPECT_CALL(mock_target, Run());
    460   resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded();
    461   base::RunLoop().RunUntilIdle();
    462   ExpectNoPendingBrandcodedConfigFetch();
    463 
    464   testing::Mock::VerifyAndClearExpectations(&mock_target);
    465   EXPECT_TRUE(resetter_delegate()->brandcoded_defaults());
    466 
    467   // Expect ready_callback to be posted immediately when the brandcoded settings
    468   // have already been loaded.
    469   EXPECT_CALL(mock_target, Run());
    470   resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
    471       mock_target.CreateClosure());
    472   base::RunLoop().RunUntilIdle();
    473 
    474   // No test for a new instance of AutomaticProfileResetterDelegate. That will
    475   // need to fetch the brandcoded settings again.
    476 }
    477 
    478 TEST_F(AutomaticProfileResetterDelegateTest,
    479        FetchAndWaitOnDefaultSettingsBranded) {
    480   google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode);
    481 
    482   // Expect ready_callback to be called just after the brandcoded settings are
    483   // downloaded. Fail if it is not called, or called too early.
    484   testing::StrictMock<MockCallbackTarget> mock_target;
    485   resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
    486       mock_target.CreateClosure());
    487   base::RunLoop().RunUntilIdle();
    488   EXPECT_FALSE(resetter_delegate()->brandcoded_defaults());
    489 
    490   EXPECT_CALL(mock_target, Run());
    491   resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded();
    492   ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/);
    493   base::RunLoop().RunUntilIdle();
    494 
    495   testing::Mock::VerifyAndClearExpectations(&mock_target);
    496   const BrandcodedDefaultSettings* brandcoded_defaults =
    497       resetter_delegate()->brandcoded_defaults();
    498   ASSERT_TRUE(brandcoded_defaults);
    499   std::string homepage_url;
    500   EXPECT_TRUE(brandcoded_defaults->GetHomepage(&homepage_url));
    501   EXPECT_EQ(kTestBrandedHomepage, homepage_url);
    502 
    503   // Expect ready_callback to be posted immediately when the brandcoded settings
    504   // have already been downloaded.
    505   EXPECT_CALL(mock_target, Run());
    506   resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
    507       mock_target.CreateClosure());
    508   base::RunLoop().RunUntilIdle();
    509 }
    510 
    511 TEST_F(AutomaticProfileResetterDelegateTest,
    512        FetchAndWaitOnDefaultSettingsBrandedFailure) {
    513   google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode);
    514 
    515   // Expect ready_callback to be called just after the brandcoded settings have
    516   // failed to download. Fail if it is not called, or called too early.
    517   testing::StrictMock<MockCallbackTarget> mock_target;
    518   resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
    519       mock_target.CreateClosure());
    520   base::RunLoop().RunUntilIdle();
    521 
    522   EXPECT_CALL(mock_target, Run());
    523   resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded();
    524   ExpectAndServicePendingBrandcodedConfigFetch(true /*simulate_failure*/);
    525   base::RunLoop().RunUntilIdle();
    526 
    527   testing::Mock::VerifyAndClearExpectations(&mock_target);
    528   EXPECT_TRUE(resetter_delegate()->brandcoded_defaults());
    529 
    530   // Expect ready_callback to be posted immediately when the brandcoded settings
    531   // have already been attempted to be downloaded, but failed.
    532   EXPECT_CALL(mock_target, Run());
    533   resetter_delegate()->RequestCallbackWhenBrandcodedDefaultsAreFetched(
    534       mock_target.CreateClosure());
    535   base::RunLoop().RunUntilIdle();
    536 }
    537 
    538 TEST_F(AutomaticProfileResetterDelegateTest, TriggerReset) {
    539   google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode);
    540 
    541   PrefService* prefs = profile()->GetPrefs();
    542   DCHECK(prefs);
    543   prefs->SetString(prefs::kHomePage, kTestHomepage);
    544 
    545   testing::StrictMock<MockCallbackTarget> mock_target;
    546   EXPECT_CALL(mock_target, Run());
    547   EXPECT_CALL(*resetter_delegate(), SendFeedback(testing::_)).Times(0);
    548   resetter_delegate()->TriggerProfileSettingsReset(
    549       false /*send_feedback*/, mock_target.CreateClosure());
    550   ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/);
    551   base::RunLoop().RunUntilIdle();
    552 
    553   EXPECT_EQ(kTestBrandedHomepage, prefs->GetString(prefs::kHomePage));
    554 }
    555 
    556 TEST_F(AutomaticProfileResetterDelegateTest,
    557        TriggerResetWithDefaultSettingsAlreadyLoaded) {
    558   google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode);
    559 
    560   PrefService* prefs = profile()->GetPrefs();
    561   DCHECK(prefs);
    562   prefs->SetString(prefs::kHomePage, kTestHomepage);
    563 
    564   resetter_delegate()->FetchBrandcodedDefaultSettingsIfNeeded();
    565   ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/);
    566   base::RunLoop().RunUntilIdle();
    567 
    568   testing::StrictMock<MockCallbackTarget> mock_target;
    569   EXPECT_CALL(mock_target, Run());
    570   EXPECT_CALL(*resetter_delegate(), SendFeedback(testing::_)).Times(0);
    571   resetter_delegate()->TriggerProfileSettingsReset(
    572       false /*send_feedback*/, mock_target.CreateClosure());
    573   base::RunLoop().RunUntilIdle();
    574 
    575   EXPECT_EQ(kTestBrandedHomepage, prefs->GetString(prefs::kHomePage));
    576 }
    577 
    578 TEST_F(AutomaticProfileResetterDelegateTest,
    579        TriggerResetAndSendFeedback) {
    580   google_brand::BrandForTesting scoped_brand_for_testing(kTestBrandcode);
    581 
    582   PrefService* prefs = profile()->GetPrefs();
    583   DCHECK(prefs);
    584   prefs->SetString(prefs::kHomePage, kTestHomepage);
    585 
    586   testing::StrictMock<MockCallbackTarget> mock_target;
    587   EXPECT_CALL(mock_target, Run());
    588   EXPECT_CALL(*resetter_delegate(),
    589               SendFeedback(testing::HasSubstr(kTestHomepage)));
    590 
    591   resetter_delegate()->TriggerProfileSettingsReset(
    592       true /*send_feedback*/, mock_target.CreateClosure());
    593   ExpectAndServicePendingBrandcodedConfigFetch(false /*simulate_failure*/);
    594   base::RunLoop().RunUntilIdle();
    595 }
    596 
    597 TEST_F(AutomaticProfileResetterDelegateTest, ShowAndDismissPrompt) {
    598   resetter_delegate()->TriggerPrompt();
    599   if (ProfileResetGlobalError::IsSupportedOnPlatform())
    600     ExpectResetPromptState(true /*active*/);
    601   else
    602     ExpectResetPromptState(false /*active*/);
    603   resetter_delegate()->DismissPrompt();
    604   ExpectResetPromptState(false /*active*/);
    605   resetter_delegate()->DismissPrompt();
    606 }
    607 
    608 }  // namespace
    609