blob: 940a6ae46579c2b81d59bbd291f912e0cba743f4 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/collaboration/internal/collaboration_service_impl.h"
#include <memory>
#include "base/android/device_info.h"
#include "base/test/run_until.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "components/collaboration/internal/collaboration_controller.h"
#include "components/collaboration/public/pref_names.h"
#include "components/collaboration/test_support/mock_collaboration_controller_delegate.h"
#include "components/data_sharing/public/data_sharing_service.h"
#include "components/data_sharing/public/features.h"
#include "components/data_sharing/test_support/mock_data_sharing_service.h"
#include "components/saved_tab_groups/test_support/mock_tab_group_sync_service.h"
#include "components/saved_tab_groups/test_support/saved_tab_group_test_utils.h"
#include "components/signin/public/base/signin_pref_names.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "components/sync/base/features.h"
#include "components/sync/test/test_sync_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "google_apis/gaia/gaia_id.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using data_sharing::GroupData;
using data_sharing::GroupId;
using data_sharing::GroupMember;
using data_sharing::MemberRole;
using signin::PrimaryAccountChangeEvent;
using testing::_;
using testing::Return;
namespace collaboration {
namespace {
constexpr GaiaId::Literal kUserGaia("gaia_id");
constexpr GaiaId::Literal kOtherUserGaia("other_gaia_id");
constexpr char kConsumerUserEmail[] = "test@email.com";
constexpr char kOtherConsumerUserEmail[] = "other.test@email.com";
constexpr char kManagedUserEmail[] = "test@google.com";
constexpr char kGroupId[] = "/?-group_id";
constexpr char kAccessToken[] = "/?-access_token";
} // namespace
class CollaborationServiceImplTest : public testing::Test {
public:
CollaborationServiceImplTest() = default;
~CollaborationServiceImplTest() override = default;
void SetUp() override {
#if BUILDFLAG(IS_ANDROID)
if (base::android::device_info::is_automotive()) {
// TODO(crbug.com/399444939): Re-enable once automotive is supported.
GTEST_SKIP() << "Test shouldn't run on automotive builders.";
}
#endif
test_sync_service_ = std::make_unique<syncer::TestSyncService>();
profile_pref_service_.registry()->RegisterIntegerPref(
prefs::kSharedTabGroupsManagedAccountSetting, 0 /* enabled */);
profile_pref_service_.registry()->RegisterBooleanPref(
::prefs::kSigninAllowed, true);
profile_pref_service_.registry()->RegisterBooleanPref(
::prefs::kSigninAllowedOnNextStartup, true);
#if BUILDFLAG(IS_IOS)
local_pref_service_.registry()->RegisterIntegerPref(
::prefs::kBrowserSigninPolicy,
static_cast<int>(BrowserSigninMode::kEnabled));
#endif
InitService();
}
void TearDown() override { service_.reset(); }
void InitService() {
service_ = std::make_unique<CollaborationServiceImpl>(
&mock_tab_group_sync_service_, &mock_data_sharing_service_,
identity_test_env_.identity_manager(), &profile_pref_service_,
&local_pref_service_);
service_->OnSyncServiceInitialized(test_sync_service_.get());
}
protected:
base::test::SingleThreadTaskEnvironment task_environment_;
sync_preferences::TestingPrefServiceSyncable profile_pref_service_;
sync_preferences::TestingPrefServiceSyncable local_pref_service_;
signin::IdentityTestEnvironment identity_test_env_;
std::unique_ptr<syncer::TestSyncService> test_sync_service_;
tab_groups::MockTabGroupSyncService mock_tab_group_sync_service_;
data_sharing::MockDataSharingService mock_data_sharing_service_;
std::unique_ptr<CollaborationServiceImpl> service_;
};
TEST_F(CollaborationServiceImplTest, ConstructionAndEmptyServiceCheck) {
EXPECT_FALSE(service_->IsEmptyService());
}
TEST_F(CollaborationServiceImplTest, GetCurrentUserRoleForGroup) {
GroupData group_data = GroupData();
GroupMember group_member = GroupMember();
group_member.gaia_id = kUserGaia;
group_member.role = MemberRole::kOwner;
group_data.members.push_back(group_member);
data_sharing::GroupId group_id = data_sharing::GroupId(kGroupId);
// Empty or non existent group should return unknown role.
EXPECT_CALL(mock_data_sharing_service_, ReadGroup(group_id))
.WillOnce(Return(std::nullopt));
EXPECT_EQ(service_->GetCurrentUserRoleForGroup(group_id),
MemberRole::kUnknown);
// No current primary account should return unknown role.
EXPECT_CALL(mock_data_sharing_service_, ReadGroup(group_id))
.WillRepeatedly(Return(group_data));
EXPECT_EQ(service_->GetCurrentUserRoleForGroup(group_id),
MemberRole::kUnknown);
identity_test_env_.MakeAccountAvailable(
kConsumerUserEmail,
{.primary_account_consent_level = signin::ConsentLevel::kSignin,
.gaia_id = kUserGaia});
EXPECT_EQ(service_->GetCurrentUserRoleForGroup(group_id), MemberRole::kOwner);
}
TEST_F(CollaborationServiceImplTest, GetServiceStatus_Disabled) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures({},
{data_sharing::features::kDataSharingFeature,
data_sharing::features::kDataSharingJoinOnly});
InitService();
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kDisabled);
}
TEST_F(CollaborationServiceImplTest, GetServiceStatus_JoinOnly) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures({data_sharing::features::kDataSharingJoinOnly},
{data_sharing::features::kDataSharingFeature});
InitService();
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kAllowedToJoin);
}
TEST_F(CollaborationServiceImplTest, GetServiceStatus_Create) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures({data_sharing::features::kDataSharingFeature},
{data_sharing::features::kDataSharingJoinOnly});
InitService();
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kEnabledCreateAndJoin);
}
TEST_F(CollaborationServiceImplTest, GetServiceStatus_CreateOverridesJoinOnly) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures({data_sharing::features::kDataSharingJoinOnly,
data_sharing::features::kDataSharingFeature},
{});
InitService();
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kEnabledCreateAndJoin);
}
TEST_F(CollaborationServiceImplTest, GetServiceStatus_SigninDisabledByUser) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
data_sharing::features::kDataSharingFeature);
// Set signin preference to disable signin.
profile_pref_service_.SetBoolean(::prefs::kSigninAllowed, false);
profile_pref_service_.SetBoolean(::prefs::kSigninAllowedOnNextStartup, false);
InitService();
EXPECT_EQ(service_->GetServiceStatus().signin_status,
SigninStatus::kSigninDisabled);
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kEnabledCreateAndJoin);
EXPECT_EQ(service_->GetServiceStatus().IsAllowedToJoin(), true);
EXPECT_EQ(service_->GetServiceStatus().IsAllowedToCreate(), false);
}
#if !BUILDFLAG(IS_IOS)
TEST_F(CollaborationServiceImplTest, GetServiceStatus_SigninDisabledByPolicy) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
data_sharing::features::kDataSharingFeature);
#if BUILDFLAG(IS_ANDROID)
profile_pref_service_.SetBoolean(::prefs::kSigninAllowed, false);
profile_pref_service_.SetManagedPref(::prefs::kSigninAllowed,
base::Value(false));
#else
profile_pref_service_.SetBoolean(::prefs::kSigninAllowedOnNextStartup, false);
profile_pref_service_.SetManagedPref(::prefs::kSigninAllowedOnNextStartup,
base::Value(false));
#endif
InitService();
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kDisabledForPolicy);
}
#endif
TEST_F(CollaborationServiceImplTest, GetServiceStatus_ManagedAccount) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(
data_sharing::features::kDataSharingFeature);
InitService();
profile_pref_service_.SetInteger(prefs::kSharedTabGroupsManagedAccountSetting,
1 /* disabled */);
EXPECT_EQ(service_->GetServiceStatus().signin_status,
SigninStatus::kNotSignedIn);
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kEnabledCreateAndJoin);
// Signin a managed account.
identity_test_env_.MakePrimaryAccountAvailable(kManagedUserEmail,
signin::ConsentLevel::kSignin);
EXPECT_EQ(service_->GetServiceStatus().signin_status,
SigninStatus::kSignedIn);
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kDisabledForPolicy);
// Signin a consumer account re-enable the feature.
identity_test_env_.MakePrimaryAccountAvailable(kConsumerUserEmail,
signin::ConsentLevel::kSignin);
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kEnabledCreateAndJoin);
}
TEST_F(CollaborationServiceImplTest, StartJoinFlow) {
GURL url("http://www.example.com/");
// Invalid url parsing starts a join flow with empty GroupToken.
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate_invalid =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_invalid_ptr =
mock_delegate_invalid.get();
EXPECT_CALL(*mock_delegate_invalid, OnFlowFinished());
service_->StartJoinFlow(std::move(mock_delegate_invalid), url);
// Wait for post tasks.
EXPECT_TRUE(base::test::RunUntil(
[&]() { return service_->GetJoinControllersForTesting().size() == 1; }));
const std::map<data_sharing::GroupToken,
std::unique_ptr<CollaborationController>>& join_flows =
service_->GetJoinControllersForTesting();
EXPECT_TRUE(join_flows.find(data_sharing::GroupToken()) != join_flows.end());
// New join flow will be appended with a valid url parsing and will stop all
// conflicting flows.
url = GURL(data_sharing::features::kDataSharingURL.Get() + "?g=" + kGroupId +
"&t=" + kAccessToken);
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_ptr = mock_delegate.get();
EXPECT_CALL(*mock_delegate, OnFlowFinished());
bool invalid_cancel_called = false;
EXPECT_CALL(*delegate_invalid_ptr, Cancel(_))
.WillOnce([&](CollaborationControllerDelegate::ResultCallback result) {
invalid_cancel_called = true;
std::move(result).Run(
CollaborationControllerDelegate::Outcome::kSuccess);
return true;
});
service_->StartJoinFlow(std::move(mock_delegate), url);
// Wait for post tasks.
EXPECT_TRUE(base::test::RunUntil(
[&]() { return service_->GetJoinControllersForTesting().size() == 1; }));
EXPECT_TRUE(invalid_cancel_called);
bool cancel_called = false;
EXPECT_CALL(*delegate_ptr, Cancel(_))
.WillOnce([&](CollaborationControllerDelegate::ResultCallback result) {
cancel_called = true;
std::move(result).Run(
CollaborationControllerDelegate::Outcome::kSuccess);
return true;
});
// Existing join flow will stop all conflicting flows and will be appended
// similar to a new join flow.
service_->StartJoinFlow(
std::make_unique<MockCollaborationControllerDelegate>(), url);
EXPECT_EQ(service_->GetJoinControllersForTesting().size(), 1u);
EXPECT_TRUE(cancel_called);
}
TEST_F(CollaborationServiceImplTest, SyncStatusChanges) {
// By default the test sync service is signed in with sync and every DataType
// enabled.
EXPECT_EQ(service_->GetServiceStatus().sync_status, SyncStatus::kSyncEnabled);
// Remove user's tab group setting.
test_sync_service_->GetUserSettings()->SetSelectedTypes(
/*sync_everything=*/false,
/*types=*/{});
test_sync_service_->FireStateChanged();
EXPECT_EQ(service_->GetServiceStatus().sync_status,
SyncStatus::kSyncWithoutTabGroup);
if (base::FeatureList::IsEnabled(
syncer::kReplaceSyncPromosWithSignInPromos)) {
// If sync-the-feature is not required, kNotSyncing is never happening.
test_sync_service_->SetSignedOut();
test_sync_service_->FireStateChanged();
EXPECT_EQ(service_->GetServiceStatus().sync_status,
SyncStatus::kSyncWithoutTabGroup);
} else {
// Sign out removes sync consent.
test_sync_service_->SetSignedOut();
test_sync_service_->FireStateChanged();
EXPECT_EQ(service_->GetServiceStatus().sync_status,
SyncStatus::kNotSyncing);
}
}
TEST_F(CollaborationServiceImplTest, SyncTypeDisabledByEnterprise) {
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
// Set up a policy to disable Tabs.
test_sync_service_->GetUserSettings()->SetTypeIsManagedByPolicy(
syncer::UserSelectableType::kTabs, true);
test_sync_service_->FireStateChanged();
EXPECT_EQ(service_->GetServiceStatus().sync_status,
SyncStatus::kSyncDisabledByEnterprise);
// Reset the policy.
test_sync_service_->GetUserSettings()->SetTypeIsManagedByPolicy(
syncer::UserSelectableType::kTabs, false);
test_sync_service_->FireStateChanged();
EXPECT_EQ(service_->GetServiceStatus().sync_status, SyncStatus::kSyncEnabled);
// Set up a policy to disable History.
test_sync_service_->GetUserSettings()->SetTypeIsManagedByPolicy(
syncer::UserSelectableType::kHistory, true);
test_sync_service_->FireStateChanged();
EXPECT_EQ(service_->GetServiceStatus().sync_status,
SyncStatus::kSyncDisabledByEnterprise);
#else
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(syncer::kReplaceSyncPromosWithSignInPromos);
// Set up a policy to disable Saved Tab Groups.
test_sync_service_->GetUserSettings()->SetTypeIsManagedByPolicy(
syncer::UserSelectableType::kSavedTabGroups, true);
test_sync_service_->FireStateChanged();
EXPECT_EQ(service_->GetServiceStatus().sync_status,
SyncStatus::kSyncDisabledByEnterprise);
#endif
}
TEST_F(CollaborationServiceImplTest, SyncDisabledByEnterprise) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(syncer::kReplaceSyncPromosWithSignInPromos);
// Disable sync by enterprise policy.
test_sync_service_->SetAllowedByEnterprisePolicy(false);
test_sync_service_->FireStateChanged();
EXPECT_EQ(service_->GetServiceStatus().sync_status,
SyncStatus::kSyncDisabledByEnterprise);
}
TEST_F(CollaborationServiceImplTest, SyncStatusChanges_SettingInProgress) {
// By default the test sync service is signed in with sync and every DataType
// enabled.
EXPECT_EQ(service_->GetServiceStatus().sync_status, SyncStatus::kSyncEnabled);
// Setup in progress does not change sync status.
test_sync_service_->SetSetupInProgress();
test_sync_service_->SetSignedOut();
test_sync_service_->FireStateChanged();
EXPECT_EQ(service_->GetServiceStatus().sync_status, SyncStatus::kSyncEnabled);
}
TEST_F(CollaborationServiceImplTest, ConsumerSigninChanges) {
EXPECT_EQ(service_->GetServiceStatus().signin_status,
SigninStatus::kNotSignedIn);
identity_test_env_.SetPrimaryAccount(kConsumerUserEmail,
signin::ConsentLevel::kSignin);
EXPECT_EQ(service_->GetServiceStatus().signin_status,
SigninStatus::kSignedInPaused);
identity_test_env_.SetRefreshTokenForPrimaryAccount();
EXPECT_EQ(service_->GetServiceStatus().signin_status,
SigninStatus::kSignedIn);
}
TEST_F(CollaborationServiceImplTest, DeleteGroup) {
data_sharing::GroupId group_id = data_sharing::GroupId(kGroupId);
EXPECT_CALL(mock_tab_group_sync_service_,
OnCollaborationRemoved(syncer::CollaborationId(kGroupId)));
EXPECT_CALL(mock_data_sharing_service_, DeleteGroup(group_id, _))
.WillOnce(
[](const data_sharing::GroupId&,
base::OnceCallback<void(
data_sharing::DataSharingService::PeopleGroupActionOutcome)>
callback) {
std::move(callback).Run(data_sharing::DataSharingService::
PeopleGroupActionOutcome::kSuccess);
});
base::RunLoop run_loop;
service_->DeleteGroup(group_id,
base::BindOnce(
[](base::RunLoop* run_loop, bool success) {
ASSERT_TRUE(success);
run_loop->Quit();
},
&run_loop));
run_loop.Run();
}
TEST_F(CollaborationServiceImplTest, LeaveGroup) {
data_sharing::GroupId group_id = data_sharing::GroupId(kGroupId);
EXPECT_CALL(mock_tab_group_sync_service_,
OnCollaborationRemoved(syncer::CollaborationId(kGroupId)));
EXPECT_CALL(mock_data_sharing_service_, LeaveGroup(group_id, _))
.WillOnce(
[](const data_sharing::GroupId&,
base::OnceCallback<void(
data_sharing::DataSharingService::PeopleGroupActionOutcome)>
callback) {
std::move(callback).Run(data_sharing::DataSharingService::
PeopleGroupActionOutcome::kSuccess);
});
base::RunLoop run_loop;
service_->LeaveGroup(group_id, base::BindOnce(
[](base::RunLoop* run_loop, bool success) {
ASSERT_TRUE(success);
run_loop->Quit();
},
&run_loop));
run_loop.Run();
}
TEST_F(CollaborationServiceImplTest, CancelAllFlows) {
GURL url = GURL(data_sharing::features::kDataSharingURL.Get() +
"?g=" + kGroupId + "&t=" + kAccessToken);
// New join flow will be appended with a valid url parsing and will stop all
// conflicting flows.
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_ptr = mock_delegate.get();
EXPECT_CALL(*mock_delegate, OnFlowFinished());
service_->StartJoinFlow(std::move(mock_delegate), url);
// Wait for post tasks.
EXPECT_TRUE(base::test::RunUntil(
[&]() { return service_->GetJoinControllersForTesting().size() == 1; }));
bool cancel_called = false;
EXPECT_CALL(*delegate_ptr, Cancel(_))
.WillOnce([&](CollaborationControllerDelegate::ResultCallback result) {
cancel_called = true;
std::move(result).Run(
CollaborationControllerDelegate::Outcome::kSuccess);
return true;
});
service_->CancelAllFlows();
EXPECT_TRUE(cancel_called);
// Wait for post tasks.
EXPECT_TRUE(service_->GetJoinControllersForTesting().size() == 0);
EXPECT_TRUE(service_->GetDeletingControllersCountForTesting() == 1);
EXPECT_TRUE(base::test::RunUntil([&]() {
return service_->GetDeletingControllersCountForTesting() == 0;
}));
}
TEST_F(CollaborationServiceImplTest,
OnPrimaryAccountChanged_NoChange_DoesntCancelJoin) {
// Start a join flow.
GURL url = GURL(data_sharing::features::kDataSharingURL.Get() +
"?g=" + kGroupId + "&t=" + kAccessToken);
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_ptr = mock_delegate.get();
service_->StartJoinFlow(std::move(mock_delegate), url);
EXPECT_CALL(*delegate_ptr, Cancel(_)).Times(0);
// Prepare a kNoChange event.
PrimaryAccountChangeEvent::State state;
PrimaryAccountChangeEvent event_details(
state, state, signin_metrics::AccessPoint::kUnknown);
// Process the event.
service_->OnPrimaryAccountChanged(event_details);
}
TEST_F(CollaborationServiceImplTest,
OnPrimaryAccountChanged_NoChange_DoesntCancelShare) {
// Start a share flow.
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_ptr = mock_delegate.get();
service_->StartShareOrManageFlow(
std::move(mock_delegate), tab_groups::test::GenerateRandomTabGroupID(),
CollaborationServiceShareOrManageEntryPoint::kUnknown);
EXPECT_CALL(*delegate_ptr, Cancel(_)).Times(0);
// Prepare a kNoChange event.
PrimaryAccountChangeEvent::State state;
PrimaryAccountChangeEvent event_details(
state, state, signin_metrics::AccessPoint::kUnknown);
// Process the event.
service_->OnPrimaryAccountChanged(event_details);
}
TEST_F(CollaborationServiceImplTest,
OnPrimaryAccountChanged_SigningInFromUnsignedIn_DoesntCancelJoin) {
// Start a join flow.
GURL url = GURL(data_sharing::features::kDataSharingURL.Get() +
"?g=" + kGroupId + "&t=" + kAccessToken);
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_ptr = mock_delegate.get();
service_->StartJoinFlow(std::move(mock_delegate), url);
EXPECT_CALL(*delegate_ptr, Cancel(_)).Times(0);
// Prepare a kSet event from unsigned in to signed in.
PrimaryAccountChangeEvent::State previous_state;
CoreAccountInfo account_info;
account_info.gaia = kUserGaia;
account_info.account_id = CoreAccountId::FromGaiaId(account_info.gaia);
account_info.email = kConsumerUserEmail;
PrimaryAccountChangeEvent::State current_state(account_info,
signin::ConsentLevel::kSignin);
PrimaryAccountChangeEvent event_details(
previous_state, current_state, signin_metrics::AccessPoint::kUnknown);
// Process the event.
service_->OnPrimaryAccountChanged(event_details);
}
TEST_F(CollaborationServiceImplTest,
OnPrimaryAccountChanged_SigningInFromUnsignedIn_DoesntCancelShare) {
// Start a share flow.
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_ptr = mock_delegate.get();
service_->StartShareOrManageFlow(
std::move(mock_delegate), tab_groups::test::GenerateRandomTabGroupID(),
CollaborationServiceShareOrManageEntryPoint::kUnknown);
EXPECT_CALL(*delegate_ptr, Cancel(_)).Times(0);
// Prepare a kSet event from unsigned in to signed in.
PrimaryAccountChangeEvent::State previous_state;
CoreAccountInfo account_info;
account_info.gaia = kUserGaia;
account_info.account_id = CoreAccountId::FromGaiaId(account_info.gaia);
account_info.email = kConsumerUserEmail;
PrimaryAccountChangeEvent::State current_state(account_info,
signin::ConsentLevel::kSignin);
PrimaryAccountChangeEvent event_details(
previous_state, current_state, signin_metrics::AccessPoint::kUnknown);
// Process the event.
service_->OnPrimaryAccountChanged(event_details);
}
TEST_F(CollaborationServiceImplTest,
OnPrimaryAccountChanged_SwitchingAccount_CancelsJoin) {
// Start a join flow.
GURL url = GURL(data_sharing::features::kDataSharingURL.Get() +
"?g=" + kGroupId + "&t=" + kAccessToken);
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_ptr = mock_delegate.get();
service_->StartJoinFlow(std::move(mock_delegate), url);
bool cancel_called = false;
EXPECT_CALL(*delegate_ptr, Cancel(_))
.WillOnce([&](CollaborationControllerDelegate::ResultCallback result) {
cancel_called = true;
std::move(result).Run(
CollaborationControllerDelegate::Outcome::kSuccess);
return true;
});
// Prepare a kSet event, switching accounts.
CoreAccountInfo account_info_1;
account_info_1.gaia = kUserGaia;
account_info_1.account_id = CoreAccountId::FromGaiaId(account_info_1.gaia);
account_info_1.email = kConsumerUserEmail;
PrimaryAccountChangeEvent::State previous_state(
account_info_1, signin::ConsentLevel::kSignin);
CoreAccountInfo account_info_2;
account_info_2.gaia = kOtherUserGaia;
account_info_2.account_id = CoreAccountId::FromGaiaId(account_info_2.gaia);
account_info_2.email = kOtherConsumerUserEmail;
PrimaryAccountChangeEvent::State current_state(account_info_2,
signin::ConsentLevel::kSignin);
PrimaryAccountChangeEvent event_details(
previous_state, current_state, signin_metrics::AccessPoint::kUnknown);
// Process the event.
service_->OnPrimaryAccountChanged(event_details);
EXPECT_TRUE(cancel_called);
}
TEST_F(CollaborationServiceImplTest,
OnPrimaryAccountChanged_SwitchingAccount_CancelsShare) {
// Start a share flow.
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_ptr = mock_delegate.get();
service_->StartShareOrManageFlow(
std::move(mock_delegate), tab_groups::test::GenerateRandomTabGroupID(),
CollaborationServiceShareOrManageEntryPoint::kUnknown);
bool cancel_called = false;
EXPECT_CALL(*delegate_ptr, Cancel(_))
.WillOnce([&](CollaborationControllerDelegate::ResultCallback result) {
cancel_called = true;
std::move(result).Run(
CollaborationControllerDelegate::Outcome::kSuccess);
return true;
});
// Prepare a kSet event, switching accounts.
CoreAccountInfo account_info_1;
account_info_1.gaia = kUserGaia;
account_info_1.account_id = CoreAccountId::FromGaiaId(account_info_1.gaia);
account_info_1.email = kConsumerUserEmail;
PrimaryAccountChangeEvent::State previous_state(
account_info_1, signin::ConsentLevel::kSignin);
CoreAccountInfo account_info_2;
account_info_2.gaia = kOtherUserGaia;
account_info_2.account_id = CoreAccountId::FromGaiaId(account_info_2.gaia);
account_info_2.email = kOtherConsumerUserEmail;
PrimaryAccountChangeEvent::State current_state(account_info_2,
signin::ConsentLevel::kSignin);
PrimaryAccountChangeEvent event_details(
previous_state, current_state, signin_metrics::AccessPoint::kUnknown);
// Process the event.
service_->OnPrimaryAccountChanged(event_details);
EXPECT_TRUE(cancel_called);
}
TEST_F(CollaborationServiceImplTest,
OnPrimaryAccountChanged_Cleared_CancelsJoin) {
// Start a join flow.
GURL url = GURL(data_sharing::features::kDataSharingURL.Get() +
"?g=" + kGroupId + "&t=" + kAccessToken);
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_ptr = mock_delegate.get();
service_->StartJoinFlow(std::move(mock_delegate), url);
bool cancel_called = false;
EXPECT_CALL(*delegate_ptr, Cancel(_))
.WillOnce([&](CollaborationControllerDelegate::ResultCallback result) {
cancel_called = true;
std::move(result).Run(
CollaborationControllerDelegate::Outcome::kSuccess);
return true;
});
// Prepare a kCleared event.
CoreAccountInfo account_info;
account_info.gaia = kUserGaia;
account_info.account_id = CoreAccountId::FromGaiaId(account_info.gaia);
account_info.email = kConsumerUserEmail;
PrimaryAccountChangeEvent::State previous_state(
account_info, signin::ConsentLevel::kSignin);
PrimaryAccountChangeEvent::State current_state;
PrimaryAccountChangeEvent event_details(
previous_state, current_state, signin_metrics::ProfileSignout::kTest);
// Process the event.
service_->OnPrimaryAccountChanged(event_details);
EXPECT_TRUE(cancel_called);
}
TEST_F(CollaborationServiceImplTest,
OnPrimaryAccountChanged_Cleared_CancelsShare) {
// Start a share flow.
std::unique_ptr<MockCollaborationControllerDelegate> mock_delegate =
std::make_unique<MockCollaborationControllerDelegate>();
MockCollaborationControllerDelegate* delegate_ptr = mock_delegate.get();
service_->StartShareOrManageFlow(
std::move(mock_delegate), tab_groups::test::GenerateRandomTabGroupID(),
CollaborationServiceShareOrManageEntryPoint::kUnknown);
bool cancel_called = false;
EXPECT_CALL(*delegate_ptr, Cancel(_))
.WillOnce([&](CollaborationControllerDelegate::ResultCallback result) {
cancel_called = true;
std::move(result).Run(
CollaborationControllerDelegate::Outcome::kSuccess);
return true;
});
// Prepare a kCleared event.
CoreAccountInfo account_info;
account_info.gaia = kUserGaia;
account_info.account_id = CoreAccountId::FromGaiaId(account_info.gaia);
account_info.email = kConsumerUserEmail;
PrimaryAccountChangeEvent::State previous_state(
account_info, signin::ConsentLevel::kSignin);
PrimaryAccountChangeEvent::State current_state;
PrimaryAccountChangeEvent event_details(
previous_state, current_state, signin_metrics::ProfileSignout::kTest);
// Process the event.
service_->OnPrimaryAccountChanged(event_details);
EXPECT_TRUE(cancel_called);
}
TEST_F(CollaborationServiceImplTest,
GetServiceStatus_VersionOutOfDateShowUpdateChromeUi) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
{data_sharing::features::kDataSharingFeature,
data_sharing::features::kDataSharingEnableUpdateChromeUI,
data_sharing::features::kSharedDataTypesKillSwitch},
{data_sharing::features::kDataSharingJoinOnly});
InitService();
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kVersionOutOfDateShowUpdateChromeUi);
}
TEST_F(CollaborationServiceImplTest, GetServiceStatus_VersionOutOfDate) {
base::test::ScopedFeatureList feature_list;
feature_list.InitWithFeatures(
{
data_sharing::features::kDataSharingJoinOnly,
data_sharing::features::kSharedDataTypesKillSwitch,
},
{data_sharing::features::kDataSharingFeature,
data_sharing::features::kDataSharingEnableUpdateChromeUI});
InitService();
EXPECT_EQ(service_->GetServiceStatus().collaboration_status,
CollaborationStatus::kVersionOutOfDate);
}
} // namespace collaboration