1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/files/file_path.h"
7 #include "base/memory/ref_counted.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/common/cloud_print/cloud_print_constants.h"
13 #include "chrome/service/cloud_print/cloud_print_service_helpers.h"
14 #include "chrome/service/cloud_print/cloud_print_token_store.h"
15 #include "chrome/service/cloud_print/print_system.h"
16 #include "chrome/service/cloud_print/printer_job_handler.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/http/http_status_code.h"
19 #include "net/url_request/test_url_fetcher_factory.h"
20 #include "net/url_request/url_request_status.h"
21 #include "net/url_request/url_request_test_util.h"
22 #include "printing/backend/print_backend.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 using ::testing::AtLeast
;
27 using ::testing::DoAll
;
28 using ::testing::Exactly
;
29 using ::testing::Invoke
;
30 using ::testing::InvokeWithoutArgs
;
31 using ::testing::NiceMock
;
32 using ::testing::Return
;
33 using ::testing::SaveArg
;
34 using ::testing::Sequence
;
35 using ::testing::SetArgPointee
;
36 using ::testing::StrictMock
;
39 namespace cloud_print
{
43 using base::StringPrintf
;
45 const char kExampleCloudPrintServerURL
[] = "https://www.google.com/cloudprint/";
47 const char kExamplePrintTicket
[] = "{\"MediaType\":\"plain\","
48 "\"Resolution\":\"300x300dpi\",\"PageRegion\":\"Letter\","
49 "\"InputSlot\":\"auto\",\"PageSize\":\"Letter\",\"EconoMode\":\"off\"}";
52 // The fillowing constants will all be constructed with StringPrintf. The
53 // following types of parameters are possible:
54 // job number(int): ID # of job from given job list. All job IDs follow the
55 // format __example_job_idN for some N.
56 // fetch reason(string): Fetch reason used by the code. The job list URL
57 // requested by PrinterJobHandler has an extra parameter that signifies when
58 // the request was triggered.
59 // status string(string): Status of print job, one of IN_PROGRESS, DONE or ERROR
60 // job object list(string/JSON formatted): a comma-separated list of job objects
62 // StringPrintf parameters: job number, job number, job number, job number
63 const char kExampleJobObject
[] = "{"
67 " \"printerName\": \"Example Printer\","
68 " \"status\": \"QUEUED\","
69 " \"ownerId\": \"sampleuser@gmail.com\","
70 " \"ticketUrl\": \"https://www.google.com/cloudprint/ticket?exampleURI%d\","
71 " \"printerid\": \"__example_printer_id\","
72 " \"printerType\": \"GOOGLE\","
73 " \"contentType\": \"text/html\","
74 " \"fileUrl\": \"https://www.google.com/cloudprint/download?exampleURI%d\","
75 " \"id\": \"__example_job_id%d\","
77 " \"title\": \"Example Job %d\","
78 " \"errorCode\": \"\","
79 " \"numberOfPages\": 3"
82 // StringPrintf parameters: job object list
83 const char kExampleJobListResponse
[] = "{"
88 " \"xsrf_token\": \"AIp06DjUd3AV6BO0aujB9NvM2a9ZbogxOQ:1360021066932\","
92 " \"sampleuser@gmail.com\""
96 " \"__example_printer_id\""
99 " \"user\": \"sampleuser@gmail.com\""
104 // StringPrintf parameters: job number
105 const char kExampleJobID
[] = "__example_job_id%d";
107 // StringPrintf parameters: job number
108 const char kExamplePrintTicketURI
[] =
109 "https://www.google.com/cloudprint/ticket?exampleURI%d";
111 // StringPrintf parameters: job number
112 const char kExamplePrintDownloadURI
[] =
113 "https://www.google.com/cloudprint/download?exampleURI%d";
115 // StringPrintf parameters: job number
116 const char kExampleUpdateDoneURI
[] =
117 "https://www.google.com/cloudprint/control?jobid=__example_job_id%d"
118 "&status=DONE&code=0&message=&numpages=0&pagesprinted=0";
120 // StringPrintf parameters: job number
121 const char kExampleUpdateErrorURI
[] =
122 "https://www.google.com/cloudprint/control?jobid=__example_job_id%d"
125 // StringPrintf parameters: fetch reason
126 const char kExamplePrinterJobListURI
[] =
127 "https://www.google.com/cloudprint/fetch"
128 "?printerid=__example_printer_id&deb=%s";
130 // StringPrintf parameters: status string, job number, status string (repeat)
131 const char kExampleControlResponse
[] = "{"
132 " \"success\": true,"
133 " \"message\": \"Print job updated successfully.\","
134 " \"xsrf_token\": \"AIp06DjKgbfGalbqzj23V1bU6i-vtR2B4w:1360023068789\","
138 " \"sampleuser@gmail.com\""
142 " \"AIp06DgeGIETs42Cj28QWmxGPWVDiaXwVQ:1360023041852\""
148 " \"__example_job_id%d\""
151 " \"user\": \"sampleuser@gmail.com\""
157 " \"printerName\": \"Example Printer\","
158 " \"status\": \"%s\","
159 " \"ownerId\": \"sampleuser@gmail.com\","
160 " \"ticketUrl\": \"https://www.google.com/cloudprint/ticket?exampleURI1\","
161 " \"printerid\": \"__example_printer_id\","
162 " \"contentType\": \"text/html\","
163 " \"fileUrl\": \"https://www.google.com/cloudprint/download?exampleURI1\","
164 " \"id\": \"__example_job_id1\","
165 " \"message\": \"\","
166 " \"title\": \"Example Job\","
167 " \"errorCode\": \"\","
168 " \"numberOfPages\": 3"
172 const char kExamplePrinterID
[] = "__example_printer_id";
174 const char kExamplePrinterCapabilities
[] = "";
176 const char kExampleCapsMimeType
[] = "";
178 // These can stay empty
179 const char kExampleDefaults
[] = "";
181 const char kExampleDefaultMimeType
[] = "";
183 // Since we're not connecting to the server, this can be any non-empty string.
184 const char kExampleCloudPrintOAuthToken
[] = "__SAMPLE_TOKEN";
187 // Not actually printing, no need for real PDF.
188 const char kExamplePrintData
[] = "__EXAMPLE_PRINT_DATA";
190 const char kExampleJobDownloadResponseHeaders
[] =
191 "Content-Type: Application/PDF\n";
193 const char kExampleTicketDownloadResponseHeaders
[] =
194 "Content-Type: application/json\n";
196 const char kExamplePrinterName
[] = "Example Printer";
198 const char kExamplePrinterDescription
[] = "Example Description";
200 // These are functions used to construct the various sample strings.
201 std::string
JobListResponse(int num_jobs
) {
202 std::string job_objects
;
203 for (int i
= 0; i
< num_jobs
; i
++) {
204 job_objects
= job_objects
+ StringPrintf(kExampleJobObject
, i
+1, i
+1, i
+1,
206 if (i
!= num_jobs
-1) job_objects
= job_objects
+ ",";
208 return StringPrintf(kExampleJobListResponse
, job_objects
.c_str());
211 GURL
JobListURI(const char* reason
) {
212 return GURL(StringPrintf(kExamplePrinterJobListURI
, reason
));
215 GURL
DoneURI(int job_num
) {
216 return GURL(StringPrintf(kExampleUpdateDoneURI
, job_num
));
219 GURL
ErrorURI(int job_num
) {
220 return GURL(StringPrintf(kExampleUpdateErrorURI
, job_num
));
223 GURL
TicketURI(int job_num
) {
224 return GURL(StringPrintf(kExamplePrintTicketURI
, job_num
));
227 GURL
DownloadURI(int job_num
) {
228 return GURL(StringPrintf(kExamplePrintDownloadURI
, job_num
));
231 GURL
InProgressURI(int job_num
) {
232 return GetUrlForJobStatusUpdate(GURL(kExampleCloudPrintServerURL
),
233 StringPrintf(kExampleJobID
, job_num
),
234 PRINT_JOB_STATUS_IN_PROGRESS
,
238 std::string
StatusResponse(int job_num
, const char* status_string
) {
239 return StringPrintf(kExampleControlResponse
,
247 class CloudPrintURLFetcherNoServiceProcess
248 : public CloudPrintURLFetcher
{
250 CloudPrintURLFetcherNoServiceProcess() :
251 context_getter_(new net::TestURLRequestContextGetter(
252 base::MessageLoopProxy::current())) {}
254 virtual net::URLRequestContextGetter
* GetRequestContextGetter() OVERRIDE
{
255 return context_getter_
.get();
258 virtual ~CloudPrintURLFetcherNoServiceProcess() {}
260 scoped_refptr
<net::URLRequestContextGetter
> context_getter_
;
264 class CloudPrintURLFetcherNoServiceProcessFactory
265 : public CloudPrintURLFetcherFactory
{
267 virtual CloudPrintURLFetcher
* CreateCloudPrintURLFetcher() OVERRIDE
{
268 return new CloudPrintURLFetcherNoServiceProcess
;
271 virtual ~CloudPrintURLFetcherNoServiceProcessFactory() {}
275 // This class handles the callback from FakeURLFetcher
276 // It is a separate class because callback methods must be
277 // on RefCounted classes
279 class TestURLFetcherCallback
{
281 scoped_ptr
<net::FakeURLFetcher
> CreateURLFetcher(
283 net::URLFetcherDelegate
* d
,
284 const std::string
& response_data
,
285 net::HttpStatusCode response_code
,
286 net::URLRequestStatus::Status status
) {
287 scoped_ptr
<net::FakeURLFetcher
> fetcher(
288 new net::FakeURLFetcher(url
, d
, response_data
, response_code
, status
));
289 OnRequestCreate(url
, fetcher
.get());
290 return fetcher
.Pass();
292 MOCK_METHOD2(OnRequestCreate
,
293 void(const GURL
&, net::FakeURLFetcher
*));
297 class MockPrinterJobHandlerDelegate
298 : public PrinterJobHandler::Delegate
{
300 MOCK_METHOD0(OnAuthError
, void());
301 MOCK_METHOD1(OnPrinterDeleted
, void(const std::string
& str
));
303 virtual ~MockPrinterJobHandlerDelegate() {}
307 class MockPrintServerWatcher
308 : public PrintSystem::PrintServerWatcher
{
310 MOCK_METHOD1(StartWatching
,
311 bool(PrintSystem::PrintServerWatcher::Delegate
* d
));
312 MOCK_METHOD0(StopWatching
, bool());
314 MockPrintServerWatcher();
315 PrintSystem::PrintServerWatcher::Delegate
* delegate() const {
319 friend class scoped_refptr
<NiceMock
<MockPrintServerWatcher
> >;
320 friend class scoped_refptr
<StrictMock
<MockPrintServerWatcher
> >;
321 friend class scoped_refptr
<MockPrintServerWatcher
>;
324 virtual ~MockPrintServerWatcher() {}
327 PrintSystem::PrintServerWatcher::Delegate
* delegate_
;
330 class MockPrinterWatcher
: public PrintSystem::PrinterWatcher
{
332 MOCK_METHOD1(StartWatching
, bool(PrintSystem::PrinterWatcher::Delegate
* d
));
333 MOCK_METHOD0(StopWatching
, bool());
334 MOCK_METHOD1(GetCurrentPrinterInfo
,
335 bool(printing::PrinterBasicInfo
* printer_info
));
337 MockPrinterWatcher();
338 PrintSystem::PrinterWatcher::Delegate
* delegate() const { return delegate_
; }
340 friend class scoped_refptr
<NiceMock
<MockPrinterWatcher
> >;
341 friend class scoped_refptr
<StrictMock
<MockPrinterWatcher
> >;
342 friend class scoped_refptr
<MockPrinterWatcher
>;
345 virtual ~MockPrinterWatcher() {}
348 PrintSystem::PrinterWatcher::Delegate
* delegate_
;
352 class MockJobSpooler
: public PrintSystem::JobSpooler
{
354 MOCK_METHOD8(Spool
, bool(
355 const std::string
& print_ticket
,
356 const std::string
& print_ticket_mime_type
,
357 const base::FilePath
& print_data_file_path
,
358 const std::string
& print_data_mime_type
,
359 const std::string
& printer_name
,
360 const std::string
& job_title
,
361 const std::vector
<std::string
>& tags
,
362 PrintSystem::JobSpooler::Delegate
* delegate
));
365 PrintSystem::JobSpooler::Delegate
* delegate() const { return delegate_
; }
367 friend class scoped_refptr
<NiceMock
<MockJobSpooler
> >;
368 friend class scoped_refptr
<StrictMock
<MockJobSpooler
> >;
369 friend class scoped_refptr
<MockJobSpooler
>;
372 virtual ~MockJobSpooler() {}
375 PrintSystem::JobSpooler::Delegate
* delegate_
;
380 class MockPrintSystem
: public PrintSystem
{
383 PrintSystem::PrintSystemResult
succeed() {
384 return PrintSystem::PrintSystemResult(true, "success");
387 PrintSystem::PrintSystemResult
fail() {
388 return PrintSystem::PrintSystemResult(false, "failure");
391 MockJobSpooler
& JobSpooler() { return *job_spooler_
.get(); }
393 MockPrinterWatcher
& PrinterWatcher() { return *printer_watcher_
.get(); }
395 MockPrintServerWatcher
& PrintServerWatcher() {
396 return *print_server_watcher_
.get();
399 MOCK_METHOD0(Init
, PrintSystem::PrintSystemResult());
400 MOCK_METHOD1(EnumeratePrinters
, PrintSystem::PrintSystemResult(
401 printing::PrinterList
* printer_list
));
404 GetPrinterCapsAndDefaults
,
405 void(const std::string
& printer_name
,
406 const PrintSystem::PrinterCapsAndDefaultsCallback
& callback
));
408 MOCK_METHOD1(IsValidPrinter
, bool(const std::string
& printer_name
));
410 MOCK_METHOD3(ValidatePrintTicket
,
411 bool(const std::string
& printer_name
,
412 const std::string
& print_ticket_data
,
413 const std::string
& print_ticket_mime_type
));
415 MOCK_METHOD3(GetJobDetails
, bool(const std::string
& printer_name
,
416 PlatformJobId job_id
,
417 PrintJobDetails
* job_details
));
419 MOCK_METHOD0(CreatePrintServerWatcher
, PrintSystem::PrintServerWatcher
*());
420 MOCK_METHOD1(CreatePrinterWatcher
,
421 PrintSystem::PrinterWatcher
*(const std::string
& printer_name
));
422 MOCK_METHOD0(CreateJobSpooler
, PrintSystem::JobSpooler
*());
424 MOCK_METHOD0(UseCddAndCjt
, bool());
425 MOCK_METHOD0(GetSupportedMimeTypes
, std::string());
427 friend class scoped_refptr
<NiceMock
<MockPrintSystem
> >;
428 friend class scoped_refptr
<StrictMock
<MockPrintSystem
> >;
429 friend class scoped_refptr
<MockPrintSystem
>;
432 virtual ~MockPrintSystem() {}
435 scoped_refptr
<MockJobSpooler
> job_spooler_
;
436 scoped_refptr
<MockPrinterWatcher
> printer_watcher_
;
437 scoped_refptr
<MockPrintServerWatcher
> print_server_watcher_
;
441 class PrinterJobHandlerTest
: public ::testing::Test
{
443 PrinterJobHandlerTest();
444 virtual void SetUp() OVERRIDE
;
445 virtual void TearDown() OVERRIDE
;
447 bool GetPrinterInfo(printing::PrinterBasicInfo
* info
);
448 void SendCapsAndDefaults(
449 const std::string
& printer_name
,
450 const PrintSystem::PrinterCapsAndDefaultsCallback
& callback
);
451 void AddMimeHeader(const GURL
& url
, net::FakeURLFetcher
* fetcher
);
452 void AddTicketMimeHeader(const GURL
& url
, net::FakeURLFetcher
* fetcher
);
453 bool PostSpoolSuccess();
454 void SetUpJobSuccessTest(int job_num
);
455 void BeginTest(int timeout_seconds
);
456 void MakeJobFetchReturnNoJobs();
458 static void MessageLoopQuitNowHelper(base::MessageLoop
* message_loop
);
459 static void MessageLoopQuitSoonHelper(base::MessageLoop
* message_loop
);
461 base::MessageLoopForIO loop_
;
462 TestURLFetcherCallback url_callback_
;
463 MockPrinterJobHandlerDelegate jobhandler_delegate_
;
464 CloudPrintTokenStore token_store_
;
465 CloudPrintURLFetcherNoServiceProcessFactory cloud_print_factory_
;
466 scoped_refptr
<PrinterJobHandler
> job_handler_
;
467 scoped_refptr
<NiceMock
<MockPrintSystem
> > print_system_
;
468 net::FakeURLFetcherFactory factory_
;
469 printing::PrinterBasicInfo basic_info_
;
470 printing::PrinterCapsAndDefaults caps_and_defaults_
;
471 PrinterJobHandler::PrinterInfoFromCloud info_from_cloud_
;
475 void PrinterJobHandlerTest::SetUp() {
476 basic_info_
.printer_name
= kExamplePrinterName
;
477 basic_info_
.printer_description
= kExamplePrinterDescription
;
478 basic_info_
.is_default
= 0;
480 info_from_cloud_
.printer_id
= kExamplePrinterID
;
481 info_from_cloud_
.tags_hash
= GetHashOfPrinterInfo(basic_info_
);
483 info_from_cloud_
.caps_hash
= base::MD5String(kExamplePrinterCapabilities
);
484 info_from_cloud_
.current_xmpp_timeout
= 300;
485 info_from_cloud_
.pending_xmpp_timeout
= 0;
487 caps_and_defaults_
.printer_capabilities
= kExamplePrinterCapabilities
;
488 caps_and_defaults_
.caps_mime_type
= kExampleCapsMimeType
;
489 caps_and_defaults_
.printer_defaults
= kExampleDefaults
;
490 caps_and_defaults_
.defaults_mime_type
= kExampleDefaultMimeType
;
492 print_system_
= new NiceMock
<MockPrintSystem
>();
494 token_store_
.SetToken(kExampleCloudPrintOAuthToken
);
496 ON_CALL(print_system_
->PrinterWatcher(), GetCurrentPrinterInfo(_
))
497 .WillByDefault(Invoke(this, &PrinterJobHandlerTest::GetPrinterInfo
));
499 ON_CALL(*print_system_
.get(), GetPrinterCapsAndDefaults(_
, _
))
500 .WillByDefault(Invoke(this, &PrinterJobHandlerTest::SendCapsAndDefaults
));
502 CloudPrintURLFetcher::set_factory(&cloud_print_factory_
);
505 void PrinterJobHandlerTest::MakeJobFetchReturnNoJobs() {
506 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonStartup
),
507 JobListResponse(0), net::HTTP_OK
,
508 net::URLRequestStatus::SUCCESS
);
509 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonFailure
),
510 JobListResponse(0), net::HTTP_OK
,
511 net::URLRequestStatus::SUCCESS
);
512 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonRetry
),
513 JobListResponse(0), net::HTTP_OK
,
514 net::URLRequestStatus::SUCCESS
);
517 void PrinterJobHandlerTest::MessageLoopQuitNowHelper(
518 base::MessageLoop
* message_loop
) {
519 message_loop
->QuitWhenIdle();
522 void PrinterJobHandlerTest::MessageLoopQuitSoonHelper(
523 base::MessageLoop
* message_loop
) {
524 message_loop
->message_loop_proxy()->PostTask(
525 FROM_HERE
, base::Bind(&MessageLoopQuitNowHelper
, message_loop
));
528 PrinterJobHandlerTest::PrinterJobHandlerTest()
529 : factory_(NULL
, base::Bind(&TestURLFetcherCallback::CreateURLFetcher
,
530 base::Unretained(&url_callback_
))) {
533 bool PrinterJobHandlerTest::PostSpoolSuccess() {
534 base::MessageLoop::current()->PostTask(
536 base::Bind(&PrinterJobHandler::OnJobSpoolSucceeded
, job_handler_
, 0));
538 // Everything that would be posted on the printer thread queue
539 // has been posted, we can tell the main message loop to quit when idle
540 // and not worry about it idling while the print thread does work
541 base::MessageLoop::current()->PostTask(
542 FROM_HERE
, base::Bind(&MessageLoopQuitSoonHelper
, &loop_
));
546 void PrinterJobHandlerTest::AddMimeHeader(const GURL
& url
,
547 net::FakeURLFetcher
* fetcher
) {
548 scoped_refptr
<net::HttpResponseHeaders
> download_headers
=
549 new net::HttpResponseHeaders(kExampleJobDownloadResponseHeaders
);
550 fetcher
->set_response_headers(download_headers
);
553 void PrinterJobHandlerTest::AddTicketMimeHeader(const GURL
& url
,
554 net::FakeURLFetcher
* fetcher
) {
555 scoped_refptr
<net::HttpResponseHeaders
> download_headers
=
556 new net::HttpResponseHeaders(kExampleTicketDownloadResponseHeaders
);
557 fetcher
->set_response_headers(download_headers
);
561 void PrinterJobHandlerTest::SetUpJobSuccessTest(int job_num
) {
562 factory_
.SetFakeResponse(TicketURI(job_num
),
563 kExamplePrintTicket
, net::HTTP_OK
,
564 net::URLRequestStatus::SUCCESS
);
565 factory_
.SetFakeResponse(DownloadURI(job_num
),
566 kExamplePrintData
, net::HTTP_OK
,
567 net::URLRequestStatus::SUCCESS
);
569 factory_
.SetFakeResponse(DoneURI(job_num
),
570 StatusResponse(job_num
, "DONE"),
572 net::URLRequestStatus::SUCCESS
);
573 factory_
.SetFakeResponse(InProgressURI(job_num
),
574 StatusResponse(job_num
, "IN_PROGRESS"),
576 net::URLRequestStatus::SUCCESS
);
578 // The times requirement is relaxed for the ticket URI
579 // in order to accommodate TicketDownloadFailureTest
580 EXPECT_CALL(url_callback_
, OnRequestCreate(TicketURI(job_num
), _
))
582 .WillOnce(Invoke(this, &PrinterJobHandlerTest::AddTicketMimeHeader
));
584 EXPECT_CALL(url_callback_
, OnRequestCreate(DownloadURI(job_num
), _
))
586 .WillOnce(Invoke(this, &PrinterJobHandlerTest::AddMimeHeader
));
588 EXPECT_CALL(url_callback_
, OnRequestCreate(InProgressURI(job_num
), _
))
591 EXPECT_CALL(url_callback_
, OnRequestCreate(DoneURI(job_num
), _
))
594 EXPECT_CALL(print_system_
->JobSpooler(),
595 Spool(kExamplePrintTicket
, _
, _
, _
, _
, _
, _
, _
))
597 .WillOnce(InvokeWithoutArgs(this,
598 &PrinterJobHandlerTest::PostSpoolSuccess
));
601 void PrinterJobHandlerTest::BeginTest(int timeout_seconds
) {
602 job_handler_
= new PrinterJobHandler(basic_info_
,
604 GURL(kExampleCloudPrintServerURL
),
606 &jobhandler_delegate_
);
608 job_handler_
->Initialize();
610 base::MessageLoop::current()->PostDelayedTask(
612 base::Bind(&PrinterJobHandlerTest::MessageLoopQuitSoonHelper
,
613 base::MessageLoop::current()),
614 base::TimeDelta::FromSeconds(timeout_seconds
));
616 base::MessageLoop::current()->Run();
619 void PrinterJobHandlerTest::SendCapsAndDefaults(
620 const std::string
& printer_name
,
621 const PrintSystem::PrinterCapsAndDefaultsCallback
& callback
) {
622 callback
.Run(true, printer_name
, caps_and_defaults_
);
625 bool PrinterJobHandlerTest::GetPrinterInfo(printing::PrinterBasicInfo
* info
) {
630 void PrinterJobHandlerTest::TearDown() {
632 CloudPrintURLFetcher::set_factory(NULL
);
635 void PrinterJobHandlerTest::IdleOut() {
636 base::MessageLoop::current()->RunUntilIdle();
639 MockPrintServerWatcher::MockPrintServerWatcher() : delegate_(NULL
) {
640 ON_CALL(*this, StartWatching(_
))
641 .WillByDefault(DoAll(SaveArg
<0>(&delegate_
), Return(true)));
642 ON_CALL(*this, StopWatching()).WillByDefault(Return(true));
646 MockPrinterWatcher::MockPrinterWatcher() : delegate_(NULL
) {
647 ON_CALL(*this, StartWatching(_
))
648 .WillByDefault(DoAll(SaveArg
<0>(&delegate_
), Return(true)));
649 ON_CALL(*this, StopWatching()).WillByDefault(Return(true));
652 MockJobSpooler::MockJobSpooler() : delegate_(NULL
) {
653 ON_CALL(*this, Spool(_
, _
, _
, _
, _
, _
, _
, _
))
654 .WillByDefault(DoAll(SaveArg
<7>(&delegate_
), Return(true)));
657 MockPrintSystem::MockPrintSystem()
658 : job_spooler_(new NiceMock
<MockJobSpooler
>()),
659 printer_watcher_(new NiceMock
<MockPrinterWatcher
>()),
660 print_server_watcher_(new NiceMock
<MockPrintServerWatcher
>()) {
661 ON_CALL(*this, CreateJobSpooler()).WillByDefault(Return(job_spooler_
.get()));
663 ON_CALL(*this, CreatePrinterWatcher(_
))
664 .WillByDefault(Return(printer_watcher_
.get()));
666 ON_CALL(*this, CreatePrintServerWatcher())
667 .WillByDefault(Return(print_server_watcher_
.get()));
669 ON_CALL(*this, IsValidPrinter(_
)).
670 WillByDefault(Return(true));
672 ON_CALL(*this, ValidatePrintTicket(_
, _
, _
)).
673 WillByDefault(Return(true));
676 // This test simulates an end-to-end printing of a document
677 // but tests only non-failure cases.
678 // Disabled - http://crbug.com/184245
679 TEST_F(PrinterJobHandlerTest
, DISABLED_HappyPathTest
) {
680 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonStartup
),
681 JobListResponse(1), net::HTTP_OK
,
682 net::URLRequestStatus::SUCCESS
);
683 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonQueryMore
),
684 JobListResponse(0), net::HTTP_OK
,
685 net::URLRequestStatus::SUCCESS
);
687 EXPECT_CALL(url_callback_
,
688 OnRequestCreate(JobListURI(kJobFetchReasonStartup
), _
))
690 EXPECT_CALL(url_callback_
,
691 OnRequestCreate(JobListURI(kJobFetchReasonQueryMore
), _
))
694 SetUpJobSuccessTest(1);
698 TEST_F(PrinterJobHandlerTest
, TicketDownloadFailureTest
) {
699 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonStartup
),
700 JobListResponse(2), net::HTTP_OK
,
701 net::URLRequestStatus::SUCCESS
);
702 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonFailure
),
703 JobListResponse(2), net::HTTP_OK
,
704 net::URLRequestStatus::SUCCESS
);
705 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonQueryMore
),
706 JobListResponse(0), net::HTTP_OK
,
707 net::URLRequestStatus::SUCCESS
);
708 factory_
.SetFakeResponse(TicketURI(1), std::string(),
709 net::HTTP_INTERNAL_SERVER_ERROR
,
710 net::URLRequestStatus::FAILED
);
712 EXPECT_CALL(url_callback_
, OnRequestCreate(TicketURI(1), _
))
714 .WillOnce(Invoke(this, &PrinterJobHandlerTest::AddTicketMimeHeader
));
716 EXPECT_CALL(url_callback_
,
717 OnRequestCreate(JobListURI(kJobFetchReasonStartup
), _
))
720 EXPECT_CALL(url_callback_
,
721 OnRequestCreate(JobListURI(kJobFetchReasonQueryMore
), _
))
724 EXPECT_CALL(url_callback_
,
725 OnRequestCreate(JobListURI(kJobFetchReasonFailure
), _
))
728 SetUpJobSuccessTest(2);
732 // TODO(noamsml): Figure out how to make this test not take 1 second and
734 TEST_F(PrinterJobHandlerTest
, DISABLED_ManyFailureTest
) {
735 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonStartup
),
736 JobListResponse(1), net::HTTP_OK
,
737 net::URLRequestStatus::SUCCESS
);
738 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonFailure
),
739 JobListResponse(1), net::HTTP_OK
,
740 net::URLRequestStatus::SUCCESS
);
741 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonRetry
),
742 JobListResponse(1), net::HTTP_OK
,
743 net::URLRequestStatus::SUCCESS
);
744 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonQueryMore
),
745 JobListResponse(0), net::HTTP_OK
,
746 net::URLRequestStatus::SUCCESS
);
748 EXPECT_CALL(url_callback_
,
749 OnRequestCreate(JobListURI(kJobFetchReasonStartup
), _
))
752 EXPECT_CALL(url_callback_
,
753 OnRequestCreate(JobListURI(kJobFetchReasonQueryMore
), _
))
756 EXPECT_CALL(url_callback_
,
757 OnRequestCreate(JobListURI(kJobFetchReasonFailure
), _
))
760 EXPECT_CALL(url_callback_
,
761 OnRequestCreate(JobListURI(kJobFetchReasonRetry
), _
))
764 SetUpJobSuccessTest(1);
766 factory_
.SetFakeResponse(TicketURI(1),
768 net::HTTP_INTERNAL_SERVER_ERROR
,
769 net::URLRequestStatus::FAILED
);
771 loop_
.PostDelayedTask(FROM_HERE
,
772 base::Bind(&net::FakeURLFetcherFactory::SetFakeResponse
,
773 base::Unretained(&factory_
),
777 net::URLRequestStatus::SUCCESS
),
778 base::TimeDelta::FromSeconds(1));
785 // TODO(noamsml): Figure out how to make this test not take ~64-~2048 (depending
786 // constant values) seconds and re-enable it
787 TEST_F(PrinterJobHandlerTest
, DISABLED_CompleteFailureTest
) {
788 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonStartup
),
789 JobListResponse(1), net::HTTP_OK
,
790 net::URLRequestStatus::SUCCESS
);
791 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonFailure
),
792 JobListResponse(1), net::HTTP_OK
,
793 net::URLRequestStatus::SUCCESS
);
794 factory_
.SetFakeResponse(JobListURI(kJobFetchReasonRetry
),
795 JobListResponse(1), net::HTTP_OK
,
796 net::URLRequestStatus::SUCCESS
);
797 factory_
.SetFakeResponse(ErrorURI(1), StatusResponse(1, "ERROR"),
798 net::HTTP_OK
, net::URLRequestStatus::SUCCESS
);
799 factory_
.SetFakeResponse(TicketURI(1), std::string(),
800 net::HTTP_INTERNAL_SERVER_ERROR
,
801 net::URLRequestStatus::FAILED
);
803 EXPECT_CALL(url_callback_
,
804 OnRequestCreate(JobListURI(kJobFetchReasonStartup
), _
))
807 EXPECT_CALL(url_callback_
,
808 OnRequestCreate(JobListURI(kJobFetchReasonFailure
), _
))
811 EXPECT_CALL(url_callback_
,
812 OnRequestCreate(JobListURI(kJobFetchReasonRetry
), _
))
815 EXPECT_CALL(url_callback_
, OnRequestCreate(ErrorURI(1), _
))
817 .WillOnce(InvokeWithoutArgs(
818 this, &PrinterJobHandlerTest::MakeJobFetchReturnNoJobs
));
820 EXPECT_CALL(url_callback_
, OnRequestCreate(TicketURI(1), _
))
821 .Times(AtLeast(kNumRetriesBeforeAbandonJob
));
826 } // namespace cloud_print