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