| Index: chrome/browser/policy/device_management_backend_impl_unittest.cc
|
| diff --git a/chrome/browser/policy/device_management_backend_impl_unittest.cc b/chrome/browser/policy/device_management_backend_impl_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1e93f3a6ef6e6356d7ee025fd5055b84f54a8319
|
| --- /dev/null
|
| +++ b/chrome/browser/policy/device_management_backend_impl_unittest.cc
|
| @@ -0,0 +1,375 @@
|
| +// Copyright (c) 2010 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/device_management_backend_impl.h"
|
| +
|
| +#include "base/message_loop.h"
|
| +#include "base/string_split.h"
|
| +#include "chrome/browser/browser_thread.h"
|
| +#include "chrome/browser/policy/device_management_backend_mock.h"
|
| +#include "chrome/common/net/test_url_fetcher_factory.h"
|
| +#include "net/base/escape.h"
|
| +#include "net/url_request/url_request_status.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +
|
| +using testing::_;
|
| +
|
| +namespace policy {
|
| +
|
| +namespace {
|
| +
|
| +const char kServiceURL[] = "https://example.com/management_service";
|
| +
|
| +// Encoded error response messages for testing the error code paths.
|
| +const char kResponseEmpty[] = "\x08\x00";
|
| +const char kResponseErrorManagementNotSupported[] = "\x08\x01";
|
| +const char kResponseErrorDeviceNotFound[] = "\x08\x02";
|
| +const char kResponseErrorManagementTokenInvalid[] = "\x08\x03";
|
| +const char kResponseErrorActivationPending[] = "\x08\x04";
|
| +
|
| +#define PROTO_STRING(name) (std::string(name, arraysize(name) - 1))
|
| +
|
| +} // namespace
|
| +
|
| +// Unit tests for the google apps policy backend. The pattern here is each test
|
| +// case triggeres a request and installs a mock delegate. The test will run and
|
| +// the default action installed on the test delegate will quit the loop.
|
| +template<typename TESTBASE>
|
| +class DeviceManagementBackendImplTestBase : public TESTBASE {
|
| + protected:
|
| + DeviceManagementBackendImplTestBase()
|
| + : io_thread_(BrowserThread::IO, &loop_),
|
| + service_(kServiceURL) {}
|
| +
|
| + virtual void SetUp() {
|
| + URLFetcher::set_factory(&factory_);
|
| + }
|
| +
|
| + virtual void TearDown() {
|
| + URLFetcher::set_factory(NULL);
|
| + loop_.RunAllPending();
|
| + }
|
| +
|
| + MessageLoopForUI loop_;
|
| + BrowserThread io_thread_;
|
| + TestURLFetcherFactory factory_;
|
| + DeviceManagementBackendImpl service_;
|
| +};
|
| +
|
| +struct FailedRequestParams {
|
| + FailedRequestParams(DeviceManagementBackend::ErrorCode expected_error,
|
| + URLRequestStatus::Status request_status,
|
| + int http_status,
|
| + const std::string& response)
|
| + : expected_error_(expected_error),
|
| + request_status_(request_status, 0),
|
| + http_status_(http_status),
|
| + response_(response) {}
|
| +
|
| + DeviceManagementBackend::ErrorCode expected_error_;
|
| + URLRequestStatus request_status_;
|
| + int http_status_;
|
| + std::string response_;
|
| +};
|
| +
|
| +// A parameterized test case for erroneous response situations, they're mostly
|
| +// the same for all kinds of requests.
|
| +class DeviceManagementBackendImplFailedRequestTest
|
| + : public DeviceManagementBackendImplTestBase<
|
| + testing::TestWithParam<FailedRequestParams> > {
|
| +};
|
| +
|
| +TEST_P(DeviceManagementBackendImplFailedRequestTest, RegisterRequest) {
|
| + DeviceRegisterResponseDelegateMock mock;
|
| + EXPECT_CALL(mock, OnError(GetParam().expected_error_));
|
| + em::DeviceRegisterRequest request;
|
| + service_.ProcessRegisterRequest("token", "device id", request, &mock);
|
| + TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
|
| + ASSERT_TRUE(fetcher);
|
| +
|
| + fetcher->delegate()->OnURLFetchComplete(fetcher,
|
| + GURL(kServiceURL),
|
| + GetParam().request_status_,
|
| + GetParam().http_status_,
|
| + ResponseCookies(),
|
| + GetParam().response_);
|
| +}
|
| +
|
| +TEST_P(DeviceManagementBackendImplFailedRequestTest, UnregisterRequest) {
|
| + DeviceUnregisterResponseDelegateMock mock;
|
| + EXPECT_CALL(mock, OnError(GetParam().expected_error_));
|
| + em::DeviceUnregisterRequest request;
|
| + service_.ProcessUnregisterRequest("token", request, &mock);
|
| + TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
|
| + ASSERT_TRUE(fetcher);
|
| +
|
| + fetcher->delegate()->OnURLFetchComplete(fetcher,
|
| + GURL(kServiceURL),
|
| + GetParam().request_status_,
|
| + GetParam().http_status_,
|
| + ResponseCookies(),
|
| + GetParam().response_);
|
| +}
|
| +
|
| +TEST_P(DeviceManagementBackendImplFailedRequestTest, PolicyRequest) {
|
| + DevicePolicyResponseDelegateMock mock;
|
| + EXPECT_CALL(mock, OnError(GetParam().expected_error_));
|
| + em::DevicePolicyRequest request;
|
| + request.set_policy_scope("Chrome");
|
| + em::DevicePolicySettingRequest* setting_request =
|
| + request.add_setting_request();
|
| + setting_request->set_key("policy");
|
| + service_.ProcessPolicyRequest("token", request, &mock);
|
| + TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
|
| + ASSERT_TRUE(fetcher);
|
| +
|
| + fetcher->delegate()->OnURLFetchComplete(fetcher,
|
| + GURL(kServiceURL),
|
| + GetParam().request_status_,
|
| + GetParam().http_status_,
|
| + ResponseCookies(),
|
| + GetParam().response_);
|
| +}
|
| +
|
| +INSTANTIATE_TEST_CASE_P(
|
| + DeviceManagementBackendImplFailedRequestTestInstance,
|
| + DeviceManagementBackendImplFailedRequestTest,
|
| + testing::Values(
|
| + FailedRequestParams(
|
| + DeviceManagementBackend::kErrorRequestFailed,
|
| + URLRequestStatus::FAILED,
|
| + 200,
|
| + PROTO_STRING(kResponseEmpty)),
|
| + FailedRequestParams(
|
| + DeviceManagementBackend::kErrorHttpStatus,
|
| + URLRequestStatus::SUCCESS,
|
| + 500,
|
| + PROTO_STRING(kResponseEmpty)),
|
| + FailedRequestParams(
|
| + DeviceManagementBackend::kErrorResponseDecoding,
|
| + URLRequestStatus::SUCCESS,
|
| + 200,
|
| + PROTO_STRING("Not a protobuf.")),
|
| + FailedRequestParams(
|
| + DeviceManagementBackend::kErrorServiceManagementNotSupported,
|
| + URLRequestStatus::SUCCESS,
|
| + 200,
|
| + PROTO_STRING(kResponseErrorManagementNotSupported)),
|
| + FailedRequestParams(
|
| + DeviceManagementBackend::kErrorServiceDeviceNotFound,
|
| + URLRequestStatus::SUCCESS,
|
| + 200,
|
| + PROTO_STRING(kResponseErrorDeviceNotFound)),
|
| + FailedRequestParams(
|
| + DeviceManagementBackend::kErrorServiceManagementTokenInvalid,
|
| + URLRequestStatus::SUCCESS,
|
| + 200,
|
| + PROTO_STRING(kResponseErrorManagementTokenInvalid)),
|
| + FailedRequestParams(
|
| + DeviceManagementBackend::kErrorServiceActivationPending,
|
| + URLRequestStatus::SUCCESS,
|
| + 200,
|
| + PROTO_STRING(kResponseErrorActivationPending))));
|
| +
|
| +class DeviceManagementBackendImplTest
|
| + : public DeviceManagementBackendImplTestBase<testing::Test> {
|
| +};
|
| +
|
| +MATCHER_P(MessageEquals, reference, "") {
|
| + std::string reference_data;
|
| + std::string arg_data;
|
| + return arg.SerializeToString(&arg_data) &&
|
| + reference.SerializeToString(&reference_data) &&
|
| + arg_data == reference_data;
|
| +}
|
| +
|
| +// Simple query parameter parser for testing.
|
| +class QueryParams {
|
| + public:
|
| + explicit QueryParams(const std::string& query) {
|
| + base::SplitStringIntoKeyValuePairs(query, '=', '&', ¶ms_);
|
| + }
|
| +
|
| + bool Check(const std::string& name, const std::string& expected_value) {
|
| + bool found = false;
|
| + for (ParamMap::const_iterator i(params_.begin()); i != params_.end(); ++i) {
|
| + std::string unescaped_name(
|
| + UnescapeURLComponent(i->first,
|
| + UnescapeRule::NORMAL |
|
| + UnescapeRule::SPACES |
|
| + UnescapeRule::URL_SPECIAL_CHARS |
|
| + UnescapeRule::CONTROL_CHARS |
|
| + UnescapeRule::REPLACE_PLUS_WITH_SPACE));
|
| + if (unescaped_name == name) {
|
| + if (found)
|
| + return false;
|
| + found = true;
|
| + std::string unescaped_value(
|
| + UnescapeURLComponent(i->second,
|
| + UnescapeRule::NORMAL |
|
| + UnescapeRule::SPACES |
|
| + UnescapeRule::URL_SPECIAL_CHARS |
|
| + UnescapeRule::CONTROL_CHARS |
|
| + UnescapeRule::REPLACE_PLUS_WITH_SPACE));
|
| + if (unescaped_value != expected_value)
|
| + return false;
|
| + }
|
| + }
|
| + return found;
|
| + }
|
| +
|
| + private:
|
| + typedef std::vector<std::pair<std::string, std::string> > ParamMap;
|
| + ParamMap params_;
|
| +};
|
| +
|
| +TEST_F(DeviceManagementBackendImplTest, RegisterRequest) {
|
| + DeviceRegisterResponseDelegateMock mock;
|
| + em::DeviceRegisterResponse expected_response;
|
| + expected_response.set_device_management_token("mtoken");
|
| + EXPECT_CALL(mock, HandleRegisterResponse(MessageEquals(expected_response)));
|
| + em::DeviceRegisterRequest request;
|
| + service_.ProcessRegisterRequest("token", "device id", request, &mock);
|
| + TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
|
| + ASSERT_TRUE(fetcher);
|
| +
|
| + // Check the data the fetcher received.
|
| + const GURL& request_url(fetcher->original_url());
|
| + const GURL service_url(kServiceURL);
|
| + EXPECT_EQ(service_url.scheme(), request_url.scheme());
|
| + EXPECT_EQ(service_url.host(), request_url.host());
|
| + EXPECT_EQ(service_url.port(), request_url.port());
|
| + EXPECT_EQ(service_url.path(), request_url.path());
|
| +
|
| + QueryParams query_params(request_url.query());
|
| + EXPECT_TRUE(query_params.Check("request", "register"));
|
| +
|
| + em::DeviceManagementRequest expected_request_wrapper;
|
| + expected_request_wrapper.mutable_register_request()->CopyFrom(request);
|
| + std::string expected_request_data;
|
| + ASSERT_TRUE(expected_request_wrapper.SerializeToString(
|
| + &expected_request_data));
|
| + EXPECT_EQ(expected_request_data, fetcher->upload_data());
|
| +
|
| + // Generate the response.
|
| + std::string response_data;
|
| + em::DeviceManagementResponse response_wrapper;
|
| + response_wrapper.set_error(em::DeviceManagementResponse::SUCCESS);
|
| + response_wrapper.mutable_register_response()->CopyFrom(expected_response);
|
| + ASSERT_TRUE(response_wrapper.SerializeToString(&response_data));
|
| + URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
|
| + fetcher->delegate()->OnURLFetchComplete(fetcher,
|
| + GURL(kServiceURL),
|
| + status,
|
| + 200,
|
| + ResponseCookies(),
|
| + response_data);
|
| +}
|
| +
|
| +TEST_F(DeviceManagementBackendImplTest, UnregisterRequest) {
|
| + DeviceUnregisterResponseDelegateMock mock;
|
| + em::DeviceUnregisterResponse expected_response;
|
| + EXPECT_CALL(mock, HandleUnregisterResponse(MessageEquals(expected_response)));
|
| + em::DeviceUnregisterRequest request;
|
| + service_.ProcessUnregisterRequest("dmtokenvalue", request, &mock);
|
| + TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
|
| + ASSERT_TRUE(fetcher);
|
| +
|
| + // Check the data the fetcher received.
|
| + const GURL& request_url(fetcher->original_url());
|
| + const GURL service_url(kServiceURL);
|
| + EXPECT_EQ(service_url.scheme(), request_url.scheme());
|
| + EXPECT_EQ(service_url.host(), request_url.host());
|
| + EXPECT_EQ(service_url.port(), request_url.port());
|
| + EXPECT_EQ(service_url.path(), request_url.path());
|
| +
|
| + QueryParams query_params(request_url.query());
|
| + EXPECT_TRUE(query_params.Check("request", "unregister"));
|
| +
|
| + em::DeviceManagementRequest expected_request_wrapper;
|
| + expected_request_wrapper.mutable_unregister_request()->CopyFrom(request);
|
| + std::string expected_request_data;
|
| + ASSERT_TRUE(expected_request_wrapper.SerializeToString(
|
| + &expected_request_data));
|
| + EXPECT_EQ(expected_request_data, fetcher->upload_data());
|
| +
|
| + // Generate the response.
|
| + std::string response_data;
|
| + em::DeviceManagementResponse response_wrapper;
|
| + response_wrapper.set_error(em::DeviceManagementResponse::SUCCESS);
|
| + response_wrapper.mutable_unregister_response()->CopyFrom(expected_response);
|
| + ASSERT_TRUE(response_wrapper.SerializeToString(&response_data));
|
| + URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
|
| + fetcher->delegate()->OnURLFetchComplete(fetcher,
|
| + GURL(kServiceURL),
|
| + status,
|
| + 200,
|
| + ResponseCookies(),
|
| + response_data);
|
| +}
|
| +
|
| +TEST_F(DeviceManagementBackendImplTest, PolicyRequest) {
|
| + DevicePolicyResponseDelegateMock mock;
|
| + em::DevicePolicyResponse expected_response;
|
| + em::DevicePolicySetting* policy_setting = expected_response.add_setting();
|
| + policy_setting->set_policy_key("policy");
|
| + policy_setting->set_watermark("fresh");
|
| + em::GenericSetting* policy_value = policy_setting->mutable_policy_value();
|
| + em::GenericNamedValue* named_value = policy_value->add_named_value();
|
| + named_value->set_name("HomepageLocation");
|
| + named_value->mutable_value()->set_value_type(
|
| + em::GenericValue::VALUE_TYPE_STRING);
|
| + named_value->mutable_value()->set_string_value("http://www.chromium.org");
|
| + named_value = policy_value->add_named_value();
|
| + named_value->set_name("HomepageIsNewTabPage");
|
| + named_value->mutable_value()->set_value_type(
|
| + em::GenericValue::VALUE_TYPE_BOOL);
|
| + named_value->mutable_value()->set_bool_value(false);
|
| + EXPECT_CALL(mock, HandlePolicyResponse(MessageEquals(expected_response)));
|
| +
|
| + em::DevicePolicyRequest request;
|
| + request.set_policy_scope("chromium");
|
| + em::DevicePolicySettingRequest* setting_request =
|
| + request.add_setting_request();
|
| + setting_request->set_key("policy");
|
| + setting_request->set_watermark("stale");
|
| + service_.ProcessPolicyRequest("dmtokenvalue", request, &mock);
|
| + TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
|
| + ASSERT_TRUE(fetcher);
|
| +
|
| + // Check the data the fetcher received.
|
| + const GURL& request_url(fetcher->original_url());
|
| + const GURL service_url(kServiceURL);
|
| + EXPECT_EQ(service_url.scheme(), request_url.scheme());
|
| + EXPECT_EQ(service_url.host(), request_url.host());
|
| + EXPECT_EQ(service_url.port(), request_url.port());
|
| + EXPECT_EQ(service_url.path(), request_url.path());
|
| +
|
| + QueryParams query_params(request_url.query());
|
| + EXPECT_TRUE(query_params.Check("request", "policy"));
|
| +
|
| + em::DeviceManagementRequest expected_request_wrapper;
|
| + expected_request_wrapper.mutable_policy_request()->CopyFrom(request);
|
| + std::string expected_request_data;
|
| + ASSERT_TRUE(expected_request_wrapper.SerializeToString(
|
| + &expected_request_data));
|
| + EXPECT_EQ(expected_request_data, fetcher->upload_data());
|
| +
|
| + // Generate the response.
|
| + std::string response_data;
|
| + em::DeviceManagementResponse response_wrapper;
|
| + response_wrapper.set_error(em::DeviceManagementResponse::SUCCESS);
|
| + response_wrapper.mutable_policy_response()->CopyFrom(expected_response);
|
| + ASSERT_TRUE(response_wrapper.SerializeToString(&response_data));
|
| + URLRequestStatus status(URLRequestStatus::SUCCESS, 0);
|
| + fetcher->delegate()->OnURLFetchComplete(fetcher,
|
| + GURL(kServiceURL),
|
| + status,
|
| + 200,
|
| + ResponseCookies(),
|
| + response_data);
|
| +}
|
| +
|
| +} // namespace policy
|
|
|