| Index: services/preferences/user_prefs_unittest.cc | 
| diff --git a/services/preferences/user_prefs_unittest.cc b/services/preferences/user_prefs_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..4fe770365bfd0564948216a2682531540288d94c | 
| --- /dev/null | 
| +++ b/services/preferences/user_prefs_unittest.cc | 
| @@ -0,0 +1,145 @@ | 
| +// Copyright 2017 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "services/preferences/public/cpp/pref_store_client.h" | 
| + | 
| +#include "base/macros.h" | 
| +#include "base/memory/ptr_util.h" | 
| +#include "base/message_loop/message_loop.h" | 
| +#include "base/run_loop.h" | 
| +#include "base/values.h" | 
| +#include "components/prefs/in_memory_pref_store.h" | 
| +#include "mojo/public/cpp/bindings/binding_set.h" | 
| +#include "services/preferences/public/cpp/persistent_pref_store_client.h" | 
| +#include "services/preferences/public/interfaces/preferences.mojom.h" | 
| +#include "services/preferences/user_prefs.h" | 
| +#include "testing/gmock/include/gmock/gmock.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| + | 
| +using testing::Invoke; | 
| +using testing::WithArg; | 
| +using testing::WithoutArgs; | 
| +using testing::_; | 
| + | 
| +namespace prefs { | 
| + | 
| +namespace { | 
| + | 
| +class PrefStoreObserverMock : public PrefStore::Observer { | 
| + public: | 
| +  MOCK_METHOD1(OnPrefValueChanged, void(const std::string&)); | 
| +  MOCK_METHOD1(OnInitializationCompleted, void(bool succeeded)); | 
| +}; | 
| + | 
| +class PrefStoreConnectorMock : public mojom::PrefStoreConnector { | 
| + public: | 
| +  MOCK_METHOD1(Connect, void(const ConnectCallback&)); | 
| +}; | 
| + | 
| +class DelayedInitializationPrefStore : public InMemoryPrefStore { | 
| + public: | 
| +  DelayedInitializationPrefStore(bool should_succeed) | 
| +      : should_succeed_(should_succeed) {} | 
| +  bool IsInitializationComplete() const override { return initialized_; } | 
| + | 
| +  void AddObserver(PrefStore::Observer* observer) override { | 
| +    observers_.AddObserver(observer); | 
| +  } | 
| + | 
| +  void RemoveObserver(PrefStore::Observer* observer) override { | 
| +    observers_.RemoveObserver(observer); | 
| +  } | 
| + | 
| +  void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override { | 
| +    DCHECK(!error_delegate); | 
| +    base::ThreadTaskRunnerHandle::Get()->PostTask( | 
| +        FROM_HERE, | 
| +        base::Bind(&DelayedInitializationPrefStore::Initialize, this)); | 
| +  } | 
| + | 
| + private: | 
| +  ~DelayedInitializationPrefStore() override = default; | 
| + | 
| +  void Initialize() { | 
| +    initialized_ = should_succeed_; | 
| +    for (auto& observer : observers_) { | 
| +      observer.OnInitializationCompleted(initialized_); | 
| +    } | 
| +  } | 
| + | 
| +  bool should_succeed_; | 
| +  bool initialized_ = false; | 
| +  base::ObserverList<PrefStore::Observer, true> observers_; | 
| +}; | 
| + | 
| +}  // namespace | 
| + | 
| +class UserPrefsTest : public testing::Test { | 
| + public: | 
| +  UserPrefsTest() = default; | 
| + | 
| +  // testing::Test: | 
| +  void SetUp() override {} | 
| + | 
| +  void TearDown() override {} | 
| + | 
| +  void CreateUserPrefs(scoped_refptr<PersistentPrefStore> backing_pref_store) { | 
| +    user_prefs_ = | 
| +        base::MakeUnique<UserPrefs>(std::move(backing_pref_store), nullptr); | 
| +    mojo::Binding<mojom::PersistentPrefStoreConnector> binding( | 
| +        user_prefs_.get()); | 
| +    pref_store_ = CreateConnection(); | 
| +  } | 
| + | 
| +  scoped_refptr<PersistentPrefStore> CreateConnection() { | 
| +    return make_scoped_refptr(new PersistentPrefStoreClient( | 
| +        bindings_.CreateInterfacePtrAndBind(user_prefs_.get()))); | 
| +  } | 
| + | 
| +  PersistentPrefStore& pref_store() { return *pref_store_; } | 
| + | 
| + private: | 
| +  base::MessageLoop message_loop_; | 
| + | 
| +  std::unique_ptr<UserPrefs> user_prefs_; | 
| +  mojo::BindingSet<mojom::PersistentPrefStoreConnector> bindings_; | 
| + | 
| +  scoped_refptr<PersistentPrefStore> pref_store_; | 
| + | 
| +  DISALLOW_COPY_AND_ASSIGN(UserPrefsTest); | 
| +}; | 
| + | 
| +TEST_F(UserPrefsTest, InitializationSuccess) { | 
| +  auto backing_pref_store = | 
| +      make_scoped_refptr(new DelayedInitializationPrefStore(true)); | 
| +  CreateUserPrefs(backing_pref_store); | 
| +  pref_store().ReadPrefsAsync(nullptr); | 
| +  PrefStoreObserverMock observer; | 
| +  pref_store().AddObserver(&observer); | 
| +  base::RunLoop run_loop; | 
| +  EXPECT_CALL(observer, OnInitializationCompleted(true)) | 
| +      .Times(1) | 
| +      .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); | 
| +  run_loop.Run(); | 
| +  EXPECT_TRUE(pref_store().IsInitializationComplete()); | 
| +  pref_store().RemoveObserver(&observer); | 
| +} | 
| + | 
| +TEST_F(UserPrefsTest, InitializationFailure) { | 
| +  auto backing_pref_store = | 
| +      make_scoped_refptr(new DelayedInitializationPrefStore(false)); | 
| +  CreateUserPrefs(backing_pref_store); | 
| +  pref_store().ReadPrefsAsync(nullptr); | 
| +  PrefStoreObserverMock observer; | 
| +  pref_store().AddObserver(&observer); | 
| +  base::RunLoop run_loop; | 
| +  EXPECT_CALL(observer, OnInitializationCompleted(false)) | 
| +      .Times(1) | 
| +      .WillOnce(WithoutArgs(Invoke([&run_loop]() { run_loop.Quit(); }))); | 
| +  run_loop.Run(); | 
| +  EXPECT_FALSE(pref_store().IsInitializationComplete()); | 
| +  pref_store().RemoveObserver(&observer); | 
| +} | 
| + | 
| +}  // namespace prefs | 
|  |