Home | History | Annotate | Download | only in sync
      1 // Copyright (c) 2012 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/sync/sync_global_error.h"
      6 
      7 #include "chrome/browser/chrome_notification_types.h"
      8 #include "chrome/browser/sync/profile_sync_service_mock.h"
      9 #include "chrome/browser/sync/sync_error_controller.h"
     10 #include "chrome/browser/sync/sync_global_error_factory.h"
     11 #include "chrome/browser/ui/browser.h"
     12 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
     13 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
     14 #include "chrome/test/base/browser_with_test_window_test.h"
     15 #include "chrome/test/base/testing_profile.h"
     16 #include "content/public/browser/notification_observer.h"
     17 #include "content/public/browser/notification_registrar.h"
     18 #include "content/public/browser/notification_source.h"
     19 #include "testing/gmock/include/gmock/gmock.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 
     22 using ::testing::NiceMock;
     23 using ::testing::Return;
     24 using ::testing::ReturnRef;
     25 using ::testing::_;
     26 
     27 namespace {
     28 
     29 class FakeLoginUIService: public LoginUIService {
     30  public:
     31   FakeLoginUIService() : LoginUIService(NULL) {}
     32 };
     33 
     34 class FakeLoginUI : public LoginUIService::LoginUI {
     35  public:
     36   FakeLoginUI() : focus_ui_call_count_(0) {}
     37 
     38   virtual ~FakeLoginUI() {}
     39 
     40   int focus_ui_call_count() const { return focus_ui_call_count_; }
     41 
     42  private:
     43   // Overridden from LoginUIService::LoginUI:
     44   virtual void FocusUI() OVERRIDE {
     45     ++focus_ui_call_count_;
     46   }
     47   virtual void CloseUI() OVERRIDE {}
     48 
     49   int focus_ui_call_count_;
     50 };
     51 
     52 KeyedService* BuildMockLoginUIService(content::BrowserContext* profile) {
     53   return new FakeLoginUIService();
     54 }
     55 
     56 // Same as BrowserWithTestWindowTest, but uses MockBrowser to test calls to
     57 // ExecuteCommand method.
     58 class SyncGlobalErrorTest : public BrowserWithTestWindowTest {
     59  public:
     60   SyncGlobalErrorTest() {}
     61   virtual ~SyncGlobalErrorTest() {}
     62 
     63   virtual void SetUp() OVERRIDE {
     64     profile_.reset(ProfileSyncServiceMock::MakeSignedInTestingProfile());
     65 
     66     BrowserWithTestWindowTest::SetUp();
     67   }
     68 
     69   Profile* profile() { return profile_.get(); }
     70 
     71  private:
     72   scoped_ptr<TestingProfile> profile_;
     73 
     74   DISALLOW_COPY_AND_ASSIGN(SyncGlobalErrorTest);
     75 };
     76 
     77 // Utility function to test that SyncGlobalError behaves correctly for the given
     78 // error condition.
     79 void VerifySyncGlobalErrorResult(NiceMock<ProfileSyncServiceMock>* service,
     80                                  FakeLoginUIService* login_ui_service,
     81                                  Browser* browser,
     82                                  SyncErrorController* error,
     83                                  SyncGlobalError* global_error,
     84                                  GoogleServiceAuthError::State error_state,
     85                                  bool is_signed_in,
     86                                  bool is_error) {
     87   EXPECT_CALL(*service, HasSyncSetupCompleted())
     88               .WillRepeatedly(Return(is_signed_in));
     89 
     90   GoogleServiceAuthError auth_error(error_state);
     91   EXPECT_CALL(*service, GetAuthError()).WillRepeatedly(ReturnRef(auth_error));
     92 
     93   error->OnStateChanged();
     94   EXPECT_EQ(is_error, error->HasError());
     95 
     96   // If there is an error then a menu item and bubble view should be shown.
     97   EXPECT_EQ(is_error, global_error->HasMenuItem());
     98   EXPECT_EQ(is_error, global_error->HasBubbleView());
     99 
    100   // If there is an error then labels should not be empty.
    101   EXPECT_NE(0, global_error->MenuItemCommandID());
    102   EXPECT_NE(is_error, global_error->MenuItemLabel().empty());
    103   EXPECT_NE(is_error, global_error->GetBubbleViewAcceptButtonLabel().empty());
    104 
    105   // We never have a cancel button.
    106   EXPECT_TRUE(global_error->GetBubbleViewCancelButtonLabel().empty());
    107   // We always return a hardcoded title.
    108   EXPECT_FALSE(global_error->GetBubbleViewTitle().empty());
    109 
    110   // Test message handler.
    111   if (is_error) {
    112     FakeLoginUI* login_ui = static_cast<FakeLoginUI*>(
    113         login_ui_service->current_login_ui());
    114     global_error->ExecuteMenuItem(browser);
    115     ASSERT_GT(login_ui->focus_ui_call_count(), 0);
    116     global_error->BubbleViewAcceptButtonPressed(browser);
    117     global_error->BubbleViewDidClose(browser);
    118   }
    119 }
    120 
    121 } // namespace
    122 
    123 // Test that SyncGlobalError shows an error if a passphrase is required.
    124 TEST_F(SyncGlobalErrorTest, PassphraseGlobalError) {
    125   NiceMock<ProfileSyncServiceMock> service(profile());
    126 
    127   FakeLoginUIService* login_ui_service = static_cast<FakeLoginUIService*>(
    128       LoginUIServiceFactory::GetInstance()->SetTestingFactoryAndUse(
    129           profile(), BuildMockLoginUIService));
    130   FakeLoginUI login_ui;
    131   login_ui_service->SetLoginUI(&login_ui);
    132 
    133   SyncErrorController error(&service);
    134   SyncGlobalError global_error(&error, &service);
    135 
    136   browser_sync::SyncBackendHost::Status status;
    137   EXPECT_CALL(service, QueryDetailedSyncStatus(_))
    138               .WillRepeatedly(Return(false));
    139 
    140   EXPECT_CALL(service, IsPassphraseRequired())
    141               .WillRepeatedly(Return(true));
    142   EXPECT_CALL(service, IsPassphraseRequiredForDecryption())
    143               .WillRepeatedly(Return(true));
    144   VerifySyncGlobalErrorResult(
    145       &service, login_ui_service, browser(), &error, &global_error,
    146       GoogleServiceAuthError::NONE, true /* signed in*/, true /* error */);
    147 
    148   // Check that no menu item is shown if there is no error.
    149   EXPECT_CALL(service, IsPassphraseRequired())
    150               .WillRepeatedly(Return(false));
    151   EXPECT_CALL(service, IsPassphraseRequiredForDecryption())
    152               .WillRepeatedly(Return(false));
    153   VerifySyncGlobalErrorResult(
    154       &service, login_ui_service, browser(), &error, &global_error,
    155       GoogleServiceAuthError::NONE, true /* signed in */, false /* no error */);
    156 
    157   // Check that no menu item is shown if sync setup is not completed.
    158   EXPECT_CALL(service, IsPassphraseRequired())
    159               .WillRepeatedly(Return(true));
    160   EXPECT_CALL(service, IsPassphraseRequiredForDecryption())
    161               .WillRepeatedly(Return(true));
    162   VerifySyncGlobalErrorResult(
    163       &service, login_ui_service, browser(), &error, &global_error,
    164       GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS,
    165       false /* not signed in */, false /* no error */);
    166 
    167   global_error.Shutdown();
    168 }
    169