background_contents_service_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2010 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 <string> 6 7#include "base/basictypes.h" 8#include "base/command_line.h" 9#include "base/scoped_ptr.h" 10#include "base/utf_string_conversions.h" 11#include "chrome/browser/background_contents_service.h" 12#include "chrome/browser/browser_list.h" 13#include "chrome/browser/prefs/pref_service.h" 14#include "chrome/browser/tab_contents/background_contents.h" 15#include "chrome/common/pref_names.h" 16#include "chrome/test/testing_browser_process.h" 17#include "chrome/test/testing_browser_process_test.h" 18#include "chrome/test/testing_profile.h" 19#include "googleurl/src/gurl.h" 20#include "testing/gtest/include/gtest/gtest.h" 21#include "testing/platform_test.h" 22 23class BackgroundContentsServiceTest : public TestingBrowserProcessTest { 24 public: 25 BackgroundContentsServiceTest() {} 26 ~BackgroundContentsServiceTest() {} 27 void SetUp() { 28 command_line_.reset(new CommandLine(CommandLine::NO_PROGRAM)); 29 } 30 31 DictionaryValue* GetPrefs(Profile* profile) { 32 return profile->GetPrefs()->GetMutableDictionary( 33 prefs::kRegisteredBackgroundContents); 34 } 35 36 // Returns the stored pref URL for the passed app id. 37 std::string GetPrefURLForApp(Profile* profile, const string16& appid) { 38 DictionaryValue* pref = GetPrefs(profile); 39 EXPECT_TRUE(pref->HasKey(UTF16ToUTF8(appid))); 40 DictionaryValue* value; 41 pref->GetDictionaryWithoutPathExpansion(UTF16ToUTF8(appid), &value); 42 std::string url; 43 value->GetString("url", &url); 44 return url; 45 } 46 47 scoped_ptr<CommandLine> command_line_; 48}; 49 50class MockBackgroundContents : public BackgroundContents { 51 public: 52 explicit MockBackgroundContents(Profile* profile) 53 : appid_(ASCIIToUTF16("app_id")), 54 profile_(profile) { 55 } 56 MockBackgroundContents(Profile* profile, const std::string& id) 57 : appid_(ASCIIToUTF16(id)), 58 profile_(profile) { 59 } 60 61 void SendOpenedNotification(BackgroundContentsService* service) { 62 string16 frame_name = ASCIIToUTF16("background"); 63 BackgroundContentsOpenedDetails details = { 64 this, frame_name, appid_ }; 65 service->BackgroundContentsOpened(&details); 66 } 67 68 virtual void Navigate(GURL url) { 69 url_ = url; 70 NotificationService::current()->Notify( 71 NotificationType::BACKGROUND_CONTENTS_NAVIGATED, 72 Source<Profile>(profile_), 73 Details<BackgroundContents>(this)); 74 } 75 virtual const GURL& GetURL() const { return url_; } 76 77 void MockClose(Profile* profile) { 78 NotificationService::current()->Notify( 79 NotificationType::BACKGROUND_CONTENTS_CLOSED, 80 Source<Profile>(profile), 81 Details<BackgroundContents>(this)); 82 delete this; 83 } 84 85 ~MockBackgroundContents() { 86 NotificationService::current()->Notify( 87 NotificationType::BACKGROUND_CONTENTS_DELETED, 88 Source<Profile>(profile_), 89 Details<BackgroundContents>(this)); 90 } 91 92 const string16& appid() { return appid_; } 93 94 private: 95 GURL url_; 96 97 // The ID of our parent application 98 string16 appid_; 99 100 // Parent profile 101 Profile* profile_; 102}; 103 104TEST_F(BackgroundContentsServiceTest, Create) { 105 // Check for creation and leaks. 106 TestingProfile profile; 107 BackgroundContentsService service(&profile, command_line_.get()); 108} 109 110TEST_F(BackgroundContentsServiceTest, BackgroundContentsCreateDestroy) { 111 TestingProfile profile; 112 BackgroundContentsService service(&profile, command_line_.get()); 113 MockBackgroundContents* contents = new MockBackgroundContents(&profile); 114 EXPECT_FALSE(service.IsTracked(contents)); 115 contents->SendOpenedNotification(&service); 116 EXPECT_TRUE(service.IsTracked(contents)); 117 delete contents; 118 EXPECT_FALSE(service.IsTracked(contents)); 119} 120 121TEST_F(BackgroundContentsServiceTest, BackgroundContentsUrlAdded) { 122 TestingProfile profile; 123 GetPrefs(&profile)->Clear(); 124 BackgroundContentsService service(&profile, command_line_.get()); 125 GURL orig_url; 126 GURL url("http://a/"); 127 GURL url2("http://a/"); 128 { 129 scoped_ptr<MockBackgroundContents> contents( 130 new MockBackgroundContents(&profile)); 131 EXPECT_EQ(0U, GetPrefs(&profile)->size()); 132 contents->SendOpenedNotification(&service); 133 134 contents->Navigate(url); 135 EXPECT_EQ(1U, GetPrefs(&profile)->size()); 136 EXPECT_EQ(url.spec(), GetPrefURLForApp(&profile, contents->appid())); 137 138 // Navigate the contents to a new url, should not change url. 139 contents->Navigate(url2); 140 EXPECT_EQ(1U, GetPrefs(&profile)->size()); 141 EXPECT_EQ(url.spec(), GetPrefURLForApp(&profile, contents->appid())); 142 } 143 // Contents are deleted, url should persist. 144 EXPECT_EQ(1U, GetPrefs(&profile)->size()); 145} 146 147TEST_F(BackgroundContentsServiceTest, BackgroundContentsUrlAddedAndClosed) { 148 TestingProfile profile; 149 GetPrefs(&profile)->Clear(); 150 BackgroundContentsService service(&profile, command_line_.get()); 151 GURL url("http://a/"); 152 MockBackgroundContents* contents = new MockBackgroundContents(&profile); 153 EXPECT_EQ(0U, GetPrefs(&profile)->size()); 154 contents->SendOpenedNotification(&service); 155 contents->Navigate(url); 156 EXPECT_EQ(1U, GetPrefs(&profile)->size()); 157 EXPECT_EQ(url.spec(), GetPrefURLForApp(&profile, contents->appid())); 158 159 // Fake a window closed by script. 160 contents->MockClose(&profile); 161 EXPECT_EQ(0U, GetPrefs(&profile)->size()); 162} 163 164// Test what happens if a BackgroundContents shuts down (say, due to a renderer 165// crash) then is restarted. Should not persist URL twice. 166TEST_F(BackgroundContentsServiceTest, RestartBackgroundContents) { 167 TestingProfile profile; 168 GetPrefs(&profile)->Clear(); 169 BackgroundContentsService service(&profile, command_line_.get()); 170 GURL url("http://a/"); 171 { 172 scoped_ptr<MockBackgroundContents> contents(new MockBackgroundContents( 173 &profile, "appid")); 174 contents->SendOpenedNotification(&service); 175 contents->Navigate(url); 176 EXPECT_EQ(1U, GetPrefs(&profile)->size()); 177 EXPECT_EQ(url.spec(), GetPrefURLForApp(&profile, contents->appid())); 178 } 179 // Contents deleted, url should be persisted. 180 EXPECT_EQ(1U, GetPrefs(&profile)->size()); 181 182 { 183 // Reopen the BackgroundContents to the same URL, we should not register the 184 // URL again. 185 scoped_ptr<MockBackgroundContents> contents(new MockBackgroundContents( 186 &profile, "appid")); 187 contents->SendOpenedNotification(&service); 188 contents->Navigate(url); 189 EXPECT_EQ(1U, GetPrefs(&profile)->size()); 190 } 191} 192 193// Ensures that BackgroundContentsService properly tracks the association 194// between a BackgroundContents and its parent extension, including 195// unregistering the BC when the extension is uninstalled. 196TEST_F(BackgroundContentsServiceTest, TestApplicationIDLinkage) { 197 TestingProfile profile; 198 BackgroundContentsService service(&profile, command_line_.get()); 199 GetPrefs(&profile)->Clear(); 200 201 EXPECT_EQ(NULL, service.GetAppBackgroundContents(ASCIIToUTF16("appid"))); 202 MockBackgroundContents* contents = new MockBackgroundContents(&profile, 203 "appid"); 204 scoped_ptr<MockBackgroundContents> contents2( 205 new MockBackgroundContents(&profile, "appid2")); 206 contents->SendOpenedNotification(&service); 207 EXPECT_EQ(contents, service.GetAppBackgroundContents(contents->appid())); 208 contents2->SendOpenedNotification(&service); 209 EXPECT_EQ(contents2.get(), service.GetAppBackgroundContents( 210 contents2->appid())); 211 EXPECT_EQ(0U, GetPrefs(&profile)->size()); 212 213 // Navigate the contents, then make sure the one associated with the extension 214 // is unregistered. 215 GURL url("http://a/"); 216 GURL url2("http://b/"); 217 contents->Navigate(url); 218 EXPECT_EQ(1U, GetPrefs(&profile)->size()); 219 contents2->Navigate(url2); 220 EXPECT_EQ(2U, GetPrefs(&profile)->size()); 221 service.ShutdownAssociatedBackgroundContents(ASCIIToUTF16("appid")); 222 EXPECT_FALSE(service.IsTracked(contents)); 223 EXPECT_EQ(NULL, service.GetAppBackgroundContents(ASCIIToUTF16("appid"))); 224 EXPECT_EQ(1U, GetPrefs(&profile)->size()); 225 EXPECT_EQ(url2.spec(), GetPrefURLForApp(&profile, contents2->appid())); 226} 227