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