Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / local_discovery / privet_http_unittest.cc
1 // Copyright 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/bind.h"
6 #include "base/json/json_reader.h"
7 #include "base/json/json_writer.h"
8 #include "base/message_loop/message_loop.h"
9 #include "chrome/browser/local_discovery/privet_http_impl.h"
10 #include "net/base/host_port_pair.h"
11 #include "net/base/net_errors.h"
12 #include "net/url_request/test_url_fetcher_factory.h"
13 #include "net/url_request/url_request_test_util.h"
14 #include "printing/pwg_raster_settings.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 #if defined(ENABLE_PRINT_PREVIEW)
19 #include "chrome/browser/local_discovery/pwg_raster_converter.h"
20 #endif  // ENABLE_PRINT_PREVIEW
21
22 using testing::StrictMock;
23 using testing::NiceMock;
24
25 namespace local_discovery {
26
27 namespace {
28
29 const char kSampleInfoResponse[] = "{"
30     "       \"version\": \"1.0\","
31     "       \"name\": \"Common printer\","
32     "       \"description\": \"Printer connected through Chrome connector\","
33     "       \"url\": \"https://www.google.com/cloudprint\","
34     "       \"type\": ["
35     "               \"printer\""
36     "       ],"
37     "       \"id\": \"\","
38     "       \"device_state\": \"idle\","
39     "       \"connection_state\": \"online\","
40     "       \"manufacturer\": \"Google\","
41     "       \"model\": \"Google Chrome\","
42     "       \"serial_number\": \"1111-22222-33333-4444\","
43     "       \"firmware\": \"24.0.1312.52\","
44     "       \"uptime\": 600,"
45     "       \"setup_url\": \"http://support.google.com/\","
46     "       \"support_url\": \"http://support.google.com/cloudprint/?hl=en\","
47     "       \"update_url\": \"http://support.google.com/cloudprint/?hl=en\","
48     "       \"x-privet-token\": \"SampleTokenForTesting\","
49     "       \"api\": ["
50     "               \"/privet/accesstoken\","
51     "               \"/privet/capabilities\","
52     "               \"/privet/printer/submitdoc\","
53     "       ]"
54     "}";
55
56 const char kSampleInfoResponseRegistered[] = "{"
57     "       \"version\": \"1.0\","
58     "       \"name\": \"Common printer\","
59     "       \"description\": \"Printer connected through Chrome connector\","
60     "       \"url\": \"https://www.google.com/cloudprint\","
61     "       \"type\": ["
62     "               \"printer\""
63     "       ],"
64     "       \"id\": \"MyDeviceID\","
65     "       \"device_state\": \"idle\","
66     "       \"connection_state\": \"online\","
67     "       \"manufacturer\": \"Google\","
68     "       \"model\": \"Google Chrome\","
69     "       \"serial_number\": \"1111-22222-33333-4444\","
70     "       \"firmware\": \"24.0.1312.52\","
71     "       \"uptime\": 600,"
72     "       \"setup_url\": \"http://support.google.com/\","
73     "       \"support_url\": \"http://support.google.com/cloudprint/?hl=en\","
74     "       \"update_url\": \"http://support.google.com/cloudprint/?hl=en\","
75     "       \"x-privet-token\": \"SampleTokenForTesting\","
76     "       \"api\": ["
77     "               \"/privet/accesstoken\","
78     "               \"/privet/capabilities\","
79     "               \"/privet/printer/submitdoc\","
80     "       ]"
81     "}";
82
83 const char kSampleRegisterStartResponse[] = "{"
84     "\"user\": \"example@google.com\","
85     "\"action\": \"start\""
86     "}";
87
88 const char kSampleRegisterGetClaimTokenResponse[] = "{"
89     "       \"action\": \"getClaimToken\","
90     "       \"user\": \"example@google.com\","
91     "       \"token\": \"MySampleToken\","
92     "       \"claim_url\": \"https://domain.com/SoMeUrL\""
93     "}";
94
95 const char kSampleRegisterCompleteResponse[] = "{"
96     "\"user\": \"example@google.com\","
97     "\"action\": \"complete\","
98     "\"device_id\": \"MyDeviceID\""
99     "}";
100
101 const char kSampleXPrivetErrorResponse[] =
102     "{ \"error\": \"invalid_x_privet_token\" }";
103
104 const char kSampleRegisterErrorTransient[] =
105     "{ \"error\": \"device_busy\", \"timeout\": 1}";
106
107 const char kSampleRegisterErrorPermanent[] =
108     "{ \"error\": \"user_cancel\" }";
109
110 const char kSampleInfoResponseBadJson[] = "{";
111
112 const char kSampleRegisterCancelResponse[] = "{"
113     "\"user\": \"example@google.com\","
114     "\"action\": \"cancel\""
115     "}";
116
117 const char kSampleCapabilitiesResponse[] = "{"
118     "\"version\" : \"1.0\","
119     "\"printer\" : {"
120     "  \"supported_content_type\" : ["
121     "   { \"content_type\" : \"application/pdf\" },"
122     "   { \"content_type\" : \"image/pwg-raster\" }"
123     "  ]"
124     "}"
125     "}";
126
127 #if defined(ENABLE_PRINT_PREVIEW)
128 const char kSampleInfoResponseWithCreatejob[] = "{"
129     "       \"version\": \"1.0\","
130     "       \"name\": \"Common printer\","
131     "       \"description\": \"Printer connected through Chrome connector\","
132     "       \"url\": \"https://www.google.com/cloudprint\","
133     "       \"type\": ["
134     "               \"printer\""
135     "       ],"
136     "       \"id\": \"\","
137     "       \"device_state\": \"idle\","
138     "       \"connection_state\": \"online\","
139     "       \"manufacturer\": \"Google\","
140     "       \"model\": \"Google Chrome\","
141     "       \"serial_number\": \"1111-22222-33333-4444\","
142     "       \"firmware\": \"24.0.1312.52\","
143     "       \"uptime\": 600,"
144     "       \"setup_url\": \"http://support.google.com/\","
145     "       \"support_url\": \"http://support.google.com/cloudprint/?hl=en\","
146     "       \"update_url\": \"http://support.google.com/cloudprint/?hl=en\","
147     "       \"x-privet-token\": \"SampleTokenForTesting\","
148     "       \"api\": ["
149     "               \"/privet/accesstoken\","
150     "               \"/privet/capabilities\","
151     "               \"/privet/printer/createjob\","
152     "               \"/privet/printer/submitdoc\","
153     "       ]"
154     "}";
155
156 const char kSampleLocalPrintResponse[] = "{"
157     "\"job_id\": \"123\","
158     "\"expires_in\": 500,"
159     "\"job_type\": \"application/pdf\","
160     "\"job_size\": 16,"
161     "\"job_name\": \"Sample job name\","
162     "}";
163
164 const char kSampleCapabilitiesResponsePWGOnly[] = "{"
165     "\"version\" : \"1.0\","
166     "\"printer\" : {"
167     "  \"supported_content_type\" : ["
168     "   { \"content_type\" : \"image/pwg-raster\" }"
169     "  ]"
170     "}"
171     "}";
172
173 const char kSampleErrorResponsePrinterBusy[] = "{"
174     "\"error\": \"invalid_print_job\","
175     "\"timeout\": 1 "
176     "}";
177
178 const char kSampleInvalidDocumentTypeResponse[] = "{"
179     "\"error\" : \"invalid_document_type\""
180     "}";
181
182 const char kSampleCreatejobResponse[] = "{ \"job_id\": \"1234\" }";
183
184 const char kSampleCapabilitiesResponseWithAnyMimetype[] = "{"
185     "\"version\" : \"1.0\","
186     "\"printer\" : {"
187     "  \"supported_content_type\" : ["
188     "   { \"content_type\" : \"*/*\" },"
189     "   { \"content_type\" : \"image/pwg-raster\" }"
190     "  ]"
191     "}"
192     "}";
193
194 const char kSampleCJT[] = "{ \"version\" : \"1.0\" }";
195
196 const char kSampleCapabilitiesResponsePWGSettings[] =
197     "{"
198     "\"version\" : \"1.0\","
199     "\"printer\" : {"
200     " \"pwg_raster_config\" : {"
201     "   \"document_sheet_back\" : \"MANUAL_TUMBLE\","
202     "   \"reverse_order_streaming\": true"
203     "  },"
204     "  \"supported_content_type\" : ["
205     "   { \"content_type\" : \"image/pwg-raster\" }"
206     "  ]"
207     "}"
208     "}";
209
210 const char kSampleCJTDuplex[] =
211     "{"
212     "\"version\" : \"1.0\","
213     "\"print\": { \"duplex\": {\"type\": \"SHORT_EDGE\"} }"
214     "}";
215 #endif  // ENABLE_PRINT_PREVIEW
216
217 // Return the representation of the given JSON that would be outputted by
218 // JSONWriter. This ensures the same JSON values are represented by the same
219 // string.
220 std::string NormalizeJson(const std::string& json) {
221   std::string result = json;
222   scoped_ptr<base::Value> value(base::JSONReader::Read(result));
223   DCHECK(value);
224   base::JSONWriter::Write(value.get(), &result);
225   return result;
226 }
227
228 class MockTestURLFetcherFactoryDelegate
229     : public net::TestURLFetcher::DelegateForTests {
230  public:
231   // Callback issued correspondingly to the call to the |Start()| method.
232   MOCK_METHOD1(OnRequestStart, void(int fetcher_id));
233
234   // Callback issued correspondingly to the call to |AppendChunkToUpload|.
235   // Uploaded chunks can be retrieved with the |upload_chunks()| getter.
236   MOCK_METHOD1(OnChunkUpload, void(int fetcher_id));
237
238   // Callback issued correspondingly to the destructor.
239   MOCK_METHOD1(OnRequestEnd, void(int fetcher_id));
240 };
241
242 class PrivetHTTPTest : public ::testing::Test {
243  public:
244   PrivetHTTPTest() {
245     PrivetURLFetcher::ResetTokenMapForTests();
246
247     request_context_= new net::TestURLRequestContextGetter(
248         base::MessageLoopProxy::current());
249     privet_client_ =
250         PrivetV1HTTPClient::CreateDefault(make_scoped_ptr<PrivetHTTPClient>(
251             new PrivetHTTPClientImpl("sampleDevice._privet._tcp.local",
252                                      net::HostPortPair("10.0.0.8", 6006),
253                                      request_context_.get())));
254     fetcher_factory_.SetDelegateForTests(&fetcher_delegate_);
255   }
256
257   virtual ~PrivetHTTPTest() {
258   }
259
260   bool SuccessfulResponseToURL(const GURL& url,
261                                const std::string& response) {
262     net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
263     EXPECT_TRUE(fetcher);
264     EXPECT_EQ(url, fetcher->GetOriginalURL());
265
266     if (!fetcher || url != fetcher->GetOriginalURL())
267       return false;
268
269     fetcher->SetResponseString(response);
270     fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
271                                               net::OK));
272     fetcher->set_response_code(200);
273     fetcher->delegate()->OnURLFetchComplete(fetcher);
274     return true;
275   }
276
277   bool SuccessfulResponseToURLAndData(const GURL& url,
278                                       const std::string& data,
279                                       const std::string& response) {
280     net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
281     EXPECT_TRUE(fetcher);
282     EXPECT_EQ(url, fetcher->GetOriginalURL());
283
284     if (!fetcher) return false;
285
286     EXPECT_EQ(data, fetcher->upload_data());
287     if (data != fetcher->upload_data()) return false;
288
289     return SuccessfulResponseToURL(url, response);
290   }
291
292   bool SuccessfulResponseToURLAndJSONData(const GURL& url,
293                                           const std::string& data,
294                                           const std::string& response) {
295     net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
296     EXPECT_TRUE(fetcher);
297     EXPECT_EQ(url, fetcher->GetOriginalURL());
298
299     if (!fetcher)
300       return false;
301
302     std::string normalized_data = NormalizeJson(data);
303     std::string normalized_upload_data = NormalizeJson(fetcher->upload_data());
304     EXPECT_EQ(normalized_data, normalized_upload_data);
305     if (normalized_data != normalized_upload_data)
306       return false;
307
308     return SuccessfulResponseToURL(url, response);
309   }
310
311   bool SuccessfulResponseToURLAndFilePath(const GURL& url,
312                                           const base::FilePath& file_path,
313                                           const std::string& response) {
314     net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
315     EXPECT_TRUE(fetcher);
316     EXPECT_EQ(url, fetcher->GetOriginalURL());
317
318     if (!fetcher) return false;
319
320     EXPECT_EQ(file_path, fetcher->upload_file_path());
321     if (file_path != fetcher->upload_file_path()) return false;
322
323     return SuccessfulResponseToURL(url, response);
324   }
325
326
327   void RunFor(base::TimeDelta time_period) {
328     base::CancelableCallback<void()> callback(base::Bind(
329         &PrivetHTTPTest::Stop, base::Unretained(this)));
330     base::MessageLoop::current()->PostDelayedTask(
331         FROM_HERE, callback.callback(), time_period);
332
333     base::MessageLoop::current()->Run();
334     callback.Cancel();
335   }
336
337   void Stop() {
338     base::MessageLoop::current()->Quit();
339   }
340
341  protected:
342   base::MessageLoop loop_;
343   scoped_refptr<net::TestURLRequestContextGetter> request_context_;
344   net::TestURLFetcherFactory fetcher_factory_;
345   scoped_ptr<PrivetV1HTTPClient> privet_client_;
346   NiceMock<MockTestURLFetcherFactoryDelegate> fetcher_delegate_;
347 };
348
349 class MockJSONCallback{
350  public:
351   MockJSONCallback() {}
352   ~MockJSONCallback() {}
353
354   void OnPrivetJSONDone(const base::DictionaryValue* value) {
355     if (!value) {
356       value_.reset();
357     } else {
358       value_.reset(value->DeepCopy());
359     }
360
361     OnPrivetJSONDoneInternal();
362   }
363
364   MOCK_METHOD0(OnPrivetJSONDoneInternal, void());
365
366   const base::DictionaryValue* value() { return value_.get(); }
367   PrivetJSONOperation::ResultCallback callback() {
368     return base::Bind(&MockJSONCallback::OnPrivetJSONDone,
369                       base::Unretained(this));
370   }
371  protected:
372   scoped_ptr<base::DictionaryValue> value_;
373 };
374
375 class MockRegisterDelegate : public PrivetRegisterOperation::Delegate {
376  public:
377   MockRegisterDelegate() {
378   }
379   ~MockRegisterDelegate() {
380   }
381
382   virtual void OnPrivetRegisterClaimToken(
383       PrivetRegisterOperation* operation,
384       const std::string& token,
385       const GURL& url) override {
386     OnPrivetRegisterClaimTokenInternal(token, url);
387   }
388
389   MOCK_METHOD2(OnPrivetRegisterClaimTokenInternal, void(
390       const std::string& token,
391       const GURL& url));
392
393   virtual void OnPrivetRegisterError(
394       PrivetRegisterOperation* operation,
395       const std::string& action,
396       PrivetRegisterOperation::FailureReason reason,
397       int printer_http_code,
398       const base::DictionaryValue* json) override {
399     // TODO(noamsml): Save and test for JSON?
400     OnPrivetRegisterErrorInternal(action, reason, printer_http_code);
401   }
402
403   MOCK_METHOD3(OnPrivetRegisterErrorInternal,
404                void(const std::string& action,
405                     PrivetRegisterOperation::FailureReason reason,
406                     int printer_http_code));
407
408   virtual void OnPrivetRegisterDone(
409       PrivetRegisterOperation* operation,
410       const std::string& device_id) override {
411     OnPrivetRegisterDoneInternal(device_id);
412   }
413
414   MOCK_METHOD1(OnPrivetRegisterDoneInternal,
415                void(const std::string& device_id));
416 };
417
418 class MockLocalPrintDelegate : public PrivetLocalPrintOperation::Delegate {
419  public:
420   MockLocalPrintDelegate() {}
421   ~MockLocalPrintDelegate() {}
422
423   virtual void OnPrivetPrintingDone(
424       const PrivetLocalPrintOperation* print_operation) {
425     OnPrivetPrintingDoneInternal();
426   }
427
428   MOCK_METHOD0(OnPrivetPrintingDoneInternal, void());
429
430   virtual void OnPrivetPrintingError(
431       const PrivetLocalPrintOperation* print_operation, int http_code) {
432     OnPrivetPrintingErrorInternal(http_code);
433   }
434
435   MOCK_METHOD1(OnPrivetPrintingErrorInternal, void(int http_code));
436 };
437
438 class PrivetInfoTest : public PrivetHTTPTest {
439  public:
440   PrivetInfoTest() {}
441
442   virtual ~PrivetInfoTest() {}
443
444   virtual void SetUp() override {
445     info_operation_ = privet_client_->CreateInfoOperation(
446         info_callback_.callback());
447   }
448
449  protected:
450   scoped_ptr<PrivetJSONOperation> info_operation_;
451   StrictMock<MockJSONCallback> info_callback_;
452 };
453
454 TEST_F(PrivetInfoTest, SuccessfulInfo) {
455   info_operation_->Start();
456
457   net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
458   ASSERT_TRUE(fetcher != NULL);
459   EXPECT_EQ(GURL("http://10.0.0.8:6006/privet/info"),
460             fetcher->GetOriginalURL());
461
462   fetcher->SetResponseString(kSampleInfoResponse);
463   fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
464                                             net::OK));
465   fetcher->set_response_code(200);
466
467   EXPECT_CALL(info_callback_, OnPrivetJSONDoneInternal());
468   fetcher->delegate()->OnURLFetchComplete(fetcher);
469 }
470
471 TEST_F(PrivetInfoTest, InfoFailureHTTP) {
472   info_operation_->Start();
473
474   net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
475   ASSERT_TRUE(fetcher != NULL);
476   fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
477                                             net::OK));
478   fetcher->set_response_code(404);
479
480   EXPECT_CALL(info_callback_, OnPrivetJSONDoneInternal());
481   fetcher->delegate()->OnURLFetchComplete(fetcher);
482 }
483
484 class PrivetRegisterTest : public PrivetHTTPTest {
485  public:
486   PrivetRegisterTest() {
487   }
488   virtual ~PrivetRegisterTest() {
489   }
490
491   virtual void SetUp() override {
492     info_operation_ = privet_client_->CreateInfoOperation(
493         info_callback_.callback());
494     register_operation_ =
495         privet_client_->CreateRegisterOperation("example@google.com",
496                                                 &register_delegate_);
497   }
498
499  protected:
500   bool SuccessfulResponseToURL(const GURL& url,
501                                const std::string& response) {
502     net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
503     EXPECT_TRUE(fetcher);
504     EXPECT_EQ(url, fetcher->GetOriginalURL());
505     if (!fetcher || url != fetcher->GetOriginalURL())
506       return false;
507
508     fetcher->SetResponseString(response);
509     fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
510                                               net::OK));
511     fetcher->set_response_code(200);
512     fetcher->delegate()->OnURLFetchComplete(fetcher);
513     return true;
514   }
515
516   scoped_ptr<PrivetJSONOperation> info_operation_;
517   NiceMock<MockJSONCallback> info_callback_;
518   scoped_ptr<PrivetRegisterOperation> register_operation_;
519   StrictMock<MockRegisterDelegate> register_delegate_;
520 };
521
522 TEST_F(PrivetRegisterTest, RegisterSuccessSimple) {
523   register_operation_->Start();
524
525   EXPECT_TRUE(SuccessfulResponseToURL(
526       GURL("http://10.0.0.8:6006/privet/info"),
527       kSampleInfoResponse));
528
529   EXPECT_TRUE(SuccessfulResponseToURL(
530       GURL("http://10.0.0.8:6006/privet/register?"
531            "action=start&user=example%40google.com"),
532       kSampleRegisterStartResponse));
533
534   EXPECT_CALL(register_delegate_, OnPrivetRegisterClaimTokenInternal(
535       "MySampleToken",
536       GURL("https://domain.com/SoMeUrL")));
537
538   EXPECT_TRUE(SuccessfulResponseToURL(
539       GURL("http://10.0.0.8:6006/privet/register?"
540            "action=getClaimToken&user=example%40google.com"),
541       kSampleRegisterGetClaimTokenResponse));
542
543   register_operation_->CompleteRegistration();
544
545   EXPECT_TRUE(SuccessfulResponseToURL(
546       GURL("http://10.0.0.8:6006/privet/register?"
547            "action=complete&user=example%40google.com"),
548       kSampleRegisterCompleteResponse));
549
550   EXPECT_CALL(register_delegate_, OnPrivetRegisterDoneInternal(
551       "MyDeviceID"));
552
553   EXPECT_TRUE(SuccessfulResponseToURL(
554       GURL("http://10.0.0.8:6006/privet/info"),
555       kSampleInfoResponseRegistered));
556 }
557
558 TEST_F(PrivetRegisterTest, RegisterXSRFFailure) {
559   register_operation_->Start();
560
561   EXPECT_TRUE(SuccessfulResponseToURL(
562       GURL("http://10.0.0.8:6006/privet/info"),
563       kSampleInfoResponse));
564
565   EXPECT_TRUE(SuccessfulResponseToURL(
566       GURL("http://10.0.0.8:6006/privet/register?"
567            "action=start&user=example%40google.com"),
568       kSampleRegisterStartResponse));
569
570   EXPECT_TRUE(SuccessfulResponseToURL(
571       GURL("http://10.0.0.8:6006/privet/register?"
572            "action=getClaimToken&user=example%40google.com"),
573       kSampleXPrivetErrorResponse));
574
575   EXPECT_TRUE(SuccessfulResponseToURL(
576       GURL("http://10.0.0.8:6006/privet/info"),
577       kSampleInfoResponse));
578
579   EXPECT_CALL(register_delegate_, OnPrivetRegisterClaimTokenInternal(
580       "MySampleToken", GURL("https://domain.com/SoMeUrL")));
581
582   EXPECT_TRUE(SuccessfulResponseToURL(
583       GURL("http://10.0.0.8:6006/privet/register?"
584            "action=getClaimToken&user=example%40google.com"),
585       kSampleRegisterGetClaimTokenResponse));
586 }
587
588 TEST_F(PrivetRegisterTest, TransientFailure) {
589   register_operation_->Start();
590
591   EXPECT_TRUE(SuccessfulResponseToURL(
592       GURL("http://10.0.0.8:6006/privet/info"),
593       kSampleInfoResponse));
594
595   EXPECT_TRUE(SuccessfulResponseToURL(
596       GURL("http://10.0.0.8:6006/privet/register?"
597            "action=start&user=example%40google.com"),
598       kSampleRegisterErrorTransient));
599
600   EXPECT_CALL(fetcher_delegate_, OnRequestStart(0));
601
602   RunFor(base::TimeDelta::FromSeconds(2));
603
604   testing::Mock::VerifyAndClearExpectations(&fetcher_delegate_);
605
606   EXPECT_TRUE(SuccessfulResponseToURL(
607       GURL("http://10.0.0.8:6006/privet/register?"
608            "action=start&user=example%40google.com"),
609       kSampleRegisterStartResponse));
610 }
611
612 TEST_F(PrivetRegisterTest, PermanentFailure) {
613   register_operation_->Start();
614
615   EXPECT_TRUE(SuccessfulResponseToURL(
616       GURL("http://10.0.0.8:6006/privet/info"),
617       kSampleInfoResponse));
618
619   EXPECT_TRUE(SuccessfulResponseToURL(
620       GURL("http://10.0.0.8:6006/privet/register?"
621            "action=start&user=example%40google.com"),
622       kSampleRegisterStartResponse));
623
624   EXPECT_CALL(register_delegate_,
625               OnPrivetRegisterErrorInternal(
626                   "getClaimToken",
627                   PrivetRegisterOperation::FAILURE_JSON_ERROR,
628                   200));
629
630   EXPECT_TRUE(SuccessfulResponseToURL(
631       GURL("http://10.0.0.8:6006/privet/register?"
632            "action=getClaimToken&user=example%40google.com"),
633       kSampleRegisterErrorPermanent));
634 }
635
636 TEST_F(PrivetRegisterTest, InfoFailure) {
637   register_operation_->Start();
638
639   EXPECT_CALL(register_delegate_,
640               OnPrivetRegisterErrorInternal(
641                   "start",
642                   PrivetRegisterOperation::FAILURE_TOKEN,
643                   -1));
644
645   EXPECT_TRUE(SuccessfulResponseToURL(
646       GURL("http://10.0.0.8:6006/privet/info"),
647       kSampleInfoResponseBadJson));
648 }
649
650 TEST_F(PrivetRegisterTest, RegisterCancel) {
651   register_operation_->Start();
652
653   EXPECT_TRUE(SuccessfulResponseToURL(
654       GURL("http://10.0.0.8:6006/privet/info"),
655       kSampleInfoResponse));
656
657   EXPECT_TRUE(SuccessfulResponseToURL(
658       GURL("http://10.0.0.8:6006/privet/register?"
659            "action=start&user=example%40google.com"),
660       kSampleRegisterStartResponse));
661
662   register_operation_->Cancel();
663
664   EXPECT_TRUE(SuccessfulResponseToURL(
665       GURL("http://10.0.0.8:6006/privet/register?"
666            "action=cancel&user=example%40google.com"),
667       kSampleRegisterCancelResponse));
668
669   // Must keep mocks alive for 3 seconds so the cancelation object can be
670   // deleted.
671   RunFor(base::TimeDelta::FromSeconds(3));
672 }
673
674 class PrivetCapabilitiesTest : public PrivetHTTPTest {
675  public:
676   PrivetCapabilitiesTest() {}
677
678   virtual ~PrivetCapabilitiesTest() {}
679
680   virtual void SetUp() override {
681     capabilities_operation_ = privet_client_->CreateCapabilitiesOperation(
682         capabilities_callback_.callback());
683   }
684
685  protected:
686   scoped_ptr<PrivetJSONOperation> capabilities_operation_;
687   StrictMock<MockJSONCallback> capabilities_callback_;
688 };
689
690 TEST_F(PrivetCapabilitiesTest, SuccessfulCapabilities) {
691   capabilities_operation_->Start();
692
693   EXPECT_TRUE(SuccessfulResponseToURL(
694       GURL("http://10.0.0.8:6006/privet/info"),
695       kSampleInfoResponse));
696
697   EXPECT_CALL(capabilities_callback_, OnPrivetJSONDoneInternal());
698
699   EXPECT_TRUE(SuccessfulResponseToURL(
700       GURL("http://10.0.0.8:6006/privet/capabilities"),
701       kSampleCapabilitiesResponse));
702
703   std::string version;
704   EXPECT_TRUE(capabilities_callback_.value()->GetString("version", &version));
705   EXPECT_EQ("1.0", version);
706 }
707
708 TEST_F(PrivetCapabilitiesTest, CacheToken) {
709   capabilities_operation_->Start();
710
711   EXPECT_TRUE(SuccessfulResponseToURL(
712       GURL("http://10.0.0.8:6006/privet/info"),
713       kSampleInfoResponse));
714
715   EXPECT_CALL(capabilities_callback_, OnPrivetJSONDoneInternal());
716
717   EXPECT_TRUE(SuccessfulResponseToURL(
718       GURL("http://10.0.0.8:6006/privet/capabilities"),
719       kSampleCapabilitiesResponse));
720
721   capabilities_operation_ = privet_client_->CreateCapabilitiesOperation(
722       capabilities_callback_.callback());
723
724   capabilities_operation_->Start();
725
726   EXPECT_CALL(capabilities_callback_, OnPrivetJSONDoneInternal());
727
728   EXPECT_TRUE(SuccessfulResponseToURL(
729       GURL("http://10.0.0.8:6006/privet/capabilities"),
730       kSampleCapabilitiesResponse));
731 }
732
733 TEST_F(PrivetCapabilitiesTest, BadToken) {
734   capabilities_operation_->Start();
735
736   EXPECT_TRUE(SuccessfulResponseToURL(
737       GURL("http://10.0.0.8:6006/privet/info"),
738       kSampleInfoResponse));
739
740   EXPECT_TRUE(SuccessfulResponseToURL(
741       GURL("http://10.0.0.8:6006/privet/capabilities"),
742       kSampleXPrivetErrorResponse));
743
744   EXPECT_TRUE(SuccessfulResponseToURL(
745       GURL("http://10.0.0.8:6006/privet/info"),
746       kSampleInfoResponse));
747
748   EXPECT_CALL(capabilities_callback_, OnPrivetJSONDoneInternal());
749
750   EXPECT_TRUE(SuccessfulResponseToURL(
751       GURL("http://10.0.0.8:6006/privet/capabilities"),
752       kSampleCapabilitiesResponse));
753 }
754
755 #if defined(ENABLE_PRINT_PREVIEW)
756 // A note on PWG raster conversion: The PWG raster converter used simply
757 // converts strings to file paths based on them by appending "test.pdf", since
758 // it's easier to test that way. Instead of using a mock, we simply check if the
759 // request is uploading a file that is based on this pattern.
760 class FakePWGRasterConverter : public PWGRasterConverter {
761  public:
762   FakePWGRasterConverter() {
763   }
764
765   ~FakePWGRasterConverter() override {}
766
767   void Start(base::RefCountedMemory* data,
768              const printing::PdfRenderSettings& conversion_settings,
769              const printing::PwgRasterSettings& bitmap_settings,
770              const ResultCallback& callback) override {
771     bitmap_settings_ = bitmap_settings;
772     std::string data_str(data->front_as<char>(), data->size());
773     callback.Run(true, base::FilePath().AppendASCII(data_str + "test.pdf"));
774   }
775
776   const printing::PwgRasterSettings& bitmap_settings() {
777     return bitmap_settings_;
778   }
779
780  private:
781   printing::PwgRasterSettings bitmap_settings_;
782 };
783
784 class PrivetLocalPrintTest : public PrivetHTTPTest {
785  public:
786   PrivetLocalPrintTest() {}
787
788   virtual ~PrivetLocalPrintTest() {}
789
790   virtual void SetUp() override {
791     PrivetURLFetcher::ResetTokenMapForTests();
792
793     local_print_operation_ = privet_client_->CreateLocalPrintOperation(
794         &local_print_delegate_);
795
796     scoped_ptr<FakePWGRasterConverter> pwg_converter(
797         new FakePWGRasterConverter);
798     pwg_converter_ = pwg_converter.get();
799     local_print_operation_->SetPWGRasterConverterForTesting(
800         pwg_converter.Pass());
801   }
802
803   scoped_refptr<base::RefCountedBytes> RefCountedBytesFromString(
804       std::string str) {
805     std::vector<unsigned char> str_vec;
806     str_vec.insert(str_vec.begin(), str.begin(), str.end());
807     return scoped_refptr<base::RefCountedBytes>(
808         base::RefCountedBytes::TakeVector(&str_vec));
809   }
810
811  protected:
812   scoped_ptr<PrivetLocalPrintOperation> local_print_operation_;
813   StrictMock<MockLocalPrintDelegate> local_print_delegate_;
814   FakePWGRasterConverter* pwg_converter_;
815 };
816
817 TEST_F(PrivetLocalPrintTest, SuccessfulLocalPrint) {
818   local_print_operation_->SetUsername("sample@gmail.com");
819   local_print_operation_->SetJobname("Sample job name");
820   local_print_operation_->SetData(RefCountedBytesFromString(
821       "Sample print data"));
822   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponse);
823   local_print_operation_->Start();
824
825   EXPECT_TRUE(SuccessfulResponseToURL(
826       GURL("http://10.0.0.8:6006/privet/info"),
827       kSampleInfoResponse));
828
829   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
830                                       kSampleInfoResponse));
831
832   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
833
834   // TODO(noamsml): Is encoding spaces as pluses standard?
835   EXPECT_TRUE(SuccessfulResponseToURLAndData(
836       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
837            "client_name=Chrome&user_name=sample%40gmail.com&"
838            "job_name=Sample+job+name"),
839       "Sample print data",
840       kSampleLocalPrintResponse));
841 }
842
843 TEST_F(PrivetLocalPrintTest, SuccessfulLocalPrintWithAnyMimetype) {
844   local_print_operation_->SetUsername("sample@gmail.com");
845   local_print_operation_->SetJobname("Sample job name");
846   local_print_operation_->SetData(
847       RefCountedBytesFromString("Sample print data"));
848   local_print_operation_->SetCapabilities(
849       kSampleCapabilitiesResponseWithAnyMimetype);
850   local_print_operation_->Start();
851
852   EXPECT_TRUE(SuccessfulResponseToURL(
853       GURL("http://10.0.0.8:6006/privet/info"),
854       kSampleInfoResponse));
855
856   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
857                                       kSampleInfoResponse));
858
859   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
860
861   // TODO(noamsml): Is encoding spaces as pluses standard?
862   EXPECT_TRUE(SuccessfulResponseToURLAndData(
863       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
864            "client_name=Chrome&user_name=sample%40gmail.com&"
865            "job_name=Sample+job+name"),
866       "Sample print data",
867       kSampleLocalPrintResponse));
868 }
869
870 TEST_F(PrivetLocalPrintTest, SuccessfulPWGLocalPrint) {
871   local_print_operation_->SetUsername("sample@gmail.com");
872   local_print_operation_->SetJobname("Sample job name");
873   local_print_operation_->SetData(
874       RefCountedBytesFromString("path/to/"));
875   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponsePWGOnly);
876   local_print_operation_->Start();
877
878   EXPECT_TRUE(SuccessfulResponseToURL(
879       GURL("http://10.0.0.8:6006/privet/info"),
880       kSampleInfoResponse));
881
882   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
883                                       kSampleInfoResponse));
884
885   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
886
887   // TODO(noamsml): Is encoding spaces as pluses standard?
888   EXPECT_TRUE(SuccessfulResponseToURLAndFilePath(
889       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
890            "client_name=Chrome&user_name=sample%40gmail.com"
891            "&job_name=Sample+job+name"),
892       base::FilePath(FILE_PATH_LITERAL("path/to/test.pdf")),
893       kSampleLocalPrintResponse));
894
895   EXPECT_EQ(printing::TRANSFORM_NORMAL,
896             pwg_converter_->bitmap_settings().odd_page_transform);
897   EXPECT_FALSE(pwg_converter_->bitmap_settings().rotate_all_pages);
898   EXPECT_FALSE(pwg_converter_->bitmap_settings().reverse_page_order);
899 }
900
901 TEST_F(PrivetLocalPrintTest, SuccessfulPWGLocalPrintDuplex) {
902   local_print_operation_->SetUsername("sample@gmail.com");
903   local_print_operation_->SetJobname("Sample job name");
904   local_print_operation_->SetData(RefCountedBytesFromString("path/to/"));
905   local_print_operation_->SetTicket(kSampleCJTDuplex);
906   local_print_operation_->SetCapabilities(
907       kSampleCapabilitiesResponsePWGSettings);
908   local_print_operation_->Start();
909
910   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
911                                       kSampleInfoResponseWithCreatejob));
912
913   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
914                                       kSampleInfoResponse));
915
916   EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
917       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
918       kSampleCJTDuplex,
919       kSampleCreatejobResponse));
920
921   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
922
923   // TODO(noamsml): Is encoding spaces as pluses standard?
924   EXPECT_TRUE(SuccessfulResponseToURLAndFilePath(
925       GURL(
926           "http://10.0.0.8:6006/privet/printer/submitdoc?"
927           "client_name=Chrome&user_name=sample%40gmail.com"
928           "&job_name=Sample+job+name&job_id=1234"),
929       base::FilePath(FILE_PATH_LITERAL("path/to/test.pdf")),
930       kSampleLocalPrintResponse));
931
932   EXPECT_EQ(printing::TRANSFORM_ROTATE_180,
933             pwg_converter_->bitmap_settings().odd_page_transform);
934   EXPECT_FALSE(pwg_converter_->bitmap_settings().rotate_all_pages);
935   EXPECT_TRUE(pwg_converter_->bitmap_settings().reverse_page_order);
936 }
937
938 TEST_F(PrivetLocalPrintTest, SuccessfulLocalPrintWithCreatejob) {
939   local_print_operation_->SetUsername("sample@gmail.com");
940   local_print_operation_->SetJobname("Sample job name");
941   local_print_operation_->SetTicket(kSampleCJT);
942   local_print_operation_->SetData(
943       RefCountedBytesFromString("Sample print data"));
944   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponse);
945   local_print_operation_->Start();
946
947   EXPECT_TRUE(SuccessfulResponseToURL(
948       GURL("http://10.0.0.8:6006/privet/info"),
949       kSampleInfoResponseWithCreatejob));
950
951   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
952                                       kSampleInfoResponse));
953
954   EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
955       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
956       kSampleCJT,
957       kSampleCreatejobResponse));
958
959   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
960
961   // TODO(noamsml): Is encoding spaces as pluses standard?
962   EXPECT_TRUE(SuccessfulResponseToURLAndData(
963       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
964            "client_name=Chrome&user_name=sample%40gmail.com&"
965            "job_name=Sample+job+name&job_id=1234"),
966       "Sample print data",
967       kSampleLocalPrintResponse));
968 }
969
970 TEST_F(PrivetLocalPrintTest, SuccessfulLocalPrintWithOverlongName) {
971   local_print_operation_->SetUsername("sample@gmail.com");
972   local_print_operation_->SetJobname(
973       "123456789:123456789:123456789:123456789:123456789:123456789:123456789:");
974   local_print_operation_->SetTicket(kSampleCJT);
975   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponse);
976   local_print_operation_->SetData(
977       RefCountedBytesFromString("Sample print data"));
978   local_print_operation_->Start();
979
980   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
981                                       kSampleInfoResponseWithCreatejob));
982
983   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
984                                       kSampleInfoResponse));
985
986   EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
987       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
988       kSampleCJT,
989       kSampleCreatejobResponse));
990
991   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
992
993   // TODO(noamsml): Is encoding spaces as pluses standard?
994   EXPECT_TRUE(SuccessfulResponseToURLAndData(
995       GURL(
996           "http://10.0.0.8:6006/privet/printer/submitdoc?"
997           "client_name=Chrome&user_name=sample%40gmail.com&"
998           "job_name=123456789%3A123456789%3A123456789%3A1...123456789"
999           "%3A123456789%3A123456789%3A&job_id=1234"),
1000       "Sample print data",
1001       kSampleLocalPrintResponse));
1002 }
1003
1004 TEST_F(PrivetLocalPrintTest, PDFPrintInvalidDocumentTypeRetry) {
1005   local_print_operation_->SetUsername("sample@gmail.com");
1006   local_print_operation_->SetJobname("Sample job name");
1007   local_print_operation_->SetTicket(kSampleCJT);
1008   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponse);
1009   local_print_operation_->SetData(
1010       RefCountedBytesFromString("sample/path/"));
1011   local_print_operation_->Start();
1012
1013   EXPECT_TRUE(SuccessfulResponseToURL(
1014       GURL("http://10.0.0.8:6006/privet/info"),
1015       kSampleInfoResponseWithCreatejob));
1016
1017   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
1018                                       kSampleInfoResponse));
1019
1020   EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
1021       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
1022       kSampleCJT,
1023       kSampleCreatejobResponse));
1024
1025   // TODO(noamsml): Is encoding spaces as pluses standard?
1026   EXPECT_TRUE(SuccessfulResponseToURLAndData(
1027       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
1028            "client_name=Chrome&user_name=sample%40gmail.com&"
1029            "job_name=Sample+job+name&job_id=1234"),
1030       "sample/path/",
1031       kSampleInvalidDocumentTypeResponse));
1032
1033   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
1034
1035   EXPECT_TRUE(SuccessfulResponseToURLAndFilePath(
1036       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
1037            "client_name=Chrome&user_name=sample%40gmail.com&"
1038            "job_name=Sample+job+name&job_id=1234"),
1039       base::FilePath(FILE_PATH_LITERAL("sample/path/test.pdf")),
1040       kSampleLocalPrintResponse));
1041 }
1042
1043 TEST_F(PrivetLocalPrintTest, LocalPrintRetryOnInvalidJobID) {
1044   local_print_operation_->SetUsername("sample@gmail.com");
1045   local_print_operation_->SetJobname("Sample job name");
1046   local_print_operation_->SetTicket(kSampleCJT);
1047   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponse);
1048   local_print_operation_->SetData(
1049       RefCountedBytesFromString("Sample print data"));
1050   local_print_operation_->Start();
1051
1052   EXPECT_TRUE(SuccessfulResponseToURL(
1053       GURL("http://10.0.0.8:6006/privet/info"),
1054       kSampleInfoResponseWithCreatejob));
1055
1056   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
1057                                       kSampleInfoResponse));
1058
1059   EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
1060       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
1061       kSampleCJT,
1062       kSampleCreatejobResponse));
1063
1064   EXPECT_TRUE(SuccessfulResponseToURLAndData(
1065       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
1066            "client_name=Chrome&user_name=sample%40gmail.com&"
1067            "job_name=Sample+job+name&job_id=1234"),
1068       "Sample print data",
1069       kSampleErrorResponsePrinterBusy));
1070
1071   RunFor(base::TimeDelta::FromSeconds(3));
1072
1073   EXPECT_TRUE(SuccessfulResponseToURL(
1074       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
1075       kSampleCreatejobResponse));
1076 }
1077 #endif  // ENABLE_PRINT_PREVIEW
1078
1079 }  // namespace
1080
1081 }  // namespace local_discovery