| // 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 "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" |
| |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_tabstrip.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "content/public/browser/web_contents.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "url/gurl.h" |
| |
| using ::testing::NiceMock; |
| |
| namespace { |
| |
| class ConstrainedWindowDelegateMock : public ConstrainedWindowMacDelegate { |
| public: |
| MOCK_METHOD1(OnConstrainedWindowClosed, void(ConstrainedWindowMac*)); |
| }; |
| |
| } // namespace |
| |
| class ConstrainedWindowMacTest : public InProcessBrowserTest { |
| public: |
| ConstrainedWindowMacTest() |
| : InProcessBrowserTest(), |
| tab0_(NULL), |
| tab1_(NULL), |
| controller_(NULL), |
| tab_view0_(NULL), |
| tab_view1_(NULL) { |
| sheet_window_.reset([[NSWindow alloc] |
| initWithContentRect:NSMakeRect(0, 0, 30, 30) |
| styleMask:NSTitledWindowMask |
| backing:NSBackingStoreBuffered |
| defer:NO]); |
| [sheet_window_ setReleasedWhenClosed:NO]; |
| sheet_.reset([[CustomConstrainedWindowSheet alloc] |
| initWithCustomWindow:sheet_window_]); |
| [sheet_ hideSheet]; |
| } |
| |
| virtual void SetUpOnMainThread() OVERRIDE { |
| AddTabAtIndex(1, GURL("about:blank"), content::PAGE_TRANSITION_LINK); |
| tab0_ = browser()->tab_strip_model()->GetWebContentsAt(0); |
| tab1_ = browser()->tab_strip_model()->GetWebContentsAt(1); |
| EXPECT_EQ(tab1_, browser()->tab_strip_model()->GetActiveWebContents()); |
| |
| controller_ = [BrowserWindowController browserWindowControllerForWindow: |
| browser()->window()->GetNativeWindow()]; |
| EXPECT_TRUE(controller_); |
| tab_view0_ = [[controller_ tabStripController] viewAtIndex:0]; |
| EXPECT_TRUE(tab_view0_); |
| tab_view1_ = [[controller_ tabStripController] viewAtIndex:1]; |
| EXPECT_TRUE(tab_view1_); |
| } |
| |
| protected: |
| base::scoped_nsobject<CustomConstrainedWindowSheet> sheet_; |
| base::scoped_nsobject<NSWindow> sheet_window_; |
| content::WebContents* tab0_; |
| content::WebContents* tab1_; |
| BrowserWindowController* controller_; |
| NSView* tab_view0_; |
| NSView* tab_view1_; |
| }; |
| |
| // Test that a sheet added to a inactive tab is not shown until the |
| // tab is activated. |
| IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, ShowInInactiveTab) { |
| // Show dialog in non active tab. |
| NiceMock<ConstrainedWindowDelegateMock> delegate; |
| ConstrainedWindowMac dialog(&delegate, tab0_, sheet_); |
| EXPECT_EQ(0.0, [sheet_window_ alphaValue]); |
| |
| // Switch to inactive tab. |
| browser()->tab_strip_model()->ActivateTabAt(0, true); |
| EXPECT_EQ(1.0, [sheet_window_ alphaValue]); |
| |
| dialog.CloseWebContentsModalDialog(); |
| } |
| |
| // If a tab has never been shown then the associated tab view for the web |
| // content will not be created. Verify that adding a constrained window to such |
| // a tab works correctly. |
| IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, ShowInUninitializedTab) { |
| scoped_ptr<content::WebContents> web_contents(content::WebContents::Create( |
| content::WebContents::CreateParams(browser()->profile()))); |
| bool was_blocked = false; |
| chrome::AddWebContents(browser(), NULL, web_contents.release(), |
| NEW_BACKGROUND_TAB, gfx::Rect(), false, &was_blocked); |
| content::WebContents* tab2 = |
| browser()->tab_strip_model()->GetWebContentsAt(2); |
| ASSERT_TRUE(tab2); |
| EXPECT_FALSE([tab2->GetNativeView() superview]); |
| |
| // Show dialog and verify that it's not visible yet. |
| NiceMock<ConstrainedWindowDelegateMock> delegate; |
| ConstrainedWindowMac dialog(&delegate, tab2, sheet_); |
| EXPECT_FALSE([sheet_window_ isVisible]); |
| |
| // Activate the tab and verify that the constrained window is shown. |
| browser()->tab_strip_model()->ActivateTabAt(2, true); |
| EXPECT_TRUE([tab2->GetNativeView() superview]); |
| EXPECT_TRUE([sheet_window_ isVisible]); |
| EXPECT_EQ(1.0, [sheet_window_ alphaValue]); |
| |
| dialog.CloseWebContentsModalDialog(); |
| } |
| |
| // Test that adding a sheet disables tab dragging. |
| IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, TabDragging) { |
| NiceMock<ConstrainedWindowDelegateMock> delegate; |
| ConstrainedWindowMac dialog(&delegate, tab1_, sheet_); |
| |
| // Verify that the dialog disables dragging. |
| EXPECT_TRUE([controller_ isTabDraggable:tab_view0_]); |
| EXPECT_FALSE([controller_ isTabDraggable:tab_view1_]); |
| |
| dialog.CloseWebContentsModalDialog(); |
| } |
| |
| // Test that closing a browser window with a sheet works. |
| IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, BrowserWindowClose) { |
| NiceMock<ConstrainedWindowDelegateMock> delegate; |
| ConstrainedWindowMac dialog(&delegate, tab1_, sheet_); |
| EXPECT_EQ(1.0, [sheet_window_ alphaValue]); |
| |
| // Close the browser window. |
| base::scoped_nsobject<NSWindow> browser_window( |
| [browser()->window()->GetNativeWindow() retain]); |
| EXPECT_TRUE([browser_window isVisible]); |
| [browser()->window()->GetNativeWindow() performClose:nil]; |
| EXPECT_FALSE([browser_window isVisible]); |
| } |
| |
| // Test that closing a tab with a sheet works. |
| IN_PROC_BROWSER_TEST_F(ConstrainedWindowMacTest, TabClose) { |
| NiceMock<ConstrainedWindowDelegateMock> delegate; |
| ConstrainedWindowMac dialog(&delegate, tab1_, sheet_); |
| EXPECT_EQ(1.0, [sheet_window_ alphaValue]); |
| |
| // Close the tab. |
| TabStripModel* tab_strip = browser()->tab_strip_model(); |
| EXPECT_EQ(2, tab_strip->count()); |
| EXPECT_TRUE(tab_strip->CloseWebContentsAt(1, |
| TabStripModel::CLOSE_USER_GESTURE)); |
| EXPECT_EQ(1, tab_strip->count()); |
| } |