blob: b6ee516845480b85c84ba6d1a81a2d4399054271 [file] [log] [blame]
// Copyright (c) 2013 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/service/cloud_print/printer_job_handler.h"
#include <memory>
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/md5.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/common/cloud_print/cloud_print_constants.h"
#include "chrome/service/cloud_print/cloud_print_service_helpers.h"
#include "chrome/service/cloud_print/cloud_print_token_store.h"
#include "chrome/service/cloud_print/print_system.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_util.h"
#include "printing/backend/print_backend.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::Exactly;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::Sequence;
using ::testing::SetArgPointee;
using ::testing::StrictMock;
using ::testing::_;
namespace cloud_print {
namespace {
using base::StringPrintf;
const char kExampleCloudPrintServerURL[] = "https://www.google.com/cloudprint/";
const char kExamplePrintTicket[] = "{\"MediaType\":\"plain\","
"\"Resolution\":\"300x300dpi\",\"PageRegion\":\"Letter\","
"\"InputSlot\":\"auto\",\"PageSize\":\"Letter\",\"EconoMode\":\"off\"}";
// The fillowing constants will all be constructed with StringPrintf. The
// following types of parameters are possible:
// job number(int): ID # of job from given job list. All job IDs follow the
// format __example_job_idN for some N.
// fetch reason(string): Fetch reason used by the code. The job list URL
// requested by PrinterJobHandler has an extra parameter that signifies when
// the request was triggered.
// status string(string): Status of print job, one of IN_PROGRESS, DONE or ERROR
// job object list(string/JSON formatted): a comma-separated list of job objects
// StringPrintf parameters: job number, job number, job number, job number
const char kExampleJobObject[] = "{"
" \"tags\": ["
" \"^own\""
" ],"
" \"printerName\": \"Example Printer\","
" \"status\": \"QUEUED\","
" \"ownerId\": \"sampleuser@gmail.com\","
" \"ticketUrl\": \"https://www.google.com/cloudprint/ticket?exampleURI%d\","
" \"printerid\": \"__example_printer_id\","
" \"printerType\": \"GOOGLE\","
" \"contentType\": \"text/html\","
" \"fileUrl\": \"https://www.google.com/cloudprint/download?exampleURI%d\","
" \"id\": \"__example_job_id%d\","
" \"message\": \"\","
" \"title\": \"Example Job %d\","
" \"errorCode\": \"\","
" \"numberOfPages\": 3"
" }";
// StringPrintf parameters: job object list
const char kExampleJobListResponse[] = "{"
" \"success\": true,"
" \"jobs\": ["
" %s"
" ],"
" \"xsrf_token\": \"AIp06DjUd3AV6BO0aujB9NvM2a9ZbogxOQ:1360021066932\","
" \"request\": {"
" \"time\": \"0\","
" \"users\": ["
" \"sampleuser@gmail.com\""
" ],"
" \"params\": {"
" \"printerid\": ["
" \"__example_printer_id\""
" ]"
" },"
" \"user\": \"sampleuser@gmail.com\""
" }"
"}";
// StringPrintf parameters: job number
const char kExampleJobID[] = "__example_job_id%d";
// StringPrintf parameters: job number
const char kExamplePrintTicketURI[] =
"https://www.google.com/cloudprint/ticket?exampleURI%d";
// StringPrintf parameters: job number
const char kExamplePrintDownloadURI[] =
"https://www.google.com/cloudprint/download?exampleURI%d";
// StringPrintf parameters: job number
const char kExampleUpdateDoneURI[] =
"https://www.google.com/cloudprint/control?jobid=__example_job_id%d"
"&status=DONE&code=0&message=&numpages=0&pagesprinted=0";
// StringPrintf parameters: job number
const char kExampleUpdateErrorURI[] =
"https://www.google.com/cloudprint/control?jobid=__example_job_id%d"
"&status=ERROR";
// StringPrintf parameters: fetch reason
const char kExamplePrinterJobListURI[] =
"https://www.google.com/cloudprint/fetch"
"?printerid=__example_printer_id&deb=%s";
// StringPrintf parameters: status string, job number, status string (repeat)
const char kExampleControlResponse[] = "{"
" \"success\": true,"
" \"message\": \"Print job updated successfully.\","
" \"xsrf_token\": \"AIp06DjKgbfGalbqzj23V1bU6i-vtR2B4w:1360023068789\","
" \"request\": {"
" \"time\": \"0\","
" \"users\": ["
" \"sampleuser@gmail.com\""
" ],"
" \"params\": {"
" \"xsrf\": ["
" \"AIp06DgeGIETs42Cj28QWmxGPWVDiaXwVQ:1360023041852\""
" ],"
" \"status\": ["
" \"%s\""
" ],"
" \"jobid\": ["
" \"__example_job_id%d\""
" ]"
" },"
" \"user\": \"sampleuser@gmail.com\""
" },"
" \"job\": {"
" \"tags\": ["
" \"^own\""
" ],"
" \"printerName\": \"Example Printer\","
" \"status\": \"%s\","
" \"ownerId\": \"sampleuser@gmail.com\","
" \"ticketUrl\": \"https://www.google.com/cloudprint/ticket?exampleURI1\","
" \"printerid\": \"__example_printer_id\","
" \"contentType\": \"text/html\","
" \"fileUrl\": \"https://www.google.com/cloudprint/download?exampleURI1\","
" \"id\": \"__example_job_id1\","
" \"message\": \"\","
" \"title\": \"Example Job\","
" \"errorCode\": \"\","
" \"numberOfPages\": 3"
" }"
"}";
const char kExamplePrinterID[] = "__example_printer_id";
const char kExamplePrinterCapabilities[] = "";
const char kExampleCapsMimeType[] = "";
// These can stay empty
const char kExampleDefaults[] = "";
const char kExampleDefaultMimeType[] = "";
// Since we're not connecting to the server, this can be any non-empty string.
const char kExampleCloudPrintOAuthToken[] = "__SAMPLE_TOKEN";
// Not actually printing, no need for real PDF.
const char kExamplePrintData[] = "__EXAMPLE_PRINT_DATA";
const char kExampleJobDownloadResponseHeaders[] =
"Content-Type: Application/PDF\n";
const char kExampleTicketDownloadResponseHeaders[] =
"Content-Type: application/json\n";
const char kExamplePrinterName[] = "Example Printer";
const char kExamplePrinterDescription[] = "Example Description";
// These are functions used to construct the various sample strings.
std::string JobListResponse(int num_jobs) {
std::string job_objects;
for (int i = 0; i < num_jobs; i++) {
job_objects = job_objects + StringPrintf(kExampleJobObject, i+1, i+1, i+1,
i+1);
if (i != num_jobs-1) job_objects = job_objects + ",";
}
return StringPrintf(kExampleJobListResponse, job_objects.c_str());
}
GURL JobListURI(const char* reason) {
return GURL(StringPrintf(kExamplePrinterJobListURI, reason));
}
GURL DoneURI(int job_num) {
return GURL(StringPrintf(kExampleUpdateDoneURI, job_num));
}
GURL ErrorURI(int job_num) {
return GURL(StringPrintf(kExampleUpdateErrorURI, job_num));
}
GURL TicketURI(int job_num) {
return GURL(StringPrintf(kExamplePrintTicketURI, job_num));
}
GURL DownloadURI(int job_num) {
return GURL(StringPrintf(kExamplePrintDownloadURI, job_num));
}
GURL InProgressURI(int job_num) {
return GetUrlForJobStatusUpdate(GURL(kExampleCloudPrintServerURL),
StringPrintf(kExampleJobID, job_num),
PRINT_JOB_STATUS_IN_PROGRESS,
0);
}
std::string StatusResponse(int job_num, const char* status_string) {
return StringPrintf(kExampleControlResponse,
status_string,
job_num,
status_string);
}
} // namespace
class CloudPrintURLFetcherNoServiceProcess
: public CloudPrintURLFetcher {
public:
CloudPrintURLFetcherNoServiceProcess()
: CloudPrintURLFetcher(PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS),
context_getter_(new net::TestURLRequestContextGetter(
base::ThreadTaskRunnerHandle::Get())) {}
protected:
net::URLRequestContextGetter* GetRequestContextGetter() override {
return context_getter_.get();
}
~CloudPrintURLFetcherNoServiceProcess() override {}
private:
scoped_refptr<net::URLRequestContextGetter> context_getter_;
};
class CloudPrintURLFetcherNoServiceProcessFactory
: public CloudPrintURLFetcherFactory {
public:
CloudPrintURLFetcher* CreateCloudPrintURLFetcher() override {
return new CloudPrintURLFetcherNoServiceProcess;
}
~CloudPrintURLFetcherNoServiceProcessFactory() override {}
};
// This class handles the callback from FakeURLFetcher
// It is a separate class because callback methods must be
// on RefCounted classes
class TestURLFetcherCallback {
public:
std::unique_ptr<net::FakeURLFetcher> CreateURLFetcher(
const GURL& url,
net::URLFetcherDelegate* d,
const std::string& response_data,
net::HttpStatusCode response_code,
net::URLRequestStatus::Status status) {
std::unique_ptr<net::FakeURLFetcher> fetcher(
new net::FakeURLFetcher(url, d, response_data, response_code, status));
OnRequestCreate(url, fetcher.get());
return fetcher;
}
MOCK_METHOD2(OnRequestCreate,
void(const GURL&, net::FakeURLFetcher*));
};
class MockPrinterJobHandlerDelegate
: public PrinterJobHandler::Delegate {
public:
MOCK_METHOD0(OnAuthError, void());
MOCK_METHOD1(OnPrinterDeleted, void(const std::string& str));
~MockPrinterJobHandlerDelegate() override {}
};
class MockPrintServerWatcher
: public PrintSystem::PrintServerWatcher {
public:
MOCK_METHOD1(StartWatching,
bool(PrintSystem::PrintServerWatcher::Delegate* d));
MOCK_METHOD0(StopWatching, bool());
MockPrintServerWatcher();
PrintSystem::PrintServerWatcher::Delegate* delegate() const {
return delegate_;
}
friend class scoped_refptr<NiceMock<MockPrintServerWatcher> >;
friend class scoped_refptr<StrictMock<MockPrintServerWatcher> >;
friend class scoped_refptr<MockPrintServerWatcher>;
protected:
~MockPrintServerWatcher() override {}
private:
PrintSystem::PrintServerWatcher::Delegate* delegate_;
};
class MockPrinterWatcher : public PrintSystem::PrinterWatcher {
public:
MOCK_METHOD1(StartWatching, bool(PrintSystem::PrinterWatcher::Delegate* d));
MOCK_METHOD0(StopWatching, bool());
MOCK_METHOD1(GetCurrentPrinterInfo,
bool(printing::PrinterBasicInfo* printer_info));
MockPrinterWatcher();
PrintSystem::PrinterWatcher::Delegate* delegate() const { return delegate_; }
friend class scoped_refptr<NiceMock<MockPrinterWatcher> >;
friend class scoped_refptr<StrictMock<MockPrinterWatcher> >;
friend class scoped_refptr<MockPrinterWatcher>;
protected:
~MockPrinterWatcher() override {}
private:
PrintSystem::PrinterWatcher::Delegate* delegate_;
};
class MockJobSpooler : public PrintSystem::JobSpooler {
public:
MOCK_METHOD8(Spool, bool(
const std::string& print_ticket,
const std::string& print_ticket_mime_type,
const base::FilePath& print_data_file_path,
const std::string& print_data_mime_type,
const std::string& printer_name,
const std::string& job_title,
const std::vector<std::string>& tags,
PrintSystem::JobSpooler::Delegate* delegate));
MockJobSpooler();
PrintSystem::JobSpooler::Delegate* delegate() const { return delegate_; }
friend class scoped_refptr<NiceMock<MockJobSpooler> >;
friend class scoped_refptr<StrictMock<MockJobSpooler> >;
friend class scoped_refptr<MockJobSpooler>;
protected:
~MockJobSpooler() override {}
private:
PrintSystem::JobSpooler::Delegate* delegate_;
};
class MockPrintSystem : public PrintSystem {
public:
MockPrintSystem();
PrintSystem::PrintSystemResult succeed() {
return PrintSystem::PrintSystemResult(true, "success");
}
PrintSystem::PrintSystemResult fail() {
return PrintSystem::PrintSystemResult(false, "failure");
}
MockJobSpooler& JobSpooler() { return *job_spooler_.get(); }
MockPrinterWatcher& PrinterWatcher() { return *printer_watcher_.get(); }
MockPrintServerWatcher& PrintServerWatcher() {
return *print_server_watcher_.get();
}
MOCK_METHOD0(Init, PrintSystem::PrintSystemResult());
MOCK_METHOD1(EnumeratePrinters, PrintSystem::PrintSystemResult(
printing::PrinterList* printer_list));
MOCK_METHOD2(
GetPrinterCapsAndDefaults,
void(const std::string& printer_name,
const PrintSystem::PrinterCapsAndDefaultsCallback& callback));
MOCK_METHOD1(IsValidPrinter, bool(const std::string& printer_name));
MOCK_METHOD3(ValidatePrintTicket,
bool(const std::string& printer_name,
const std::string& print_ticket_data,
const std::string& print_ticket_mime_type));
MOCK_METHOD3(GetJobDetails, bool(const std::string& printer_name,
PlatformJobId job_id,
PrintJobDetails* job_details));
MOCK_METHOD0(CreatePrintServerWatcher, PrintSystem::PrintServerWatcher*());
MOCK_METHOD1(CreatePrinterWatcher,
PrintSystem::PrinterWatcher*(const std::string& printer_name));
MOCK_METHOD0(CreateJobSpooler, PrintSystem::JobSpooler*());
MOCK_METHOD0(UseCddAndCjt, bool());
MOCK_METHOD0(GetSupportedMimeTypes, std::string());
friend class scoped_refptr<NiceMock<MockPrintSystem> >;
friend class scoped_refptr<StrictMock<MockPrintSystem> >;
friend class scoped_refptr<MockPrintSystem>;
protected:
~MockPrintSystem() override {}
private:
scoped_refptr<MockJobSpooler> job_spooler_;
scoped_refptr<MockPrinterWatcher> printer_watcher_;
scoped_refptr<MockPrintServerWatcher> print_server_watcher_;
};
class PrinterJobHandlerTest : public ::testing::Test {
public:
PrinterJobHandlerTest();
void SetUp() override;
void TearDown() override;
bool GetPrinterInfo(printing::PrinterBasicInfo* info);
void SendCapsAndDefaults(
const std::string& printer_name,
const PrintSystem::PrinterCapsAndDefaultsCallback& callback);
void AddMimeHeader(const GURL& url, net::FakeURLFetcher* fetcher);
void AddTicketMimeHeader(const GURL& url, net::FakeURLFetcher* fetcher);
bool PostSpoolSuccess();
void SetUpJobSuccessTest(int job_num);
void BeginTest(int timeout_seconds);
void MakeJobFetchReturnNoJobs();
base::MessageLoopForIO loop_;
std::unique_ptr<base::RunLoop> active_run_loop_;
TestURLFetcherCallback url_callback_;
MockPrinterJobHandlerDelegate jobhandler_delegate_;
CloudPrintTokenStore token_store_;
CloudPrintURLFetcherNoServiceProcessFactory cloud_print_factory_;
scoped_refptr<PrinterJobHandler> job_handler_;
scoped_refptr<NiceMock<MockPrintSystem> > print_system_;
net::FakeURLFetcherFactory factory_;
printing::PrinterBasicInfo basic_info_;
printing::PrinterCapsAndDefaults caps_and_defaults_;
PrinterJobHandler::PrinterInfoFromCloud info_from_cloud_;
};
void PrinterJobHandlerTest::SetUp() {
basic_info_.printer_name = kExamplePrinterName;
basic_info_.printer_description = kExamplePrinterDescription;
basic_info_.is_default = 0;
info_from_cloud_.printer_id = kExamplePrinterID;
info_from_cloud_.tags_hash = GetHashOfPrinterInfo(basic_info_);
info_from_cloud_.caps_hash = base::MD5String(kExamplePrinterCapabilities);
info_from_cloud_.current_xmpp_timeout = 300;
info_from_cloud_.pending_xmpp_timeout = 0;
caps_and_defaults_.printer_capabilities = kExamplePrinterCapabilities;
caps_and_defaults_.caps_mime_type = kExampleCapsMimeType;
caps_and_defaults_.printer_defaults = kExampleDefaults;
caps_and_defaults_.defaults_mime_type = kExampleDefaultMimeType;
print_system_ = new NiceMock<MockPrintSystem>();
token_store_.SetToken(kExampleCloudPrintOAuthToken);
ON_CALL(print_system_->PrinterWatcher(), GetCurrentPrinterInfo(_))
.WillByDefault(Invoke(this, &PrinterJobHandlerTest::GetPrinterInfo));
ON_CALL(*print_system_.get(), GetPrinterCapsAndDefaults(_, _))
.WillByDefault(Invoke(this, &PrinterJobHandlerTest::SendCapsAndDefaults));
CloudPrintURLFetcher::set_test_factory(&cloud_print_factory_);
}
void PrinterJobHandlerTest::MakeJobFetchReturnNoJobs() {
factory_.SetFakeResponse(JobListURI(kJobFetchReasonStartup),
JobListResponse(0), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(JobListURI(kJobFetchReasonFailure),
JobListResponse(0), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(JobListURI(kJobFetchReasonRetry),
JobListResponse(0), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
}
PrinterJobHandlerTest::PrinterJobHandlerTest()
: factory_(NULL, base::Bind(&TestURLFetcherCallback::CreateURLFetcher,
base::Unretained(&url_callback_))) {
}
bool PrinterJobHandlerTest::PostSpoolSuccess() {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&PrinterJobHandler::OnJobSpoolSucceeded, job_handler_, 0));
// Everything that would be posted on the printer thread queue
// has been posted, we can tell the main message loop to quit when idle
// and not worry about it idling while the print thread does work
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, active_run_loop_->QuitWhenIdleClosure());
return true;
}
void PrinterJobHandlerTest::AddMimeHeader(const GURL& url,
net::FakeURLFetcher* fetcher) {
scoped_refptr<net::HttpResponseHeaders> download_headers =
new net::HttpResponseHeaders(kExampleJobDownloadResponseHeaders);
fetcher->set_response_headers(download_headers);
}
void PrinterJobHandlerTest::AddTicketMimeHeader(const GURL& url,
net::FakeURLFetcher* fetcher) {
scoped_refptr<net::HttpResponseHeaders> download_headers =
new net::HttpResponseHeaders(kExampleTicketDownloadResponseHeaders);
fetcher->set_response_headers(download_headers);
}
void PrinterJobHandlerTest::SetUpJobSuccessTest(int job_num) {
factory_.SetFakeResponse(TicketURI(job_num),
kExamplePrintTicket, net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(DownloadURI(job_num),
kExamplePrintData, net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(DoneURI(job_num),
StatusResponse(job_num, "DONE"),
net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(InProgressURI(job_num),
StatusResponse(job_num, "IN_PROGRESS"),
net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
// The times requirement is relaxed for the ticket URI
// in order to accommodate TicketDownloadFailureTest
EXPECT_CALL(url_callback_, OnRequestCreate(TicketURI(job_num), _))
.Times(AtLeast(1))
.WillOnce(Invoke(this, &PrinterJobHandlerTest::AddTicketMimeHeader));
EXPECT_CALL(url_callback_, OnRequestCreate(DownloadURI(job_num), _))
.Times(Exactly(1))
.WillOnce(Invoke(this, &PrinterJobHandlerTest::AddMimeHeader));
EXPECT_CALL(url_callback_, OnRequestCreate(InProgressURI(job_num), _))
.Times(Exactly(1));
EXPECT_CALL(url_callback_, OnRequestCreate(DoneURI(job_num), _))
.Times(Exactly(1));
EXPECT_CALL(print_system_->JobSpooler(),
Spool(kExamplePrintTicket, _, _, _, _, _, _, _))
.Times(Exactly(1))
.WillOnce(InvokeWithoutArgs(this,
&PrinterJobHandlerTest::PostSpoolSuccess));
}
void PrinterJobHandlerTest::BeginTest(int timeout_seconds) {
job_handler_ = new PrinterJobHandler(basic_info_,
info_from_cloud_,
GURL(kExampleCloudPrintServerURL),
print_system_.get(),
&jobhandler_delegate_);
job_handler_->Initialize();
active_run_loop_ = std::make_unique<base::RunLoop>();
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, active_run_loop_->QuitWhenIdleClosure(),
base::TimeDelta::FromSeconds(timeout_seconds));
active_run_loop_->Run();
}
void PrinterJobHandlerTest::SendCapsAndDefaults(
const std::string& printer_name,
const PrintSystem::PrinterCapsAndDefaultsCallback& callback) {
callback.Run(true, printer_name, caps_and_defaults_);
}
bool PrinterJobHandlerTest::GetPrinterInfo(printing::PrinterBasicInfo* info) {
*info = basic_info_;
return true;
}
void PrinterJobHandlerTest::TearDown() {
base::RunLoop().RunUntilIdle();
CloudPrintURLFetcher::set_test_factory(nullptr);
}
MockPrintServerWatcher::MockPrintServerWatcher() : delegate_(NULL) {
ON_CALL(*this, StartWatching(_))
.WillByDefault(DoAll(SaveArg<0>(&delegate_), Return(true)));
ON_CALL(*this, StopWatching()).WillByDefault(Return(true));
}
MockPrinterWatcher::MockPrinterWatcher() : delegate_(NULL) {
ON_CALL(*this, StartWatching(_))
.WillByDefault(DoAll(SaveArg<0>(&delegate_), Return(true)));
ON_CALL(*this, StopWatching()).WillByDefault(Return(true));
}
MockJobSpooler::MockJobSpooler() : delegate_(NULL) {
ON_CALL(*this, Spool(_, _, _, _, _, _, _, _))
.WillByDefault(DoAll(SaveArg<7>(&delegate_), Return(true)));
}
MockPrintSystem::MockPrintSystem()
: job_spooler_(new NiceMock<MockJobSpooler>()),
printer_watcher_(new NiceMock<MockPrinterWatcher>()),
print_server_watcher_(new NiceMock<MockPrintServerWatcher>()) {
ON_CALL(*this, CreateJobSpooler()).WillByDefault(Return(job_spooler_.get()));
ON_CALL(*this, CreatePrinterWatcher(_))
.WillByDefault(Return(printer_watcher_.get()));
ON_CALL(*this, CreatePrintServerWatcher())
.WillByDefault(Return(print_server_watcher_.get()));
ON_CALL(*this, IsValidPrinter(_)).
WillByDefault(Return(true));
ON_CALL(*this, ValidatePrintTicket(_, _, _)).
WillByDefault(Return(true));
}
// This test simulates an end-to-end printing of a document
// but tests only non-failure cases.
// Disabled - http://crbug.com/184245
TEST_F(PrinterJobHandlerTest, DISABLED_HappyPathTest) {
factory_.SetFakeResponse(JobListURI(kJobFetchReasonStartup),
JobListResponse(1), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(JobListURI(kJobFetchReasonQueryMore),
JobListResponse(0), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonStartup), _))
.Times(Exactly(1));
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonQueryMore), _))
.Times(Exactly(1));
SetUpJobSuccessTest(1);
BeginTest(20);
}
TEST_F(PrinterJobHandlerTest, TicketDownloadFailureTest) {
factory_.SetFakeResponse(JobListURI(kJobFetchReasonStartup),
JobListResponse(2), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(JobListURI(kJobFetchReasonFailure),
JobListResponse(2), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(JobListURI(kJobFetchReasonQueryMore),
JobListResponse(0), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(TicketURI(1), std::string(),
net::HTTP_INTERNAL_SERVER_ERROR,
net::URLRequestStatus::FAILED);
EXPECT_CALL(url_callback_, OnRequestCreate(TicketURI(1), _))
.Times(AtLeast(1))
.WillOnce(Invoke(this, &PrinterJobHandlerTest::AddTicketMimeHeader));
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonStartup), _))
.Times(AtLeast(1));
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonQueryMore), _))
.Times(AtLeast(1));
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonFailure), _))
.Times(AtLeast(1));
SetUpJobSuccessTest(2);
BeginTest(20);
}
// TODO(noamsml): Figure out how to make this test not take 1 second and
// re-enable it
TEST_F(PrinterJobHandlerTest, DISABLED_ManyFailureTest) {
factory_.SetFakeResponse(JobListURI(kJobFetchReasonStartup),
JobListResponse(1), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(JobListURI(kJobFetchReasonFailure),
JobListResponse(1), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(JobListURI(kJobFetchReasonRetry),
JobListResponse(1), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(JobListURI(kJobFetchReasonQueryMore),
JobListResponse(0), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonStartup), _))
.Times(AtLeast(1));
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonQueryMore), _))
.Times(AtLeast(1));
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonFailure), _))
.Times(AtLeast(1));
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonRetry), _))
.Times(AtLeast(1));
SetUpJobSuccessTest(1);
factory_.SetFakeResponse(TicketURI(1),
std::string(),
net::HTTP_INTERNAL_SERVER_ERROR,
net::URLRequestStatus::FAILED);
loop_.task_runner()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&net::FakeURLFetcherFactory::SetFakeResponse,
base::Unretained(&factory_), TicketURI(1),
kExamplePrintTicket, net::HTTP_OK,
net::URLRequestStatus::SUCCESS),
base::TimeDelta::FromSeconds(1));
BeginTest(5);
}
// TODO(noamsml): Figure out how to make this test not take ~64-~2048 (depending
// constant values) seconds and re-enable it
TEST_F(PrinterJobHandlerTest, DISABLED_CompleteFailureTest) {
factory_.SetFakeResponse(JobListURI(kJobFetchReasonStartup),
JobListResponse(1), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(JobListURI(kJobFetchReasonFailure),
JobListResponse(1), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(JobListURI(kJobFetchReasonRetry),
JobListResponse(1), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(ErrorURI(1), StatusResponse(1, "ERROR"),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
factory_.SetFakeResponse(TicketURI(1), std::string(),
net::HTTP_INTERNAL_SERVER_ERROR,
net::URLRequestStatus::FAILED);
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonStartup), _))
.Times(AtLeast(1));
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonFailure), _))
.Times(AtLeast(1));
EXPECT_CALL(url_callback_,
OnRequestCreate(JobListURI(kJobFetchReasonRetry), _))
.Times(AtLeast(1));
EXPECT_CALL(url_callback_, OnRequestCreate(ErrorURI(1), _))
.Times(Exactly(1))
.WillOnce(InvokeWithoutArgs(
this, &PrinterJobHandlerTest::MakeJobFetchReturnNoJobs));
EXPECT_CALL(url_callback_, OnRequestCreate(TicketURI(1), _))
.Times(AtLeast(kNumRetriesBeforeAbandonJob));
BeginTest(70);
}
} // namespace cloud_print