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 33namespace gcm { 34 35namespace { 36 37const char kTestAccountID[] = "user@example.com"; 38const char kTestAppID[] = "TestApp"; 39const char kUserID[] = "user"; 40 41KeyedService* 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 54class 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 106GCMProfileServiceTest::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 113GCMProfileServiceTest::~GCMProfileServiceTest() { 114} 115 116FakeGCMClient* GCMProfileServiceTest::GetGCMClient() const { 117 return static_cast<FakeGCMClient*>( 118 gcm_profile_service_->driver()->GetGCMClientForTesting()); 119} 120 121void 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 133void GCMProfileServiceTest::TearDown() { 134 gcm_profile_service_->driver()->RemoveAppHandler(kTestAppID); 135} 136 137void 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 146void 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 153void 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 160void 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 172void 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 182void 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 195void 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 204void GCMProfileServiceTest::UnregisterCompleted( 205 const base::Closure& callback, 206 GCMClient::Result result) { 207 unregistration_result_ = result; 208 callback.Run(); 209} 210 211void 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 220TEST_F(GCMProfileServiceTest, CreateGCMProfileServiceBeforeSignIn) { 221 CreateGCMProfileService(); 222 EXPECT_FALSE(driver()->IsStarted()); 223 224 SignIn(); 225 EXPECT_TRUE(driver()->IsStarted()); 226} 227 228TEST_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 237TEST_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 249TEST_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 266TEST_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