Home | History | Annotate | Download | only in gcm
      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