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