Home | History | Annotate | Download | only in invalidation
      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 "base/run_loop.h"
      6 #include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
      7 #include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
      8 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
      9 #include "chrome/test/base/testing_profile.h"
     10 #include "components/gcm_driver/fake_gcm_driver.h"
     11 #include "components/gcm_driver/gcm_driver.h"
     12 #include "components/invalidation/gcm_invalidation_bridge.h"
     13 #include "content/public/test/test_browser_thread_bundle.h"
     14 #include "google_apis/gaia/fake_identity_provider.h"
     15 #include "google_apis/gaia/google_service_auth_error.h"
     16 #include "net/base/ip_endpoint.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace invalidation {
     20 namespace {
     21 
     22 // Implementation of GCMDriver::Register that always succeeds with the same
     23 // registrationId.
     24 class CustomFakeGCMDriver : public gcm::FakeGCMDriver {
     25  public:
     26   CustomFakeGCMDriver() {}
     27   virtual ~CustomFakeGCMDriver() {}
     28 
     29  protected:
     30   // FakeGCMDriver override:
     31   virtual void RegisterImpl(
     32       const std::string& app_id,
     33       const std::vector<std::string>& sender_ids) OVERRIDE {
     34     base::MessageLoop::current()->PostTask(
     35         FROM_HERE,
     36         base::Bind(&CustomFakeGCMDriver::RegisterFinished,
     37                    base::Unretained(this),
     38                    app_id,
     39                    std::string("registration.id"),
     40                    gcm::GCMClient::SUCCESS));
     41   }
     42 
     43  private:
     44   DISALLOW_COPY_AND_ASSIGN(CustomFakeGCMDriver);
     45 };
     46 
     47 class GCMInvalidationBridgeTest : public ::testing::Test {
     48  protected:
     49   GCMInvalidationBridgeTest()
     50       : connection_online_(false) {}
     51 
     52   virtual ~GCMInvalidationBridgeTest() {}
     53 
     54   virtual void SetUp() OVERRIDE {
     55     TestingProfile::Builder builder;
     56     builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
     57                               &BuildAutoIssuingFakeProfileOAuth2TokenService);
     58     profile_ = builder.Build();
     59 
     60     FakeProfileOAuth2TokenService* token_service =
     61         (FakeProfileOAuth2TokenService*)
     62         ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get());
     63     token_service->IssueRefreshTokenForUser("", "fake_refresh_token");
     64     gcm_driver_.reset(new CustomFakeGCMDriver());
     65 
     66     identity_provider_.reset(new FakeIdentityProvider(token_service));
     67     bridge_.reset(new GCMInvalidationBridge(gcm_driver_.get(),
     68                                             identity_provider_.get()));
     69 
     70     delegate_ = bridge_->CreateDelegate();
     71     delegate_->Initialize(
     72         base::Bind(&GCMInvalidationBridgeTest::ConnectionStateChanged,
     73                    base::Unretained(this)));
     74     RunLoop();
     75   }
     76 
     77   void RunLoop() {
     78     base::RunLoop run_loop;
     79     run_loop.RunUntilIdle();
     80   }
     81 
     82  public:
     83   void RegisterFinished(const std::string& registration_id,
     84                         gcm::GCMClient::Result result) {
     85     registration_id_ = registration_id;
     86   }
     87 
     88   void RequestTokenFinished(const GoogleServiceAuthError& error,
     89                             const std::string& token) {
     90     issued_tokens_.push_back(token);
     91     request_token_errors_.push_back(error);
     92   }
     93 
     94   void ConnectionStateChanged(bool online) {
     95     connection_online_ = online;
     96   }
     97 
     98   content::TestBrowserThreadBundle thread_bundle_;
     99   scoped_ptr<Profile> profile_;
    100   scoped_ptr<gcm::GCMDriver> gcm_driver_;
    101   scoped_ptr<FakeIdentityProvider> identity_provider_;
    102 
    103   std::vector<std::string> issued_tokens_;
    104   std::vector<GoogleServiceAuthError> request_token_errors_;
    105   std::string registration_id_;
    106   bool connection_online_;
    107 
    108   scoped_ptr<GCMInvalidationBridge> bridge_;
    109   scoped_ptr<syncer::GCMNetworkChannelDelegate> delegate_;
    110 };
    111 
    112 TEST_F(GCMInvalidationBridgeTest, RequestToken) {
    113   // Make sure that call to RequestToken reaches OAuth2TokenService and gets
    114   // back to callback.
    115   delegate_->RequestToken(
    116       base::Bind(&GCMInvalidationBridgeTest::RequestTokenFinished,
    117                  base::Unretained(this)));
    118   RunLoop();
    119   EXPECT_EQ(1U, issued_tokens_.size());
    120   EXPECT_NE("", issued_tokens_[0]);
    121   EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), request_token_errors_[0]);
    122 }
    123 
    124 TEST_F(GCMInvalidationBridgeTest, RequestTokenTwoConcurrentRequests) {
    125   // First call should finish with REQUEST_CANCELLED error.
    126   delegate_->RequestToken(
    127       base::Bind(&GCMInvalidationBridgeTest::RequestTokenFinished,
    128                  base::Unretained(this)));
    129   // Second request should succeed.
    130   delegate_->RequestToken(
    131       base::Bind(&GCMInvalidationBridgeTest::RequestTokenFinished,
    132                  base::Unretained(this)));
    133   RunLoop();
    134 
    135   EXPECT_EQ(2U, issued_tokens_.size());
    136 
    137   EXPECT_EQ("", issued_tokens_[0]);
    138   EXPECT_EQ(GoogleServiceAuthError::REQUEST_CANCELED,
    139             request_token_errors_[0].state());
    140 
    141   EXPECT_NE("", issued_tokens_[1]);
    142   EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), request_token_errors_[1]);
    143 }
    144 
    145 TEST_F(GCMInvalidationBridgeTest, Register) {
    146   EXPECT_TRUE(registration_id_.empty());
    147   delegate_->Register(base::Bind(&GCMInvalidationBridgeTest::RegisterFinished,
    148                                  base::Unretained(this)));
    149   RunLoop();
    150 
    151   EXPECT_FALSE(registration_id_.empty());
    152 }
    153 
    154 TEST_F(GCMInvalidationBridgeTest, ConnectionState) {
    155   EXPECT_FALSE(connection_online_);
    156   bridge_->OnConnected(net::IPEndPoint());
    157   RunLoop();
    158   EXPECT_TRUE(connection_online_);
    159   bridge_->OnDisconnected();
    160   RunLoop();
    161   EXPECT_FALSE(connection_online_);
    162 }
    163 
    164 }  // namespace
    165 }  // namespace invalidation
    166