15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ostream>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/message_loop/message_loop.h"
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
11a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/run_loop.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/device_management_service.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/mock_device_management_service.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_test_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Mock;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kServiceUrl[] = "https://example.com/management_service";
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Encoded empty response messages for testing the error code paths.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kResponseEmpty[] = "\x08\x00";
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PROTO_STRING(name) (std::string(name, arraysize(name) - 1))
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some helper constants.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kGaiaAuthToken[] = "gaia-auth-token";
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOAuthToken[] = "oauth-token";
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDMToken[] = "device-management-token";
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kClientID[] = "device-id";
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kRobotAuthCode[] = "robot-oauth-auth-code";
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Unit tests for the device management policy service. The tests are run
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// against a TestURLFetcherFactory that is used to short-circuit the request
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// without calling into the actual network stack.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeviceManagementServiceTestBase : public testing::Test {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
52a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  DeviceManagementServiceTestBase() {
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request_context_ =
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        new net::TestURLRequestContextGetter(loop_.message_loop_proxy());
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ResetService();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitializeService();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  ~DeviceManagementServiceTestBase() {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_.reset();
61a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    base::RunLoop().RunUntilIdle();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResetService() {
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<DeviceManagementService::Configuration> configuration(
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        new MockDeviceManagementServiceConfiguration(kServiceUrl));
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    service_.reset(new DeviceManagementService(configuration.Pass()));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitializeService() {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_->ScheduleInitialization(0);
72a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    base::RunLoop().RunUntilIdle();
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* GetFetcher() {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return factory_.GetFetcherByID(DeviceManagementService::kURLFetcherID);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeviceManagementRequestJob* StartRegistrationJob() {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceManagementRequestJob* job =
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        service_->CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION,
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            request_context_);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->SetGaiaToken(kGaiaAuthToken);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->SetOAuthToken(kOAuthToken);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->SetClientID(kClientID);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->GetRequest()->mutable_register_request();
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job->SetRetryCallback(base::Bind(
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this)));
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->Start(base::Bind(&DeviceManagementServiceTestBase::OnJobDone,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::Unretained(this)));
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return job;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DeviceManagementRequestJob* StartApiAuthCodeFetchJob() {
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DeviceManagementRequestJob* job = service_->CreateJob(
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH,
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        request_context_);
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    job->SetGaiaToken(kGaiaAuthToken);
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    job->SetOAuthToken(kOAuthToken);
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    job->SetClientID(kClientID);
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    job->GetRequest()->mutable_service_api_access_request();
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    job->SetRetryCallback(base::Bind(
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this)));
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    job->Start(base::Bind(&DeviceManagementServiceTestBase::OnJobDone,
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          base::Unretained(this)));
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return job;
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeviceManagementRequestJob* StartUnregistrationJob() {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceManagementRequestJob* job =
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        service_->CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION,
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            request_context_);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->SetDMToken(kDMToken);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->SetClientID(kClientID);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->GetRequest()->mutable_unregister_request();
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job->SetRetryCallback(base::Bind(
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this)));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->Start(base::Bind(&DeviceManagementServiceTestBase::OnJobDone,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::Unretained(this)));
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return job;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeviceManagementRequestJob* StartPolicyFetchJob() {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceManagementRequestJob* job =
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH,
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            request_context_);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->SetGaiaToken(kGaiaAuthToken);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->SetOAuthToken(kOAuthToken);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->SetClientID(kClientID);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::PolicyFetchRequest* fetch_request =
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        job->GetRequest()->mutable_policy_request()->add_request();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetch_request->set_policy_type(dm_protocol::kChromeUserPolicyType);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job->SetRetryCallback(base::Bind(
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this)));
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->Start(base::Bind(&DeviceManagementServiceTestBase::OnJobDone,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::Unretained(this)));
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return job;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeviceManagementRequestJob* StartAutoEnrollmentJob() {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceManagementRequestJob* job =
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        service_->CreateJob(DeviceManagementRequestJob::TYPE_AUTO_ENROLLMENT,
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            request_context_);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->SetClientID(kClientID);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    em::DeviceAutoEnrollmentRequest* request =
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        job->GetRequest()->mutable_auto_enrollment_request();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request->set_modulus(1);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request->set_remainder(0);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    job->SetRetryCallback(base::Bind(
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &DeviceManagementServiceTestBase::OnJobRetry, base::Unretained(this)));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job->Start(base::Bind(&DeviceManagementServiceTestBase::OnJobDone,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::Unretained(this)));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return job;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SendResponse(net::TestURLFetcher* fetcher,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const net::URLRequestStatus request_status,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int http_status,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    const std::string& response) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_url(GURL(kServiceUrl));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_status(request_status);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_response_code(http_status);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->SetResponseString(response);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->delegate()->OnURLFetchComplete(fetcher);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  MOCK_METHOD3(OnJobDone, void(DeviceManagementStatus, int,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const em::DeviceManagementResponse&));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD1(OnJobRetry, void(DeviceManagementRequestJob*));
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::MessageLoop loop_;
17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  scoped_refptr<net::TestURLRequestContextGetter> request_context_;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::TestURLFetcherFactory factory_;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementService> service_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct FailedRequestParams {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailedRequestParams(DeviceManagementStatus expected_status,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      net::URLRequestStatus::Status request_status,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      int http_status,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const std::string& response)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : expected_status_(expected_status),
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request_status_(request_status, 0),
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        http_status_(http_status),
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        response_(response) {}
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeviceManagementStatus expected_status_;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus request_status_;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int http_status_;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintTo(const FailedRequestParams& params, std::ostream* os) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *os << "FailedRequestParams " << params.expected_status_
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << " " << params.request_status_.status()
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << " " << params.http_status_;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A parameterized test case for erroneous response situations, they're mostly
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the same for all kinds of requests.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeviceManagementServiceFailedRequestTest
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public DeviceManagementServiceTestBase,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public testing::WithParamInterface<FailedRequestParams> {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(DeviceManagementServiceFailedRequestTest, RegisterRequest) {
208b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(GetParam().expected_status_, _, _));
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               GetParam().response_);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_P(DeviceManagementServiceFailedRequestTest, ApiAuthCodeFetchRequest) {
219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(GetParam().expected_status_, _, _));
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      StartApiAuthCodeFetchJob());
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(fetcher);
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_,
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               GetParam().response_);
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(DeviceManagementServiceFailedRequestTest, UnregisterRequest) {
231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(GetParam().expected_status_, _, _));
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartUnregistrationJob());
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               GetParam().response_);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(DeviceManagementServiceFailedRequestTest, PolicyRequest) {
242b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(GetParam().expected_status_, _, _));
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartPolicyFetchJob());
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               GetParam().response_);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(DeviceManagementServiceFailedRequestTest, AutoEnrollmentRequest) {
253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(GetParam().expected_status_, _, _));
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartAutoEnrollmentJob());
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(fetcher, GetParam().request_status_, GetParam().http_status_,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               GetParam().response_);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceManagementServiceFailedRequestTestInstance,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DeviceManagementServiceFailedRequestTest,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::Values(
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_REQUEST_FAILED,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::FAILED,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            200,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty)),
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_HTTP_STATUS_ERROR,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            666,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty)),
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_RESPONSE_DECODING_ERROR,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            200,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING("Not a protobuf.")),
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            403,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty)),
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            405,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty)),
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_SERVICE_DEVICE_ID_CONFLICT,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            409,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty)),
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_SERVICE_DEVICE_NOT_FOUND,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            410,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty)),
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            401,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty)),
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_REQUEST_INVALID,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            400,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty)),
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_TEMPORARY_UNAVAILABLE,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            404,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty)),
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_SERVICE_ACTIVATION_PENDING,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            412,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty)),
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FailedRequestParams(
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            DM_STATUS_SERVICE_MISSING_LICENSES,
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::URLRequestStatus::SUCCESS,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            402,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PROTO_STRING(kResponseEmpty))));
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simple query parameter parser for testing.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QueryParams {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit QueryParams(const std::string& query) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SplitStringIntoKeyValuePairs(query, '=', '&', &params_);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Check(const std::string& name, const std::string& expected_value) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool found = false;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (ParamMap::const_iterator i(params_.begin()); i != params_.end(); ++i) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string unescaped_name(net::UnescapeURLComponent(
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          i->first,
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          net::UnescapeRule::NORMAL |
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          net::UnescapeRule::SPACES |
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          net::UnescapeRule::URL_SPECIAL_CHARS |
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          net::UnescapeRule::CONTROL_CHARS |
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          net::UnescapeRule::REPLACE_PLUS_WITH_SPACE));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (unescaped_name == name) {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (found)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return false;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        found = true;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string unescaped_value(net::UnescapeURLComponent(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            i->second,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::UnescapeRule::NORMAL |
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::UnescapeRule::SPACES |
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::UnescapeRule::URL_SPECIAL_CHARS |
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::UnescapeRule::CONTROL_CHARS |
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            net::UnescapeRule::REPLACE_PLUS_WITH_SPACE));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (unescaped_value != expected_value)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return false;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return found;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::vector<std::pair<std::string, std::string> > ParamMap;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ParamMap params_;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeviceManagementServiceTest
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public DeviceManagementServiceTestBase {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CheckURLAndQueryParams(const GURL& request_url,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const std::string& request_type,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const std::string& device_id) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL service_url(kServiceUrl);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(service_url.scheme(), request_url.scheme());
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(service_url.host(), request_url.host());
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(service_url.port(), request_url.port());
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(service_url.path(), request_url.path());
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QueryParams query_params(request_url.query());
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(query_params.Check(dm_protocol::kParamRequest, request_type));
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(query_params.Check(dm_protocol::kParamDeviceID, device_id));
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(query_params.Check(dm_protocol::kParamDeviceType,
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   dm_protocol::kValueDeviceType));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(query_params.Check(dm_protocol::kParamAppType,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   dm_protocol::kValueAppType));
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MATCHER_P(MessageEquals, reference, "") {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string reference_data;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string arg_data;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return arg.SerializeToString(&arg_data) &&
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         reference.SerializeToString(&reference_data) &&
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         arg_data == reference_data;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DeviceManagementServiceTest, RegisterRequest) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::DeviceManagementResponse expected_response;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_response.mutable_register_response()->
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set_device_management_token(kDMToken);
402b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _,
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               MessageEquals(expected_response)));
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckURLAndQueryParams(fetcher->GetOriginalURL(),
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         dm_protocol::kValueRequestRegister,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         kClientID);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected_data;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data));
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_data, fetcher->upload_data());
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate the response.
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(expected_response.SerializeToString(&response_data));
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(fetcher, status, 200, response_data);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(DeviceManagementServiceTest, ApiAuthCodeFetchRequest) {
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  em::DeviceManagementResponse expected_response;
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  expected_response.mutable_service_api_access_response()->set_auth_code(
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kRobotAuthCode);
428b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _,
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               MessageEquals(expected_response)));
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      StartApiAuthCodeFetchJob());
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(fetcher);
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckURLAndQueryParams(fetcher->GetOriginalURL(),
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         dm_protocol::kValueRequestApiAuthorization,
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         kClientID);
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string expected_data;
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data));
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(expected_data, fetcher->upload_data());
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Generate the response.
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string response_data;
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(expected_response.SerializeToString(&response_data));
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponse(fetcher, status, 200, response_data);
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DeviceManagementServiceTest, UnregisterRequest) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::DeviceManagementResponse expected_response;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_response.mutable_unregister_response();
454b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               MessageEquals(expected_response)));
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartUnregistrationJob());
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the data the fetcher received.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& request_url(fetcher->GetOriginalURL());
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL service_url(kServiceUrl);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(service_url.scheme(), request_url.scheme());
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(service_url.host(), request_url.host());
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(service_url.port(), request_url.port());
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(service_url.path(), request_url.path());
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckURLAndQueryParams(fetcher->GetOriginalURL(),
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         dm_protocol::kValueRequestUnregister,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         kClientID);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected_data;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(request_job->GetRequest()->SerializeToString(&expected_data));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_data, fetcher->upload_data());
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate the response.
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(expected_response.SerializeToString(&response_data));
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(fetcher, status, 200, response_data);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DeviceManagementServiceTest, CancelRegisterRequest) {
485b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There shouldn't be any callbacks.
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_job.reset();
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(DeviceManagementServiceTest, CancelApiAuthCodeFetch) {
496b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      StartApiAuthCodeFetchJob());
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(fetcher);
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // There shouldn't be any callbacks.
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request_job.reset();
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DeviceManagementServiceTest, CancelUnregisterRequest) {
508b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartUnregistrationJob());
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There shouldn't be any callbacks.
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_job.reset();
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DeviceManagementServiceTest, CancelPolicyRequest) {
519b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartPolicyFetchJob());
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There shouldn't be any callbacks.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_job.reset();
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DeviceManagementServiceTest, JobQueueing) {
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start with a non-initialized service.
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResetService();
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  em::DeviceManagementResponse expected_response;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_response.mutable_register_response()->
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set_device_management_token(kDMToken);
536b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(DM_STATUS_SUCCESS, _,
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               MessageEquals(expected_response)));
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a request. We should not see any fetchers being created.
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(fetcher);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now initialize the service. That should start the job.
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeService();
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher = GetFetcher();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  factory_.RemoveFetcherFromMap(DeviceManagementService::kURLFetcherID);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the request is processed as expected.
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(expected_response.SerializeToString(&response_data));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendResponse(fetcher, status, 200, response_data);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DeviceManagementServiceTest, CancelRequestAfterShutdown) {
559b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartPolicyFetchJob());
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shutdown the service and cancel the job afterwards.
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_->Shutdown();
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_job.reset();
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION_P(ResetPointer, pointer) {
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pointer->reset();
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DeviceManagementServiceTest, CancelDuringCallback) {
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a request.
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
580b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(_, _, _))
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(ResetPointer(&request_job));
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate a callback.
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponse(fetcher, status, 500, std::string());
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Job should have been reset.
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(request_job.get());
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DeviceManagementServiceTest, RetryOnProxyError) {
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a request.
594b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_));
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE((fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY) == 0);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL original_url(fetcher->GetOriginalURL());
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string upload_data(fetcher->upload_data());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate a callback with a proxy failure.
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus status(net::URLRequestStatus::FAILED,
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               net::ERR_PROXY_CONNECTION_FAILED);
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponse(fetcher, status, 200, std::string());
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that a new URLFetcher was started that bypasses the proxy.
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher = GetFetcher();
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_url, fetcher->GetOriginalURL());
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(upload_data, fetcher->upload_data());
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DeviceManagementServiceTest, RetryOnBadResponseFromProxy) {
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make a request.
619b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_));
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE((fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY) == 0);
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL original_url(fetcher->GetOriginalURL());
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string upload_data(fetcher->upload_data());
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->set_was_fetched_via_proxy(true);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::HttpResponseHeaders> headers;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  headers = new net::HttpResponseHeaders(
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\0Content-type: bad/type\0\0");
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher->set_response_headers(headers);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate a callback with a valid http response, that was generated by
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a bad/wrong proxy.
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestStatus status;
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SendResponse(fetcher, status, 200, std::string());
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that a new URLFetcher was started that bypasses the proxy.
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher = GetFetcher();
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE((fetcher->GetLoadFlags() & net::LOAD_BYPASS_PROXY) != 0);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(original_url, fetcher->GetOriginalURL());
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(upload_data, fetcher->upload_data());
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DeviceManagementServiceTest, RetryOnNetworkChanges) {
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make a request.
649b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_));
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(fetcher);
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL original_url(fetcher->GetOriginalURL());
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string original_upload_data(fetcher->upload_data());
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make it fail with ERR_NETWORK_CHANGED.
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED,
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            net::ERR_NETWORK_CHANGED));
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->set_url(GURL(kServiceUrl));
6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->delegate()->OnURLFetchComplete(fetcher);
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that a new URLFetcher was started that retries this job, after
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // having called OnJobRetry.
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(this);
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher = GetFetcher();
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(fetcher);
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(original_url, fetcher->GetOriginalURL());
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(original_upload_data, fetcher->upload_data());
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(net::URLRequestStatus::SUCCESS, fetcher->GetStatus().status());
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DeviceManagementServiceTest, RetryLimit) {
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<DeviceManagementRequestJob> request_job(StartRegistrationJob());
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Simulate 3 failed network requests.
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < 3; ++i) {
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Make the current fetcher fail with ERR_NETWORK_CHANGED.
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    net::TestURLFetcher* fetcher = GetFetcher();
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(fetcher);
682b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    EXPECT_CALL(*this, OnJobDone(_, _, _)).Times(0);
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(*this, OnJobRetry(_));
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED,
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              net::ERR_NETWORK_CHANGED));
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->set_url(GURL(kServiceUrl));
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->delegate()->OnURLFetchComplete(fetcher);
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Mock::VerifyAndClearExpectations(this);
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // At the next failure the DeviceManagementService should give up retrying and
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // pass the error code to the job's owner.
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::TestURLFetcher* fetcher = GetFetcher();
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(fetcher);
695b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_CALL(*this, OnJobDone(DM_STATUS_REQUEST_FAILED, _, _));
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(*this, OnJobRetry(_)).Times(0);
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED,
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            net::ERR_NETWORK_CHANGED));
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->set_url(GURL(kServiceUrl));
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fetcher->delegate()->OnURLFetchComplete(fetcher);
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(this);
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace policy
705