Upstream version 7.35.139.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_.reset(new PrivetHTTPClientImpl(
246         "sampleDevice._privet._tcp.local",
247         net::HostPortPair("10.0.0.8", 6006),
248         request_context_.get()));
249     fetcher_factory_.SetDelegateForTests(&fetcher_delegate_);
250   }
251
252   virtual ~PrivetHTTPTest() {
253   }
254
255   bool SuccessfulResponseToURL(const GURL& url,
256                                const std::string& response) {
257     net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
258     EXPECT_TRUE(fetcher);
259     EXPECT_EQ(url, fetcher->GetOriginalURL());
260
261     if (!fetcher || url != fetcher->GetOriginalURL())
262       return false;
263
264     fetcher->SetResponseString(response);
265     fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
266                                               net::OK));
267     fetcher->set_response_code(200);
268     fetcher->delegate()->OnURLFetchComplete(fetcher);
269     return true;
270   }
271
272   bool SuccessfulResponseToURLAndData(const GURL& url,
273                                       const std::string& data,
274                                       const std::string& response) {
275     net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
276     EXPECT_TRUE(fetcher);
277     EXPECT_EQ(url, fetcher->GetOriginalURL());
278
279     if (!fetcher) return false;
280
281     EXPECT_EQ(data, fetcher->upload_data());
282     if (data != fetcher->upload_data()) return false;
283
284     return SuccessfulResponseToURL(url, response);
285   }
286
287   bool SuccessfulResponseToURLAndJSONData(const GURL& url,
288                                           const std::string& data,
289                                           const std::string& response) {
290     net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
291     EXPECT_TRUE(fetcher);
292     EXPECT_EQ(url, fetcher->GetOriginalURL());
293
294     if (!fetcher)
295       return false;
296
297     std::string normalized_data = NormalizeJson(data);
298     std::string normalized_upload_data = NormalizeJson(fetcher->upload_data());
299     EXPECT_EQ(normalized_data, normalized_upload_data);
300     if (normalized_data != normalized_upload_data)
301       return false;
302
303     return SuccessfulResponseToURL(url, response);
304   }
305
306   bool SuccessfulResponseToURLAndFilePath(const GURL& url,
307                                           const base::FilePath& file_path,
308                                           const std::string& response) {
309     net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
310     EXPECT_TRUE(fetcher);
311     EXPECT_EQ(url, fetcher->GetOriginalURL());
312
313     if (!fetcher) return false;
314
315     EXPECT_EQ(file_path, fetcher->upload_file_path());
316     if (file_path != fetcher->upload_file_path()) return false;
317
318     return SuccessfulResponseToURL(url, response);
319   }
320
321
322   void RunFor(base::TimeDelta time_period) {
323     base::CancelableCallback<void()> callback(base::Bind(
324         &PrivetHTTPTest::Stop, base::Unretained(this)));
325     base::MessageLoop::current()->PostDelayedTask(
326         FROM_HERE, callback.callback(), time_period);
327
328     base::MessageLoop::current()->Run();
329     callback.Cancel();
330   }
331
332   void Stop() {
333     base::MessageLoop::current()->Quit();
334   }
335
336  protected:
337   base::MessageLoop loop_;
338   scoped_refptr<net::TestURLRequestContextGetter> request_context_;
339   net::TestURLFetcherFactory fetcher_factory_;
340   scoped_ptr<PrivetHTTPClient> privet_client_;
341   NiceMock<MockTestURLFetcherFactoryDelegate> fetcher_delegate_;
342 };
343
344 class MockJSONCallback{
345  public:
346   MockJSONCallback() {}
347   ~MockJSONCallback() {}
348
349   void OnPrivetJSONDone(const base::DictionaryValue* value) {
350     if (!value) {
351       value_.reset();
352     } else {
353       value_.reset(value->DeepCopy());
354     }
355
356     OnPrivetJSONDoneInternal();
357   }
358
359   MOCK_METHOD0(OnPrivetJSONDoneInternal, void());
360
361   const base::DictionaryValue* value() { return value_.get(); }
362   PrivetJSONOperation::ResultCallback callback() {
363     return base::Bind(&MockJSONCallback::OnPrivetJSONDone,
364                       base::Unretained(this));
365   }
366  protected:
367   scoped_ptr<base::DictionaryValue> value_;
368 };
369
370 class MockRegisterDelegate : public PrivetRegisterOperation::Delegate {
371  public:
372   MockRegisterDelegate() {
373   }
374   ~MockRegisterDelegate() {
375   }
376
377   virtual void OnPrivetRegisterClaimToken(
378       PrivetRegisterOperation* operation,
379       const std::string& token,
380       const GURL& url) OVERRIDE {
381     OnPrivetRegisterClaimTokenInternal(token, url);
382   }
383
384   MOCK_METHOD2(OnPrivetRegisterClaimTokenInternal, void(
385       const std::string& token,
386       const GURL& url));
387
388   virtual void OnPrivetRegisterError(
389       PrivetRegisterOperation* operation,
390       const std::string& action,
391       PrivetRegisterOperation::FailureReason reason,
392       int printer_http_code,
393       const base::DictionaryValue* json) OVERRIDE {
394     // TODO(noamsml): Save and test for JSON?
395     OnPrivetRegisterErrorInternal(action, reason, printer_http_code);
396   }
397
398   MOCK_METHOD3(OnPrivetRegisterErrorInternal,
399                void(const std::string& action,
400                     PrivetRegisterOperation::FailureReason reason,
401                     int printer_http_code));
402
403   virtual void OnPrivetRegisterDone(
404       PrivetRegisterOperation* operation,
405       const std::string& device_id) OVERRIDE {
406     OnPrivetRegisterDoneInternal(device_id);
407   }
408
409   MOCK_METHOD1(OnPrivetRegisterDoneInternal,
410                void(const std::string& device_id));
411 };
412
413 class MockLocalPrintDelegate : public PrivetLocalPrintOperation::Delegate {
414  public:
415   MockLocalPrintDelegate() {}
416   ~MockLocalPrintDelegate() {}
417
418   virtual void OnPrivetPrintingDone(
419       const PrivetLocalPrintOperation* print_operation) {
420     OnPrivetPrintingDoneInternal();
421   }
422
423   MOCK_METHOD0(OnPrivetPrintingDoneInternal, void());
424
425   virtual void OnPrivetPrintingError(
426       const PrivetLocalPrintOperation* print_operation, int http_code) {
427     OnPrivetPrintingErrorInternal(http_code);
428   }
429
430   MOCK_METHOD1(OnPrivetPrintingErrorInternal, void(int http_code));
431 };
432
433 // A note on PWG raster conversion: The PWG raster converter used simply
434 // converts strings to file paths based on them by appending "test.pdf", since
435 // it's easier to test that way. Instead of using a mock, we simply check if the
436 // request is uploading a file that is based on this pattern.
437 class FakePWGRasterConverter : public PWGRasterConverter {
438  public:
439   FakePWGRasterConverter() {
440   }
441
442   virtual ~FakePWGRasterConverter() {
443   }
444
445   virtual void Start(base::RefCountedMemory* data,
446                      const printing::PdfRenderSettings& conversion_settings,
447                      const printing::PwgRasterSettings& bitmap_settings,
448                      const ResultCallback& callback) OVERRIDE {
449     bitmap_settings_ = bitmap_settings;
450     std::string data_str(data->front_as<char>(), data->size());
451     callback.Run(true, base::FilePath().AppendASCII(data_str + "test.pdf"));
452   }
453
454   const printing::PwgRasterSettings& bitmap_settings() {
455     return bitmap_settings_;
456   }
457
458  private:
459   printing::PwgRasterSettings bitmap_settings_;
460 };
461
462 TEST_F(PrivetHTTPTest, CreatePrivetStorageList) {
463   MockJSONCallback mock_callback;
464   scoped_ptr<PrivetJSONOperation> storage_list_operation =
465       privet_client_->CreateStorageListOperation(
466           "/path/to/nothing",
467           mock_callback.callback());
468   storage_list_operation->Start();
469
470   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
471                                       kSampleInfoResponse));
472
473   EXPECT_CALL(mock_callback, OnPrivetJSONDoneInternal());
474
475   EXPECT_TRUE(SuccessfulResponseToURL(
476       GURL("http://10.0.0.8:6006/privet/storage/list?path=/path/to/nothing"),
477       kSampleEmptyJSONResponse));
478 }
479
480 class PrivetInfoTest : public PrivetHTTPTest {
481  public:
482   PrivetInfoTest() {}
483
484   virtual ~PrivetInfoTest() {}
485
486   virtual void SetUp() OVERRIDE {
487     info_operation_ = privet_client_->CreateInfoOperation(
488         info_callback_.callback());
489   }
490
491  protected:
492   scoped_ptr<PrivetJSONOperation> info_operation_;
493   StrictMock<MockJSONCallback> info_callback_;
494 };
495
496 TEST_F(PrivetInfoTest, SuccessfulInfo) {
497   info_operation_->Start();
498
499   net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
500   ASSERT_TRUE(fetcher != NULL);
501   EXPECT_EQ(GURL("http://10.0.0.8:6006/privet/info"),
502             fetcher->GetOriginalURL());
503
504   fetcher->SetResponseString(kSampleInfoResponse);
505   fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
506                                             net::OK));
507   fetcher->set_response_code(200);
508
509   EXPECT_CALL(info_callback_, OnPrivetJSONDoneInternal());
510   fetcher->delegate()->OnURLFetchComplete(fetcher);
511 };
512
513 TEST_F(PrivetInfoTest, InfoFailureHTTP) {
514   info_operation_->Start();
515
516   net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
517   ASSERT_TRUE(fetcher != NULL);
518   fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
519                                             net::OK));
520   fetcher->set_response_code(404);
521
522   EXPECT_CALL(info_callback_, OnPrivetJSONDoneInternal());
523   fetcher->delegate()->OnURLFetchComplete(fetcher);
524 };
525
526 class PrivetRegisterTest : public PrivetHTTPTest {
527  public:
528   PrivetRegisterTest() {
529   }
530   virtual ~PrivetRegisterTest() {
531   }
532
533   virtual void SetUp() OVERRIDE {
534     info_operation_ = privet_client_->CreateInfoOperation(
535         info_callback_.callback());
536     register_operation_ =
537         privet_client_->CreateRegisterOperation("example@google.com",
538                                                 &register_delegate_);
539   }
540
541  protected:
542   bool SuccessfulResponseToURL(const GURL& url,
543                                const std::string& response) {
544     net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0);
545     EXPECT_TRUE(fetcher);
546     EXPECT_EQ(url, fetcher->GetOriginalURL());
547     if (!fetcher || url != fetcher->GetOriginalURL())
548       return false;
549
550     fetcher->SetResponseString(response);
551     fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::SUCCESS,
552                                               net::OK));
553     fetcher->set_response_code(200);
554     fetcher->delegate()->OnURLFetchComplete(fetcher);
555     return true;
556   }
557
558   scoped_ptr<PrivetJSONOperation> info_operation_;
559   NiceMock<MockJSONCallback> info_callback_;
560   scoped_ptr<PrivetRegisterOperation> register_operation_;
561   StrictMock<MockRegisterDelegate> register_delegate_;
562 };
563
564 TEST_F(PrivetRegisterTest, RegisterSuccessSimple) {
565   register_operation_->Start();
566
567   EXPECT_TRUE(SuccessfulResponseToURL(
568       GURL("http://10.0.0.8:6006/privet/info"),
569       kSampleInfoResponse));
570
571   EXPECT_TRUE(SuccessfulResponseToURL(
572       GURL("http://10.0.0.8:6006/privet/register?"
573            "action=start&user=example%40google.com"),
574       kSampleRegisterStartResponse));
575
576   EXPECT_CALL(register_delegate_, OnPrivetRegisterClaimTokenInternal(
577       "MySampleToken",
578       GURL("https://domain.com/SoMeUrL")));
579
580   EXPECT_TRUE(SuccessfulResponseToURL(
581       GURL("http://10.0.0.8:6006/privet/register?"
582            "action=getClaimToken&user=example%40google.com"),
583       kSampleRegisterGetClaimTokenResponse));
584
585   register_operation_->CompleteRegistration();
586
587   EXPECT_TRUE(SuccessfulResponseToURL(
588       GURL("http://10.0.0.8:6006/privet/register?"
589            "action=complete&user=example%40google.com"),
590       kSampleRegisterCompleteResponse));
591
592   EXPECT_CALL(register_delegate_, OnPrivetRegisterDoneInternal(
593       "MyDeviceID"));
594
595   EXPECT_TRUE(SuccessfulResponseToURL(
596       GURL("http://10.0.0.8:6006/privet/info"),
597       kSampleInfoResponseRegistered));
598 }
599
600 TEST_F(PrivetRegisterTest, RegisterXSRFFailure) {
601   register_operation_->Start();
602
603   EXPECT_TRUE(SuccessfulResponseToURL(
604       GURL("http://10.0.0.8:6006/privet/info"),
605       kSampleInfoResponse));
606
607   EXPECT_TRUE(SuccessfulResponseToURL(
608       GURL("http://10.0.0.8:6006/privet/register?"
609            "action=start&user=example%40google.com"),
610       kSampleRegisterStartResponse));
611
612   EXPECT_TRUE(SuccessfulResponseToURL(
613       GURL("http://10.0.0.8:6006/privet/register?"
614            "action=getClaimToken&user=example%40google.com"),
615       kSampleXPrivetErrorResponse));
616
617   EXPECT_TRUE(SuccessfulResponseToURL(
618       GURL("http://10.0.0.8:6006/privet/info"),
619       kSampleInfoResponse));
620
621   EXPECT_CALL(register_delegate_, OnPrivetRegisterClaimTokenInternal(
622       "MySampleToken", GURL("https://domain.com/SoMeUrL")));
623
624   EXPECT_TRUE(SuccessfulResponseToURL(
625       GURL("http://10.0.0.8:6006/privet/register?"
626            "action=getClaimToken&user=example%40google.com"),
627       kSampleRegisterGetClaimTokenResponse));
628 }
629
630 TEST_F(PrivetRegisterTest, TransientFailure) {
631   register_operation_->Start();
632
633   EXPECT_TRUE(SuccessfulResponseToURL(
634       GURL("http://10.0.0.8:6006/privet/info"),
635       kSampleInfoResponse));
636
637   EXPECT_TRUE(SuccessfulResponseToURL(
638       GURL("http://10.0.0.8:6006/privet/register?"
639            "action=start&user=example%40google.com"),
640       kSampleRegisterErrorTransient));
641
642   EXPECT_CALL(fetcher_delegate_, OnRequestStart(0));
643
644   RunFor(base::TimeDelta::FromSeconds(2));
645
646   testing::Mock::VerifyAndClearExpectations(&fetcher_delegate_);
647
648   EXPECT_TRUE(SuccessfulResponseToURL(
649       GURL("http://10.0.0.8:6006/privet/register?"
650            "action=start&user=example%40google.com"),
651       kSampleRegisterStartResponse));
652 }
653
654 TEST_F(PrivetRegisterTest, PermanentFailure) {
655   register_operation_->Start();
656
657   EXPECT_TRUE(SuccessfulResponseToURL(
658       GURL("http://10.0.0.8:6006/privet/info"),
659       kSampleInfoResponse));
660
661   EXPECT_TRUE(SuccessfulResponseToURL(
662       GURL("http://10.0.0.8:6006/privet/register?"
663            "action=start&user=example%40google.com"),
664       kSampleRegisterStartResponse));
665
666   EXPECT_CALL(register_delegate_,
667               OnPrivetRegisterErrorInternal(
668                   "getClaimToken",
669                   PrivetRegisterOperation::FAILURE_JSON_ERROR,
670                   200));
671
672   EXPECT_TRUE(SuccessfulResponseToURL(
673       GURL("http://10.0.0.8:6006/privet/register?"
674            "action=getClaimToken&user=example%40google.com"),
675       kSampleRegisterErrorPermanent));
676 }
677
678 TEST_F(PrivetRegisterTest, InfoFailure) {
679   register_operation_->Start();
680
681   EXPECT_CALL(register_delegate_,
682               OnPrivetRegisterErrorInternal(
683                   "start",
684                   PrivetRegisterOperation::FAILURE_TOKEN,
685                   -1));
686
687   EXPECT_TRUE(SuccessfulResponseToURL(
688       GURL("http://10.0.0.8:6006/privet/info"),
689       kSampleInfoResponseBadJson));
690 }
691
692 TEST_F(PrivetRegisterTest, RegisterCancel) {
693   register_operation_->Start();
694
695   EXPECT_TRUE(SuccessfulResponseToURL(
696       GURL("http://10.0.0.8:6006/privet/info"),
697       kSampleInfoResponse));
698
699   EXPECT_TRUE(SuccessfulResponseToURL(
700       GURL("http://10.0.0.8:6006/privet/register?"
701            "action=start&user=example%40google.com"),
702       kSampleRegisterStartResponse));
703
704   register_operation_->Cancel();
705
706   EXPECT_TRUE(SuccessfulResponseToURL(
707       GURL("http://10.0.0.8:6006/privet/register?"
708            "action=cancel&user=example%40google.com"),
709       kSampleRegisterCancelResponse));
710
711   // Must keep mocks alive for 3 seconds so the cancelation object can be
712   // deleted.
713   RunFor(base::TimeDelta::FromSeconds(3));
714 }
715
716 class PrivetCapabilitiesTest : public PrivetHTTPTest {
717  public:
718   PrivetCapabilitiesTest() {}
719
720   virtual ~PrivetCapabilitiesTest() {}
721
722   virtual void SetUp() OVERRIDE {
723     capabilities_operation_ = privet_client_->CreateCapabilitiesOperation(
724         capabilities_callback_.callback());
725   }
726
727  protected:
728   scoped_ptr<PrivetJSONOperation> capabilities_operation_;
729   StrictMock<MockJSONCallback> capabilities_callback_;
730 };
731
732 TEST_F(PrivetCapabilitiesTest, SuccessfulCapabilities) {
733   capabilities_operation_->Start();
734
735   EXPECT_TRUE(SuccessfulResponseToURL(
736       GURL("http://10.0.0.8:6006/privet/info"),
737       kSampleInfoResponse));
738
739   EXPECT_CALL(capabilities_callback_, OnPrivetJSONDoneInternal());
740
741   EXPECT_TRUE(SuccessfulResponseToURL(
742       GURL("http://10.0.0.8:6006/privet/capabilities"),
743       kSampleCapabilitiesResponse));
744
745   std::string version;
746   EXPECT_TRUE(capabilities_callback_.value()->GetString("version", &version));
747   EXPECT_EQ("1.0", version);
748 };
749
750 TEST_F(PrivetCapabilitiesTest, CacheToken) {
751   capabilities_operation_->Start();
752
753   EXPECT_TRUE(SuccessfulResponseToURL(
754       GURL("http://10.0.0.8:6006/privet/info"),
755       kSampleInfoResponse));
756
757   EXPECT_CALL(capabilities_callback_, OnPrivetJSONDoneInternal());
758
759   EXPECT_TRUE(SuccessfulResponseToURL(
760       GURL("http://10.0.0.8:6006/privet/capabilities"),
761       kSampleCapabilitiesResponse));
762
763   capabilities_operation_ = privet_client_->CreateCapabilitiesOperation(
764       capabilities_callback_.callback());
765
766   capabilities_operation_->Start();
767
768   EXPECT_CALL(capabilities_callback_, OnPrivetJSONDoneInternal());
769
770   EXPECT_TRUE(SuccessfulResponseToURL(
771       GURL("http://10.0.0.8:6006/privet/capabilities"),
772       kSampleCapabilitiesResponse));
773 };
774
775 TEST_F(PrivetCapabilitiesTest, BadToken) {
776   capabilities_operation_->Start();
777
778   EXPECT_TRUE(SuccessfulResponseToURL(
779       GURL("http://10.0.0.8:6006/privet/info"),
780       kSampleInfoResponse));
781
782   EXPECT_TRUE(SuccessfulResponseToURL(
783       GURL("http://10.0.0.8:6006/privet/capabilities"),
784       kSampleXPrivetErrorResponse));
785
786   EXPECT_TRUE(SuccessfulResponseToURL(
787       GURL("http://10.0.0.8:6006/privet/info"),
788       kSampleInfoResponse));
789
790   EXPECT_CALL(capabilities_callback_, OnPrivetJSONDoneInternal());
791
792   EXPECT_TRUE(SuccessfulResponseToURL(
793       GURL("http://10.0.0.8:6006/privet/capabilities"),
794       kSampleCapabilitiesResponse));
795 };
796
797 class PrivetLocalPrintTest : public PrivetHTTPTest {
798  public:
799   PrivetLocalPrintTest() {}
800
801   virtual ~PrivetLocalPrintTest() {}
802
803   virtual void SetUp() OVERRIDE {
804     PrivetURLFetcher::ResetTokenMapForTests();
805
806     local_print_operation_ = privet_client_->CreateLocalPrintOperation(
807         &local_print_delegate_);
808
809     scoped_ptr<FakePWGRasterConverter> pwg_converter(
810         new FakePWGRasterConverter);
811     pwg_converter_ = pwg_converter.get();
812     local_print_operation_->SetPWGRasterConverterForTesting(
813         pwg_converter.PassAs<PWGRasterConverter>());
814   }
815
816   scoped_refptr<base::RefCountedBytes> RefCountedBytesFromString(
817       std::string str) {
818     std::vector<unsigned char> str_vec;
819     str_vec.insert(str_vec.begin(), str.begin(), str.end());
820     return scoped_refptr<base::RefCountedBytes>(
821         base::RefCountedBytes::TakeVector(&str_vec));
822   }
823
824  protected:
825   scoped_ptr<PrivetLocalPrintOperation> local_print_operation_;
826   StrictMock<MockLocalPrintDelegate> local_print_delegate_;
827   FakePWGRasterConverter* pwg_converter_;
828 };
829
830 TEST_F(PrivetLocalPrintTest, SuccessfulLocalPrint) {
831   local_print_operation_->SetUsername("sample@gmail.com");
832   local_print_operation_->SetJobname("Sample job name");
833   local_print_operation_->SetData(RefCountedBytesFromString(
834       "Sample print data"));
835   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponse);
836   local_print_operation_->Start();
837
838   EXPECT_TRUE(SuccessfulResponseToURL(
839       GURL("http://10.0.0.8:6006/privet/info"),
840       kSampleInfoResponse));
841
842   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
843                                       kSampleInfoResponse));
844
845   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
846
847   // TODO(noamsml): Is encoding spaces as pluses standard?
848   EXPECT_TRUE(SuccessfulResponseToURLAndData(
849       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
850            "client_name=Chrome&user_name=sample%40gmail.com&"
851            "job_name=Sample+job+name"),
852       "Sample print data",
853       kSampleLocalPrintResponse));
854 };
855
856 TEST_F(PrivetLocalPrintTest, SuccessfulLocalPrintWithAnyMimetype) {
857   local_print_operation_->SetUsername("sample@gmail.com");
858   local_print_operation_->SetJobname("Sample job name");
859   local_print_operation_->SetData(
860       RefCountedBytesFromString("Sample print data"));
861   local_print_operation_->SetCapabilities(
862       kSampleCapabilitiesResponseWithAnyMimetype);
863   local_print_operation_->Start();
864
865   EXPECT_TRUE(SuccessfulResponseToURL(
866       GURL("http://10.0.0.8:6006/privet/info"),
867       kSampleInfoResponse));
868
869   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
870                                       kSampleInfoResponse));
871
872   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
873
874   // TODO(noamsml): Is encoding spaces as pluses standard?
875   EXPECT_TRUE(SuccessfulResponseToURLAndData(
876       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
877            "client_name=Chrome&user_name=sample%40gmail.com&"
878            "job_name=Sample+job+name"),
879       "Sample print data",
880       kSampleLocalPrintResponse));
881 };
882
883 TEST_F(PrivetLocalPrintTest, SuccessfulPWGLocalPrint) {
884   local_print_operation_->SetUsername("sample@gmail.com");
885   local_print_operation_->SetJobname("Sample job name");
886   local_print_operation_->SetData(
887       RefCountedBytesFromString("path/to/"));
888   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponsePWGOnly);
889   local_print_operation_->Start();
890
891   EXPECT_TRUE(SuccessfulResponseToURL(
892       GURL("http://10.0.0.8:6006/privet/info"),
893       kSampleInfoResponse));
894
895   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
896                                       kSampleInfoResponse));
897
898   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
899
900   // TODO(noamsml): Is encoding spaces as pluses standard?
901   EXPECT_TRUE(SuccessfulResponseToURLAndFilePath(
902       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
903            "client_name=Chrome&user_name=sample%40gmail.com"
904            "&job_name=Sample+job+name"),
905       base::FilePath(FILE_PATH_LITERAL("path/to/test.pdf")),
906       kSampleLocalPrintResponse));
907
908   EXPECT_EQ(printing::TRANSFORM_NORMAL,
909             pwg_converter_->bitmap_settings().odd_page_transform);
910   EXPECT_FALSE(pwg_converter_->bitmap_settings().rotate_all_pages);
911   EXPECT_FALSE(pwg_converter_->bitmap_settings().reverse_page_order);
912 };
913
914 TEST_F(PrivetLocalPrintTest, SuccessfulPWGLocalPrintDuplex) {
915   local_print_operation_->SetUsername("sample@gmail.com");
916   local_print_operation_->SetJobname("Sample job name");
917   local_print_operation_->SetData(RefCountedBytesFromString("path/to/"));
918   local_print_operation_->SetTicket(kSampleCJTDuplex);
919   local_print_operation_->SetCapabilities(
920       kSampleCapabilitiesResponsePWGSettings);
921   local_print_operation_->Start();
922
923   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
924                                       kSampleInfoResponseWithCreatejob));
925
926   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
927                                       kSampleInfoResponse));
928
929   EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
930       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
931       kSampleCJTDuplex,
932       kSampleCreatejobResponse));
933
934   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
935
936   // TODO(noamsml): Is encoding spaces as pluses standard?
937   EXPECT_TRUE(SuccessfulResponseToURLAndFilePath(
938       GURL(
939           "http://10.0.0.8:6006/privet/printer/submitdoc?"
940           "client_name=Chrome&user_name=sample%40gmail.com"
941           "&job_name=Sample+job+name&job_id=1234"),
942       base::FilePath(FILE_PATH_LITERAL("path/to/test.pdf")),
943       kSampleLocalPrintResponse));
944
945   EXPECT_EQ(printing::TRANSFORM_ROTATE_180,
946             pwg_converter_->bitmap_settings().odd_page_transform);
947   EXPECT_FALSE(pwg_converter_->bitmap_settings().rotate_all_pages);
948   EXPECT_TRUE(pwg_converter_->bitmap_settings().reverse_page_order);
949 };
950
951 TEST_F(PrivetLocalPrintTest, SuccessfulLocalPrintWithCreatejob) {
952   local_print_operation_->SetUsername("sample@gmail.com");
953   local_print_operation_->SetJobname("Sample job name");
954   local_print_operation_->SetTicket(kSampleCJT);
955   local_print_operation_->SetData(
956       RefCountedBytesFromString("Sample print data"));
957   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponse);
958   local_print_operation_->Start();
959
960   EXPECT_TRUE(SuccessfulResponseToURL(
961       GURL("http://10.0.0.8:6006/privet/info"),
962       kSampleInfoResponseWithCreatejob));
963
964   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
965                                       kSampleInfoResponse));
966
967   EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
968       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
969       kSampleCJT,
970       kSampleCreatejobResponse));
971
972   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
973
974   // TODO(noamsml): Is encoding spaces as pluses standard?
975   EXPECT_TRUE(SuccessfulResponseToURLAndData(
976       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
977            "client_name=Chrome&user_name=sample%40gmail.com&"
978            "job_name=Sample+job+name&job_id=1234"),
979       "Sample print data",
980       kSampleLocalPrintResponse));
981 };
982
983 TEST_F(PrivetLocalPrintTest, SuccessfulLocalPrintWithOverlongName) {
984   local_print_operation_->SetUsername("sample@gmail.com");
985   local_print_operation_->SetJobname(
986       "123456789:123456789:123456789:123456789:123456789:123456789:123456789:");
987   local_print_operation_->SetTicket(kSampleCJT);
988   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponse);
989   local_print_operation_->SetData(
990       RefCountedBytesFromString("Sample print data"));
991   local_print_operation_->Start();
992
993   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
994                                       kSampleInfoResponseWithCreatejob));
995
996   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
997                                       kSampleInfoResponse));
998
999   EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
1000       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
1001       kSampleCJT,
1002       kSampleCreatejobResponse));
1003
1004   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
1005
1006   // TODO(noamsml): Is encoding spaces as pluses standard?
1007   EXPECT_TRUE(SuccessfulResponseToURLAndData(
1008       GURL(
1009           "http://10.0.0.8:6006/privet/printer/submitdoc?"
1010           "client_name=Chrome&user_name=sample%40gmail.com&"
1011           "job_name=123456789%3A123456789%3A123456789%3A1...123456789"
1012           "%3A123456789%3A123456789%3A&job_id=1234"),
1013       "Sample print data",
1014       kSampleLocalPrintResponse));
1015 };
1016
1017 TEST_F(PrivetLocalPrintTest, PDFPrintInvalidDocumentTypeRetry) {
1018   local_print_operation_->SetUsername("sample@gmail.com");
1019   local_print_operation_->SetJobname("Sample job name");
1020   local_print_operation_->SetTicket(kSampleCJT);
1021   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponse);
1022   local_print_operation_->SetData(
1023       RefCountedBytesFromString("sample/path/"));
1024   local_print_operation_->Start();
1025
1026   EXPECT_TRUE(SuccessfulResponseToURL(
1027       GURL("http://10.0.0.8:6006/privet/info"),
1028       kSampleInfoResponseWithCreatejob));
1029
1030   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
1031                                       kSampleInfoResponse));
1032
1033   EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
1034       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
1035       kSampleCJT,
1036       kSampleCreatejobResponse));
1037
1038   // TODO(noamsml): Is encoding spaces as pluses standard?
1039   EXPECT_TRUE(SuccessfulResponseToURLAndData(
1040       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
1041            "client_name=Chrome&user_name=sample%40gmail.com&"
1042            "job_name=Sample+job+name&job_id=1234"),
1043       "sample/path/",
1044       kSampleInvalidDocumentTypeResponse));
1045
1046   EXPECT_CALL(local_print_delegate_, OnPrivetPrintingDoneInternal());
1047
1048   EXPECT_TRUE(SuccessfulResponseToURLAndFilePath(
1049       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
1050            "client_name=Chrome&user_name=sample%40gmail.com&"
1051            "job_name=Sample+job+name&job_id=1234"),
1052       base::FilePath(FILE_PATH_LITERAL("sample/path/test.pdf")),
1053       kSampleLocalPrintResponse));
1054 };
1055
1056 TEST_F(PrivetLocalPrintTest, LocalPrintRetryOnInvalidJobID) {
1057   local_print_operation_->SetUsername("sample@gmail.com");
1058   local_print_operation_->SetJobname("Sample job name");
1059   local_print_operation_->SetTicket(kSampleCJT);
1060   local_print_operation_->SetCapabilities(kSampleCapabilitiesResponse);
1061   local_print_operation_->SetData(
1062       RefCountedBytesFromString("Sample print data"));
1063   local_print_operation_->Start();
1064
1065   EXPECT_TRUE(SuccessfulResponseToURL(
1066       GURL("http://10.0.0.8:6006/privet/info"),
1067       kSampleInfoResponseWithCreatejob));
1068
1069   EXPECT_TRUE(SuccessfulResponseToURL(GURL("http://10.0.0.8:6006/privet/info"),
1070                                       kSampleInfoResponse));
1071
1072   EXPECT_TRUE(SuccessfulResponseToURLAndJSONData(
1073       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
1074       kSampleCJT,
1075       kSampleCreatejobResponse));
1076
1077   EXPECT_TRUE(SuccessfulResponseToURLAndData(
1078       GURL("http://10.0.0.8:6006/privet/printer/submitdoc?"
1079            "client_name=Chrome&user_name=sample%40gmail.com&"
1080            "job_name=Sample+job+name&job_id=1234"),
1081       "Sample print data",
1082       kSampleErrorResponsePrinterBusy));
1083
1084   RunFor(base::TimeDelta::FromSeconds(3));
1085
1086   EXPECT_TRUE(SuccessfulResponseToURL(
1087       GURL("http://10.0.0.8:6006/privet/printer/createjob"),
1088       kSampleCreatejobResponse));
1089 };
1090
1091
1092 }  // namespace
1093
1094 }  // namespace local_discovery