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
49namespace {
50
51const char kTestBrandcode[] = "FOOBAR";
52
53const char kTestHomepage[] = "http://google.com";
54const char kTestBrandedHomepage[] = "http://example.com";
55
56const 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.
65class 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
79class 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().
96const 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.
104void 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.
131void 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.
164class 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
252TEST_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
290TEST_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
313TEST_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
348TEST_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
373TEST_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
407TEST_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
446TEST_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
478TEST_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
511TEST_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
538TEST_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
556TEST_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
578TEST_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
597TEST_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