1 // Copyright (c) 2013 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/startup/session_crashed_infobar_delegate.h" 6 7 #include "base/prefs/pref_registry_simple.h" 8 #include "base/prefs/testing_pref_service.h" 9 #include "base/run_loop.h" 10 #include "chrome/browser/infobars/infobar_service.h" 11 #include "chrome/browser/sessions/session_service_factory.h" 12 #include "chrome/browser/ui/tabs/tab_strip_model.h" 13 #include "chrome/common/pref_names.h" 14 #include "chrome/common/url_constants.h" 15 #include "chrome/test/base/browser_with_test_window_test.h" 16 #include "chrome/test/base/scoped_testing_local_state.h" 17 #include "chrome/test/base/testing_browser_process.h" 18 19 class SessionCrashedInfoBarDelegateUnitTest : public BrowserWithTestWindowTest { 20 public: 21 virtual void SetUp() OVERRIDE { 22 pref_service.registry() 23 ->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true); 24 pref_service.registry()->RegisterBooleanPref(prefs::kWasRestarted, false); 25 static_cast<TestingBrowserProcess*>(g_browser_process) 26 ->SetLocalState(&pref_service); 27 // This needs to be called after the local state is set, because it will 28 // create a browser which will try to read from the local state. 29 BrowserWithTestWindowTest::SetUp(); 30 } 31 32 virtual void TearDown() OVERRIDE { 33 static_cast<TestingBrowserProcess*>(g_browser_process)->SetLocalState(NULL); 34 BrowserWithTestWindowTest::TearDown(); 35 } 36 37 private: 38 TestingPrefServiceSimple pref_service; 39 }; 40 41 TEST_F(SessionCrashedInfoBarDelegateUnitTest, DetachingTabWithCrashedInfoBar) { 42 SessionServiceFactory::SetForTestProfile( 43 browser()->profile(), 44 static_cast<SessionService*>( 45 SessionServiceFactory::GetInstance()->BuildServiceInstanceFor( 46 browser()->profile()))); 47 48 // Create a browser which we can close during the test. 49 Browser::CreateParams params(browser()->profile(), 50 browser()->host_desktop_type()); 51 scoped_ptr<Browser> first_browser( 52 chrome::CreateBrowserWithTestWindowForParams(¶ms)); 53 AddTab(first_browser.get(), GURL(chrome::kChromeUINewTabURL)); 54 55 // Attach the crashed infobar to it. 56 SessionCrashedInfoBarDelegate::Create(first_browser.get()); 57 58 TabStripModel* tab_strip = first_browser->tab_strip_model(); 59 ASSERT_EQ(1, tab_strip->count()); 60 content::WebContents* web_contents = tab_strip->GetWebContentsAt(0); 61 InfoBarService* infobar_service = 62 InfoBarService::FromWebContents(web_contents); 63 EXPECT_EQ(1U, infobar_service->infobar_count()); 64 scoped_ptr<ConfirmInfoBarDelegate> infobar(InfoBarService::FromWebContents( 65 web_contents)->infobar_at(0)->AsConfirmInfoBarDelegate()); 66 ASSERT_TRUE(infobar); 67 68 // Open another browser. 69 scoped_ptr<Browser> opened_browser( 70 chrome::CreateBrowserWithTestWindowForParams(¶ms)); 71 72 // Move the tab which is destroying the crash info bar to the new browser. 73 tab_strip->DetachWebContentsAt(0); 74 tab_strip = opened_browser->tab_strip_model(); 75 tab_strip->AppendWebContents(web_contents, true); 76 77 // Close the original browser. 78 first_browser->window()->Close(); 79 first_browser.reset(); 80 81 ASSERT_EQ(1, tab_strip->count()); 82 web_contents = tab_strip->GetWebContentsAt(0); 83 infobar_service = InfoBarService::FromWebContents(web_contents); 84 EXPECT_EQ(1U, infobar_service->infobar_count()); 85 86 // This used to crash. 87 infobar->Accept(); 88 89 // Ramp down the test. 90 tab_strip->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE); 91 } 92