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