blob: 7e33b303485f1ac026837563700305d9af4236be [file] [log] [blame]
// Copyright 2018 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.
#include "chrome/browser/ash/policy/remote_commands/device_command_start_crd_session_job.h"
#include <map>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/ash/app_mode/arc/arc_kiosk_app_manager.h"
#include "chrome/browser/ash/app_mode/kiosk_app_manager.h"
#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h"
#include "chrome/browser/ash/settings/device_settings_test_helper.h"
#include "chrome/browser/device_identity/device_oauth2_token_service.h"
#include "chrome/browser/device_identity/device_oauth2_token_service_factory.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chromeos/cryptohome/system_salt_getter.h"
#include "components/policy/core/common/features.h"
#include "components/policy/proto/device_management_backend.pb.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_task_environment.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/user_activity/user_activity_detector.h"
namespace policy {
namespace em = enterprise_management;
namespace {
using base::test::TestFuture;
constexpr char kResultCodeFieldName[] = "resultCode";
constexpr char kResultMessageFieldName[] = "message";
constexpr char kResultAccessCodeFieldName[] = "accessCode";
constexpr char kResultLastActivityFieldName[] = "lastActivitySec";
constexpr RemoteCommandJob::UniqueIDType kUniqueID = 123456789;
constexpr char kTestOAuthToken[] = "test-oauth-token";
constexpr char kTestAccessCode[] = "111122223333";
constexpr char kTestNoOAuthTokenReason[] = "Not authorized.";
constexpr char kTestAccountEmail[] = "test.account.email@example.com";
constexpr char kIdlenessCutoffFieldName[] = "idlenessCutoffSec";
constexpr char kTerminateUponInputFieldName[] = "terminateUponInput";
// Macro expecting success. We are using a macro because a function would
// report any error against the line in the function, and not against the
// place where EXPECT_SUCCESS is called.
#define EXPECT_SUCCESS(result_) \
({ \
EXPECT_EQ(result.status, RemoteCommandJob::Status::SUCCEEDED); \
EXPECT_EQ(result.payload, CreateSuccessPayload(kTestAccessCode)); \
})
// Macro expecting error. We are using a macro because a function would
// report any error against the line in the function, and not against the
// place where EXPECT_ERROR is called.
#define EXPECT_ERROR(result_, error_code, ...) \
({ \
EXPECT_EQ(result.status, RemoteCommandJob::Status::FAILED); \
EXPECT_EQ(result.payload, CreateErrorPayload(error_code, ##__VA_ARGS__)); \
})
em::RemoteCommand GenerateCommandProto(RemoteCommandJob::UniqueIDType unique_id,
base::TimeDelta age_of_command,
base::TimeDelta idleness_cutoff,
bool terminate_upon_input) {
em::RemoteCommand command_proto;
command_proto.set_type(
enterprise_management::RemoteCommand_Type_DEVICE_START_CRD_SESSION);
command_proto.set_command_id(unique_id);
command_proto.set_age_of_command(age_of_command.InMilliseconds());
std::string payload;
base::Value root_dict(base::Value::Type::DICTIONARY);
root_dict.SetKey(kIdlenessCutoffFieldName,
base::Value((int)idleness_cutoff.InSeconds()));
root_dict.SetKey(kTerminateUponInputFieldName,
base::Value(terminate_upon_input));
base::JSONWriter::Write(root_dict, &payload);
command_proto.set_payload(payload);
return command_proto;
}
class StubCRDHostDelegate : public DeviceCommandStartCRDSessionJob::Delegate {
public:
StubCRDHostDelegate() = default;
~StubCRDHostDelegate() override = default;
void SetHasActiveSession(bool value) { has_active_session_ = value; }
void MakeAccessCodeFetchFail() { access_code_success_ = false; }
// Returns if TerminateSession() was called to terminate the active session.
bool IsActiveSessionTerminated() const { return terminate_session_called_; }
// Returns the |SessionParameters| sent to the last StartCRDHostAndGetCode()
// call.
SessionParameters session_parameters() {
EXPECT_TRUE(received_session_parameters_.has_value());
return received_session_parameters_.value_or(SessionParameters{});
}
// DeviceCommandStartCRDSessionJob::Delegate implementation:
bool HasActiveSession() const override;
void TerminateSession(base::OnceClosure callback) override;
void StartCRDHostAndGetCode(
const SessionParameters& parameters,
DeviceCommandStartCRDSessionJob::AccessCodeCallback success_callback,
DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) override;
private:
bool has_active_session_ = false;
bool access_code_success_ = true;
bool terminate_session_called_ = false;
absl::optional<SessionParameters> received_session_parameters_;
};
bool StubCRDHostDelegate::HasActiveSession() const {
return has_active_session_;
}
void StubCRDHostDelegate::TerminateSession(base::OnceClosure callback) {
has_active_session_ = false;
terminate_session_called_ = true;
std::move(callback).Run();
}
void StubCRDHostDelegate::StartCRDHostAndGetCode(
const SessionParameters& parameters,
DeviceCommandStartCRDSessionJob::AccessCodeCallback success_callback,
DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) {
received_session_parameters_ = parameters;
if (access_code_success_) {
std::move(success_callback).Run(kTestAccessCode);
} else {
std::move(error_callback)
.Run(DeviceCommandStartCRDSessionJob::FAILURE_CRD_HOST_ERROR,
std::string());
}
}
struct Result {
RemoteCommandJob::Status status;
std::string payload;
};
} // namespace
class DeviceCommandStartCRDSessionJobTest : public ash::DeviceSettingsTestBase {
public:
DeviceCommandStartCRDSessionJobTest()
: ash::DeviceSettingsTestBase(
base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
// ash::DeviceSettingsTestBase implementation:
void SetUp() override {
DeviceSettingsTestBase::SetUp();
test_start_time_ = base::TimeTicks::Now();
user_activity_detector_ = std::make_unique<ui::UserActivityDetector>();
arc_kiosk_app_manager_ = std::make_unique<ash::ArcKioskAppManager>();
web_kiosk_app_manager_ = std::make_unique<ash::WebKioskAppManager>();
// SystemSaltGetter is used by the token service.
chromeos::SystemSaltGetter::Initialize();
DeviceOAuth2TokenServiceFactory::Initialize(
test_url_loader_factory_.GetSafeWeakWrapper(), &local_state_);
RegisterLocalState(local_state_.registry());
}
void TearDown() override {
DeviceOAuth2TokenServiceFactory::Shutdown();
chromeos::SystemSaltGetter::Shutdown();
web_kiosk_app_manager_.reset();
arc_kiosk_app_manager_.reset();
DeviceSettingsTestBase::TearDown();
}
Result RunJobAndWaitForResult() {
InitializeAndRunJob();
return future_result_.Get();
}
std::string CreateSuccessPayload(const std::string& access_code);
std::string CreateErrorPayload(
DeviceCommandStartCRDSessionJob::ResultCode result_code,
const std::string& error_message);
std::string CreateNotIdlePayload(base::TimeDelta idleness);
void LogInAsManagedGuestSessionUser() {
const AccountId account_id(AccountId::FromUserEmail(kTestAccountEmail));
user_manager().AddPublicAccountUser(account_id);
user_manager().LoginUser(account_id);
}
void LogInAsRegularUser() {
const AccountId account_id(AccountId::FromUserEmail(kTestAccountEmail));
user_manager().AddUser(account_id);
user_manager().LoginUser(account_id);
}
void LogInAsAffiliatedUser() {
const AccountId account_id(AccountId::FromUserEmail(kTestAccountEmail));
user_manager().AddUserWithAffiliation(account_id, /*is_affiliated=*/true);
user_manager().LoginUser(account_id);
}
void LogInAsGuestUser() {
const user_manager::User* user = user_manager().AddGuestUser();
user_manager().LoginUser(user->GetAccountId());
}
void LogInAsKioskAppUser() {
const AccountId account_id(AccountId::FromUserEmail(kTestAccountEmail));
user_manager().AddKioskAppUser(account_id);
user_manager().LoginUser(account_id);
}
void LogInAsArcKioskAppUser() {
const AccountId account_id(AccountId::FromUserEmail(kTestAccountEmail));
user_manager().AddArcKioskAppUser(account_id);
user_manager().LoginUser(account_id);
}
void LogInAsWebKioskAppUser() {
const AccountId account_id(AccountId::FromUserEmail(kTestAccountEmail));
user_manager().AddWebKioskAppUser(account_id);
user_manager().LoginUser(account_id);
}
void LogInAsAutoLaunchedKioskAppUser() {
LogInAsKioskAppUser();
ash::KioskAppManager::Get()
->set_current_app_was_auto_launched_with_zero_delay_for_testing(true);
}
void SetDeviceIdleTime(base::TimeDelta idle_time) {
user_activity_detector_->set_last_activity_time_for_test(
base::TimeTicks::Now() - idle_time);
}
void SetIdlenessCutoff(base::TimeDelta value) { idleness_cutoff_ = value; }
void SetOAuthToken(std::string value) { oauth_token_ = value; }
void SetTerminateUponInput(bool value) { terminate_upon_input_ = value; }
void SetRobotAccountUserName(const std::string& user_name) {
DeviceOAuth2TokenService* token_service =
DeviceOAuth2TokenServiceFactory::Get();
token_service->set_robot_account_id_for_testing(CoreAccountId(user_name));
}
void ClearOAuthToken() { oauth_token_ = absl::nullopt; }
void DeleteUserActivityDetector() { user_activity_detector_ = nullptr; }
void DeleteUserManager() { user_manager_enabler_ = nullptr; }
StubCRDHostDelegate& crd_host_delegate() { return crd_host_delegate_; }
DeviceCommandStartCRDSessionJob& job() { return job_; }
private:
ash::FakeChromeUserManager& user_manager() { return *user_manager_; }
void InitializeJob() {
bool success =
job().Init(base::TimeTicks::Now(),
GenerateCommandProto(
kUniqueID, base::TimeTicks::Now() - test_start_time_,
idleness_cutoff_, terminate_upon_input_),
nullptr);
if (oauth_token_)
job().SetOAuthTokenForTest(oauth_token_.value());
EXPECT_TRUE(success);
EXPECT_EQ(kUniqueID, job().unique_id());
EXPECT_EQ(RemoteCommandJob::NOT_STARTED, job().status());
}
// Initialize and run the remote command job.
// The result will be stored in |future_result_|.
void InitializeAndRunJob() {
InitializeJob();
bool launched = job().Run(
base::Time::Now(), base::TimeTicks::Now(),
base::BindOnce(&DeviceCommandStartCRDSessionJobTest::OnJobFinished,
base::Unretained(this)));
EXPECT_TRUE(launched);
}
// Callback invoked when the remote command job finished.
void OnJobFinished() {
std::string payload =
job().GetResultPayload() ? *job().GetResultPayload() : "<nullptr>";
future_result_.SetValue(Result{job().status(), payload});
}
std::unique_ptr<ash::ArcKioskAppManager> arc_kiosk_app_manager_;
std::unique_ptr<ash::WebKioskAppManager> web_kiosk_app_manager_;
absl::optional<std::string> oauth_token_;
base::TimeDelta idleness_cutoff_ = base::TimeDelta::FromSeconds(30);
bool terminate_upon_input_ = false;
// Automatically installed as a singleton upon creation.
std::unique_ptr<ui::UserActivityDetector> user_activity_detector_;
network::TestURLLoaderFactory test_url_loader_factory_;
TestingPrefServiceSimple local_state_;
StubCRDHostDelegate crd_host_delegate_;
DeviceCommandStartCRDSessionJob job_{&crd_host_delegate_};
// Future value that will be populated with the result once the remote command
// job is completed.
TestFuture<Result> future_result_;
base::TimeTicks test_start_time_;
};
std::string DeviceCommandStartCRDSessionJobTest::CreateSuccessPayload(
const std::string& access_code) {
std::string payload;
base::Value root(base::Value::Type::DICTIONARY);
root.SetKey(kResultCodeFieldName,
base::Value(DeviceCommandStartCRDSessionJob::SUCCESS));
root.SetKey(kResultAccessCodeFieldName, base::Value(access_code));
base::JSONWriter::Write(root, &payload);
return payload;
}
std::string DeviceCommandStartCRDSessionJobTest::CreateErrorPayload(
DeviceCommandStartCRDSessionJob::ResultCode result_code,
const std::string& error_message = "") {
std::string payload;
base::Value root(base::Value::Type::DICTIONARY);
root.SetKey(kResultCodeFieldName, base::Value(result_code));
if (!error_message.empty())
root.SetKey(kResultMessageFieldName, base::Value(error_message));
base::JSONWriter::Write(root, &payload);
return payload;
}
std::string DeviceCommandStartCRDSessionJobTest::CreateNotIdlePayload(
base::TimeDelta idleness) {
std::string payload;
base::Value root(base::Value::Type::DICTIONARY);
root.SetKey(kResultCodeFieldName,
base::Value(DeviceCommandStartCRDSessionJob::FAILURE_NOT_IDLE));
root.SetKey(kResultLastActivityFieldName,
base::Value(static_cast<int>(idleness.InSeconds())));
base::JSONWriter::Write(root, &payload);
return payload;
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldSucceedIfAccessTokenCanBeFetched) {
LogInAsAutoLaunchedKioskAppUser();
SetOAuthToken(kTestOAuthToken);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldTerminateActiveSessionAndThenSucceed) {
LogInAsAutoLaunchedKioskAppUser();
SetOAuthToken(kTestOAuthToken);
crd_host_delegate().SetHasActiveSession(true);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
EXPECT_TRUE(crd_host_delegate().IsActiveSessionTerminated());
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldFailIfOAuthTokenServiceIsNotRunning) {
DeviceOAuth2TokenServiceFactory::Shutdown();
crd_host_delegate().SetHasActiveSession(true);
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_SERVICES_NOT_READY);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldFailIfUserActivityDetectorIsNotRunning) {
DeleteUserActivityDetector();
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_SERVICES_NOT_READY);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldFailIfUserManagerIsNotRunning) {
DeleteUserManager();
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_SERVICES_NOT_READY);
}
TEST_F(DeviceCommandStartCRDSessionJobTest, ShouldFailForManagedGuestUser) {
LogInAsManagedGuestSessionUser();
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_UNSUPPORTED_USER_TYPE);
}
TEST_F(DeviceCommandStartCRDSessionJobTest, ShouldFailForGuestUser) {
LogInAsGuestUser();
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_UNSUPPORTED_USER_TYPE);
}
TEST_F(DeviceCommandStartCRDSessionJobTest, ShouldFailForAffiliatedUser) {
LogInAsAffiliatedUser();
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_UNSUPPORTED_USER_TYPE);
}
TEST_F(DeviceCommandStartCRDSessionJobTest, ShouldFailForRegularUser) {
LogInAsRegularUser();
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_UNSUPPORTED_USER_TYPE);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldFailForKioskUserWithoutAutoLaunch) {
LogInAsKioskAppUser();
ash::KioskAppManager::Get()
->set_current_app_was_auto_launched_with_zero_delay_for_testing(false);
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_UNSUPPORTED_USER_TYPE);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldSucceedForKioskUserWithZeroDelayAutoLaunch) {
SetOAuthToken(kTestOAuthToken);
LogInAsKioskAppUser();
ash::KioskAppManager::Get()
->set_current_app_was_auto_launched_with_zero_delay_for_testing(true);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldFailForArcKioskUserWithoutAutoLaunch) {
SetOAuthToken(kTestOAuthToken);
LogInAsArcKioskAppUser();
ash::ArcKioskAppManager::Get()
->set_current_app_was_auto_launched_with_zero_delay_for_testing(false);
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_UNSUPPORTED_USER_TYPE);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldSucceedForArcKioskUserWithZeroDelayAutoLaunch) {
SetOAuthToken(kTestOAuthToken);
LogInAsArcKioskAppUser();
ash::ArcKioskAppManager::Get()
->set_current_app_was_auto_launched_with_zero_delay_for_testing(true);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldFailForWebKioskUserWithoutAutoLaunch) {
SetOAuthToken(kTestOAuthToken);
LogInAsWebKioskAppUser();
ash::WebKioskAppManager::Get()
->set_current_app_was_auto_launched_with_zero_delay_for_testing(false);
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_UNSUPPORTED_USER_TYPE);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldSucceedForWebKioskUserWithZeroDelayAutoLaunch) {
SetOAuthToken(kTestOAuthToken);
LogInAsWebKioskAppUser();
ash::WebKioskAppManager::Get()
->set_current_app_was_auto_launched_with_zero_delay_for_testing(true);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldFailIfDeviceIdleTimeIsLessThanIdlenessCutoffValue) {
LogInAsAutoLaunchedKioskAppUser();
SetOAuthToken(kTestOAuthToken);
const auto idleness_cutoff = base::TimeDelta::FromSeconds(10);
const auto device_idle_time = base::TimeDelta::FromSeconds(9);
SetDeviceIdleTime(device_idle_time);
SetIdlenessCutoff(idleness_cutoff);
Result result = RunJobAndWaitForResult();
EXPECT_EQ(result.status, RemoteCommandJob::Status::FAILED);
EXPECT_EQ(result.payload, CreateNotIdlePayload(device_idle_time));
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldSucceedIfDeviceIdleTimeIsMoreThanIdlenessCutoffValue) {
LogInAsAutoLaunchedKioskAppUser();
SetOAuthToken(kTestOAuthToken);
const auto idleness_cutoff = base::TimeDelta::FromSeconds(10);
const auto device_idle_time = base::TimeDelta::FromSeconds(11);
SetDeviceIdleTime(device_idle_time);
SetIdlenessCutoff(idleness_cutoff);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldFailIfWeCantFetchTheOAuthToken) {
LogInAsAutoLaunchedKioskAppUser();
ClearOAuthToken();
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result, DeviceCommandStartCRDSessionJob::FAILURE_NO_OAUTH_TOKEN,
kTestNoOAuthTokenReason);
}
TEST_F(DeviceCommandStartCRDSessionJobTest, ShouldFailIfCRDHostReportsAnError) {
LogInAsAutoLaunchedKioskAppUser();
SetOAuthToken(kTestOAuthToken);
crd_host_delegate().MakeAccessCodeFetchFail();
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result, DeviceCommandStartCRDSessionJob::FAILURE_CRD_HOST_ERROR);
}
TEST_F(DeviceCommandStartCRDSessionJobTest, ShouldPassOAuthTokenToDelegate) {
LogInAsAutoLaunchedKioskAppUser();
SetOAuthToken("the-oauth-token");
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
EXPECT_EQ("the-oauth-token",
crd_host_delegate().session_parameters().oauth_token);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldPassRobotAccountNameToDelegate) {
LogInAsAutoLaunchedKioskAppUser();
SetOAuthToken(kTestOAuthToken);
SetRobotAccountUserName("robot-account");
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
EXPECT_EQ("robot-account",
crd_host_delegate().session_parameters().user_name);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldPassTerminateUponInputTrueToDelegate) {
LogInAsAutoLaunchedKioskAppUser();
SetOAuthToken(kTestOAuthToken);
SetTerminateUponInput(true);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
EXPECT_EQ(true,
crd_host_delegate().session_parameters().terminate_upon_input);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldPassTerminateUponInputFalseToDelegate) {
LogInAsAutoLaunchedKioskAppUser();
SetOAuthToken(kTestOAuthToken);
SetTerminateUponInput(false);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
EXPECT_EQ(false,
crd_host_delegate().session_parameters().terminate_upon_input);
}
TEST_F(DeviceCommandStartCRDSessionJobTest,
ShouldPassShowConfirmationDialogFalseToDelegateForKioskUsers) {
LogInAsAutoLaunchedKioskAppUser();
SetOAuthToken(kTestOAuthToken);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
EXPECT_EQ(false,
crd_host_delegate().session_parameters().show_confirmation_dialog);
}
// This test fixture enables the |kCRDForManagedUserSessions| feature flag,
// and tests the additional functionality enabled by the flag.
class DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest
: public DeviceCommandStartCRDSessionJobTest {
public:
DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest() = default;
DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest(
const DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest&) =
delete;
DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest& operator=(
const DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest&) =
delete;
~DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest() override =
default;
private:
base::test::ScopedFeatureList enable_crd_for_user_sessions_{
features::kCRDForManagedUserSessions};
};
TEST_F(DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest,
ShouldSucceedForKioskUserWithZeroDelayAutoLaunch) {
SetOAuthToken(kTestOAuthToken);
LogInAsKioskAppUser();
ash::KioskAppManager::Get()
->set_current_app_was_auto_launched_with_zero_delay_for_testing(true);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
}
TEST_F(DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest,
ShouldFailForRegularUsers) {
LogInAsRegularUser();
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_UNSUPPORTED_USER_TYPE);
}
TEST_F(DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest,
ShouldFailForGuestUsers) {
// Note that guest user != managed guest user
LogInAsGuestUser();
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_UNSUPPORTED_USER_TYPE);
}
TEST_F(DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest,
ShouldFailIfNoUserIsLoggedIn) {
Result result = RunJobAndWaitForResult();
EXPECT_ERROR(result,
DeviceCommandStartCRDSessionJob::FAILURE_UNSUPPORTED_USER_TYPE);
}
TEST_F(DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest,
ShouldSucceedForManagedGuestUser) {
SetOAuthToken(kTestOAuthToken);
LogInAsManagedGuestSessionUser();
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
}
TEST_F(DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest,
ShouldSucceedForAffiliatedUser) {
SetOAuthToken(kTestOAuthToken);
LogInAsAffiliatedUser();
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
}
TEST_F(DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest,
ShouldPassShowConfirmationDialogTrueToDelegateForManagedGuestUser) {
LogInAsManagedGuestSessionUser();
SetOAuthToken(kTestOAuthToken);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
EXPECT_EQ(true,
crd_host_delegate().session_parameters().show_confirmation_dialog);
}
TEST_F(DeviceCommandStartCRDSessionJobWithCRDForUserSessionsFeatureTest,
ShouldPassShowConfirmationDialogTrueToDelegateForAffiliatedUser) {
LogInAsAffiliatedUser();
SetOAuthToken(kTestOAuthToken);
Result result = RunJobAndWaitForResult();
EXPECT_SUCCESS(result);
EXPECT_EQ(true,
crd_host_delegate().session_parameters().show_confirmation_dialog);
}
} // namespace policy