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 <vector> 6 7 #include "base/prefs/pref_service.h" 8 #include "chrome/browser/password_manager/password_generation_manager.h" 9 #include "chrome/browser/password_manager/password_manager.h" 10 #include "chrome/browser/password_manager/password_manager_delegate_impl.h" 11 #include "chrome/browser/sync/profile_sync_service.h" 12 #include "chrome/browser/sync/profile_sync_service_factory.h" 13 #include "chrome/common/pref_names.h" 14 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 15 #include "chrome/test/base/testing_profile.h" 16 #include "content/public/test/test_browser_thread.h" 17 #include "testing/gtest/include/gtest/gtest.h" 18 19 class TestPasswordGenerationManager : public PasswordGenerationManager { 20 public: 21 explicit TestPasswordGenerationManager(content::WebContents* contents) 22 : PasswordGenerationManager(contents) {} 23 virtual ~TestPasswordGenerationManager() {} 24 25 virtual void SendStateToRenderer(content::RenderViewHost* host, 26 bool enabled) OVERRIDE { 27 sent_states_.push_back(enabled); 28 } 29 30 const std::vector<bool>& GetSentStates() { 31 return sent_states_; 32 } 33 34 void ClearSentStates() { 35 sent_states_.clear(); 36 } 37 38 private: 39 std::vector<bool> sent_states_; 40 41 DISALLOW_COPY_AND_ASSIGN(TestPasswordGenerationManager); 42 }; 43 44 class PasswordGenerationManagerTest : public ChromeRenderViewHostTestHarness { 45 protected: 46 virtual void SetUp() OVERRIDE { 47 SetThreadBundleOptions(content::TestBrowserThreadBundle::REAL_IO_THREAD); 48 ChromeRenderViewHostTestHarness::SetUp(); 49 50 password_generation_manager_.reset( 51 new TestPasswordGenerationManager(web_contents())); 52 } 53 54 virtual void TearDown() OVERRIDE { 55 ChromeRenderViewHostTestHarness::TearDown(); 56 } 57 58 void UpdateState(bool new_renderer) { 59 password_generation_manager_->UpdateState(NULL, new_renderer); 60 } 61 62 scoped_ptr<TestPasswordGenerationManager> password_generation_manager_; 63 }; 64 65 class IncognitoPasswordGenerationManagerTest : 66 public PasswordGenerationManagerTest { 67 public: 68 virtual content::BrowserContext* CreateBrowserContext() OVERRIDE { 69 // Create an incognito profile. 70 TestingProfile::Builder builder; 71 scoped_ptr<TestingProfile> profile = builder.Build(); 72 profile->set_incognito(true); 73 return profile.release(); 74 } 75 }; 76 77 TEST_F(PasswordGenerationManagerTest, UpdateState) { 78 PasswordManagerDelegateImpl::CreateForWebContents(web_contents()); 79 PasswordManager::CreateForWebContentsAndDelegate( 80 web_contents(), 81 PasswordManagerDelegateImpl::FromWebContents(web_contents())); 82 83 PrefService* prefs = profile()->GetPrefs(); 84 85 // Always set password sync enabled so we can test the behavior of password 86 // generation. 87 prefs->SetBoolean(prefs::kSyncKeepEverythingSynced, false); 88 ProfileSyncService* sync_service = ProfileSyncServiceFactory::GetForProfile( 89 profile()); 90 sync_service->SetSyncSetupCompleted(); 91 syncer::ModelTypeSet preferred_set; 92 preferred_set.Put(syncer::PASSWORDS); 93 sync_service->ChangePreferredDataTypes(preferred_set); 94 95 // Enabled state remains false, should not sent. 96 prefs->SetBoolean(prefs::kPasswordGenerationEnabled, false); 97 UpdateState(false); 98 EXPECT_EQ(0u, password_generation_manager_->GetSentStates().size()); 99 100 // Enabled state from false to true, should sent true. 101 prefs->SetBoolean(prefs::kPasswordGenerationEnabled, true); 102 UpdateState(false); 103 EXPECT_EQ(1u, password_generation_manager_->GetSentStates().size()); 104 EXPECT_TRUE(password_generation_manager_->GetSentStates()[0]); 105 password_generation_manager_->ClearSentStates(); 106 107 // Enabled states remains true, should not sent. 108 prefs->SetBoolean(prefs::kPasswordGenerationEnabled, true); 109 UpdateState(false); 110 EXPECT_EQ(0u, password_generation_manager_->GetSentStates().size()); 111 112 // Enabled states from true to false, should sent false. 113 prefs->SetBoolean(prefs::kPasswordGenerationEnabled, false); 114 UpdateState(false); 115 EXPECT_EQ(1u, password_generation_manager_->GetSentStates().size()); 116 EXPECT_FALSE(password_generation_manager_->GetSentStates()[0]); 117 password_generation_manager_->ClearSentStates(); 118 119 // When a new render_view is created, we send the state even if it's the 120 // same. 121 UpdateState(true); 122 EXPECT_EQ(1u, password_generation_manager_->GetSentStates().size()); 123 EXPECT_FALSE(password_generation_manager_->GetSentStates()[0]); 124 password_generation_manager_->ClearSentStates(); 125 } 126 127 TEST_F(PasswordGenerationManagerTest, UpdatePasswordSyncState) { 128 PasswordManagerDelegateImpl::CreateForWebContents(web_contents()); 129 PasswordManager::CreateForWebContentsAndDelegate( 130 web_contents(), 131 PasswordManagerDelegateImpl::FromWebContents(web_contents())); 132 133 PrefService* prefs = profile()->GetPrefs(); 134 135 // Allow this test to control what should get synced. 136 prefs->SetBoolean(prefs::kSyncKeepEverythingSynced, false); 137 // Always set password generation enabled check box so we can test the 138 // behavior of password sync. 139 prefs->SetBoolean(prefs::kPasswordGenerationEnabled, true); 140 141 // Sync some things, but not passwords. Shouldn't send anything since 142 // password generation is disabled by default. 143 ProfileSyncService* sync_service = ProfileSyncServiceFactory::GetForProfile( 144 profile()); 145 sync_service->SetSyncSetupCompleted(); 146 syncer::ModelTypeSet preferred_set; 147 preferred_set.Put(syncer::EXTENSIONS); 148 preferred_set.Put(syncer::PREFERENCES); 149 sync_service->ChangePreferredDataTypes(preferred_set); 150 syncer::ModelTypeSet new_set = sync_service->GetActiveDataTypes(); 151 UpdateState(false); 152 EXPECT_EQ(0u, password_generation_manager_->GetSentStates().size()); 153 154 // Now sync passwords. 155 preferred_set.Put(syncer::PASSWORDS); 156 sync_service->ChangePreferredDataTypes(preferred_set); 157 UpdateState(false); 158 EXPECT_EQ(1u, password_generation_manager_->GetSentStates().size()); 159 EXPECT_TRUE(password_generation_manager_->GetSentStates()[0]); 160 password_generation_manager_->ClearSentStates(); 161 162 // Add some additional synced state. Nothing should be sent. 163 preferred_set.Put(syncer::THEMES); 164 sync_service->ChangePreferredDataTypes(preferred_set); 165 UpdateState(false); 166 EXPECT_EQ(0u, password_generation_manager_->GetSentStates().size()); 167 168 // Disable syncing. This should disable the feature. 169 sync_service->DisableForUser(); 170 UpdateState(false); 171 EXPECT_EQ(1u, password_generation_manager_->GetSentStates().size()); 172 EXPECT_FALSE(password_generation_manager_->GetSentStates()[0]); 173 password_generation_manager_->ClearSentStates(); 174 175 // When a new render_view is created, we send the state even if it's the 176 // same. 177 UpdateState(true); 178 EXPECT_EQ(1u, password_generation_manager_->GetSentStates().size()); 179 EXPECT_FALSE(password_generation_manager_->GetSentStates()[0]); 180 password_generation_manager_->ClearSentStates(); 181 } 182 183 TEST_F(IncognitoPasswordGenerationManagerTest, 184 UpdatePasswordSyncStateIncognito) { 185 // Disable password manager by going incognito, and enable syncing. The 186 // feature should still be disabled, and nothing will be sent. 187 PasswordManagerDelegateImpl::CreateForWebContents(web_contents()); 188 PasswordManager::CreateForWebContentsAndDelegate( 189 web_contents(), 190 PasswordManagerDelegateImpl::FromWebContents(web_contents())); 191 192 PrefService* prefs = profile()->GetPrefs(); 193 194 // Allow this test to control what should get synced. 195 prefs->SetBoolean(prefs::kSyncKeepEverythingSynced, false); 196 // Always set password generation enabled check box so we can test the 197 // behavior of password sync. 198 prefs->SetBoolean(prefs::kPasswordGenerationEnabled, true); 199 200 browser_sync::SyncPrefs sync_prefs(profile()->GetPrefs()); 201 sync_prefs.SetSyncSetupCompleted(); 202 UpdateState(false); 203 EXPECT_EQ(0u, password_generation_manager_->GetSentStates().size()); 204 } 205