Index: chrome/service/cloud_print/printer_job_handler_unittest.cc |
diff --git a/chrome/service/cloud_print/printer_job_handler_unittest.cc b/chrome/service/cloud_print/printer_job_handler_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ebb22032f899bad506bb25f0e868495d96a05d3c |
--- /dev/null |
+++ b/chrome/service/cloud_print/printer_job_handler_unittest.cc |
@@ -0,0 +1,438 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/file_path.h" |
+#include "base/md5.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/message_loop.h" |
+#include "base/message_loop_proxy.h" |
+#include "base/stringprintf.h" |
+#include "chrome/common/cloud_print/cloud_print_constants.h" |
+#include "chrome/service/cloud_print/cloud_print_helpers.h" |
+#include "chrome/service/cloud_print/cloud_print_token_store.h" |
+#include "chrome/service/cloud_print/print_system.h" |
+#include "chrome/service/cloud_print/printer_job_handler.h" |
+#include "chrome/service/cloud_print/printer_job_handler_unittest_constants.h" |
+#include "net/http/http_response_headers.h" |
+#include "net/url_request/test_url_fetcher_factory.h" |
+#include "net/url_request/url_request_test_util.h" |
+#include "printing/backend/print_backend.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using ::testing::AtLeast; |
+using ::testing::Exactly; |
+using ::testing::Sequence; |
+using ::testing::Return; |
+using ::testing::SaveArg; |
+using ::testing::DoAll; |
+using ::testing::_; |
+using ::testing::NiceMock; |
+using ::testing::StrictMock; |
+using ::testing::Invoke; |
+using ::testing::SetArgPointee; |
+using ::testing::InvokeWithoutArgs; |
+ |
+namespace cloud_print { |
+ |
+class CloudPrintURLFetcherNoServiceProcess |
+ : public CloudPrintURLFetcher { |
+ protected: |
+ net::URLRequestContextGetter* GetRequestContextGetter() { |
+ return new net::TestURLRequestContextGetter( |
+ base::MessageLoopProxy::current()); |
+ } |
+}; |
+ |
+ |
+class CloudPrintURLFetcherNoServiceProcessFactory |
+ : public CloudPrintURLFetcherFactory { |
+ public: |
+ CloudPrintURLFetcher* CreateCloudPrintURLFetcher() { |
+ return new CloudPrintURLFetcherNoServiceProcess; |
+ } |
+}; |
+ |
+ |
+// This class handles the callback from FakeURLFetcher |
+// It is a separate class because callback methods must be |
+// on RefCounted classes |
+ |
+class TestURLFetcherCallback |
+ : public base::RefCounted<TestURLFetcherCallback> { |
+ public: |
+ net::FakeURLFetcher* CreateURLFetcher( |
+ const GURL& url, |
+ net::URLFetcherDelegate* d, |
+ const std::string& response_data, bool success) { |
+ net::FakeURLFetcher* fetcher = |
+ new net::FakeURLFetcher(url, d, response_data, success); |
+ OnRequestCreate(url, fetcher); |
+ return fetcher; |
+ } |
+ MOCK_METHOD2(OnRequestCreate, |
+ void(const GURL&, net::FakeURLFetcher*)); |
+}; |
+ |
+ |
+class MockPrinterJobHandlerDelegate |
+ : public PrinterJobHandler::Delegate { |
+ public: |
+ MOCK_METHOD0(OnAuthError, void()); |
+ MOCK_METHOD1(OnPrinterDeleted, void(const std::string& str)); |
+}; |
+ |
+ |
+class MockPrintServerWatcher |
+ : public PrintSystem::PrintServerWatcher { |
+ protected: |
+ PrintSystem::PrintServerWatcher::Delegate* delegate_; |
+ |
+ bool SetDelegate(PrintSystem::PrintServerWatcher::Delegate* d) { |
+ delegate_ = d; |
+ return true; |
+ } |
+ |
+ public: |
+ MOCK_METHOD1(StartWatching, |
+ bool(PrintSystem::PrintServerWatcher::Delegate* d)); |
+ MOCK_METHOD0(StopWatching, bool()); |
+ |
+ MockPrintServerWatcher(); |
+ PrintSystem::PrintServerWatcher::Delegate* Delegate() { |
+ return delegate_; |
+ } |
+}; |
+ |
+class MockPrinterWatcher : public PrintSystem::PrinterWatcher { |
+ protected: |
+ PrintSystem::PrinterWatcher::Delegate* delegate_; |
+ |
+ bool SetDelegate(PrintSystem::PrinterWatcher::Delegate* d) { |
+ delegate_ = d; |
+ return true; |
+ } |
+ |
+ public: |
+ MOCK_METHOD1(StartWatching, bool(PrintSystem::PrinterWatcher::Delegate* d)); |
+ MOCK_METHOD0(StopWatching, bool()); |
+ MOCK_METHOD1(GetCurrentPrinterInfo, |
+ bool(printing::PrinterBasicInfo* printer_info)); |
+ |
+ MockPrinterWatcher(); |
+ PrintSystem::PrinterWatcher::Delegate* Delegate() { return delegate_; } |
+}; |
+ |
+ |
+class MockJobSpooler : public PrintSystem::JobSpooler { |
+ protected: |
+ PrintSystem::JobSpooler::Delegate* delegate_; |
+ public: |
+ MOCK_METHOD7(Spool, bool( |
+ const std::string& print_ticket, |
+ const FilePath& print_data_file_path, |
+ const std::string& print_data_mime_type, |
+ const std::string& printer_name, |
+ const std::string& job_title, |
+ const std::vector<std::string>& tags, |
+ PrintSystem::JobSpooler::Delegate* delegate)); |
+ |
+ MockJobSpooler(); |
+ PrintSystem::JobSpooler::Delegate* Delegate() { return delegate_; } |
+}; |
+ |
+ |
+ |
+class MockPrintSystem : public PrintSystem { |
+ protected: |
+ scoped_refptr<MockJobSpooler> job_spooler_; |
+ scoped_refptr<MockPrinterWatcher> printer_watcher_; |
+ scoped_refptr<MockPrintServerWatcher> print_server_watcher_; |
+ |
+ public: |
+ MockPrintSystem(); |
+ PrintSystem::PrintSystemResult succeed() { |
+ return PrintSystem::PrintSystemResult(true, "success"); |
+ } |
+ |
+ PrintSystem::PrintSystemResult fail() { |
+ return PrintSystem::PrintSystemResult(false, "failure"); |
+ } |
+ |
+ MockJobSpooler& JobSpooler() { |
+ return *job_spooler_; |
+ } |
+ |
+ MockPrinterWatcher& PrinterWatcher() { |
+ return *printer_watcher_; |
+ } |
+ |
+ MockPrintServerWatcher& PrintServerWatcher() { |
+ return *print_server_watcher_; |
+ } |
+ |
+ |
+ MOCK_METHOD0(Init, PrintSystem::PrintSystemResult()); |
+ MOCK_METHOD1(EnumeratePrinters, PrintSystem::PrintSystemResult( |
+ printing::PrinterList* printer_list)); |
+ |
+ MOCK_METHOD2( |
+ GetPrinterCapsAndDefaults, |
+ void(const std::string& printer_name, |
+ const PrintSystem::PrinterCapsAndDefaultsCallback& callback)); |
+ |
+ |
+ MOCK_METHOD1(IsValidPrinter, bool(const std::string& printer_name)); |
+ |
+ |
+ MOCK_METHOD2(ValidatePrintTicket, bool(const std::string& printer_name, |
+ const std::string& print_ticket_data)); |
+ |
+ MOCK_METHOD3(GetJobDetails, bool(const std::string& printer_name, |
+ PlatformJobId job_id, |
+ PrintJobDetails* job_details)); |
+ |
+ |
+ |
+ MOCK_METHOD0(CreatePrintServerWatcher, PrintSystem::PrintServerWatcher*()); |
+ MOCK_METHOD1(CreatePrinterWatcher, |
+ PrintSystem::PrinterWatcher*(const std::string& printer_name)); |
+ MOCK_METHOD0(CreateJobSpooler, PrintSystem::JobSpooler*()); |
+ |
+ |
+ MOCK_METHOD0(GetSupportedMimeTypes, std::string()); |
+}; |
+ |
+ |
+class PrinterJobHandlerTest : public ::testing::Test { |
+ public: |
+ MessageLoopForIO loop_; |
+ scoped_refptr<TestURLFetcherCallback > url_callback_; |
Vitaly Buka (NO REVIEWS)
2013/02/12 21:57:08
no need space before >
Noam Samuel (WRONG ACCOUNT)
2013/02/12 22:50:18
Done.
|
+ MockPrinterJobHandlerDelegate jobhandler_delegate_; |
+ CloudPrintTokenStore token_store_; |
+ |
+ CloudPrintURLFetcherNoServiceProcessFactory cloud_print_factory_; |
+ scoped_refptr<PrinterJobHandler> job_handler_; |
+ scoped_refptr<NiceMock<MockPrintSystem> > print_system_; |
+ net::FakeURLFetcherFactory factory_; |
+ printing::PrinterBasicInfo basic_info_; |
+ printing::PrinterCapsAndDefaults caps_and_defaults_; |
+ PrinterJobHandler::PrinterInfoFromCloud info_from_cloud_; |
+ |
+ PrinterJobHandlerTest(); |
+ void TearDown(); |
+ void IdleOut(); |
+ bool GetPrinterInfo(printing::PrinterBasicInfo* info); |
+ void SendCapsAndDefaults( |
+ const std::string& printer_name, |
+ const PrintSystem::PrinterCapsAndDefaultsCallback& callback); |
+ void AddMimeHeader(const GURL& url, net::FakeURLFetcher* fetcher); |
+ bool PostSpoolSuccess(); |
+ |
+ static void MessageLoopQuitNowHelper(MessageLoop* message_loop); |
+ static void MessageLoopQuitSoonHelper(MessageLoop* message_loop); |
+}; |
+ |
+ |
+ |
+void PrinterJobHandlerTest::MessageLoopQuitNowHelper( |
+ MessageLoop* message_loop) { |
+ message_loop->QuitWhenIdle(); |
+} |
+ |
+void PrinterJobHandlerTest::MessageLoopQuitSoonHelper( |
+ MessageLoop* message_loop) { |
+ message_loop->message_loop_proxy()->PostTask( |
+ FROM_HERE, |
+ base::Bind(&MessageLoopQuitNowHelper, message_loop)); |
+} |
+ |
+PrinterJobHandlerTest::PrinterJobHandlerTest() |
+ : url_callback_(new TestURLFetcherCallback), |
+ factory_(base::Bind( |
+ &TestURLFetcherCallback::CreateURLFetcher, |
Vitaly Buka (NO REVIEWS)
2013/02/12 21:57:08
You can avoid base::RefCounted for TestURLFetcherC
Noam Samuel (WRONG ACCOUNT)
2013/02/12 22:50:18
Done.
|
+ url_callback_), NULL) { |
+ basic_info_.printer_name = kExamplePrinterName; |
+ basic_info_.printer_description = kExamplePrinterDescription; |
+ basic_info_.is_default = 0; |
+ |
Vitaly Buka (NO REVIEWS)
2013/02/12 21:57:08
recomended places for gtest initialization and shu
Noam Samuel (WRONG ACCOUNT)
2013/02/12 22:50:18
Done.
|
+ info_from_cloud_.printer_id = kExamplePrinterID; |
+ info_from_cloud_.tags_hash = GetHashOfPrinterInfo(basic_info_); |
+ |
+ info_from_cloud_.caps_hash = base::MD5String(kExamplePrinterCapabilities); |
+ |
+ caps_and_defaults_.printer_capabilities = kExamplePrinterCapabilities; |
+ caps_and_defaults_.caps_mime_type = kExampleCapsMimeType; |
+ caps_and_defaults_.printer_defaults = kExampleDefaults; |
+ caps_and_defaults_.defaults_mime_type = kExampleDefaultMimeType; |
+ |
+ print_system_ = new NiceMock<MockPrintSystem>(); |
+ |
+ token_store_.SetToken(kExampleCloudPrintOAuthToken); |
+ |
+ ON_CALL(print_system_->PrinterWatcher(), GetCurrentPrinterInfo(_)) |
+ .WillByDefault(Invoke(this, &PrinterJobHandlerTest::GetPrinterInfo)); |
+ |
+ ON_CALL(*print_system_, GetPrinterCapsAndDefaults(_, _)) |
+ .WillByDefault(Invoke(this, &PrinterJobHandlerTest::SendCapsAndDefaults)); |
+ |
+ CloudPrintURLFetcher::set_factory(&cloud_print_factory_); |
+} |
+ |
+bool PrinterJobHandlerTest::PostSpoolSuccess() { |
+ MessageLoop::current()->PostTask( |
+ FROM_HERE, |
+ base::Bind( |
+ &PrinterJobHandler::OnJobSpoolSucceeded, |
+ job_handler_, 0)); |
+ |
+ // Everything that would be posted on the printer thread queue |
+ // has been posted, we can tell the main message loop to quit when idle |
+ // and not worry about it idling while the print thread does work |
+ MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(&MessageLoopQuitSoonHelper, &loop_)); |
+ return true; |
+} |
+ |
+void PrinterJobHandlerTest::AddMimeHeader(const GURL& url, |
+ net::FakeURLFetcher* fetcher) { |
+ scoped_refptr<net::HttpResponseHeaders> download_headers = |
+ new net::HttpResponseHeaders(kExampleJobDownloadResponseHeaders); |
+ fetcher->set_response_headers(download_headers); |
+} |
+ |
+ |
+void PrinterJobHandlerTest::SendCapsAndDefaults( |
+ const std::string& printer_name, |
+ const PrintSystem::PrinterCapsAndDefaultsCallback& callback) { |
+ callback.Run(true, printer_name, caps_and_defaults_); |
+} |
+ |
+bool PrinterJobHandlerTest::GetPrinterInfo(printing::PrinterBasicInfo* info) { |
+ *info = basic_info_; |
+ return true; |
+} |
+ |
+void PrinterJobHandlerTest::TearDown() { |
+ IdleOut(); |
+} |
+ |
+void PrinterJobHandlerTest::IdleOut() { |
+ MessageLoop::current()->RunUntilIdle(); |
+} |
+ |
+MockPrintServerWatcher::MockPrintServerWatcher() : delegate_(NULL) { |
+ ON_CALL(*this, StartWatching(_)) |
+ .WillByDefault(Invoke(this, &MockPrintServerWatcher::SetDelegate)); |
+ ON_CALL(*this, StopWatching()).WillByDefault(Return(true)); |
+} |
+ |
+ |
+MockPrinterWatcher::MockPrinterWatcher() : delegate_(NULL) { |
+ ON_CALL(*this, StartWatching(_)) |
+ .WillByDefault(Invoke(this, &MockPrinterWatcher::SetDelegate)); |
+ ON_CALL(*this, StopWatching()).WillByDefault(Return(true)); |
+} |
+ |
+MockJobSpooler::MockJobSpooler() : delegate_(NULL) { |
+ ON_CALL(*this, Spool(_, _, _, _, _, _, _)) |
+ .WillByDefault(DoAll(SaveArg<6>(&delegate_), Return(true))); |
+} |
+ |
+ |
+MockPrintSystem::MockPrintSystem() |
+ : job_spooler_(new NiceMock<MockJobSpooler>()), |
+ printer_watcher_(new NiceMock<MockPrinterWatcher>()), |
+ print_server_watcher_(new NiceMock<MockPrintServerWatcher>()) { |
+ ON_CALL(*this, CreateJobSpooler()) |
+ .WillByDefault(Return(job_spooler_)); |
+ |
+ ON_CALL(*this, CreatePrinterWatcher(_)) |
+ .WillByDefault(Return(printer_watcher_)); |
+ |
+ ON_CALL(*this, CreatePrintServerWatcher()) |
+ .WillByDefault(Return(print_server_watcher_)); |
+ |
+ ON_CALL(*this, IsValidPrinter(_)). |
+ WillByDefault(Return(true)); |
+ |
+ ON_CALL(*this, ValidatePrintTicket(_, _)). |
+ WillByDefault(Return(true)); |
+}; |
+ |
+// This test simulates an end-to-end printing of a document |
+// but tests only non-failure cases. |
+TEST_F(PrinterJobHandlerTest, HappyPathTest) { |
+ GURL InProgressURL = |
+ GetUrlForJobStatusUpdate(GURL(kExampleCloudPrintServerURL), |
+ kExampleJobID, |
+ PRINT_JOB_STATUS_IN_PROGRESS); |
+ |
+ factory_.SetFakeResponse(kExamplePrintTicketURI, kExamplePrintTicket, true); |
+ factory_.SetFakeResponse(kExamplePrintDownloadURI, kExamplePrintData, true); |
+ factory_.SetFakeResponse( |
+ StringPrintf(kExamplePrinterJobListURI, kJobFetchReasonStartup), |
+ kExampleJobListResponse, true); |
+ |
+ |
+ factory_.SetFakeResponse( |
+ base::StringPrintf(kExamplePrinterJobListURI, kJobFetchReasonQueryMore), |
+ kExampleJobListResponseEmpty, true); |
+ |
+ factory_.SetFakeResponse( |
+ kExampleUpdateDoneURL, |
+ base::StringPrintf(kExampleControlResponse, "DONE", "DONE"), true); |
+ |
+ factory_.SetFakeResponse( |
+ InProgressURL.spec(), |
+ base::StringPrintf(kExampleControlResponse, |
+ "IN_PROGRESS", "IN_PROGRESS"), |
+ true); |
+ |
+ |
+ job_handler_ = new PrinterJobHandler(basic_info_, info_from_cloud_, |
+ GURL(kExampleCloudPrintServerURL), |
+ print_system_, &jobhandler_delegate_); |
+ |
+ EXPECT_CALL(*url_callback_, OnRequestCreate( |
+ GURL(base::StringPrintf(kExamplePrinterJobListURI, "startup")), _)) |
+ .Times(Exactly(1)); |
+ |
+ EXPECT_CALL(*url_callback_, OnRequestCreate( |
+ GURL(base::StringPrintf(kExamplePrinterJobListURI, "querymore")), _)) |
+ .Times(Exactly(1)); |
+ |
+ EXPECT_CALL(*url_callback_, OnRequestCreate(GURL(kExamplePrintTicketURI), _)) |
+ .Times(Exactly(1)); |
+ |
+ EXPECT_CALL(*url_callback_, OnRequestCreate( |
+ GURL(kExamplePrintDownloadURI), _)) |
+ .Times(Exactly(1)) |
+ .WillOnce(Invoke(this, &PrinterJobHandlerTest::AddMimeHeader)); |
+ |
+ EXPECT_CALL(*url_callback_, OnRequestCreate(InProgressURL, _)) |
+ .Times(Exactly(1)); |
+ |
+ EXPECT_CALL(*url_callback_, OnRequestCreate(GURL(kExampleUpdateDoneURL), _)) |
+ .Times(Exactly(1)); |
+ |
+ EXPECT_CALL(print_system_->JobSpooler(), |
+ Spool(kExamplePrintTicket, _, _, _, _, _, _)) |
+ .Times(Exactly(1)) |
+ .WillOnce(InvokeWithoutArgs(this, |
+ &PrinterJobHandlerTest::PostSpoolSuccess)); |
+ |
+ |
+ job_handler_->Initialize(); |
+ |
+ MessageLoop::current()->PostDelayedTask( |
+ FROM_HERE, |
+ base::Bind(&PrinterJobHandlerTest::MessageLoopQuitSoonHelper, |
+ MessageLoop::current()), |
+ base::TimeDelta::FromSeconds(1)); |
+ |
+ MessageLoop::current()->Run(); |
+} |
Vitaly Buka (NO REVIEWS)
2013/02/12 21:57:08
empty line before } // namespace cloud_print
Noam Samuel (WRONG ACCOUNT)
2013/02/12 22:50:18
Done.
|
+} // namespace cloud_print |
+ |