Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / chrome / service / cloud_print / printer_job_handler_unittest.cc
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.
4
5 #include "base/files/file_path.h"
6 #include "base/md5.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"
25
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;
37 using ::testing::_;
38
39 namespace cloud_print {
40
41 namespace {
42
43 using base::StringPrintf;
44
45 const char kExampleCloudPrintServerURL[] = "https://www.google.com/cloudprint/";
46
47 const char kExamplePrintTicket[] = "{\"MediaType\":\"plain\","
48     "\"Resolution\":\"300x300dpi\",\"PageRegion\":\"Letter\","
49     "\"InputSlot\":\"auto\",\"PageSize\":\"Letter\",\"EconoMode\":\"off\"}";
50
51
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
61
62 // StringPrintf parameters: job number, job number, job number, job number
63 const char kExampleJobObject[] = "{"
64 "   \"tags\": ["
65 "    \"^own\""
66 "   ],"
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\","
76 "   \"message\": \"\","
77 "   \"title\": \"Example Job %d\","
78 "   \"errorCode\": \"\","
79 "   \"numberOfPages\": 3"
80 "  }";
81
82 // StringPrintf parameters: job object list
83 const char kExampleJobListResponse[] = "{"
84 " \"success\": true,"
85 " \"jobs\": ["
86 " %s"
87 " ],"
88 " \"xsrf_token\": \"AIp06DjUd3AV6BO0aujB9NvM2a9ZbogxOQ:1360021066932\","
89 " \"request\": {"
90 "  \"time\": \"0\","
91 "  \"users\": ["
92 "   \"sampleuser@gmail.com\""
93 "  ],"
94 "  \"params\": {"
95 "   \"printerid\": ["
96 "    \"__example_printer_id\""
97 "   ]"
98 "  },"
99 "  \"user\": \"sampleuser@gmail.com\""
100 " }"
101 "}";
102
103
104 // StringPrintf parameters: job number
105 const char kExampleJobID[] = "__example_job_id%d";
106
107 // StringPrintf parameters: job number
108 const char kExamplePrintTicketURI[] =
109     "https://www.google.com/cloudprint/ticket?exampleURI%d";
110
111 // StringPrintf parameters: job number
112 const char kExamplePrintDownloadURI[] =
113     "https://www.google.com/cloudprint/download?exampleURI%d";
114
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";
119
120 // StringPrintf parameters: job number
121 const char kExampleUpdateErrorURI[] =
122     "https://www.google.com/cloudprint/control?jobid=__example_job_id%d"
123     "&status=ERROR";
124
125 // StringPrintf parameters: fetch reason
126 const char kExamplePrinterJobListURI[] =
127     "https://www.google.com/cloudprint/fetch"
128     "?printerid=__example_printer_id&deb=%s";
129
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\","
135 " \"request\": {"
136 "  \"time\": \"0\","
137 "  \"users\": ["
138 "   \"sampleuser@gmail.com\""
139 "  ],"
140 "  \"params\": {"
141 "   \"xsrf\": ["
142 "    \"AIp06DgeGIETs42Cj28QWmxGPWVDiaXwVQ:1360023041852\""
143 "   ],"
144 "   \"status\": ["
145 "    \"%s\""
146 "   ],"
147 "   \"jobid\": ["
148 "    \"__example_job_id%d\""
149 "   ]"
150 "  },"
151 "  \"user\": \"sampleuser@gmail.com\""
152 " },"
153 " \"job\": {"
154 "  \"tags\": ["
155 "   \"^own\""
156 "  ],"
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"
169 " }"
170 "}";
171
172 const char kExamplePrinterID[] = "__example_printer_id";
173
174 const char kExamplePrinterCapabilities[] = "";
175
176 const char kExampleCapsMimeType[] = "";
177
178 // These can stay empty
179 const char kExampleDefaults[] = "";
180
181 const char kExampleDefaultMimeType[] = "";
182
183 // Since we're not connecting to the server, this can be any non-empty string.
184 const char kExampleCloudPrintOAuthToken[] = "__SAMPLE_TOKEN";
185
186
187 // Not actually printing, no need for real PDF.
188 const char kExamplePrintData[] = "__EXAMPLE_PRINT_DATA";
189
190 const char kExampleJobDownloadResponseHeaders[] =
191     "Content-Type: Application/PDF\n";
192
193 const char kExamplePrinterName[] = "Example Printer";
194
195 const char kExamplePrinterDescription[] = "Example Description";
196
197 // These are functions used to construct the various sample strings.
198 std::string JobListResponse(int num_jobs) {
199   std::string job_objects;
200   for (int i = 0; i < num_jobs; i++) {
201     job_objects = job_objects + StringPrintf(kExampleJobObject, i+1, i+1, i+1,
202                                              i+1);
203     if (i != num_jobs-1) job_objects = job_objects + ",";
204   }
205   return StringPrintf(kExampleJobListResponse, job_objects.c_str());
206 }
207
208 GURL JobListURI(const char* reason) {
209   return GURL(StringPrintf(kExamplePrinterJobListURI, reason));
210 }
211
212 GURL DoneURI(int job_num) {
213   return GURL(StringPrintf(kExampleUpdateDoneURI, job_num));
214 }
215
216 GURL ErrorURI(int job_num) {
217   return GURL(StringPrintf(kExampleUpdateErrorURI, job_num));
218 }
219
220 GURL TicketURI(int job_num) {
221   return GURL(StringPrintf(kExamplePrintTicketURI, job_num));
222 }
223
224 GURL DownloadURI(int job_num) {
225   return GURL(StringPrintf(kExamplePrintDownloadURI, job_num));
226 }
227
228 GURL InProgressURI(int job_num) {
229   return GetUrlForJobStatusUpdate(GURL(kExampleCloudPrintServerURL),
230                                   StringPrintf(kExampleJobID, job_num),
231                                   PRINT_JOB_STATUS_IN_PROGRESS,
232                                   0);
233 }
234
235 std::string StatusResponse(int job_num, const char* status_string) {
236   return StringPrintf(kExampleControlResponse,
237                       status_string,
238                       job_num,
239                       status_string);
240 }
241
242 }  // namespace
243
244 class CloudPrintURLFetcherNoServiceProcess
245     : public CloudPrintURLFetcher {
246  public:
247   CloudPrintURLFetcherNoServiceProcess() :
248       context_getter_(new net::TestURLRequestContextGetter(
249           base::MessageLoopProxy::current())) {}
250  protected:
251   virtual net::URLRequestContextGetter* GetRequestContextGetter() OVERRIDE {
252     return context_getter_.get();
253   }
254
255   virtual ~CloudPrintURLFetcherNoServiceProcess() {}
256  private:
257   scoped_refptr<net::URLRequestContextGetter> context_getter_;
258 };
259
260
261 class CloudPrintURLFetcherNoServiceProcessFactory
262     : public CloudPrintURLFetcherFactory {
263  public:
264   virtual CloudPrintURLFetcher* CreateCloudPrintURLFetcher() OVERRIDE {
265     return new CloudPrintURLFetcherNoServiceProcess;
266   }
267
268   virtual ~CloudPrintURLFetcherNoServiceProcessFactory() {}
269 };
270
271
272 // This class handles the callback from FakeURLFetcher
273 // It is a separate class because callback methods must be
274 // on RefCounted classes
275
276 class TestURLFetcherCallback {
277  public:
278   scoped_ptr<net::FakeURLFetcher> CreateURLFetcher(
279       const GURL& url,
280       net::URLFetcherDelegate* d,
281       const std::string& response_data,
282       net::HttpStatusCode response_code,
283       net::URLRequestStatus::Status status) {
284     scoped_ptr<net::FakeURLFetcher> fetcher(
285         new net::FakeURLFetcher(url, d, response_data, response_code, status));
286     OnRequestCreate(url, fetcher.get());
287     return fetcher.Pass();
288   }
289   MOCK_METHOD2(OnRequestCreate,
290                void(const GURL&, net::FakeURLFetcher*));
291 };
292
293
294 class MockPrinterJobHandlerDelegate
295     : public PrinterJobHandler::Delegate {
296  public:
297   MOCK_METHOD0(OnAuthError, void());
298   MOCK_METHOD1(OnPrinterDeleted, void(const std::string& str));
299
300   virtual ~MockPrinterJobHandlerDelegate() {}
301 };
302
303
304 class MockPrintServerWatcher
305     : public PrintSystem::PrintServerWatcher {
306  public:
307   MOCK_METHOD1(StartWatching,
308                bool(PrintSystem::PrintServerWatcher::Delegate* d));
309   MOCK_METHOD0(StopWatching, bool());
310
311   MockPrintServerWatcher();
312   PrintSystem::PrintServerWatcher::Delegate* delegate() const {
313     return delegate_;
314   }
315
316   friend class scoped_refptr<NiceMock<MockPrintServerWatcher> >;
317   friend class scoped_refptr<StrictMock<MockPrintServerWatcher> >;
318   friend class scoped_refptr<MockPrintServerWatcher>;
319
320  protected:
321   virtual ~MockPrintServerWatcher() {}
322
323  private:
324   PrintSystem::PrintServerWatcher::Delegate* delegate_;
325 };
326
327 class MockPrinterWatcher : public PrintSystem::PrinterWatcher {
328  public:
329   MOCK_METHOD1(StartWatching, bool(PrintSystem::PrinterWatcher::Delegate* d));
330   MOCK_METHOD0(StopWatching, bool());
331   MOCK_METHOD1(GetCurrentPrinterInfo,
332                bool(printing::PrinterBasicInfo* printer_info));
333
334   MockPrinterWatcher();
335   PrintSystem::PrinterWatcher::Delegate* delegate() const { return delegate_; }
336
337   friend class scoped_refptr<NiceMock<MockPrinterWatcher> >;
338   friend class scoped_refptr<StrictMock<MockPrinterWatcher> >;
339   friend class scoped_refptr<MockPrinterWatcher>;
340
341  protected:
342   virtual ~MockPrinterWatcher() {}
343
344  private:
345   PrintSystem::PrinterWatcher::Delegate* delegate_;
346 };
347
348
349 class MockJobSpooler : public PrintSystem::JobSpooler {
350  public:
351   MOCK_METHOD7(Spool, bool(
352       const std::string& print_ticket,
353       const base::FilePath& print_data_file_path,
354       const std::string& print_data_mime_type,
355       const std::string& printer_name,
356       const std::string& job_title,
357       const std::vector<std::string>& tags,
358       PrintSystem::JobSpooler::Delegate* delegate));
359
360   MockJobSpooler();
361   PrintSystem::JobSpooler::Delegate* delegate() const  { return delegate_; }
362
363   friend class scoped_refptr<NiceMock<MockJobSpooler> >;
364   friend class scoped_refptr<StrictMock<MockJobSpooler> >;
365   friend class scoped_refptr<MockJobSpooler>;
366
367  protected:
368   virtual ~MockJobSpooler() {}
369
370  private:
371   PrintSystem::JobSpooler::Delegate* delegate_;
372 };
373
374
375
376 class MockPrintSystem : public PrintSystem {
377  public:
378   MockPrintSystem();
379   PrintSystem::PrintSystemResult succeed() {
380     return PrintSystem::PrintSystemResult(true, "success");
381   }
382
383   PrintSystem::PrintSystemResult fail() {
384     return PrintSystem::PrintSystemResult(false, "failure");
385   }
386
387   MockJobSpooler& JobSpooler() { return *job_spooler_.get(); }
388
389   MockPrinterWatcher& PrinterWatcher() { return *printer_watcher_.get(); }
390
391   MockPrintServerWatcher& PrintServerWatcher() {
392     return *print_server_watcher_.get();
393   }
394
395   MOCK_METHOD0(Init, PrintSystem::PrintSystemResult());
396   MOCK_METHOD1(EnumeratePrinters, PrintSystem::PrintSystemResult(
397       printing::PrinterList* printer_list));
398
399   MOCK_METHOD2(
400       GetPrinterCapsAndDefaults,
401       void(const std::string& printer_name,
402            const PrintSystem::PrinterCapsAndDefaultsCallback& callback));
403
404   MOCK_METHOD1(IsValidPrinter, bool(const std::string& printer_name));
405
406   MOCK_METHOD2(ValidatePrintTicket, bool(const std::string& printer_name,
407                                          const std::string& print_ticket_data));
408
409   MOCK_METHOD3(GetJobDetails, bool(const std::string& printer_name,
410                                     PlatformJobId job_id,
411                                     PrintJobDetails* job_details));
412
413   MOCK_METHOD0(CreatePrintServerWatcher, PrintSystem::PrintServerWatcher*());
414   MOCK_METHOD1(CreatePrinterWatcher,
415                PrintSystem::PrinterWatcher*(const std::string& printer_name));
416   MOCK_METHOD0(CreateJobSpooler, PrintSystem::JobSpooler*());
417
418   MOCK_METHOD0(GetSupportedMimeTypes, std::string());
419
420   friend class scoped_refptr<NiceMock<MockPrintSystem> >;
421   friend class scoped_refptr<StrictMock<MockPrintSystem> >;
422   friend class scoped_refptr<MockPrintSystem>;
423
424  protected:
425   virtual ~MockPrintSystem() {}
426
427  private:
428   scoped_refptr<MockJobSpooler> job_spooler_;
429   scoped_refptr<MockPrinterWatcher> printer_watcher_;
430   scoped_refptr<MockPrintServerWatcher> print_server_watcher_;
431 };
432
433
434 class PrinterJobHandlerTest : public ::testing::Test {
435  public:
436   PrinterJobHandlerTest();
437   virtual void SetUp() OVERRIDE;
438   virtual void TearDown() OVERRIDE;
439   void IdleOut();
440   bool GetPrinterInfo(printing::PrinterBasicInfo* info);
441   void SendCapsAndDefaults(
442       const std::string& printer_name,
443       const PrintSystem::PrinterCapsAndDefaultsCallback& callback);
444   void AddMimeHeader(const GURL& url, net::FakeURLFetcher* fetcher);
445   bool PostSpoolSuccess();
446   void SetUpJobSuccessTest(int job_num);
447   void BeginTest(int timeout_seconds);
448   void MakeJobFetchReturnNoJobs();
449
450   static void MessageLoopQuitNowHelper(base::MessageLoop* message_loop);
451   static void MessageLoopQuitSoonHelper(base::MessageLoop* message_loop);
452
453   base::MessageLoopForIO loop_;
454   TestURLFetcherCallback url_callback_;
455   MockPrinterJobHandlerDelegate jobhandler_delegate_;
456   CloudPrintTokenStore token_store_;
457   CloudPrintURLFetcherNoServiceProcessFactory cloud_print_factory_;
458   scoped_refptr<PrinterJobHandler> job_handler_;
459   scoped_refptr<NiceMock<MockPrintSystem> > print_system_;
460   net::FakeURLFetcherFactory factory_;
461   printing::PrinterBasicInfo basic_info_;
462   printing::PrinterCapsAndDefaults caps_and_defaults_;
463   PrinterJobHandler::PrinterInfoFromCloud info_from_cloud_;
464 };
465
466
467 void PrinterJobHandlerTest::SetUp() {
468   basic_info_.printer_name = kExamplePrinterName;
469   basic_info_.printer_description = kExamplePrinterDescription;
470   basic_info_.is_default = 0;
471
472   info_from_cloud_.printer_id = kExamplePrinterID;
473   info_from_cloud_.tags_hash = GetHashOfPrinterInfo(basic_info_);
474
475   info_from_cloud_.caps_hash = base::MD5String(kExamplePrinterCapabilities);
476   info_from_cloud_.current_xmpp_timeout = 300;
477   info_from_cloud_.pending_xmpp_timeout = 0;
478
479   caps_and_defaults_.printer_capabilities = kExamplePrinterCapabilities;
480   caps_and_defaults_.caps_mime_type = kExampleCapsMimeType;
481   caps_and_defaults_.printer_defaults = kExampleDefaults;
482   caps_and_defaults_.defaults_mime_type = kExampleDefaultMimeType;
483
484   print_system_ = new NiceMock<MockPrintSystem>();
485
486   token_store_.SetToken(kExampleCloudPrintOAuthToken);
487
488   ON_CALL(print_system_->PrinterWatcher(), GetCurrentPrinterInfo(_))
489       .WillByDefault(Invoke(this, &PrinterJobHandlerTest::GetPrinterInfo));
490
491   ON_CALL(*print_system_.get(), GetPrinterCapsAndDefaults(_, _))
492       .WillByDefault(Invoke(this, &PrinterJobHandlerTest::SendCapsAndDefaults));
493
494   CloudPrintURLFetcher::set_factory(&cloud_print_factory_);
495 }
496
497 void PrinterJobHandlerTest::MakeJobFetchReturnNoJobs() {
498   factory_.SetFakeResponse(JobListURI(kJobFetchReasonStartup),
499                            JobListResponse(0), net::HTTP_OK,
500                            net::URLRequestStatus::SUCCESS);
501   factory_.SetFakeResponse(JobListURI(kJobFetchReasonFailure),
502                            JobListResponse(0), net::HTTP_OK,
503                            net::URLRequestStatus::SUCCESS);
504   factory_.SetFakeResponse(JobListURI(kJobFetchReasonRetry),
505                            JobListResponse(0), net::HTTP_OK,
506                            net::URLRequestStatus::SUCCESS);
507 }
508
509 void PrinterJobHandlerTest::MessageLoopQuitNowHelper(
510     base::MessageLoop* message_loop) {
511   message_loop->QuitWhenIdle();
512 }
513
514 void PrinterJobHandlerTest::MessageLoopQuitSoonHelper(
515     base::MessageLoop* message_loop) {
516   message_loop->message_loop_proxy()->PostTask(
517       FROM_HERE, base::Bind(&MessageLoopQuitNowHelper, message_loop));
518 }
519
520 PrinterJobHandlerTest::PrinterJobHandlerTest()
521     : factory_(NULL, base::Bind(&TestURLFetcherCallback::CreateURLFetcher,
522                                 base::Unretained(&url_callback_))) {
523 }
524
525 bool PrinterJobHandlerTest::PostSpoolSuccess() {
526   base::MessageLoop::current()->PostTask(
527       FROM_HERE,
528       base::Bind(&PrinterJobHandler::OnJobSpoolSucceeded, job_handler_, 0));
529
530   // Everything that would be posted on the printer thread queue
531   // has been posted, we can tell the main message loop to quit when idle
532   // and not worry about it idling while the print thread does work
533   base::MessageLoop::current()->PostTask(
534       FROM_HERE, base::Bind(&MessageLoopQuitSoonHelper, &loop_));
535   return true;
536 }
537
538 void PrinterJobHandlerTest::AddMimeHeader(const GURL& url,
539                                           net::FakeURLFetcher* fetcher) {
540   scoped_refptr<net::HttpResponseHeaders> download_headers =
541       new net::HttpResponseHeaders(kExampleJobDownloadResponseHeaders);
542   fetcher->set_response_headers(download_headers);
543 }
544
545
546 void PrinterJobHandlerTest::SetUpJobSuccessTest(int job_num) {
547   factory_.SetFakeResponse(TicketURI(job_num),
548                            kExamplePrintTicket, net::HTTP_OK,
549                            net::URLRequestStatus::SUCCESS);
550   factory_.SetFakeResponse(DownloadURI(job_num),
551                            kExamplePrintData, net::HTTP_OK,
552                            net::URLRequestStatus::SUCCESS);
553
554   factory_.SetFakeResponse(DoneURI(job_num),
555                            StatusResponse(job_num, "DONE"),
556                            net::HTTP_OK,
557                            net::URLRequestStatus::SUCCESS);
558   factory_.SetFakeResponse(InProgressURI(job_num),
559                            StatusResponse(job_num, "IN_PROGRESS"),
560                            net::HTTP_OK,
561                            net::URLRequestStatus::SUCCESS);
562
563   // The times requirement is relaxed for the ticket URI
564   // in order to accommodate TicketDownloadFailureTest
565   EXPECT_CALL(url_callback_, OnRequestCreate(TicketURI(job_num), _))
566       .Times(AtLeast(1));
567
568   EXPECT_CALL(url_callback_, OnRequestCreate(DownloadURI(job_num), _))
569       .Times(Exactly(1))
570       .WillOnce(Invoke(this, &PrinterJobHandlerTest::AddMimeHeader));
571
572   EXPECT_CALL(url_callback_, OnRequestCreate(InProgressURI(job_num), _))
573       .Times(Exactly(1));
574
575   EXPECT_CALL(url_callback_, OnRequestCreate(DoneURI(job_num), _))
576       .Times(Exactly(1));
577
578   EXPECT_CALL(print_system_->JobSpooler(),
579               Spool(kExamplePrintTicket, _, _, _, _, _, _))
580       .Times(Exactly(1))
581       .WillOnce(InvokeWithoutArgs(this,
582                                   &PrinterJobHandlerTest::PostSpoolSuccess));
583 }
584
585 void PrinterJobHandlerTest::BeginTest(int timeout_seconds) {
586   job_handler_ = new PrinterJobHandler(basic_info_,
587                                        info_from_cloud_,
588                                        GURL(kExampleCloudPrintServerURL),
589                                        print_system_.get(),
590                                        &jobhandler_delegate_);
591
592   job_handler_->Initialize();
593
594   base::MessageLoop::current()->PostDelayedTask(
595       FROM_HERE,
596       base::Bind(&PrinterJobHandlerTest::MessageLoopQuitSoonHelper,
597                  base::MessageLoop::current()),
598       base::TimeDelta::FromSeconds(timeout_seconds));
599
600   base::MessageLoop::current()->Run();
601 }
602
603 void PrinterJobHandlerTest::SendCapsAndDefaults(
604     const std::string& printer_name,
605     const PrintSystem::PrinterCapsAndDefaultsCallback& callback) {
606   callback.Run(true, printer_name, caps_and_defaults_);
607 }
608
609 bool PrinterJobHandlerTest::GetPrinterInfo(printing::PrinterBasicInfo* info) {
610   *info = basic_info_;
611   return true;
612 }
613
614 void PrinterJobHandlerTest::TearDown() {
615   IdleOut();
616   CloudPrintURLFetcher::set_factory(NULL);
617 }
618
619 void PrinterJobHandlerTest::IdleOut() {
620   base::MessageLoop::current()->RunUntilIdle();
621 }
622
623 MockPrintServerWatcher::MockPrintServerWatcher() : delegate_(NULL) {
624   ON_CALL(*this, StartWatching(_))
625       .WillByDefault(DoAll(SaveArg<0>(&delegate_), Return(true)));
626   ON_CALL(*this, StopWatching()).WillByDefault(Return(true));
627 }
628
629
630 MockPrinterWatcher::MockPrinterWatcher() : delegate_(NULL) {
631   ON_CALL(*this, StartWatching(_))
632       .WillByDefault(DoAll(SaveArg<0>(&delegate_), Return(true)));
633   ON_CALL(*this, StopWatching()).WillByDefault(Return(true));
634 }
635
636 MockJobSpooler::MockJobSpooler() : delegate_(NULL) {
637   ON_CALL(*this, Spool(_, _, _, _, _, _, _))
638       .WillByDefault(DoAll(SaveArg<6>(&delegate_), Return(true)));
639 }
640
641 MockPrintSystem::MockPrintSystem()
642     : job_spooler_(new NiceMock<MockJobSpooler>()),
643       printer_watcher_(new NiceMock<MockPrinterWatcher>()),
644       print_server_watcher_(new NiceMock<MockPrintServerWatcher>()) {
645   ON_CALL(*this, CreateJobSpooler()).WillByDefault(Return(job_spooler_.get()));
646
647   ON_CALL(*this, CreatePrinterWatcher(_))
648       .WillByDefault(Return(printer_watcher_.get()));
649
650   ON_CALL(*this, CreatePrintServerWatcher())
651       .WillByDefault(Return(print_server_watcher_.get()));
652
653   ON_CALL(*this, IsValidPrinter(_)).
654       WillByDefault(Return(true));
655
656   ON_CALL(*this, ValidatePrintTicket(_, _)).
657       WillByDefault(Return(true));
658 };
659
660 // This test simulates an end-to-end printing of a document
661 // but tests only non-failure cases.
662 // Disabled - http://crbug.com/184245
663 TEST_F(PrinterJobHandlerTest, DISABLED_HappyPathTest) {
664   factory_.SetFakeResponse(JobListURI(kJobFetchReasonStartup),
665                            JobListResponse(1), net::HTTP_OK,
666                            net::URLRequestStatus::SUCCESS);
667   factory_.SetFakeResponse(JobListURI(kJobFetchReasonQueryMore),
668                            JobListResponse(0), net::HTTP_OK,
669                            net::URLRequestStatus::SUCCESS);
670
671   EXPECT_CALL(url_callback_,
672               OnRequestCreate(JobListURI(kJobFetchReasonStartup), _))
673       .Times(Exactly(1));
674   EXPECT_CALL(url_callback_,
675               OnRequestCreate(JobListURI(kJobFetchReasonQueryMore), _))
676       .Times(Exactly(1));
677
678   SetUpJobSuccessTest(1);
679   BeginTest(20);
680 }
681
682 TEST_F(PrinterJobHandlerTest, TicketDownloadFailureTest) {
683   factory_.SetFakeResponse(JobListURI(kJobFetchReasonStartup),
684                            JobListResponse(2), net::HTTP_OK,
685                            net::URLRequestStatus::SUCCESS);
686   factory_.SetFakeResponse(JobListURI(kJobFetchReasonFailure),
687                            JobListResponse(2), net::HTTP_OK,
688                            net::URLRequestStatus::SUCCESS);
689   factory_.SetFakeResponse(JobListURI(kJobFetchReasonQueryMore),
690                            JobListResponse(0), net::HTTP_OK,
691                            net::URLRequestStatus::SUCCESS);
692   factory_.SetFakeResponse(TicketURI(1), std::string(),
693                            net::HTTP_INTERNAL_SERVER_ERROR,
694                            net::URLRequestStatus::FAILED);
695
696   EXPECT_CALL(url_callback_, OnRequestCreate(TicketURI(1), _))
697       .Times(AtLeast(1));
698
699   EXPECT_CALL(url_callback_,
700               OnRequestCreate(JobListURI(kJobFetchReasonStartup), _))
701       .Times(AtLeast(1));
702
703   EXPECT_CALL(url_callback_,
704               OnRequestCreate(JobListURI(kJobFetchReasonQueryMore), _))
705       .Times(AtLeast(1));
706
707   EXPECT_CALL(url_callback_,
708               OnRequestCreate(JobListURI(kJobFetchReasonFailure), _))
709       .Times(AtLeast(1));
710
711   SetUpJobSuccessTest(2);
712   BeginTest(20);
713 }
714
715 // TODO(noamsml): Figure out how to make this test not take 1 second and
716 // re-enable it
717 TEST_F(PrinterJobHandlerTest, DISABLED_ManyFailureTest) {
718   factory_.SetFakeResponse(JobListURI(kJobFetchReasonStartup),
719                            JobListResponse(1), net::HTTP_OK,
720                            net::URLRequestStatus::SUCCESS);
721   factory_.SetFakeResponse(JobListURI(kJobFetchReasonFailure),
722                            JobListResponse(1), net::HTTP_OK,
723                            net::URLRequestStatus::SUCCESS);
724   factory_.SetFakeResponse(JobListURI(kJobFetchReasonRetry),
725                            JobListResponse(1), net::HTTP_OK,
726                            net::URLRequestStatus::SUCCESS);
727   factory_.SetFakeResponse(JobListURI(kJobFetchReasonQueryMore),
728                            JobListResponse(0), net::HTTP_OK,
729                            net::URLRequestStatus::SUCCESS);
730
731   EXPECT_CALL(url_callback_,
732               OnRequestCreate(JobListURI(kJobFetchReasonStartup), _))
733       .Times(AtLeast(1));
734
735   EXPECT_CALL(url_callback_,
736               OnRequestCreate(JobListURI(kJobFetchReasonQueryMore), _))
737       .Times(AtLeast(1));
738
739   EXPECT_CALL(url_callback_,
740               OnRequestCreate(JobListURI(kJobFetchReasonFailure), _))
741       .Times(AtLeast(1));
742
743   EXPECT_CALL(url_callback_,
744               OnRequestCreate(JobListURI(kJobFetchReasonRetry), _))
745       .Times(AtLeast(1));
746
747   SetUpJobSuccessTest(1);
748
749   factory_.SetFakeResponse(TicketURI(1),
750                            std::string(),
751                            net::HTTP_INTERNAL_SERVER_ERROR,
752                            net::URLRequestStatus::FAILED);
753
754   loop_.PostDelayedTask(FROM_HERE,
755                         base::Bind(&net::FakeURLFetcherFactory::SetFakeResponse,
756                                    base::Unretained(&factory_),
757                                    TicketURI(1),
758                                    kExamplePrintTicket,
759                                    net::HTTP_OK,
760                                    net::URLRequestStatus::SUCCESS),
761                         base::TimeDelta::FromSeconds(1));
762
763
764   BeginTest(5);
765 }
766
767
768 // TODO(noamsml): Figure out how to make this test not take ~64-~2048 (depending
769 // constant values) seconds and re-enable it
770 TEST_F(PrinterJobHandlerTest, DISABLED_CompleteFailureTest) {
771   factory_.SetFakeResponse(JobListURI(kJobFetchReasonStartup),
772                            JobListResponse(1), net::HTTP_OK,
773                            net::URLRequestStatus::SUCCESS);
774   factory_.SetFakeResponse(JobListURI(kJobFetchReasonFailure),
775                            JobListResponse(1), net::HTTP_OK,
776                            net::URLRequestStatus::SUCCESS);
777   factory_.SetFakeResponse(JobListURI(kJobFetchReasonRetry),
778                            JobListResponse(1), net::HTTP_OK,
779                            net::URLRequestStatus::SUCCESS);
780   factory_.SetFakeResponse(ErrorURI(1), StatusResponse(1, "ERROR"),
781                            net::HTTP_OK, net::URLRequestStatus::SUCCESS);
782   factory_.SetFakeResponse(TicketURI(1), std::string(),
783                            net::HTTP_INTERNAL_SERVER_ERROR,
784                            net::URLRequestStatus::FAILED);
785
786   EXPECT_CALL(url_callback_,
787               OnRequestCreate(JobListURI(kJobFetchReasonStartup), _))
788       .Times(AtLeast(1));
789
790   EXPECT_CALL(url_callback_,
791               OnRequestCreate(JobListURI(kJobFetchReasonFailure), _))
792       .Times(AtLeast(1));
793
794   EXPECT_CALL(url_callback_,
795               OnRequestCreate(JobListURI(kJobFetchReasonRetry), _))
796       .Times(AtLeast(1));
797
798   EXPECT_CALL(url_callback_, OnRequestCreate(ErrorURI(1), _))
799       .Times(Exactly(1))
800       .WillOnce(InvokeWithoutArgs(
801           this, &PrinterJobHandlerTest::MakeJobFetchReturnNoJobs));
802
803   EXPECT_CALL(url_callback_, OnRequestCreate(TicketURI(1), _))
804       .Times(AtLeast(kNumRetriesBeforeAbandonJob));
805
806   BeginTest(70);
807 }
808
809 }  // namespace cloud_print