// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/policy_test_utils.h"
#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/policy_constants.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/test_extension_registry_observer.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "url/gurl.h"
namespace extensions {
namespace policy_test_utils {
namespace {
constexpr char kFileNameToIntercept[] = "update_manifest.xml";
// Replace "mock.http" with "127.0.0.1:<port>" on "update_manifest.xml" files.
// Host resolver doesn't work here because the test file doesn't know the
// correct port number.
std::unique_ptr<net::test_server::HttpResponse> InterceptMockHttp(
net::EmbeddedTestServer* embedded_test_server,
const net::test_server::HttpRequest& request) {
if (request.GetURL().ExtractFileName() != kFileNameToIntercept) {
return nullptr;
}
base::FilePath test_data_dir;
base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
// Remove the leading '/'.
std::string relative_manifest_path = request.GetURL().path().substr(1);
std::string manifest_response;
CHECK(base::ReadFileToString(test_data_dir.Append(relative_manifest_path),
&manifest_response));
base::ReplaceSubstringsAfterOffset(
&manifest_response, 0, "mock.http",
embedded_test_server->host_port_pair().ToString());
auto response = std::make_unique<net::test_server::BasicHttpResponse>();
response->set_content_type("text/xml");
response->set_content(manifest_response);
return response;
}
} // namespace
void SetUpEmbeddedTestServer(net::EmbeddedTestServer* embedded_test_server) {
embedded_test_server->RegisterRequestHandler(
base::BindRepeating(&InterceptMockHttp, embedded_test_server));
}
void SetExtensionInstallForcelistPolicy(
const ExtensionId& extension_id,
const GURL& update_manifest_url,
Profile* profile,
policy::MockConfigurationPolicyProvider* policy_provider) {
// Extensions that are force-installed come from an update URL, which defaults
// to the webstore. Use a mock URL for test with an update manifest that
// includes the crx file of the test extension.
base::Value::List forcelist;
forcelist.Append(base::StringPrintf("%s;%s", extension_id.c_str(),
update_manifest_url.spec().c_str()));
policy::PolicyMap policy;
policy.Set(policy::key::kExtensionInstallForcelist,
policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
policy::POLICY_SOURCE_CLOUD, base::Value(std::move(forcelist)),
nullptr);
// Set the policy and wait until the extension is installed.
extensions::TestExtensionRegistryObserver observer(
ExtensionRegistry::Get(profile));
policy_provider->UpdateChromePolicy(policy);
observer.WaitForExtensionLoaded();
}
} // namespace policy_test_utils
} // namespace extensions