blob: ce457c5c7aac5a7a937fa373175a82862af7daa3 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/recent_tabs/recent_tabs_coordinator.h"
#import <UIKit/UIKit.h>
#include <memory>
#include "components/browser_sync/profile_sync_service.h"
#include "components/browser_sync/profile_sync_service_mock.h"
#include "components/sync_sessions/open_tabs_ui_delegate.h"
#include "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
#include "ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.h"
#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
#include "ios/chrome/browser/sync/sync_setup_service.h"
#include "ios/chrome/browser/sync/sync_setup_service_factory.h"
#include "ios/chrome/browser/sync/sync_setup_service_mock.h"
#import "ios/chrome/browser/ui/recent_tabs/sessions_sync_user_state.h"
#include "ios/chrome/test/block_cleanup_test.h"
#include "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
#include "ios/web/public/test/test_web_thread_bundle.h"
#include "services/identity/public/cpp/identity_manager.h"
#include "services/identity/public/cpp/identity_test_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "third_party/ocmock/OCMock/OCMock.h"
#import "third_party/ocmock/gtest_support.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using testing::_;
using testing::AtLeast;
using testing::Return;
namespace {
std::unique_ptr<KeyedService> CreateSyncSetupService(
web::BrowserState* context) {
ios::ChromeBrowserState* chrome_browser_state =
ios::ChromeBrowserState::FromBrowserState(context);
syncer::SyncService* sync_service =
ProfileSyncServiceFactory::GetForBrowserState(chrome_browser_state);
return std::make_unique<SyncSetupServiceMock>(sync_service);
}
class ProfileSyncServiceMockForRecentTabsTableCoordinator
: public browser_sync::ProfileSyncServiceMock {
public:
explicit ProfileSyncServiceMockForRecentTabsTableCoordinator(
InitParams init_params)
: browser_sync::ProfileSyncServiceMock(std::move(init_params)) {}
~ProfileSyncServiceMockForRecentTabsTableCoordinator() override {}
MOCK_METHOD0(GetOpenTabsUIDelegate, sync_sessions::OpenTabsUIDelegate*());
};
std::unique_ptr<KeyedService>
BuildMockProfileSyncServiceForRecentTabsTableCoordinator(
web::BrowserState* context) {
return std::make_unique<ProfileSyncServiceMockForRecentTabsTableCoordinator>(
CreateProfileSyncServiceParamsForTest(
nullptr, ios::ChromeBrowserState::FromBrowserState(context)));
}
class OpenTabsUIDelegateMock : public sync_sessions::OpenTabsUIDelegate {
public:
OpenTabsUIDelegateMock() {}
~OpenTabsUIDelegateMock() override {}
MOCK_CONST_METHOD2(GetSyncedFaviconForPageURL,
bool(const std::string& pageurl,
scoped_refptr<base::RefCountedMemory>* favicon_png));
MOCK_METHOD1(
GetAllForeignSessions,
bool(std::vector<const sync_sessions::SyncedSession*>* sessions));
MOCK_METHOD3(GetForeignTab,
bool(const std::string& tag,
const SessionID tab_id,
const sessions::SessionTab** tab));
MOCK_METHOD1(DeleteForeignSession, void(const std::string& tag));
MOCK_METHOD2(GetForeignSession,
bool(const std::string& tag,
std::vector<const sessions::SessionWindow*>* windows));
MOCK_METHOD2(GetForeignSessionTabs,
bool(const std::string& tag,
std::vector<const sessions::SessionTab*>* tabs));
MOCK_METHOD1(GetLocalSession,
bool(const sync_sessions::SyncedSession** local));
};
class RecentTabsTableCoordinatorTest : public BlockCleanupTest {
public:
RecentTabsTableCoordinatorTest() : no_error_(GoogleServiceAuthError::NONE) {}
protected:
void SetUp() override {
BlockCleanupTest::SetUp();
TestChromeBrowserState::Builder test_cbs_builder;
test_cbs_builder.AddTestingFactory(
SyncSetupServiceFactory::GetInstance(),
base::BindRepeating(&CreateSyncSetupService));
test_cbs_builder.AddTestingFactory(
ProfileSyncServiceFactory::GetInstance(),
base::BindRepeating(
&BuildMockProfileSyncServiceForRecentTabsTableCoordinator));
chrome_browser_state_ = test_cbs_builder.Build();
ProfileSyncServiceMockForRecentTabsTableCoordinator* sync_service =
static_cast<ProfileSyncServiceMockForRecentTabsTableCoordinator*>(
ProfileSyncServiceFactory::GetForBrowserState(
chrome_browser_state_.get()));
EXPECT_CALL(*sync_service, GetAuthError())
.WillRepeatedly(::testing::ReturnRef(no_error_));
ON_CALL(*sync_service, GetRegisteredDataTypes())
.WillByDefault(Return(syncer::ModelTypeSet()));
sync_service->Initialize();
EXPECT_CALL(*sync_service, GetTransportState())
.WillRepeatedly(Return(syncer::SyncService::TransportState::ACTIVE));
EXPECT_CALL(*sync_service, GetOpenTabsUIDelegate())
.WillRepeatedly(Return(nullptr));
}
void TearDown() override {
[coordinator_ stop];
coordinator_ = nil;
BlockCleanupTest::TearDown();
}
void SetupSyncState(BOOL signedIn,
BOOL syncEnabled,
BOOL hasForeignSessions) {
if (signedIn) {
identity_test_env_.MakePrimaryAccountAvailable("test@test.com");
} else if (identity_test_env_.identity_manager()->HasPrimaryAccount()) {
identity_test_env_.identity_manager()->ClearPrimaryAccount(
identity::IdentityManager::ClearAccountTokensAction::kDefault,
signin_metrics::SIGNOUT_TEST,
signin_metrics::SignoutDelete::IGNORE_METRIC);
}
SyncSetupServiceMock* syncSetupService = static_cast<SyncSetupServiceMock*>(
SyncSetupServiceFactory::GetForBrowserState(
chrome_browser_state_.get()));
EXPECT_CALL(*syncSetupService, IsSyncEnabled())
.WillRepeatedly(Return(syncEnabled));
EXPECT_CALL(*syncSetupService, IsDataTypePreferred(syncer::PROXY_TABS))
.WillRepeatedly(Return(true));
EXPECT_CALL(*syncSetupService, GetSyncServiceState())
.WillRepeatedly(Return(SyncSetupService::kNoSyncServiceError));
if (syncEnabled) {
ProfileSyncServiceMockForRecentTabsTableCoordinator* sync_service =
static_cast<ProfileSyncServiceMockForRecentTabsTableCoordinator*>(
ProfileSyncServiceFactory::GetForBrowserState(
chrome_browser_state_.get()));
open_tabs_ui_delegate_.reset(new OpenTabsUIDelegateMock());
EXPECT_CALL(*sync_service, GetOpenTabsUIDelegate())
.WillRepeatedly(Return(open_tabs_ui_delegate_.get()));
EXPECT_CALL(*open_tabs_ui_delegate_, GetAllForeignSessions(_))
.WillRepeatedly(Return(hasForeignSessions));
}
}
void CreateController() {
// Sets up the test expectations for the Sync Service Observer Bridge.
// RecentTabsTableCoordinator must be added as an observer of
// ProfileSyncService changes and removed when it is destroyed.
browser_sync::ProfileSyncServiceMock* sync_service =
static_cast<browser_sync::ProfileSyncServiceMock*>(
ProfileSyncServiceFactory::GetForBrowserState(
chrome_browser_state_.get()));
EXPECT_CALL(*sync_service, AddObserver(_)).Times(AtLeast(1));
EXPECT_CALL(*sync_service, RemoveObserver(_)).Times(AtLeast(1));
coordinator_ = [[RecentTabsCoordinator alloc]
initWithBaseViewController:nil
browserState:chrome_browser_state_.get()];
[coordinator_ start];
}
protected:
web::TestWebThreadBundle thread_bundle_;
GoogleServiceAuthError no_error_;
IOSChromeScopedTestingLocalState local_state_;
identity::IdentityTestEnvironment identity_test_env_;
std::unique_ptr<TestChromeBrowserState> chrome_browser_state_;
std::unique_ptr<OpenTabsUIDelegateMock> open_tabs_ui_delegate_;
// Must be declared *after* |chrome_browser_state_| so it can outlive it.
RecentTabsCoordinator* coordinator_;
};
TEST_F(RecentTabsTableCoordinatorTest, TestConstructorDestructor) {
CreateController();
EXPECT_TRUE(coordinator_);
}
TEST_F(RecentTabsTableCoordinatorTest, TestUserSignedOut) {
SetupSyncState(NO, NO, NO);
CreateController();
}
TEST_F(RecentTabsTableCoordinatorTest, TestUserSignedInSyncOff) {
SetupSyncState(YES, NO, NO);
CreateController();
}
TEST_F(RecentTabsTableCoordinatorTest, TestUserSignedInSyncInProgress) {
SetupSyncState(YES, YES, NO);
CreateController();
}
TEST_F(RecentTabsTableCoordinatorTest, TestUserSignedInSyncOnWithSessions) {
SetupSyncState(YES, YES, YES);
CreateController();
}
} // namespace