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