print_dialog_cloud_uitest.cc revision 3f50c38dc070f4bb515c1b64450dae14f316474e
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 <functional> 9 10#include "base/file_path.h" 11#include "base/file_util.h" 12#include "base/path_service.h" 13#include "base/singleton.h" 14#include "base/threading/thread_restrictions.h" 15#include "base/values.h" 16#include "chrome/browser/browser_list.h" 17#include "chrome/browser/browser_thread.h" 18#include "chrome/browser/dom_ui/chrome_url_data_manager.h" 19#include "chrome/browser/printing/cloud_print/cloud_print_url.h" 20#include "chrome/browser/renderer_host/render_view_host.h" 21#include "chrome/browser/tab_contents/tab_contents.h" 22#include "chrome/common/chrome_paths.h" 23#include "chrome/common/url_constants.h" 24#include "chrome/test/in_process_browser_test.h" 25#include "chrome/test/ui_test_utils.h" 26#include "net/url_request/url_request_filter.h" 27#include "net/url_request/url_request_test_job.h" 28#include "net/url_request/url_request_unittest.h" 29 30namespace { 31 32class TestData { 33 public: 34 static TestData* GetInstance() { 35 return Singleton<TestData>::get(); 36 } 37 38 const char* GetTestData() { 39 // Fetching this data blocks the IO thread, but we don't really care because 40 // this is a test. 41 base::ThreadRestrictions::ScopedAllowIO allow_io; 42 43 if (test_data_.empty()) { 44 FilePath test_data_directory; 45 PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory); 46 FilePath test_file = 47 test_data_directory.AppendASCII("printing/cloud_print_uitest.html"); 48 file_util::ReadFileToString(test_file, &test_data_); 49 } 50 return test_data_.c_str(); 51 } 52 private: 53 TestData() {} 54 55 std::string test_data_; 56 57 friend struct DefaultSingletonTraits<TestData>; 58}; 59 60// A simple test net::URLRequestJob. We don't care what it does, only that 61// whether it starts and finishes. 62class SimpleTestJob : public URLRequestTestJob { 63 public: 64 explicit SimpleTestJob(net::URLRequest* request) 65 : URLRequestTestJob(request, test_headers(), 66 TestData::GetInstance()->GetTestData(), true) {} 67 68 virtual void GetResponseInfo(net::HttpResponseInfo* info) { 69 URLRequestTestJob::GetResponseInfo(info); 70 if (request_->url().SchemeIsSecure()) { 71 // Make up a fake certificate for this response since we don't have 72 // access to the real SSL info. 73 const char* kCertIssuer = "Chrome Internal"; 74 const int kLifetimeDays = 100; 75 76 info->ssl_info.cert = 77 new net::X509Certificate(request_->url().GetWithEmptyPath().spec(), 78 kCertIssuer, 79 base::Time::Now(), 80 base::Time::Now() + 81 base::TimeDelta::FromDays(kLifetimeDays)); 82 info->ssl_info.cert_status = 0; 83 info->ssl_info.security_bits = -1; 84 } 85 } 86 87 private: 88 ~SimpleTestJob() {} 89}; 90 91class TestController { 92 public: 93 static TestController* GetInstance() { 94 return Singleton<TestController>::get(); 95 } 96 void set_result(bool value) { 97 result_ = value; 98 } 99 bool result() { 100 return result_; 101 } 102 void set_expected_url(const GURL& url) { 103 expected_url_ = url; 104 } 105 const GURL expected_url() { 106 return expected_url_; 107 } 108 void set_delegate(TestDelegate* delegate) { 109 delegate_ = delegate; 110 } 111 TestDelegate* delegate() { 112 return delegate_; 113 } 114 void set_use_delegate(bool value) { 115 use_delegate_ = value; 116 } 117 bool use_delegate() { 118 return use_delegate_; 119 } 120 private: 121 TestController() 122 : result_(false), 123 use_delegate_(false), 124 delegate_(NULL) {} 125 126 bool result_; 127 bool use_delegate_; 128 GURL expected_url_; 129 TestDelegate* delegate_; 130 131 friend struct DefaultSingletonTraits<TestController>; 132}; 133 134} // namespace 135 136class PrintDialogCloudTest : public InProcessBrowserTest { 137 public: 138 PrintDialogCloudTest() : handler_added_(false) { 139 PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_); 140 } 141 142 // Must be static for handing into AddHostnameHandler. 143 static net::URLRequest::ProtocolFactory Factory; 144 145 class AutoQuitDelegate : public TestDelegate { 146 public: 147 AutoQuitDelegate() {} 148 149 virtual void OnResponseCompleted(net::URLRequest* request) { 150 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 151 new MessageLoop::QuitTask()); 152 } 153 }; 154 155 virtual void SetUp() { 156 TestController::GetInstance()->set_result(false); 157 InProcessBrowserTest::SetUp(); 158 } 159 160 virtual void TearDown() { 161 if (handler_added_) { 162 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); 163 filter->RemoveHostnameHandler(scheme_, host_name_); 164 handler_added_ = false; 165 TestController::GetInstance()->set_delegate(NULL); 166 } 167 InProcessBrowserTest::TearDown(); 168 } 169 170 // Normally this is something I would expect could go into SetUp(), 171 // but there seems to be some timing or ordering related issue with 172 // the test harness that made that flaky. Calling this from the 173 // individual test functions seems to fix that. 174 void AddTestHandlers() { 175 if (!handler_added_) { 176 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); 177 GURL cloud_print_service_url = 178 CloudPrintURL(browser()->profile()). 179 GetCloudPrintServiceURL(); 180 scheme_ = cloud_print_service_url.scheme(); 181 host_name_ = cloud_print_service_url.host(); 182 filter->AddHostnameHandler(scheme_, host_name_, 183 &PrintDialogCloudTest::Factory); 184 handler_added_ = true; 185 186 GURL cloud_print_dialog_url = 187 CloudPrintURL(browser()->profile()). 188 GetCloudPrintServiceDialogURL(); 189 TestController::GetInstance()->set_expected_url(cloud_print_dialog_url); 190 TestController::GetInstance()->set_delegate(&delegate_); 191 } 192 193 CreateDialogForTest(); 194 } 195 196 void CreateDialogForTest() { 197 FilePath path_to_pdf = 198 test_data_directory_.AppendASCII("printing/cloud_print_uitest.pdf"); 199 BrowserThread::PostTask( 200 BrowserThread::UI, FROM_HERE, 201 NewRunnableFunction(&PrintDialogCloud::CreateDialogImpl, path_to_pdf)); 202 } 203 204 bool handler_added_; 205 std::string scheme_; 206 std::string host_name_; 207 FilePath test_data_directory_; 208 AutoQuitDelegate delegate_; 209}; 210 211net::URLRequestJob* PrintDialogCloudTest::Factory(net::URLRequest* request, 212 const std::string& scheme) { 213 if (TestController::GetInstance()->use_delegate()) 214 request->set_delegate(TestController::GetInstance()->delegate()); 215 if (request && 216 (request->url() == TestController::GetInstance()->expected_url())) { 217 TestController::GetInstance()->set_result(true); 218 } 219 return new SimpleTestJob(request); 220} 221 222IN_PROC_BROWSER_TEST_F(PrintDialogCloudTest, HandlersRegistered) { 223 BrowserList::SetLastActive(browser()); 224 ASSERT_TRUE(BrowserList::GetLastActive()); 225 226 AddTestHandlers(); 227 228 TestController::GetInstance()->set_use_delegate(true); 229 230 ui_test_utils::RunMessageLoop(); 231 232 ASSERT_TRUE(TestController::GetInstance()->result()); 233} 234 235#if defined(OS_CHROMEOS) 236// Disabled until the extern URL is live so that the Print menu item 237// can be enabled for Chromium OS. 238IN_PROC_BROWSER_TEST_F(PrintDialogCloudTest, DISABLED_DialogGrabbed) { 239 BrowserList::SetLastActive(browser()); 240 ASSERT_TRUE(BrowserList::GetLastActive()); 241 242 AddTestHandlers(); 243 244 // This goes back one step further for the Chrome OS case, to making 245 // sure 'window.print()' gets to the right place. 246 ASSERT_TRUE(browser()->GetSelectedTabContents()); 247 ASSERT_TRUE(browser()->GetSelectedTabContents()->render_view_host()); 248 249 std::wstring window_print(L"window.print()"); 250 browser()->GetSelectedTabContents()->render_view_host()-> 251 ExecuteJavascriptInWebFrame(std::wstring(), window_print); 252 253 ui_test_utils::RunMessageLoop(); 254 255 ASSERT_TRUE(TestController::GetInstance()->result()); 256} 257#endif 258