blob: 20ec082e473c4e14a704355050587e1e54f4d59e [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/policy/machine_level_user_cloud_policy_register_watcher.h"
#include <utility>
#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/policy/browser_dm_token_storage.h"
#include "chrome/browser/ui/enterprise_startup_dialog.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::InvokeWithoutArgs;
using ::testing::Return;
using ::testing::_;
using RegisterResult =
policy::MachineLevelUserCloudPolicyController::RegisterResult;
namespace policy {
namespace {
constexpr char kEnrollmentToken[] = "enrollment-token";
constexpr char kDMToken[] = "dm-token";
constexpr char kClientId[] = "client-id";
// A fake token storage class for tested code to get enrollment token and DM
// token.
class FakeDMTokenStorage : public BrowserDMTokenStorage {
public:
FakeDMTokenStorage() = default;
std::string RetrieveDMToken() override { return dm_token_; }
std::string RetrieveEnrollmentToken() override { return enrollment_token_; }
std::string RetrieveClientId() override { return kClientId; }
bool ShouldDisplayErrorMessageOnFailure() override {
return should_display_error_message_on_failure_;
}
std::string InitClientId() override {
NOTREACHED();
return std::string();
}
std::string InitEnrollmentToken() override {
NOTREACHED();
return std::string();
}
std::string InitDMToken() override {
NOTREACHED();
return std::string();
}
bool InitEnrollmentErrorOption() override {
NOTREACHED();
return true;
}
void SaveDMToken(const std::string& dm_token) override { NOTREACHED(); }
void set_dm_token(const std::string& dm_token) { dm_token_ = dm_token; }
void set_enrollment_token(const std::string& enrollment_token) {
enrollment_token_ = enrollment_token;
}
void set_should_display_error_message_on_failure(bool should_display) {
should_display_error_message_on_failure_ = should_display;
}
private:
std::string enrollment_token_;
std::string dm_token_;
bool should_display_error_message_on_failure_ = true;
DISALLOW_COPY_AND_ASSIGN(FakeDMTokenStorage);
};
// A fake MachineLevelUserCloudPolicyController that notifies all observers the
// machine level user cloud policy enrollment process has been finished.
class FakeMachineLevelUserCloudPolicyController
: public MachineLevelUserCloudPolicyController {
public:
FakeMachineLevelUserCloudPolicyController() = default;
void FireNotification(bool succeeded) {
NotifyPolicyRegisterFinished(succeeded);
}
private:
DISALLOW_COPY_AND_ASSIGN(FakeMachineLevelUserCloudPolicyController);
};
// A mock EnterpriseStartDialog to mimic the behavior of real dialog.
class MockEnterpriseStartupDialog : public EnterpriseStartupDialog {
public:
MockEnterpriseStartupDialog() = default;
~MockEnterpriseStartupDialog() override {
// |callback_| exists if we're mocking the process that dialog is dismissed
// automatically.
if (callback_) {
std::move(callback_).Run(false /* was_accepted */,
true /* can_show_browser_window */);
}
}
MOCK_METHOD1(DisplayLaunchingInformationWithThrobber,
void(const base::string16&));
MOCK_METHOD2(DisplayErrorMessage,
void(const base::string16&,
const base::Optional<base::string16>&));
MOCK_METHOD0(IsShowing, bool());
void SetCallback(EnterpriseStartupDialog::DialogResultCallback callback) {
callback_ = std::move(callback);
}
void UserClickedTheButton(bool confirmed) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback_), confirmed,
false /* can_show_browser_window */));
}
private:
DialogResultCallback callback_;
DISALLOW_COPY_AND_ASSIGN(MockEnterpriseStartupDialog);
};
} // namespace
class MachineLevelUserCloudPolicyRegisterWatcherTest : public ::testing::Test {
public:
MachineLevelUserCloudPolicyRegisterWatcherTest()
: watcher_(&controller_),
dialog_(std::make_unique<MockEnterpriseStartupDialog>()),
dialog_ptr_(dialog_.get()) {
BrowserDMTokenStorage::SetForTesting(&storage_);
storage_.set_enrollment_token(kEnrollmentToken);
storage_.set_dm_token(std::string());
watcher_.SetDialogCreationCallbackForTesting(
base::BindOnce(&MachineLevelUserCloudPolicyRegisterWatcherTest::
CreateEnterpriseStartupDialog,
base::Unretained(this)));
}
protected:
FakeDMTokenStorage* storage() { return &storage_; }
FakeMachineLevelUserCloudPolicyController* controller() {
return &controller_;
}
MachineLevelUserCloudPolicyRegisterWatcher* watcher() { return &watcher_; }
MockEnterpriseStartupDialog* dialog() { return dialog_ptr_; }
std::unique_ptr<EnterpriseStartupDialog> CreateEnterpriseStartupDialog(
EnterpriseStartupDialog::DialogResultCallback callback) {
dialog_->SetCallback(std::move(callback));
return std::move(dialog_);
}
private:
content::TestBrowserThreadBundle browser_thread_bundle_;
FakeMachineLevelUserCloudPolicyController controller_;
MachineLevelUserCloudPolicyRegisterWatcher watcher_;
FakeDMTokenStorage storage_;
std::unique_ptr<MockEnterpriseStartupDialog> dialog_;
MockEnterpriseStartupDialog* dialog_ptr_;
DISALLOW_COPY_AND_ASSIGN(MachineLevelUserCloudPolicyRegisterWatcherTest);
};
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest,
NoEnrollmentNeededWithDMToken) {
storage()->set_dm_token(kDMToken);
EXPECT_EQ(RegisterResult::kEnrollmentSuccessBeforeDialogDisplayed,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
}
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest,
NoEnrollmentNeededWithoutEnrollmentToken) {
storage()->set_enrollment_token(std::string());
storage()->set_dm_token(std::string());
EXPECT_EQ(RegisterResult::kNoEnrollmentNeeded,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
}
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest, EnrollmentSucceed) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_));
EXPECT_CALL(*dialog(), IsShowing()).WillOnce(Return(true));
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(
&FakeMachineLevelUserCloudPolicyController::FireNotification,
base::Unretained(controller()), true));
EXPECT_EQ(RegisterResult::kEnrollmentSuccess,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kShown,
1);
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kClosedSuccess,
1);
}
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest,
EnrollmentSucceedWithNoErrorMessageSetup) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_));
EXPECT_CALL(*dialog(), IsShowing()).WillOnce(Return(true));
storage()->set_should_display_error_message_on_failure(false);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(
&FakeMachineLevelUserCloudPolicyController::FireNotification,
base::Unretained(controller()), true));
EXPECT_EQ(RegisterResult::kEnrollmentSuccess,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kShown,
1);
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kClosedSuccess,
1);
}
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest,
EnrollmentFailedAndQuit) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_));
EXPECT_CALL(*dialog(), DisplayErrorMessage(_, _))
.WillOnce(
InvokeWithoutArgs([this] { dialog()->UserClickedTheButton(false); }));
EXPECT_CALL(*dialog(), IsShowing()).WillOnce(Return(true));
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(
&FakeMachineLevelUserCloudPolicyController::FireNotification,
base::Unretained(controller()), false));
EXPECT_EQ(RegisterResult::kQuitDueToFailure,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kShown,
1);
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kClosedFail,
1);
}
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest,
EnrollmentFailedAndRestart) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_));
EXPECT_CALL(*dialog(), DisplayErrorMessage(_, _))
.WillOnce(
InvokeWithoutArgs([this] { dialog()->UserClickedTheButton(true); }));
EXPECT_CALL(*dialog(), IsShowing()).WillOnce(Return(true));
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(
&FakeMachineLevelUserCloudPolicyController::FireNotification,
base::Unretained(controller()), false));
EXPECT_EQ(RegisterResult::kRestartDueToFailure,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kShown,
1);
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kClosedRelaunch,
1);
}
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest,
EnrollmentCanceledBeforeFinish) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_));
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&MockEnterpriseStartupDialog::UserClickedTheButton,
base::Unretained(dialog()), false));
EXPECT_EQ(RegisterResult::kQuitDueToFailure,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kShown,
1);
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kClosedAbort,
1);
}
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest,
EnrollmentCanceledBeforeFinishWithNoErrorMessageSetup) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_));
storage()->set_should_display_error_message_on_failure(false);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&MockEnterpriseStartupDialog::UserClickedTheButton,
base::Unretained(dialog()), false));
EXPECT_EQ(RegisterResult::kQuitDueToFailure,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kShown,
1);
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kClosedAbort,
1);
}
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest,
EnrollmentFailedBeforeDialogDisplay) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*dialog(), DisplayErrorMessage(_, _))
.WillOnce(
InvokeWithoutArgs([this] { dialog()->UserClickedTheButton(false); }));
controller()->FireNotification(false);
EXPECT_EQ(RegisterResult::kQuitDueToFailure,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kShown,
1);
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kClosedFail,
1);
}
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest,
EnrollmentFailedWithoutErrorMessage) {
base::HistogramTester histogram_tester;
EXPECT_CALL(*dialog(), DisplayLaunchingInformationWithThrobber(_));
EXPECT_CALL(*dialog(), IsShowing()).WillOnce(Return(true));
storage()->set_should_display_error_message_on_failure(false);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(
&FakeMachineLevelUserCloudPolicyController::FireNotification,
base::Unretained(controller()), false));
EXPECT_EQ(RegisterResult::kEnrollmentFailedSilently,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kShown,
1);
histogram_tester.ExpectBucketCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
MachineLevelUserCloudPolicyRegisterWatcher::EnrollmentStartupDialog::
kClosedFailAndIgnore,
1);
}
TEST_F(MachineLevelUserCloudPolicyRegisterWatcherTest,
EnrollmentFailedBeforeDialogDisplayWithoutErrorMessage) {
base::HistogramTester histogram_tester;
storage()->set_should_display_error_message_on_failure(false);
controller()->FireNotification(false);
EXPECT_EQ(RegisterResult::kEnrollmentFailedSilentlyBeforeDialogDisplayed,
watcher()->WaitUntilCloudPolicyEnrollmentFinished());
histogram_tester.ExpectTotalCount(
MachineLevelUserCloudPolicyRegisterWatcher::kStartupDialogHistogramName,
0);
}
} // namespace policy