// Copyright (c) 2015 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 "base/base64.h"
#include "base/json/json_reader.h"
#include "base/json/string_escape.h"
#include "base/stl_util.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/login/demo_mode/demo_setup_controller.h"
#include "chrome/browser/chromeos/login/demo_mode/demo_setup_test_utils.h"
#include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h"
#include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper.h"
#include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.h"
#include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_mock.h"
#include "chrome/browser/chromeos/login/login_manager_test.h"
#include "chrome/browser/chromeos/login/startup_utils.h"
#include "chrome/browser/chromeos/login/test/js_checker.h"
#include "chrome/browser/chromeos/login/test/oobe_configuration_waiter.h"
#include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
#include "chrome/browser/chromeos/login/ui/login_display_host.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/policy/enrollment_status_chromeos.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/chromeos_test_utils.h"
#include "chromeos/dbus/dbus_switches.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_auth_policy_client.h"
#include "chromeos/dbus/fake_update_engine_client.h"
#include "chromeos/dbus/shill_manager_client.h"
#include "chromeos/dbus/upstart_client.h"
#include "chromeos/network/network_state_handler.h"
#include "components/language/core/browser/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "ui/base/ime/chromeos/input_method_manager.h"
#include "ui/base/ime/chromeos/input_method_util.h"

using chromeos::test::SetupDummyOfflinePolicyDir;
using testing::_;
using testing::Invoke;
using testing::InvokeWithoutArgs;

namespace chromeos {

namespace {

#define AD_JS_ELEMENT "document.querySelector('#oauth-enroll-ad-join-ui')."
constexpr char kAdMachineNameInput[] = AD_JS_ELEMENT "$.machineNameInput";
constexpr char kAdMachineOrgUnitInput[] = AD_JS_ELEMENT "$.orgUnitInput";
constexpr char kAdEncryptionTypesSelect[] = AD_JS_ELEMENT "$.encryptionList";
constexpr char kAdMoreOptionsSave[] = AD_JS_ELEMENT "$.moreOptionsSave.click()";
constexpr char kAdUsernameInput[] = AD_JS_ELEMENT "$.userInput";
constexpr char kAdPasswordInput[] = AD_JS_ELEMENT "$.passwordInput";
constexpr char kAdSubmitCreds[] = AD_JS_ELEMENT "$$('#nextButton').click()";
constexpr char kAdConfigurationSelect[] = AD_JS_ELEMENT "$.joinConfigSelect";
constexpr char kAdCredentialsStep[] = AD_JS_ELEMENT "$.credsStep";
constexpr char kAdJoinConfigurationForm[] = AD_JS_ELEMENT "$.joinConfig";
constexpr char kAdUnlockConfigurationStep[] = AD_JS_ELEMENT "$.unlockStep";
constexpr char kAdUnlockConfigurationSkipButtonTap[] =
    AD_JS_ELEMENT "$$('#skipButton').click()";
constexpr char kAdUnlockConfigurationSubmitButtonTap[] =
    AD_JS_ELEMENT "$$('#unlockButton').click()";
constexpr char kAdUnlockPasswordInput[] = AD_JS_ELEMENT "$.unlockPasswordInput";
constexpr char kAdBackToUnlockConfigurationButtonTap[] =
    AD_JS_ELEMENT "$$('#backToUnlockButton').click()";
#undef AD_JS_ELEMENT
constexpr char kAdUserDomain[] = "user.domain.com";
constexpr char kAdMachineDomain[] = "machine.domain.com";
constexpr char kAdMachineDomainDN[] =
    "OU=leaf,OU=root,DC=machine,DC=domain,DC=com";
constexpr const char* kAdOrganizationlUnit[] = {"leaf", "root"};
constexpr char kAdTestUser[] = "test_user@user.domain.com";
constexpr char kDMToken[] = "dm_token";
constexpr char kAdDomainJoinEncryptedConfig[] =
    "W/x3ToZtYrHTzD21dlx2MrMhs2bDFTNmvew/toQhO+RdBV8XmQfJqVMaRtIO+Uji6zBueUyxcl"
    "MtiFJnimvYh0DUFQ5PJ3PY49BPACPnrGws51or1pEZJkXiKOEapRwNfqHz5tOnvFS1VqSvcv6Z"
    "JQqFQHKfvodGiEZv52+iViQTCSup8VJWCtfJxy/LxqHly/4xaUDNn8Sbbv8V/j8HUxc7/rwmnm"
    "R5B6qxIYDfYOpZWQXnVunlB2bBkcCEgXdS9YN+opsftlkNPsVrcdHUWwCmqxxAsuVZaTfxu+7C"
    "ZhSG72VH3BtQUsyGoh9evSIhAcid1CGbSx16sJVZyhZVXMF9D80AEl6aWDyxh43iJy0AgLpfkP"
    "mfkpZ3+iv0EJocFUhFINrq0fble+wE8KsOtlUBne4jFA/fifOrRBoIdXdLLz3+FbL4A7zY9qbd"
    "PbDw5J5W3nnaJWhTd5R765LbPp7wNAzdPh4a++E0dUUSVXO2K5HkAopV9RkeDea2kaxOLi1ioj"
    "H8fxubSHp4e8ZYSAX4N9JkJWiDurp8yEpUno2aw2Y7HafkMs0GMnO0sdkJfLZrnDq9wkZh7bMD"
    "6sp5tiOqVbTG6QH1BdlJBryTAjlrMFL6y7zFvfMZSJhbI6VwQyskGX/TOYEnsXuWEpRBxtDVV/"
    "QLUWM0orFELZPoPdeuH3dACsEv4mMBo8hWlKu/S3SHXt2hrvI1PXDO10AOHy8CPNPs7p/LeuJq"
    "XHRYOKsuNZnYbFJR1r+rZhkvYFpn6dHOLbe7RScqkq9cUYVvxK84COIdbEay9w1Son4sFJZszi"
    "Ve+uc/oFWcVp6GZPzvWSfjrTXYqIFDw/WsC8mYMgqOvTZCKj6M3pUyvc7bT3hIPqGXZyp5Pmzb"
    "jpCn95i8tlnjfmiZaDjl3HxrY15zvw==";
constexpr char kAdDomainJoinUnlockedConfig[] = R"!!!(
[
  {
    "name": "Sales",
    "ad_username": "domain_join_account@example.com",
    "ad_password": "test123",
    "computer_ou": "OU=sales,DC=example,DC=com",
    "encryption_types": "all"
  },
  {
    "name": "Marketing",
    "ad_username": "domain_join_account@example.com",
    "ad_password": "test123",
    "computer_ou": "OU=marketing,DC=example,DC=com"
  },
  {
    "name": "Engineering",
    "ad_username": "other_domain_join_account@example.com",
    "ad_password": "test345",
    "computer_ou": "OU=engineering,DC=example,DC=com",
    "computer_name_validation_regex": "^DEVICE_\\d+$"
  }
]
)!!!";

class MockAuthPolicyClient : public FakeAuthPolicyClient {
 public:
  MockAuthPolicyClient() = default;
  ~MockAuthPolicyClient() override = default;
  void JoinAdDomain(const authpolicy::JoinDomainRequest& request,
                    int password_fd,
                    JoinCallback callback) override {
    if (expected_request_) {
      ASSERT_EQ(expected_request_->SerializeAsString(),
                request.SerializeAsString());
      expected_request_.reset();
    }
    FakeAuthPolicyClient::JoinAdDomain(request, password_fd,
                                       std::move(callback));
  }

  void set_expected_request(
      std::unique_ptr<authpolicy::JoinDomainRequest> expected_request) {
    expected_request_ = std::move(expected_request);
  }

 private:
  std::unique_ptr<authpolicy::JoinDomainRequest> expected_request_;
};

}  // namespace

class EnterpriseEnrollmentTestBase : public LoginManagerTest {
 public:
  explicit EnterpriseEnrollmentTestBase(bool should_initialize_webui)
      : LoginManagerTest(true /*should_launch_browser*/,
                         should_initialize_webui) {
    enrollment_setup_functions_.clear();

    EnterpriseEnrollmentHelper::SetupEnrollmentHelperMock(
        [](EnterpriseEnrollmentHelper::EnrollmentStatusConsumer*
               status_consumer,
           const policy::EnrollmentConfig& enrollment_config,
           const std::string& enrolling_user_domain) {

          auto* mock = new EnterpriseEnrollmentHelperMock(status_consumer);
          for (OnSetupEnrollmentHelper fn : enrollment_setup_functions_)
            fn(mock);
          return (EnterpriseEnrollmentHelper*)mock;
        });
  }

  using OnSetupEnrollmentHelper =
      std::function<void(EnterpriseEnrollmentHelperMock*)>;

  // The given function will be executed when the next enrollment helper is
  // created.
  void AddEnrollmentSetupFunction(OnSetupEnrollmentHelper on_setup) {
    enrollment_setup_functions_.push_back(on_setup);
  }

  // Set up expectations for enrollment credentials.
  void ExpectEnrollmentCredentials() {
    AddEnrollmentSetupFunction(
        [](EnterpriseEnrollmentHelperMock* enrollment_helper) {
          EXPECT_CALL(*enrollment_helper,
                      EnrollUsingAuthCode("test_auth_code", _));

          ON_CALL(*enrollment_helper, ClearAuth(_))
              .WillByDefault(Invoke(
                  [](const base::Closure& callback) { callback.Run(); }));
        });
  }

  // Submits regular enrollment credentials.
  void SubmitEnrollmentCredentials() {
    enrollment_screen()->OnLoginDone("testuser@test.com", "test_auth_code");
  }

  void DisableAttributePromptUpdate() {
    AddEnrollmentSetupFunction(
        [](EnterpriseEnrollmentHelperMock* enrollment_helper) {
          EXPECT_CALL(*enrollment_helper, GetDeviceAttributeUpdatePermission())
              .WillOnce(InvokeWithoutArgs([enrollment_helper]() {
                enrollment_helper->status_consumer()
                    ->OnDeviceAttributeUpdatePermission(false);
              }));
        });
  }

  // Forces an attribute prompt to display.
  void ExpectAttributePromptUpdate() {
    AddEnrollmentSetupFunction(
        [](EnterpriseEnrollmentHelperMock* enrollment_helper) {
          // Causes the attribute-prompt flow to activate.
          ON_CALL(*enrollment_helper, GetDeviceAttributeUpdatePermission())
              .WillByDefault(InvokeWithoutArgs([enrollment_helper]() {
                enrollment_helper->status_consumer()
                    ->OnDeviceAttributeUpdatePermission(true);
              }));

          // Ensures we receive the updates attributes.
          EXPECT_CALL(*enrollment_helper,
                      UpdateDeviceAttributes("asset_id", "location"));
        });
  }

  // Fills out the UI with device attribute information and submits it.
  void SubmitAttributePromptUpdate() {
    // Fill out the attribute prompt info and submit it.
    test::OobeJS().ExecuteAsync(
        "$('oauth-enroll-asset-id').value = 'asset_id'");
    test::OobeJS().ExecuteAsync(
        "$('oauth-enroll-location').value = 'location'");
    test::OobeJS().Evaluate("$('enroll-attributes-submit-button').fire('tap')");
  }

  // Completes the enrollment process.
  void CompleteEnrollment() {
    enrollment_screen()->OnDeviceEnrolled();

    // Make sure all other pending JS calls have complete.
    ExecutePendingJavaScript();
  }

  // Makes sure that all pending JS calls have been executed. It is important
  // to make this a separate call from the DOM checks because JSChecker uses
  // a different IPC message for JS communication than the login code. This
  // means that the JS script ordering is not preserved between the login code
  // and the test code.
  void ExecutePendingJavaScript() { test::OobeJS().Evaluate(";"); }

  // Returns true if there are any DOM elements with the given class.
  bool IsStepDisplayed(const std::string& step) {
    const std::string js =
        "document.getElementsByClassName('oauth-enroll-state-" + step +
        "').length";
    int count = test::OobeJS().GetInt(js);
    return count > 0;
  }

  // Setup the enrollment screen.
  void ShowEnrollmentScreen() {
    LoginDisplayHost* host = LoginDisplayHost::default_host();
    ASSERT_TRUE(host != nullptr);
    host->StartWizard(OobeScreen::SCREEN_OOBE_ENROLLMENT);
    OobeScreenWaiter(OobeScreen::SCREEN_OOBE_ENROLLMENT).Wait();
    ASSERT_TRUE(enrollment_screen() != nullptr);
    ASSERT_TRUE(WizardController::default_controller() != nullptr);
    ASSERT_FALSE(StartupUtils::IsOobeCompleted());
  }

  // Helper method to return the current EnrollmentScreen instance.
  EnrollmentScreen* enrollment_screen() {
    return EnrollmentScreen::Get(
        WizardController::default_controller()->screen_manager());
  }

 private:
  static std::vector<OnSetupEnrollmentHelper> enrollment_setup_functions_;

  DISALLOW_COPY_AND_ASSIGN(EnterpriseEnrollmentTestBase);
};

std::vector<EnterpriseEnrollmentTestBase::OnSetupEnrollmentHelper>
    EnterpriseEnrollmentTestBase::enrollment_setup_functions_;

class EnterpriseEnrollmentTest : public EnterpriseEnrollmentTestBase {
 public:
  EnterpriseEnrollmentTest()
      : EnterpriseEnrollmentTestBase(true /* should_initialize_webui */) {}

 private:
  DISALLOW_COPY_AND_ASSIGN(EnterpriseEnrollmentTest);
};

class ActiveDirectoryJoinTest : public EnterpriseEnrollmentTest {
 public:
  ActiveDirectoryJoinTest() = default;

  void SetUp() override {
    DBusThreadManager::GetSetterForTesting()->SetAuthPolicyClient(
        std::make_unique<MockAuthPolicyClient>());
    mock_auth_policy_client()->DisableOperationDelayForTesting();
    EnterpriseEnrollmentTestBase::SetUp();
  }

  void CheckActiveDirectoryCredentialsShown() {
    EXPECT_TRUE(IsStepDisplayed("ad-join"));
    test::OobeJS().ExpectFalse(std::string(kAdCredentialsStep) + ".hidden");
    test::OobeJS().ExpectTrue(std::string(kAdUnlockConfigurationStep) +
                              ".hidden");
  }

  void CheckConfigurationSelectionVisible(bool visible) {
    test::OobeJS().ExpectNE(std::string(kAdJoinConfigurationForm) + ".hidden",
                            visible);
  }

  void CheckActiveDirectoryUnlockConfigurationShown() {
    EXPECT_TRUE(IsStepDisplayed("ad-join"));
    test::OobeJS().ExpectFalse(std::string(kAdUnlockConfigurationStep) +
                               ".hidden");
    test::OobeJS().ExpectTrue(std::string(kAdCredentialsStep) + ".hidden");
  }

  void SkipUnlockStep() {
    test::OobeJS().ExecuteAsync(kAdUnlockConfigurationSkipButtonTap);
    ExecutePendingJavaScript();
  }

  void GetBackToUnlockStep() {
    test::OobeJS().ExecuteAsync(kAdBackToUnlockConfigurationButtonTap);
    ExecutePendingJavaScript();
  }

  void SendUnlockPassword(const std::string& password) {
    const std::string set_unlock_password =
        std::string(kAdUnlockPasswordInput) + ".value = '" + password + "'";
    test::OobeJS().ExecuteAsync(set_unlock_password);
    test::OobeJS().ExecuteAsync(kAdUnlockConfigurationSubmitButtonTap);
    ExecutePendingJavaScript();
  }

  void CheckUnlockPasswordValid(bool is_expected_valid) {
    test::OobeJS().ExpectNE(std::string(kAdUnlockPasswordInput) + ".invalid",
                            is_expected_valid);
  }

  void SetConfigValue(size_t config_idx) {
    test::OobeJS().ExecuteAsync(kAdConfigurationSelect +
                                (".value = " + std::to_string(config_idx)));
    // Trigger selection handler.
    test::OobeJS().ExecuteAsync(kAdConfigurationSelect +
                                std::string(".click()"));
  }

  void CheckAttributeValue(const base::Value* config_value,
                           const std::string& default_value,
                           const std::string& js_element) {
    std::string expected_value(default_value);
    if (config_value)
      expected_value = config_value->GetString();
    test::OobeJS().ExpectTrue(js_element + " === '" + expected_value + "'");
  }

  void CheckAttributeValueAndDisabled(const base::Value* config_value,
                                      const std::string& default_value,
                                      const std::string& js_element) {
    CheckAttributeValue(config_value, default_value, js_element + ".value");
    const bool is_disabled = bool(config_value);
    test::OobeJS().ExpectEQ(js_element + ".disabled", is_disabled);
  }

  // Checks pattern attribute on the machine name input field. If |config_value|
  // is nullptr the attribute should be undefined.
  void CheckPatternAttribute(const base::Value* config_value) {
    if (config_value) {
      std::string escaped_pattern;
      // Escape regex pattern.
      EXPECT_TRUE(base::EscapeJSONString(config_value->GetString(),
                                         false /* put_in_quotes */,
                                         &escaped_pattern));
      test::OobeJS().ExpectTrue(std::string(kAdMachineNameInput) +
                                ".pattern  === '" + escaped_pattern + "'");
    } else {
      test::OobeJS().ExpectTrue("typeof " + std::string(kAdMachineNameInput) +
                                ".pattern === 'undefined'");
    }
  }

  // Goes through |configuration| which is JSON (see
  // kAdDomainJoinUnlockedConfig). Selects each of them and checks that all the
  // input fields are set correctly. Also checks if there is a "Custom" option
  // which does not set any fields.
  void CheckPossibleConfiguration(const std::string& configuration) {
    std::unique_ptr<base::ListValue> options =
        base::ListValue::From(base::JSONReader::Read(
            configuration,
            base::JSONParserOptions::JSON_ALLOW_TRAILING_COMMAS));
    base::DictionaryValue custom_option;
    custom_option.SetKey("name", base::Value("Custom"));
    options->GetList().emplace_back(std::move(custom_option));
    for (size_t i = 0; i < options->GetList().size(); ++i) {
      const base::Value& option = options->GetList()[i];
      SetConfigValue(i);

      CheckAttributeValue(
          option.FindKeyOfType("name", base::Value::Type::STRING), "",
          std::string(kAdConfigurationSelect) + ".selectedOptions[0].label");

      CheckAttributeValueAndDisabled(
          option.FindKeyOfType("ad_username", base::Value::Type::STRING), "",
          std::string(kAdUsernameInput));

      CheckAttributeValueAndDisabled(
          option.FindKeyOfType("ad_password", base::Value::Type::STRING), "",
          std::string(kAdPasswordInput));

      CheckAttributeValueAndDisabled(
          option.FindKeyOfType("computer_ou", base::Value::Type::STRING), "",
          std::string(kAdMachineOrgUnitInput));

      CheckAttributeValueAndDisabled(
          option.FindKeyOfType("encryption_types", base::Value::Type::STRING),
          "strong", std::string(kAdEncryptionTypesSelect));

      CheckPatternAttribute(option.FindKeyOfType(
          "computer_name_validation_regex", base::Value::Type::STRING));
    }
  }

  // Submits Active Directory domain join credentials.
  void SubmitActiveDirectoryCredentials(const std::string& machine_name,
                                        const std::string& machine_dn,
                                        const std::string& encryption_types,
                                        const std::string& username,
                                        const std::string& password) {
    EXPECT_TRUE(IsStepDisplayed("ad-join"));
    test::OobeJS().ExpectFalse(std::string(kAdCredentialsStep) + ".hidden");
    test::OobeJS().ExpectTrue(std::string(kAdUnlockConfigurationStep) +
                              ".hidden");
    test::OobeJS().ExpectFalse(std::string(kAdMachineNameInput) + ".hidden");
    test::OobeJS().ExpectFalse(std::string(kAdUsernameInput) + ".hidden");
    test::OobeJS().ExpectFalse(std::string(kAdPasswordInput) + ".hidden");
    const std::string set_machine_name =
        std::string(kAdMachineNameInput) + ".value = '" + machine_name + "'";
    const std::string set_username =
        std::string(kAdUsernameInput) + ".value = '" + username + "'";
    const std::string set_password =
        std::string(kAdPasswordInput) + ".value = '" + password + "'";
    const std::string set_machine_dn =
        std::string(kAdMachineOrgUnitInput) + ".value = '" + machine_dn + "'";
    test::OobeJS().ExecuteAsync(set_machine_name);
    test::OobeJS().ExecuteAsync(set_username);
    test::OobeJS().ExecuteAsync(set_password);
    test::OobeJS().ExecuteAsync(set_machine_dn);
    if (!encryption_types.empty()) {
      const std::string set_encryption_types =
          std::string(kAdEncryptionTypesSelect) + ".value = '" +
          encryption_types + "'";
      test::OobeJS().ExecuteAsync(set_encryption_types);
    }
    test::OobeJS().ExecuteAsync(kAdMoreOptionsSave);
    test::OobeJS().ExecuteAsync(kAdSubmitCreds);
    ExecutePendingJavaScript();
  }

  void ClickRetryOnErrorScreen() {
    test::OobeJS().ExecuteAsync(
        "document.querySelector('"
        "#oauth-enroll-active-directory-join-error-card').$.submitButton"
        ".click()");
    ExecutePendingJavaScript();
  }

  void SetExpectedJoinRequest(
      const std::string& machine_name,
      const std::string& machine_domain,
      authpolicy::KerberosEncryptionTypes encryption_types,
      std::vector<std::string> organizational_unit,
      const std::string& username,
      const std::string& dm_token) {
    auto request = std::make_unique<authpolicy::JoinDomainRequest>();
    if (!machine_name.empty())
      request->set_machine_name(machine_name);
    if (!machine_domain.empty())
      request->set_machine_domain(machine_domain);
    for (std::string& it : organizational_unit)
      request->add_machine_ou()->swap(it);
    if (!username.empty())
      request->set_user_principal_name(username);
    if (!dm_token.empty())
      request->set_dm_token(dm_token);
    request->set_kerberos_encryption_types(encryption_types);
    mock_auth_policy_client()->set_expected_request(std::move(request));
  }

  // Forces the Active Directory domain join flow during enterprise enrollment.
  void SetupActiveDirectoryJoin(const std::string& expected_domain,
                                const std::string& domain_join_config) {
    AddEnrollmentSetupFunction(
        [this, expected_domain, domain_join_config](
            EnterpriseEnrollmentHelperMock* enrollment_helper) {
          // Causes the attribute-prompt flow to activate.
          EXPECT_CALL(*enrollment_helper,
                      EnrollUsingAuthCode("test_auth_code", _))
              .WillOnce(InvokeWithoutArgs(
                  [this, expected_domain, domain_join_config]() {
                    this->enrollment_screen()->JoinDomain(
                        kDMToken, domain_join_config,
                        base::BindOnce(
                            [](const std::string& expected_domain,
                               const std::string& domain) {
                              ASSERT_EQ(expected_domain, domain);
                            },
                            expected_domain));
                  }));
        });
  }

  MockAuthPolicyClient* mock_auth_policy_client() {
    return static_cast<MockAuthPolicyClient*>(
        DBusThreadManager::Get()->GetAuthPolicyClient());
  }

  void SetupActiveDirectoryJSNotifications() {
    test::OobeJS().ExecuteAsync(
        "var originalShowStep = login.OAuthEnrollmentScreen.showStep;\n"
        "login.OAuthEnrollmentScreen.showStep = function(step) {\n"
        "  originalShowStep(step);\n"
        "  if (step == 'working') {\n"
        "    window.domAutomationController.send('ShowSpinnerScreen');\n"
        "  }"
        "}\n"
        "var originalShowError = login.OAuthEnrollmentScreen.showError;\n"
        "login.OAuthEnrollmentScreen.showError = function(message, retry) {\n"
        "  originalShowError(message, retry);\n"
        "  window.domAutomationController.send('ShowADJoinError');\n"
        "}\n");
    test::OobeJS().ExecuteAsync(
        "var originalSetAdJoinParams ="
        "    login.OAuthEnrollmentScreen.setAdJoinParams;"
        "login.OAuthEnrollmentScreen.setAdJoinParams = function("
        "    machineName, user, errorState, showUnlockConfig) {"
        "  originalSetAdJoinParams("
        "      machineName, user, errorState, showUnlockConfig);"
        "  window.domAutomationController.send('ShowJoinDomainError');"
        "}");
    test::OobeJS().ExecuteAsync(
        "var originalSetAdJoinConfiguration ="
        "    login.OAuthEnrollmentScreen.setAdJoinConfiguration;"
        "login.OAuthEnrollmentScreen.setAdJoinConfiguration = function("
        "    options) {"
        "  originalSetAdJoinConfiguration(options);"
        "  window.domAutomationController.send('SetAdJoinConfiguration');"
        "}");
  }

  void WaitForMessage(content::DOMMessageQueue* message_queue,
                      const std::string& expected_message) {
    std::string message;
    do {
      ASSERT_TRUE(message_queue->WaitForMessage(&message));
    } while (message != expected_message);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ActiveDirectoryJoinTest);
};

class EnterpriseEnrollmentConfigurationTest
    : public EnterpriseEnrollmentTestBase {
 public:
  EnterpriseEnrollmentConfigurationTest()
      : EnterpriseEnrollmentTestBase(false) {}

  void StartWizard() {
    LoginDisplayHost* host = LoginDisplayHost::default_host();
    ASSERT_TRUE(host != nullptr);
    OobeScreenWaiter waiter(OobeScreen::SCREEN_OOBE_WELCOME);
    host->StartWizard(OobeScreen::SCREEN_OOBE_WELCOME);

    // Make sure that OOBE is run as an "official" build.
    WizardController* wizard_controller =
        WizardController::default_controller();
    wizard_controller->is_official_build_ = true;

    waiter.Wait();

    ASSERT_TRUE(WizardController::default_controller() != nullptr);
    ASSERT_FALSE(StartupUtils::IsOobeCompleted());
  }

  void LoadConfiguration() {
    OobeConfiguration::set_skip_check_for_testing(false);
    // Make sure configuration is loaded
    base::RunLoop run_loop;
    OOBEConfigurationWaiter waiter;

    OobeConfiguration::Get()->CheckConfiguration();

    const bool ready = waiter.IsConfigurationLoaded(run_loop.QuitClosure());
    if (!ready)
      run_loop.Run();

    // Let screens to settle.
    base::RunLoop().RunUntilIdle();
  }

  void SimulateOfflineEnvironment() {
    DemoSetupController* controller =
        WizardController::default_controller()->demo_setup_controller();

    // Simulate offline data directory.
    ASSERT_TRUE(test::SetupDummyOfflinePolicyDir("test", &fake_policy_dir_));
    controller->SetOfflineDataDirForTest(fake_policy_dir_.GetPath());
  }

  void SetUpInProcessBrowserTestFixture() override {
    OobeConfiguration::set_skip_check_for_testing(true);
    std::unique_ptr<chromeos::DBusThreadManagerSetter> dbus_setter =
        chromeos::DBusThreadManager::GetSetterForTesting();

    fake_update_engine_client_ = new chromeos::FakeUpdateEngineClient();

    dbus_setter->SetUpdateEngineClient(
        std::unique_ptr<chromeos::UpdateEngineClient>(
            fake_update_engine_client_));

    EnterpriseEnrollmentTestBase::SetUpInProcessBrowserTestFixture();
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    // File name is based on the test name.
    base::FilePath file;
    ASSERT_TRUE(GetTestFileName(".json", &file));

    command_line->AppendSwitchPath(chromeos::switches::kFakeOobeConfiguration,
                                   file);

    command_line->AppendSwitch(chromeos::switches::kEnableOfflineDemoMode);
    command_line->AppendSwitchASCII(switches::kArcAvailability,
                                    "officially-supported");
    EnterpriseEnrollmentTestBase::SetUpCommandLine(command_line);
  }

  // Stores a name of the configuration (actual test name followed by |prefix|)
  // to |file|.
  // Returns true iff |file| exists.
  bool GetTestFileName(const std::string& suffix, base::FilePath* file) {
    const ::testing::TestInfo* const test_info =
        ::testing::UnitTest::GetInstance()->current_test_info();
    const std::string filename = std::string(test_info->name()) + suffix;
    return test_utils::GetTestDataPath("oobe_configuration", filename, file);
  }

  // Overridden from InProcessBrowserTest:
  void SetUpOnMainThread() override {
    // Set up fake networks.
    // TODO(pmarko): Find a way for FakeShillManagerClient to be initialized
    // automatically (https://crbug.com/847422).
    DBusThreadManager::Get()
        ->GetShillManagerClient()
        ->GetTestInterface()
        ->SetupDefaultEnvironment();

    EnterpriseEnrollmentTestBase::SetUpOnMainThread();
    LoadConfiguration();

    // Make sure that OOBE is run as an "official" build.
    WizardController* wizard_controller =
        WizardController::default_controller();
    wizard_controller->is_official_build_ = true;

    // Clear portal list (as it is by default in OOBE).
    NetworkHandler::Get()->network_state_handler()->SetCheckPortalList("");
  }

  void TearDownOnMainThread() override {
    enrollment_screen()->enrollment_helper_.reset();
    EnterpriseEnrollmentTestBase::TearDownOnMainThread();
  }

  // Set up expectations for token enrollment.
  void ExpectTokenEnrollment() {
    AddEnrollmentSetupFunction(
        [](EnterpriseEnrollmentHelperMock* enrollment_helper) {
          EXPECT_CALL(*enrollment_helper,
                      EnrollUsingEnrollmentToken(
                          "00000000-1111-2222-3333-444444444444"))
              .WillOnce(InvokeWithoutArgs([enrollment_helper]() {
                enrollment_helper->status_consumer()->OnDeviceEnrolled();
              }));
        });
  }

 protected:
  // Owned by DBusThreadManagerSetter
  chromeos::FakeUpdateEngineClient* fake_update_engine_client_;

  base::ScopedTempDir fake_policy_dir_;

 private:
  DISALLOW_COPY_AND_ASSIGN(EnterpriseEnrollmentConfigurationTest);
};

#if defined(MEMORY_SANITIZER)
#define TEST_DISABLED_ON_MSAN(test_fixture, test_name) \
  IN_PROC_BROWSER_TEST_F(test_fixture, DISABLED_##test_name)
#else
#define TEST_DISABLED_ON_MSAN(test_fixture, test_name) \
  IN_PROC_BROWSER_TEST_F(test_fixture, test_name)
#endif

// Shows the enrollment screen and simulates an enrollment complete event. We
// verify that the enrollmenth helper receives the correct auth code.
// Flaky on MSAN. https://crbug.com/876362
TEST_DISABLED_ON_MSAN(EnterpriseEnrollmentTest,
                      TestAuthCodeGetsProperlyReceivedFromGaia) {
  ShowEnrollmentScreen();
  ExpectEnrollmentCredentials();
  SubmitEnrollmentCredentials();

  // We need to reset enrollment_screen->enrollment_helper_, otherwise we will
  // get some errors on shutdown.
  enrollment_screen()->enrollment_helper_.reset();
}

// Shows the enrollment screen and simulates an enrollment failure. Verifies
// that the error screen is displayed.
// TODO(crbug.com/690634): Disabled due to timeout flakiness.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentTest,
                       DISABLED_TestProperPageGetsLoadedOnEnrollmentFailure) {
  ShowEnrollmentScreen();

  enrollment_screen()->OnEnrollmentError(policy::EnrollmentStatus::ForStatus(
      policy::EnrollmentStatus::REGISTRATION_FAILED));
  ExecutePendingJavaScript();

  // Verify that the error page is displayed.
  EXPECT_TRUE(IsStepDisplayed("error"));
  EXPECT_FALSE(IsStepDisplayed("success"));
}

// Shows the enrollment screen and simulates a successful enrollment. Verifies
// that the success screen is then displayed.
// Flaky on MSAN. https://crbug.com/876362
TEST_DISABLED_ON_MSAN(EnterpriseEnrollmentTest,
                      TestProperPageGetsLoadedOnEnrollmentSuccess) {
  ShowEnrollmentScreen();
  DisableAttributePromptUpdate();
  SubmitEnrollmentCredentials();
  CompleteEnrollment();

  // Verify that the success page is displayed.
  EXPECT_TRUE(IsStepDisplayed("success"));
  EXPECT_FALSE(IsStepDisplayed("error"));

  // We have to remove the enrollment_helper before the dtor gets called.
  enrollment_screen()->enrollment_helper_.reset();
}

// Shows the enrollment screen and mocks the enrollment helper to request an
// attribute prompt screen. Verifies the attribute prompt screen is displayed.
// Verifies that the data the user enters into the attribute prompt screen is
// received by the enrollment helper.
// Flaky on MSAN. https://crbug.com/876362
TEST_DISABLED_ON_MSAN(EnterpriseEnrollmentTest,
                      TestAttributePromptPageGetsLoaded) {
  ShowEnrollmentScreen();
  ExpectAttributePromptUpdate();
  SubmitEnrollmentCredentials();
  CompleteEnrollment();

  // Make sure the attribute-prompt view is open.
  EXPECT_TRUE(IsStepDisplayed("attribute-prompt"));
  EXPECT_FALSE(IsStepDisplayed("success"));
  EXPECT_FALSE(IsStepDisplayed("error"));

  SubmitAttributePromptUpdate();

  // We have to remove the enrollment_helper before the dtor gets called.
  enrollment_screen()->enrollment_helper_.reset();
}

// Shows the enrollment screen and mocks the enrollment helper to show Active
// Directory domain join screen. Verifies the domain join screen is displayed.
// Submits Active Directory credentials. Verifies that the AuthpolicyClient
// calls us back with the correct realm.
// Timeouts on MSAN with polymer2. https://crbug.com/887577
TEST_DISABLED_ON_MSAN(ActiveDirectoryJoinTest,
                      TestActiveDirectoryEnrollment_Success) {
  ShowEnrollmentScreen();
  DisableAttributePromptUpdate();
  SetupActiveDirectoryJoin(kAdUserDomain, std::string());
  SubmitEnrollmentCredentials();

  chromeos::DBusThreadManager::Get()
      ->GetUpstartClient()
      ->StartAuthPolicyService();

  CheckActiveDirectoryCredentialsShown();
  CheckConfigurationSelectionVisible(false);
  content::DOMMessageQueue message_queue;
  SetupActiveDirectoryJSNotifications();
  SetExpectedJoinRequest("machine_name", "" /* machine_domain */,
                         authpolicy::KerberosEncryptionTypes::ENC_TYPES_ALL,
                         {} /* machine_ou */, kAdTestUser, kDMToken);
  SubmitActiveDirectoryCredentials("machine_name", "" /* machine_dn */, "all",
                                   kAdTestUser, "password");
  WaitForMessage(&message_queue, "\"ShowSpinnerScreen\"");
  EXPECT_FALSE(IsStepDisplayed("ad-join"));

  CompleteEnrollment();
  // Verify that the success page is displayed.
  EXPECT_TRUE(IsStepDisplayed("success"));
  EXPECT_FALSE(IsStepDisplayed("error"));

  // We have to remove the enrollment_helper before the dtor gets called.
  enrollment_screen()->enrollment_helper_.reset();
}

// Verifies that the distinguished name specified on the Active Directory join
// domain screen correctly parsed and passed into AuthPolicyClient.
// Timeouts on MSAN with polymer2. https://crbug.com/887577
TEST_DISABLED_ON_MSAN(ActiveDirectoryJoinTest,
                      TestActiveDirectoryEnrollment_DistinguishedName) {
  ShowEnrollmentScreen();
  DisableAttributePromptUpdate();
  SetupActiveDirectoryJoin(kAdMachineDomain, std::string());
  SubmitEnrollmentCredentials();

  chromeos::DBusThreadManager::Get()
      ->GetUpstartClient()
      ->StartAuthPolicyService();

  content::DOMMessageQueue message_queue;
  SetupActiveDirectoryJSNotifications();
  SetExpectedJoinRequest(
      "machine_name", kAdMachineDomain,
      authpolicy::KerberosEncryptionTypes::ENC_TYPES_STRONG,
      std::vector<std::string>(
          kAdOrganizationlUnit,
          kAdOrganizationlUnit + base::size(kAdOrganizationlUnit)),
      kAdTestUser, kDMToken);
  SubmitActiveDirectoryCredentials("machine_name", kAdMachineDomainDN,
                                   "" /* encryption_types */, kAdTestUser,
                                   "password");
  WaitForMessage(&message_queue, "\"ShowSpinnerScreen\"");
  EXPECT_FALSE(IsStepDisplayed("ad-join"));

  CompleteEnrollment();
  // Verify that the success page is displayed.
  EXPECT_TRUE(IsStepDisplayed("success"));
  EXPECT_FALSE(IsStepDisplayed("error"));

  // We have to remove the enrollment_helper before the dtor gets called.
  enrollment_screen()->enrollment_helper_.reset();
}

// Shows the enrollment screen and mocks the enrollment helper to show Active
// Directory domain join screen. Verifies the domain join screen is displayed.
// Submits Active Directory different incorrect credentials. Verifies that the
// correct error is displayed.
// Timeouts on MSAN with polymer2. https://crbug.com/887577
TEST_DISABLED_ON_MSAN(ActiveDirectoryJoinTest,
                      TestActiveDirectoryEnrollment_UIErrors) {
  ShowEnrollmentScreen();
  SetupActiveDirectoryJoin(kAdUserDomain, std::string());
  SubmitEnrollmentCredentials();

  chromeos::DBusThreadManager::Get()
      ->GetUpstartClient()
      ->StartAuthPolicyService();

  content::DOMMessageQueue message_queue;
  // Checking error in case of empty password. Whether password is not empty
  // being checked in the UI. Machine name length is checked after that in the
  // authpolicyd.
  SetupActiveDirectoryJSNotifications();
  SubmitActiveDirectoryCredentials("too_long_machine_name", "" /* machine_dn */,
                                   "" /* encryption_types */, kAdTestUser,
                                   "" /* password */);
  EXPECT_TRUE(IsStepDisplayed("ad-join"));
  test::OobeJS().ExpectFalse(std::string(kAdMachineNameInput) + ".invalid");
  test::OobeJS().ExpectFalse(std::string(kAdUsernameInput) + ".invalid");
  test::OobeJS().ExpectTrue(std::string(kAdPasswordInput) + ".invalid");

  // Checking error in case of too long machine name.
  SubmitActiveDirectoryCredentials("too_long_machine_name", "" /* machine_dn */,
                                   "" /* encryption_types */, kAdTestUser,
                                   "password");
  WaitForMessage(&message_queue, "\"ShowJoinDomainError\"");
  EXPECT_TRUE(IsStepDisplayed("ad-join"));
  test::OobeJS().ExpectTrue(std::string(kAdMachineNameInput) + ".invalid");
  test::OobeJS().ExpectFalse(std::string(kAdUsernameInput) + ".invalid");
  test::OobeJS().ExpectFalse(std::string(kAdPasswordInput) + ".invalid");

  // Checking error in case of bad username (without realm).
  SubmitActiveDirectoryCredentials("machine_name", "" /* machine_dn */,
                                   "" /* encryption_types */, "test_user",
                                   "password");
  WaitForMessage(&message_queue, "\"ShowJoinDomainError\"");
  EXPECT_TRUE(IsStepDisplayed("ad-join"));
  test::OobeJS().ExpectFalse(std::string(kAdMachineNameInput) + ".invalid");
  test::OobeJS().ExpectTrue(std::string(kAdUsernameInput) + ".invalid");
  test::OobeJS().ExpectFalse(std::string(kAdPasswordInput) + ".invalid");

  // We have to remove the enrollment_helper before the dtor gets called.
  enrollment_screen()->enrollment_helper_.reset();
}

// Check that correct error card is shown (Active Directory one). Also checks
// that hitting retry shows Active Directory screen again.
// Timeouts on MSAN with polymer2. https://crbug.com/887577
TEST_DISABLED_ON_MSAN(ActiveDirectoryJoinTest,
                      TestActiveDirectoryEnrollment_ErrorCard) {
  ShowEnrollmentScreen();
  SetupActiveDirectoryJoin(kAdUserDomain, std::string());
  SubmitEnrollmentCredentials();

  chromeos::DBusThreadManager::Get()
      ->GetUpstartClient()
      ->StartAuthPolicyService();

  content::DOMMessageQueue message_queue;
  SetupActiveDirectoryJSNotifications();
  // Legacy type triggers error card.
  SubmitActiveDirectoryCredentials("machine_name", "" /* machine_dn */,
                                   "legacy", kAdTestUser, "password");
  WaitForMessage(&message_queue, "\"ShowADJoinError\"");
  EXPECT_TRUE(IsStepDisplayed("active-directory-join-error"));
  ClickRetryOnErrorScreen();
  EXPECT_TRUE(IsStepDisplayed("ad-join"));

  // We have to remove the enrollment_helper before the dtor gets called.
  enrollment_screen()->enrollment_helper_.reset();
}

// Check that configuration for the streamline Active Directory domain join
// propagates correctly to the Domain Join UI.
// Timeouts on MSAN with polymer2. https://crbug.com/887577
TEST_DISABLED_ON_MSAN(ActiveDirectoryJoinTest,
                      TestActiveDirectoryEnrollment_Streamline) {
  ShowEnrollmentScreen();
  std::string binary_config;
  EXPECT_TRUE(base::Base64Decode(kAdDomainJoinEncryptedConfig, &binary_config));
  SetupActiveDirectoryJoin(kAdUserDomain, binary_config);
  SubmitEnrollmentCredentials();

  chromeos::DBusThreadManager::Get()
      ->GetUpstartClient()
      ->StartAuthPolicyService();

  ExecutePendingJavaScript();
  content::DOMMessageQueue message_queue;
  SetupActiveDirectoryJSNotifications();

  // Unlock password step should we shown.
  CheckActiveDirectoryUnlockConfigurationShown();
  CheckUnlockPasswordValid(true);

  // Test skipping the password step and getting back.
  SkipUnlockStep();
  CheckActiveDirectoryCredentialsShown();
  CheckConfigurationSelectionVisible(false);
  GetBackToUnlockStep();
  CheckActiveDirectoryUnlockConfigurationShown();

  // Enter wrong unlock password.
  SendUnlockPassword("wrong_password");
  WaitForMessage(&message_queue, "\"ShowJoinDomainError\"");
  CheckUnlockPasswordValid(false);

  // Enter right unlock password.
  SendUnlockPassword("test765!");
  WaitForMessage(&message_queue, "\"SetAdJoinConfiguration\"");
  CheckActiveDirectoryCredentialsShown();
  // Configuration selector should be visible.
  CheckConfigurationSelectionVisible(true);

  // Go through configuration.
  CheckPossibleConfiguration(kAdDomainJoinUnlockedConfig);
  enrollment_screen()->enrollment_helper_.reset();
}

// Check that configuration lets correctly pass Welcome screen.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestLeaveWelcomeScreen) {
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait();
}

// Check that language and input methods are set correctly.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestSwitchLanguageIME) {
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait();

  chromeos::input_method::InputMethodManager* imm =
      chromeos::input_method::InputMethodManager::Get();

  // Configuration specified in TestSwitchLanguageIME.json sets non-default
  // input method fo German (xkb:de:neo:ger) to ensure that input method value
  // is propagated correctly. We need to migrate public IME name to internal
  // scheme to be able to compare them.

  const std::string ime_id =
      imm->GetInputMethodUtil()->MigrateInputMethod("xkb:de:neo:ger");
  EXPECT_EQ(ime_id, imm->GetActiveIMEState()->GetCurrentInputMethod().id());

  const std::string language_code = g_browser_process->local_state()->GetString(
      language::prefs::kApplicationLocale);
  EXPECT_EQ("de", language_code);
}

// Check that configuration lets correctly start Demo mode setup.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestEnableDemoMode) {
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES).Wait();
}

// Check that configuration lets correctly pass through demo preferences.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestDemoModePreferences) {
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_NETWORK).Wait();
}

// Check that configuration lets correctly use offline demo mode on network
// screen.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestDemoModeOfflineNetwork) {
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_EULA).Wait();
}

// Check that configuration lets correctly use offline demo mode on EULA
// screen.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestDemoModeAcceptEula) {
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_ARC_TERMS_OF_SERVICE).Wait();
}

// Check that configuration lets correctly use offline demo mode on ARC++ ToS
// screen.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestDemoModeAcceptArcTos) {
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_DEMO_PREFERENCES).Wait();

  test::OobeJS().Evaluate(
      "login.ArcTermsOfServiceScreen.setTosForTesting('Test "
      "Play Store Terms of Service');");
  SimulateOfflineEnvironment();
  test::OobeJS().Evaluate(
      "$('demo-preferences-content').$$('oobe-dialog')."
      "querySelector('oobe-text-button').click();");

  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_DEMO_SETUP).Wait();
}

// Check that configuration lets correctly select a network by GUID.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestSelectNetwork) {
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_EULA).Wait();
}

// Check that configuration would proceed if there is a connected network.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestSelectConnectedNetwork) {
  StartWizard();
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_EULA).Wait();
}

// Check that configuration would not proceed with connected network if
// welcome screen is not automated.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestConnectedNetworkNoWelcome) {
  StartWizard();
  LoadConfiguration();

  OobeUI* oobe_ui = LoginDisplayHost::default_host()->GetOobeUI();
  ASSERT_EQ(OobeScreen::SCREEN_OOBE_WELCOME, oobe_ui->current_screen());
}

// Check that when configuration has ONC and EULA, we get to update screen.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, TestAcceptEula) {
  UpdateEngineClient::Status status;
  status.status = UpdateEngineClient::UPDATE_STATUS_DOWNLOADING;
  status.download_progress = 0.1;
  fake_update_engine_client_->set_default_status(status);

  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_UPDATE).Wait();
}

// Check that configuration allows to skip Update screen and get to Enrollment
// screen.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest, TestSkipUpdate) {
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_ENROLLMENT).Wait();
  EXPECT_TRUE(IsStepDisplayed("signin"));
}

// Check that when configuration has requisition, it gets applied at the
// beginning.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestDeviceRequisition) {
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_EULA).Wait();
  auto* policy_manager = g_browser_process->platform_part()
                             ->browser_policy_connector_chromeos()
                             ->GetDeviceCloudPolicyManager();
  EXPECT_EQ(policy_manager->GetDeviceRequisition(), "some_requisition");
}

// Check that configuration allows to skip Update screen and get to Enrollment
// screen.
IN_PROC_BROWSER_TEST_F(EnterpriseEnrollmentConfigurationTest,
                       TestEnrollUsingToken) {
  ExpectTokenEnrollment();
  DisableAttributePromptUpdate();
  LoadConfiguration();
  OobeScreenWaiter(OobeScreen::SCREEN_OOBE_ENROLLMENT).Wait();
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(IsStepDisplayed("success"));
}

}  // namespace chromeos
