root/chrome/browser/printing/print_preview_dialog_controller_browsertest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_quit_closure
  2. OnMessageReceived
  3. OnRequestPrintPreview
  4. request_preview_dialog_observer
  5. DidCloneToNewWebContents
  6. dialog_destroyed_
  7. dialog_destroyed
  8. WebContentsDestroyed
  9. initiator
  10. PrintPreview
  11. GetPrintPreviewDialog
  12. SetUpCommandLine
  13. SetUpOnMainThread
  14. CleanUpOnMainThread
  15. request_preview_dialog_observer
  16. IN_PROC_BROWSER_TEST_F
  17. IN_PROC_BROWSER_TEST_F

// Copyright (c) 2012 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/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/run_loop.h"
#include "chrome/browser/printing/print_preview_dialog_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/print_messages.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/browser_test_utils.h"
#include "url/gurl.h"
#include "ipc/ipc_message_macros.h"

using content::WebContents;
using content::WebContentsObserver;

class RequestPrintPreviewObserver : public WebContentsObserver {
 public:
  explicit RequestPrintPreviewObserver(WebContents* dialog)
      : WebContentsObserver(dialog) {
  }
  virtual ~RequestPrintPreviewObserver() {}

  void set_quit_closure(const base::Closure& quit_closure) {
    quit_closure_ = quit_closure;
  }

 private:
  // content::WebContentsObserver implementation.
  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
    IPC_BEGIN_MESSAGE_MAP(RequestPrintPreviewObserver, message)
      IPC_MESSAGE_HANDLER(PrintHostMsg_RequestPrintPreview,
                          OnRequestPrintPreview)
      IPC_MESSAGE_UNHANDLED(break;)
    IPC_END_MESSAGE_MAP();
    return false;  // Report not handled so the real handler receives it.
  }

  void OnRequestPrintPreview(
      const PrintHostMsg_RequestPrintPreview_Params& /* params */) {
    base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_);
  }

  base::Closure quit_closure_;

  DISALLOW_COPY_AND_ASSIGN(RequestPrintPreviewObserver);
};

class PrintPreviewDialogClonedObserver : public WebContentsObserver {
 public:
  explicit PrintPreviewDialogClonedObserver(WebContents* dialog)
      : WebContentsObserver(dialog) {
  }
  virtual ~PrintPreviewDialogClonedObserver() {}

  RequestPrintPreviewObserver* request_preview_dialog_observer() {
    return request_preview_dialog_observer_.get();
  }

 private:
  // content::WebContentsObserver implementation.
  virtual void DidCloneToNewWebContents(
      WebContents* old_web_contents,
      WebContents* new_web_contents) OVERRIDE {
    request_preview_dialog_observer_.reset(
        new RequestPrintPreviewObserver(new_web_contents));
  }

  scoped_ptr<RequestPrintPreviewObserver> request_preview_dialog_observer_;

  DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogClonedObserver);
};

class PrintPreviewDialogDestroyedObserver : public WebContentsObserver {
 public:
  explicit PrintPreviewDialogDestroyedObserver(WebContents* dialog)
      : WebContentsObserver(dialog),
        dialog_destroyed_(false) {
  }
  virtual ~PrintPreviewDialogDestroyedObserver() {}

  bool dialog_destroyed() const { return dialog_destroyed_; }

 private:
  // content::WebContentsObserver implementation.
  virtual void WebContentsDestroyed(WebContents* contents) OVERRIDE {
    dialog_destroyed_ = true;
  }

  bool dialog_destroyed_;

  DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogDestroyedObserver);
};

class PrintPreviewDialogControllerBrowserTest : public InProcessBrowserTest {
 public:
  PrintPreviewDialogControllerBrowserTest() : initiator_(NULL) {}
  virtual ~PrintPreviewDialogControllerBrowserTest() {}

  WebContents* initiator() {
    return initiator_;
  }

  void PrintPreview() {
    base::RunLoop run_loop;
    request_preview_dialog_observer()->set_quit_closure(run_loop.QuitClosure());
    chrome::Print(browser());
    run_loop.Run();
  }

  WebContents* GetPrintPreviewDialog() {
    printing::PrintPreviewDialogController* dialog_controller =
        printing::PrintPreviewDialogController::GetInstance();
    return dialog_controller->GetPrintPreviewForContents(initiator_);
  }

 private:
  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
#if !defined(GOOGLE_CHROME_BUILD)
    command_line->AppendSwitch(switches::kEnablePrintPreview);
#endif
  }

  virtual void SetUpOnMainThread() OVERRIDE {
    WebContents* first_tab =
        browser()->tab_strip_model()->GetActiveWebContents();
    ASSERT_TRUE(first_tab);

    // Open a new tab so |cloned_tab_observer_| can see it first and attach a
    // RequestPrintPreviewObserver to it before the real
    // PrintPreviewMessageHandler gets created. Thus enabling
    // RequestPrintPreviewObserver to get messages first for the purposes of
    // this test.
    cloned_tab_observer_.reset(new PrintPreviewDialogClonedObserver(first_tab));
    chrome::DuplicateTab(browser());

    initiator_ = browser()->tab_strip_model()->GetActiveWebContents();
    ASSERT_TRUE(initiator_);
    ASSERT_NE(first_tab, initiator_);
  }

  virtual void CleanUpOnMainThread() OVERRIDE {
    cloned_tab_observer_.reset();
    initiator_ = NULL;
  }

  RequestPrintPreviewObserver* request_preview_dialog_observer() {
    return cloned_tab_observer_->request_preview_dialog_observer();
  }

  scoped_ptr<PrintPreviewDialogClonedObserver> cloned_tab_observer_;
  WebContents* initiator_;

  DISALLOW_COPY_AND_ASSIGN(PrintPreviewDialogControllerBrowserTest);
};

// Test to verify that when a initiator navigates, we can create a new preview
// dialog for the new tab contents.
IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
                       NavigateFromInitiatorTab) {
  // print for the first time.
  PrintPreview();

  // Get the preview dialog for the initiator tab.
  WebContents* preview_dialog = GetPrintPreviewDialog();

  // Check a new print preview dialog got created.
  ASSERT_TRUE(preview_dialog);
  ASSERT_NE(initiator(), preview_dialog);

  // Navigate in the initiator tab. Make sure navigating destroys the print
  // preview dialog.
  PrintPreviewDialogDestroyedObserver dialog_destroyed_observer(preview_dialog);
  ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL));
  ASSERT_TRUE(dialog_destroyed_observer.dialog_destroyed());

  // Try printing again.
  PrintPreview();

  // Get the print preview dialog for the initiator tab.
  WebContents* new_preview_dialog = GetPrintPreviewDialog();

  // Check a new preview dialog got created.
  EXPECT_TRUE(new_preview_dialog);
}

// Test to verify that after reloading the initiator, it creates a new print
// preview dialog.
IN_PROC_BROWSER_TEST_F(PrintPreviewDialogControllerBrowserTest,
                       ReloadInitiatorTab) {
  // print for the first time.
  PrintPreview();

  WebContents* preview_dialog = GetPrintPreviewDialog();

  // Check a new print preview dialog got created.
  ASSERT_TRUE(preview_dialog);
  ASSERT_NE(initiator(), preview_dialog);

  // Reload the initiator. Make sure reloading destroys the print preview
  // dialog.
  PrintPreviewDialogDestroyedObserver dialog_destroyed_observer(preview_dialog);
  chrome::Reload(browser(), CURRENT_TAB);
  content::WaitForLoadStop(
      browser()->tab_strip_model()->GetActiveWebContents());
  ASSERT_TRUE(dialog_destroyed_observer.dialog_destroyed());

  // Try printing again.
  PrintPreview();

  // Create a preview dialog for the initiator tab.
  WebContents* new_preview_dialog = GetPrintPreviewDialog();
  EXPECT_TRUE(new_preview_dialog);
}

/* [<][>][^][v][top][bottom][index][help] */