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 ®ister_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