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