1// Copyright (c) 2012 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/ui/cocoa/constrained_window/constrained_window_mac.h" 6 7#include "chrome/browser/profiles/profile.h" 8#include "chrome/browser/ui/browser.h" 9#include "chrome/browser/ui/browser_tabstrip.h" 10#include "chrome/browser/ui/browser_window.h" 11#import "chrome/browser/ui/cocoa/browser_window_controller.h" 12#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h" 13#include "chrome/browser/ui/tabs/tab_strip_model.h" 14#include "chrome/test/base/in_process_browser_test.h" 15#include "content/public/browser/web_contents.h" 16#include "testing/gmock/include/gmock/gmock.h" 17#include "url/gurl.h" 18 19using ::testing::NiceMock; 20 21namespace { 22 23class ConstrainedWindowDelegateMock : public ConstrainedWindowMacDelegate { 24 public: 25 MOCK_METHOD1(OnConstrainedWindowClosed, void(ConstrainedWindowMac*)); 26}; 27 28} // namespace 29 30class ConstrainedWindowMacTest : public InProcessBrowserTest { 31 public: 32 ConstrainedWindowMacTest() 33 : InProcessBrowserTest(), 34 tab0_(NULL), 35 tab1_(NULL), 36 controller_(NULL), 37 tab_view0_(NULL), 38 tab_view1_(NULL) { 39 sheet_window_.reset([[NSWindow alloc] 40 initWithContentRect:NSMakeRect(0, 0, 30, 30) 41 styleMask:NSTitledWindowMask 42 backing:NSBackingStoreBuffered 43 defer:NO]); 44 [sheet_window_ setReleasedWhenClosed:NO]; 45 sheet_.reset([[CustomConstrainedWindowSheet alloc] 46 initWithCustomWindow:sheet_window_]); 47 [sheet_ hideSheet]; 48 } 49 50 virtual void SetUpOnMainThread() OVERRIDE { 51 AddTabAtIndex(1, GURL("about:blank"), content::PAGE_TRANSITION_LINK); 52 tab0_ = browser()->tab_strip_model()->GetWebContentsAt(0); 53 tab1_ = browser()->tab_strip_model()->GetWebContentsAt(1); 54 EXPECT_EQ(tab1_, browser()->tab_strip_model()->GetActiveWebContents()); 55 56 controller_ = [BrowserWindowController browserWindowControllerForWindow: 57 browser()->window()->GetNativeWindow()]; 58 EXPECT_TRUE(controller_); 59 tab_view0_ = [[controller_ tabStripController] viewAtIndex:0]; 60 EXPECT_TRUE(tab_view0_); 61 tab_view1_ = [[controller_ tabStripController] viewAtIndex:1]; 62 EXPECT_TRUE(tab_view1_); 63 } 64 65 protected: 66 base::scoped_nsobject<CustomConstrainedWindowSheet> sheet_; 67 base::scoped_nsobject<NSWindow> sheet_window_; 68 content::WebContents* tab0_; 69 content::WebContents* tab1_; 70 BrowserWindowController* controller_; 71 NSView* tab_view0_; 72 NSView* tab_view1_; 73}; 74 75// Test that a sheet added to a inactive tab is not shown until the 76// tab is activated. 77IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, ShowInInactiveTab) { 78 // Show dialog in non active tab. 79 NiceMock<ConstrainedWindowDelegateMock> delegate; 80 ConstrainedWindowMac dialog(&delegate, tab0_, sheet_); 81 EXPECT_EQ(0.0, [sheet_window_ alphaValue]); 82 83 // Switch to inactive tab. 84 browser()->tab_strip_model()->ActivateTabAt(0, true); 85 EXPECT_EQ(1.0, [sheet_window_ alphaValue]); 86 87 dialog.CloseWebContentsModalDialog(); 88} 89 90// If a tab has never been shown then the associated tab view for the web 91// content will not be created. Verify that adding a constrained window to such 92// a tab works correctly. 93IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, ShowInUninitializedTab) { 94 scoped_ptr<content::WebContents> web_contents(content::WebContents::Create( 95 content::WebContents::CreateParams(browser()->profile()))); 96 bool was_blocked = false; 97 chrome::AddWebContents(browser(), NULL, web_contents.release(), 98 NEW_BACKGROUND_TAB, gfx::Rect(), false, &was_blocked); 99 content::WebContents* tab2 = 100 browser()->tab_strip_model()->GetWebContentsAt(2); 101 ASSERT_TRUE(tab2); 102 EXPECT_FALSE([tab2->GetNativeView() superview]); 103 104 // Show dialog and verify that it's not visible yet. 105 NiceMock<ConstrainedWindowDelegateMock> delegate; 106 ConstrainedWindowMac dialog(&delegate, tab2, sheet_); 107 EXPECT_FALSE([sheet_window_ isVisible]); 108 109 // Activate the tab and verify that the constrained window is shown. 110 browser()->tab_strip_model()->ActivateTabAt(2, true); 111 EXPECT_TRUE([tab2->GetNativeView() superview]); 112 EXPECT_TRUE([sheet_window_ isVisible]); 113 EXPECT_EQ(1.0, [sheet_window_ alphaValue]); 114 115 dialog.CloseWebContentsModalDialog(); 116} 117 118// Test that adding a sheet disables tab dragging. 119IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, TabDragging) { 120 NiceMock<ConstrainedWindowDelegateMock> delegate; 121 ConstrainedWindowMac dialog(&delegate, tab1_, sheet_); 122 123 // Verify that the dialog disables dragging. 124 EXPECT_TRUE([controller_ isTabDraggable:tab_view0_]); 125 EXPECT_FALSE([controller_ isTabDraggable:tab_view1_]); 126 127 dialog.CloseWebContentsModalDialog(); 128} 129 130// Test that closing a browser window with a sheet works. 131IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, BrowserWindowClose) { 132 NiceMock<ConstrainedWindowDelegateMock> delegate; 133 ConstrainedWindowMac dialog(&delegate, tab1_, sheet_); 134 EXPECT_EQ(1.0, [sheet_window_ alphaValue]); 135 136 // Close the browser window. 137 base::scoped_nsobject<NSWindow> browser_window( 138 [browser()->window()->GetNativeWindow() retain]); 139 EXPECT_TRUE([browser_window isVisible]); 140 [browser()->window()->GetNativeWindow() performClose:nil]; 141 EXPECT_FALSE([browser_window isVisible]); 142} 143 144// Test that closing a tab with a sheet works. 145IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, TabClose) { 146 NiceMock<ConstrainedWindowDelegateMock> delegate; 147 ConstrainedWindowMac dialog(&delegate, tab1_, sheet_); 148 EXPECT_EQ(1.0, [sheet_window_ alphaValue]); 149 150 // Close the tab. 151 TabStripModel* tab_strip = browser()->tab_strip_model(); 152 EXPECT_EQ(2, tab_strip->count()); 153 EXPECT_TRUE(tab_strip->CloseWebContentsAt(1, 154 TabStripModel::CLOSE_USER_GESTURE)); 155 EXPECT_EQ(1, tab_strip->count()); 156} 157