print_dialog_cloud_unittest.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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 "chrome/browser/printing/print_dialog_cloud.h" 6#include "chrome/browser/printing/print_dialog_cloud_internal.h" 7 8#include "base/file_path.h" 9#include "base/file_util.h" 10#include "base/path_service.h" 11#include "base/string_util.h" 12#include "base/utf_string_conversions.h" 13#include "base/values.h" 14#include "base/weak_ptr.h" 15#include "chrome/browser/chrome_thread.h" 16#include "chrome/browser/printing/cloud_print/cloud_print_url.h" 17#include "chrome/common/chrome_paths.h" 18#include "chrome/common/notification_details.h" 19#include "chrome/common/notification_observer.h" 20#include "chrome/common/notification_registrar.h" 21#include "chrome/common/notification_source.h" 22#include "chrome/common/notification_type.h" 23#include "chrome/common/url_constants.h" 24#include "chrome/test/testing_profile.h" 25#include "testing/gtest/include/gtest/gtest.h" 26#include "testing/gmock/include/gmock/gmock.h" 27 28using testing::A; 29using testing::AtLeast; 30using testing::Eq; 31using testing::HasSubstr; 32using testing::IsNull; 33using testing::NotNull; 34using testing::Return; 35using testing::StrEq; 36using testing::_; 37 38static const char* const kPDFTestFile = "printing/cloud_print_unittest.pdf"; 39static const char* const kEmptyPDFTestFile = 40 "printing/cloud_print_emptytest.pdf"; 41static const char* const kMockJobTitle = "Mock Job Title"; 42 43FilePath GetTestDataFileName() { 44 FilePath test_data_directory; 45 PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory); 46 FilePath test_file = test_data_directory.AppendASCII(kPDFTestFile); 47 return test_file; 48} 49 50FilePath GetEmptyDataFileName() { 51 FilePath test_data_directory; 52 PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory); 53 FilePath test_file = test_data_directory.AppendASCII(kEmptyPDFTestFile); 54 return test_file; 55} 56 57char* GetTestData() { 58 static std::string sTestFileData; 59 if (sTestFileData.empty()) { 60 FilePath test_file = GetTestDataFileName(); 61 file_util::ReadFileToString(test_file, &sTestFileData); 62 } 63 return &sTestFileData[0]; 64} 65 66MATCHER_P(StringValueEq, expected, "StringValue") { 67 if (expected->Equals(&arg)) 68 return true; 69 std::string expected_string, arg_string; 70 expected->GetAsString(&expected_string); 71 arg.GetAsString(&arg_string); 72 *result_listener << "'" << arg_string 73 << "' (expected '" << expected_string << "')"; 74 return false; 75} 76 77namespace internal_cloud_print_helpers { 78 79class MockCloudPrintFlowHandler 80 : public CloudPrintFlowHandler, 81 public base::SupportsWeakPtr<MockCloudPrintFlowHandler> { 82 public: 83 explicit MockCloudPrintFlowHandler(const FilePath& path, 84 const string16& title) 85 : CloudPrintFlowHandler(path, title) {} 86 MOCK_METHOD0(DestructorCalled, void()); 87 MOCK_METHOD0(RegisterMessages, void()); 88 MOCK_METHOD3(Observe, 89 void(NotificationType type, 90 const NotificationSource& source, 91 const NotificationDetails& details)); 92 MOCK_METHOD1(SetDialogDelegate, 93 void(CloudPrintHtmlDialogDelegate* delegate)); 94 MOCK_METHOD0(CreateCloudPrintDataSender, 95 scoped_refptr<CloudPrintDataSender>()); 96}; 97 98class MockCloudPrintHtmlDialogDelegate : public CloudPrintHtmlDialogDelegate { 99 public: 100 MOCK_CONST_METHOD0(IsDialogModal, 101 bool()); 102 MOCK_CONST_METHOD0(GetDialogTitle, 103 std::wstring()); 104 MOCK_CONST_METHOD0(GetDialogContentURL, 105 GURL()); 106 MOCK_CONST_METHOD1(GetDOMMessageHandlers, 107 void(std::vector<DOMMessageHandler*>* handlers)); 108 MOCK_CONST_METHOD1(GetDialogSize, 109 void(gfx::Size* size)); 110 MOCK_CONST_METHOD0(GetDialogArgs, 111 std::string()); 112 MOCK_METHOD1(OnDialogClosed, 113 void(const std::string& json_retval)); 114 MOCK_METHOD2(OnCloseContents, 115 void(TabContents* source, bool *out_close_dialog)); 116}; 117 118} // namespace internal_cloud_print_helpers 119 120using internal_cloud_print_helpers::CloudPrintDataSenderHelper; 121using internal_cloud_print_helpers::CloudPrintDataSender; 122 123class MockExternalHtmlDialogUI : public ExternalHtmlDialogUI { 124 public: 125 MOCK_METHOD1(RenderViewCreated, 126 void(RenderViewHost* render_view_host)); 127}; 128 129class MockCloudPrintDataSenderHelper : public CloudPrintDataSenderHelper { 130 public: 131 // TODO(scottbyer): At some point this probably wants to use a 132 // MockTabContents instead of NULL, and to pre-load it with a bunch 133 // of expects/results. 134 MockCloudPrintDataSenderHelper() : CloudPrintDataSenderHelper(NULL) {} 135 MOCK_METHOD1(CallJavascriptFunction, void(const std::wstring&)); 136 MOCK_METHOD2(CallJavascriptFunction, void(const std::wstring&, 137 const Value& arg1)); 138 MOCK_METHOD3(CallJavascriptFunction, void(const std::wstring&, 139 const Value& arg1, 140 const Value& arg2)); 141}; 142 143class CloudPrintURLTest : public testing::Test { 144 public: 145 CloudPrintURLTest() {} 146 147 protected: 148 virtual void SetUp() { 149 profile_.reset(new TestingProfile()); 150 } 151 152 scoped_ptr<Profile> profile_; 153}; 154 155TEST_F(CloudPrintURLTest, CheckDefaultURLs) { 156 std::string service_url = 157 CloudPrintURL(profile_.get()). 158 GetCloudPrintServiceURL().spec(); 159 EXPECT_THAT(service_url, HasSubstr("www.google.com")); 160 EXPECT_THAT(service_url, HasSubstr("cloudprint")); 161 162 std::string dialog_url = 163 CloudPrintURL(profile_.get()). 164 GetCloudPrintServiceDialogURL().spec(); 165 EXPECT_THAT(dialog_url, HasSubstr("www.google.com")); 166 EXPECT_THAT(dialog_url, HasSubstr("/cloudprint/")); 167 EXPECT_THAT(dialog_url, HasSubstr("/client/")); 168 EXPECT_THAT(dialog_url, Not(HasSubstr("cloudprint/cloudprint"))); 169 EXPECT_THAT(dialog_url, HasSubstr("/dialog.html")); 170 171 // Repeat to make sure there isn't a transient glitch. 172 dialog_url = 173 CloudPrintURL(profile_.get()). 174 GetCloudPrintServiceDialogURL().spec(); 175 EXPECT_THAT(dialog_url, HasSubstr("www.google.com")); 176 EXPECT_THAT(dialog_url, HasSubstr("/cloudprint/")); 177 EXPECT_THAT(dialog_url, HasSubstr("/client/")); 178 EXPECT_THAT(dialog_url, Not(HasSubstr("cloudprint/cloudprint"))); 179 EXPECT_THAT(dialog_url, HasSubstr("/dialog.html")); 180} 181 182// Testing for CloudPrintDataSender needs a mock DOMUI. 183class CloudPrintDataSenderTest : public testing::Test { 184 public: 185 CloudPrintDataSenderTest() 186 : file_thread_(ChromeThread::FILE, &message_loop_), 187 io_thread_(ChromeThread::IO, &message_loop_) {} 188 189 protected: 190 virtual void SetUp() { 191 string16 mock_job_title(ASCIIToUTF16(kMockJobTitle)); 192 mock_helper_.reset(new MockCloudPrintDataSenderHelper); 193 print_data_sender_ = 194 new CloudPrintDataSender(mock_helper_.get(), mock_job_title); 195 } 196 197 scoped_refptr<CloudPrintDataSender> print_data_sender_; 198 scoped_ptr<MockCloudPrintDataSenderHelper> mock_helper_; 199 200 MessageLoop message_loop_; 201 ChromeThread file_thread_; 202 ChromeThread io_thread_; 203}; 204 205// TODO(scottbyer): DISABLED until the binary test file can get 206// checked in separate from the patch. 207TEST_F(CloudPrintDataSenderTest, CanSend) { 208 StringValue mock_job_title(kMockJobTitle); 209 EXPECT_CALL(*mock_helper_, 210 CallJavascriptFunction(_, _, StringValueEq(&mock_job_title))). 211 WillOnce(Return()); 212 213 FilePath test_data_file_name = GetTestDataFileName(); 214 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 215 NewRunnableMethod( 216 print_data_sender_.get(), 217 &CloudPrintDataSender::ReadPrintDataFile, 218 test_data_file_name)); 219 MessageLoop::current()->RunAllPending(); 220} 221 222TEST_F(CloudPrintDataSenderTest, BadFile) { 223 EXPECT_CALL(*mock_helper_, CallJavascriptFunction(_, _, _)).Times(0); 224 225#if defined(OS_WIN) 226 FilePath bad_data_file_name(L"/some/file/that/isnot/there"); 227#else 228 FilePath bad_data_file_name("/some/file/that/isnot/there"); 229#endif 230 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 231 NewRunnableMethod( 232 print_data_sender_.get(), 233 &CloudPrintDataSender::ReadPrintDataFile, 234 bad_data_file_name)); 235 MessageLoop::current()->RunAllPending(); 236} 237 238TEST_F(CloudPrintDataSenderTest, EmptyFile) { 239 EXPECT_CALL(*mock_helper_, CallJavascriptFunction(_, _, _)).Times(0); 240 241 FilePath empty_data_file_name = GetEmptyDataFileName(); 242 ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, 243 NewRunnableMethod( 244 print_data_sender_.get(), 245 &CloudPrintDataSender::ReadPrintDataFile, 246 empty_data_file_name)); 247 MessageLoop::current()->RunAllPending(); 248} 249 250// Testing for CloudPrintFlowHandler needs a mock 251// CloudPrintHtmlDialogDelegate, mock CloudPrintDataSender, and a mock 252// DOMUI. 253 254// Testing for CloudPrintHtmlDialogDelegate needs a mock 255// CloudPrintFlowHandler. 256 257using internal_cloud_print_helpers::MockCloudPrintFlowHandler; 258using internal_cloud_print_helpers::CloudPrintHtmlDialogDelegate; 259 260class CloudPrintHtmlDialogDelegateTest : public testing::Test { 261 public: 262 CloudPrintHtmlDialogDelegateTest() 263 : ui_thread_(ChromeThread::UI, &message_loop_) {} 264 265 protected: 266 virtual void SetUp() { 267 FilePath mock_path; 268 string16 mock_title; 269 MockCloudPrintFlowHandler* handler = 270 new MockCloudPrintFlowHandler(mock_path, mock_title); 271 mock_flow_handler_ = handler->AsWeakPtr(); 272 EXPECT_CALL(*mock_flow_handler_.get(), SetDialogDelegate(_)); 273 EXPECT_CALL(*mock_flow_handler_.get(), SetDialogDelegate(NULL)); 274 delegate_.reset(new CloudPrintHtmlDialogDelegate( 275 mock_flow_handler_.get(), 100, 100, std::string())); 276 } 277 278 virtual void TearDown() { 279 delegate_.reset(); 280 if (mock_flow_handler_) 281 delete mock_flow_handler_.get(); 282 } 283 284 MessageLoopForUI message_loop_; 285 ChromeThread ui_thread_; 286 base::WeakPtr<MockCloudPrintFlowHandler> mock_flow_handler_; 287 scoped_ptr<CloudPrintHtmlDialogDelegate> delegate_; 288}; 289 290TEST_F(CloudPrintHtmlDialogDelegateTest, BasicChecks) { 291 EXPECT_TRUE(delegate_->IsDialogModal()); 292 EXPECT_THAT(delegate_->GetDialogContentURL().spec(), 293 StrEq(chrome::kCloudPrintResourcesURL)); 294 EXPECT_THAT(delegate_->GetDialogTitle(), HasSubstr(L"Print")); 295 296 bool close_dialog = false; 297 delegate_->OnCloseContents(NULL, &close_dialog); 298 EXPECT_TRUE(close_dialog); 299} 300 301TEST_F(CloudPrintHtmlDialogDelegateTest, OwnedFlowDestroyed) { 302 delegate_.reset(); 303 EXPECT_THAT(mock_flow_handler_.get(), IsNull()); 304} 305 306TEST_F(CloudPrintHtmlDialogDelegateTest, UnownedFlowLetGo) { 307 std::vector<DOMMessageHandler*> handlers; 308 delegate_->GetDOMMessageHandlers(&handlers); 309 delegate_.reset(); 310 EXPECT_THAT(mock_flow_handler_.get(), NotNull()); 311} 312 313// Testing for ExternalHtmlDialogUI needs a mock TabContents, mock 314// CloudPrintHtmlDialogDelegate (provided through the mock 315// tab_contents) 316 317// Testing for PrintDialogCloud needs a mock Browser. 318