1 // Copyright 2014 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/services/gcm/gcm_profile_service.h" 6 7 #include <vector> 8 9 #include "base/bind.h" 10 #include "base/bind_helpers.h" 11 #include "base/callback.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/run_loop.h" 14 #include "chrome/browser/services/gcm/fake_signin_manager.h" 15 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" 16 #include "chrome/browser/signin/signin_manager_factory.h" 17 #include "chrome/test/base/testing_profile.h" 18 #if defined(OS_CHROMEOS) 19 #include "chromeos/dbus/dbus_thread_manager.h" 20 #endif 21 #include "components/gcm_driver/fake_gcm_app_handler.h" 22 #include "components/gcm_driver/fake_gcm_client.h" 23 #include "components/gcm_driver/fake_gcm_client_factory.h" 24 #include "components/gcm_driver/gcm_client.h" 25 #include "components/gcm_driver/gcm_client_factory.h" 26 #include "components/gcm_driver/gcm_driver.h" 27 #include "components/pref_registry/pref_registry_syncable.h" 28 #include "content/public/browser/browser_context.h" 29 #include "content/public/browser/browser_thread.h" 30 #include "content/public/test/test_browser_thread_bundle.h" 31 #include "testing/gtest/include/gtest/gtest.h" 32 33 namespace gcm { 34 35 namespace { 36 37 const char kTestAccountID[] = "user (at) example.com"; 38 const char kTestAppID[] = "TestApp"; 39 const char kUserID[] = "user"; 40 41 KeyedService* BuildGCMProfileService(content::BrowserContext* context) { 42 return new GCMProfileService( 43 Profile::FromBrowserContext(context), 44 scoped_ptr<GCMClientFactory>(new FakeGCMClientFactory( 45 FakeGCMClient::NO_DELAY_START, 46 content::BrowserThread::GetMessageLoopProxyForThread( 47 content::BrowserThread::UI), 48 content::BrowserThread::GetMessageLoopProxyForThread( 49 content::BrowserThread::IO)))); 50 } 51 52 } // namespace 53 54 class GCMProfileServiceTest : public testing::Test { 55 protected: 56 GCMProfileServiceTest(); 57 virtual ~GCMProfileServiceTest(); 58 59 // testing::Test: 60 virtual void SetUp() OVERRIDE; 61 virtual void TearDown() OVERRIDE; 62 63 FakeGCMClient* GetGCMClient() const; 64 65 void CreateGCMProfileService(); 66 void SignIn(); 67 void SignOut(); 68 69 void RegisterAndWaitForCompletion(const std::vector<std::string>& sender_ids); 70 void UnregisterAndWaitForCompletion(); 71 void SendAndWaitForCompletion(const GCMClient::OutgoingMessage& message); 72 73 void RegisterCompleted(const base::Closure& callback, 74 const std::string& registration_id, 75 GCMClient::Result result); 76 void UnregisterCompleted(const base::Closure& callback, 77 GCMClient::Result result); 78 void SendCompleted(const base::Closure& callback, 79 const std::string& message_id, 80 GCMClient::Result result); 81 82 GCMDriver* driver() const { return gcm_profile_service_->driver(); } 83 std::string registration_id() const { return registration_id_; } 84 GCMClient::Result registration_result() const { return registration_result_; } 85 GCMClient::Result unregistration_result() const { 86 return unregistration_result_; 87 } 88 std::string send_message_id() const { return send_message_id_; } 89 GCMClient::Result send_result() const { return send_result_; } 90 91 private: 92 content::TestBrowserThreadBundle thread_bundle_; 93 scoped_ptr<TestingProfile> profile_; 94 GCMProfileService* gcm_profile_service_; 95 scoped_ptr<FakeGCMAppHandler> gcm_app_handler_; 96 97 std::string registration_id_; 98 GCMClient::Result registration_result_; 99 GCMClient::Result unregistration_result_; 100 std::string send_message_id_; 101 GCMClient::Result send_result_; 102 103 DISALLOW_COPY_AND_ASSIGN(GCMProfileServiceTest); 104 }; 105 106 GCMProfileServiceTest::GCMProfileServiceTest() 107 : gcm_profile_service_(NULL), 108 gcm_app_handler_(new FakeGCMAppHandler), 109 registration_result_(GCMClient::UNKNOWN_ERROR), 110 send_result_(GCMClient::UNKNOWN_ERROR) { 111 } 112 113 GCMProfileServiceTest::~GCMProfileServiceTest() { 114 } 115 116 FakeGCMClient* GCMProfileServiceTest::GetGCMClient() const { 117 return static_cast<FakeGCMClient*>( 118 gcm_profile_service_->driver()->GetGCMClientForTesting()); 119 } 120 121 void GCMProfileServiceTest::SetUp() { 122 #if defined(OS_CHROMEOS) 123 // Create a DBus thread manager setter for its side effect. 124 // Ignore the return value. 125 chromeos::DBusThreadManager::GetSetterForTesting(); 126 #endif 127 TestingProfile::Builder builder; 128 builder.AddTestingFactory(SigninManagerFactory::GetInstance(), 129 FakeSigninManager::Build); 130 profile_ = builder.Build(); 131 } 132 133 void GCMProfileServiceTest::TearDown() { 134 gcm_profile_service_->driver()->RemoveAppHandler(kTestAppID); 135 } 136 137 void GCMProfileServiceTest::CreateGCMProfileService() { 138 gcm_profile_service_ = static_cast<GCMProfileService*>( 139 GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse( 140 profile_.get(), 141 &BuildGCMProfileService)); 142 gcm_profile_service_->driver()->AddAppHandler( 143 kTestAppID, gcm_app_handler_.get()); 144 } 145 146 void GCMProfileServiceTest::SignIn() { 147 FakeSigninManager* signin_manager = static_cast<FakeSigninManager*>( 148 SigninManagerFactory::GetInstance()->GetForProfile(profile_.get())); 149 signin_manager->SignIn(kTestAccountID); 150 base::RunLoop().RunUntilIdle(); 151 } 152 153 void GCMProfileServiceTest::SignOut() { 154 FakeSigninManager* signin_manager = static_cast<FakeSigninManager*>( 155 SigninManagerFactory::GetInstance()->GetForProfile(profile_.get())); 156 signin_manager->SignOut(signin_metrics::SIGNOUT_TEST); 157 base::RunLoop().RunUntilIdle(); 158 } 159 160 void GCMProfileServiceTest::RegisterAndWaitForCompletion( 161 const std::vector<std::string>& sender_ids) { 162 base::RunLoop run_loop; 163 gcm_profile_service_->driver()->Register( 164 kTestAppID, 165 sender_ids, 166 base::Bind(&GCMProfileServiceTest::RegisterCompleted, 167 base::Unretained(this), 168 run_loop.QuitClosure())); 169 run_loop.Run(); 170 } 171 172 void GCMProfileServiceTest::UnregisterAndWaitForCompletion() { 173 base::RunLoop run_loop; 174 gcm_profile_service_->driver()->Unregister( 175 kTestAppID, 176 base::Bind(&GCMProfileServiceTest::UnregisterCompleted, 177 base::Unretained(this), 178 run_loop.QuitClosure())); 179 run_loop.Run(); 180 } 181 182 void GCMProfileServiceTest::SendAndWaitForCompletion( 183 const GCMClient::OutgoingMessage& message) { 184 base::RunLoop run_loop; 185 gcm_profile_service_->driver()->Send( 186 kTestAppID, 187 kUserID, 188 message, 189 base::Bind(&GCMProfileServiceTest::SendCompleted, 190 base::Unretained(this), 191 run_loop.QuitClosure())); 192 run_loop.Run(); 193 } 194 195 void GCMProfileServiceTest::RegisterCompleted( 196 const base::Closure& callback, 197 const std::string& registration_id, 198 GCMClient::Result result) { 199 registration_id_ = registration_id; 200 registration_result_ = result; 201 callback.Run(); 202 } 203 204 void GCMProfileServiceTest::UnregisterCompleted( 205 const base::Closure& callback, 206 GCMClient::Result result) { 207 unregistration_result_ = result; 208 callback.Run(); 209 } 210 211 void GCMProfileServiceTest::SendCompleted( 212 const base::Closure& callback, 213 const std::string& message_id, 214 GCMClient::Result result) { 215 send_message_id_ = message_id; 216 send_result_ = result; 217 callback.Run(); 218 } 219 220 TEST_F(GCMProfileServiceTest, CreateGCMProfileServiceBeforeSignIn) { 221 CreateGCMProfileService(); 222 EXPECT_FALSE(driver()->IsStarted()); 223 224 SignIn(); 225 EXPECT_TRUE(driver()->IsStarted()); 226 } 227 228 TEST_F(GCMProfileServiceTest, CreateGCMProfileServiceAfterSignIn) { 229 SignIn(); 230 // Note that we can't check if GCM is started or not since the 231 // GCMProfileService that hosts the GCMDriver is not created yet. 232 233 CreateGCMProfileService(); 234 EXPECT_TRUE(driver()->IsStarted()); 235 } 236 237 TEST_F(GCMProfileServiceTest, SignInAgain) { 238 CreateGCMProfileService(); 239 SignIn(); 240 EXPECT_TRUE(driver()->IsStarted()); 241 242 SignOut(); 243 EXPECT_FALSE(driver()->IsStarted()); 244 245 SignIn(); 246 EXPECT_TRUE(driver()->IsStarted()); 247 } 248 249 TEST_F(GCMProfileServiceTest, RegisterAndUnregister) { 250 CreateGCMProfileService(); 251 SignIn(); 252 253 std::vector<std::string> sender_ids; 254 sender_ids.push_back("sender"); 255 RegisterAndWaitForCompletion(sender_ids); 256 257 std::string expected_registration_id = 258 GetGCMClient()->GetRegistrationIdFromSenderIds(sender_ids); 259 EXPECT_EQ(expected_registration_id, registration_id()); 260 EXPECT_EQ(GCMClient::SUCCESS, registration_result()); 261 262 UnregisterAndWaitForCompletion(); 263 EXPECT_EQ(GCMClient::SUCCESS, unregistration_result()); 264 } 265 266 TEST_F(GCMProfileServiceTest, Send) { 267 CreateGCMProfileService(); 268 SignIn(); 269 270 GCMClient::OutgoingMessage message; 271 message.id = "1"; 272 message.data["key1"] = "value1"; 273 SendAndWaitForCompletion( message); 274 275 EXPECT_EQ(message.id, send_message_id()); 276 EXPECT_EQ(GCMClient::SUCCESS, send_result()); 277 } 278 279 } // namespace gcm 280