blob: b6eac81f057538a0d5a9fda9951df1d0a78ee40b [file] [log] [blame]
[email protected]3b63f8f42011-03-28 01:54:151// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]398206c2010-06-21 01:46:082// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]0bc24b52011-01-11 01:19:475#include <string>
[email protected]398206c2010-06-21 01:46:086
7#include "base/basictypes.h"
8#include "base/command_line.h"
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/scoped_ptr.h"
[email protected]398206c2010-06-21 01:46:0810#include "base/utf_string_conversions.h"
[email protected]a07676b22011-06-17 16:36:5311#include "chrome/browser/background/background_contents_service.h"
[email protected]37858e52010-08-26 00:22:0212#include "chrome/browser/prefs/pref_service.h"
[email protected]f33bee52011-03-31 09:18:4313#include "chrome/browser/prefs/scoped_user_pref_update.h"
[email protected]398206c2010-06-21 01:46:0814#include "chrome/browser/tab_contents/background_contents.h"
[email protected]71b73f02011-04-06 15:57:2915#include "chrome/browser/ui/browser_list.h"
[email protected]432115822011-07-10 15:52:2716#include "chrome/common/chrome_notification_types.h"
[email protected]398206c2010-06-21 01:46:0817#include "chrome/common/pref_names.h"
[email protected]bf9257742011-08-11 21:01:1518#include "chrome/test/base/testing_browser_process.h"
[email protected]a4ff9eae2011-08-01 19:58:1619#include "chrome/test/base/testing_profile.h"
[email protected]398206c2010-06-21 01:46:0820#include "googleurl/src/gurl.h"
21#include "testing/gtest/include/gtest/gtest.h"
22#include "testing/platform_test.h"
23
[email protected]583844c2011-08-27 00:38:3524class BackgroundContentsServiceTest : public testing::Test {
[email protected]398206c2010-06-21 01:46:0825 public:
26 BackgroundContentsServiceTest() {}
27 ~BackgroundContentsServiceTest() {}
28 void SetUp() {
[email protected]947446b2010-10-21 03:36:3129 command_line_.reset(new CommandLine(CommandLine::NO_PROGRAM));
[email protected]398206c2010-06-21 01:46:0830 }
31
[email protected]f33bee52011-03-31 09:18:4332 const DictionaryValue* GetPrefs(Profile* profile) {
33 return profile->GetPrefs()->GetDictionary(
[email protected]398206c2010-06-21 01:46:0834 prefs::kRegisteredBackgroundContents);
35 }
36
[email protected]f33bee52011-03-31 09:18:4337 void ClearPrefs(Profile* profile) {
38 profile->GetPrefs()->ClearPref(prefs::kRegisteredBackgroundContents);
39 }
40
[email protected]398206c2010-06-21 01:46:0841 // Returns the stored pref URL for the passed app id.
42 std::string GetPrefURLForApp(Profile* profile, const string16& appid) {
[email protected]f33bee52011-03-31 09:18:4343 const DictionaryValue* pref = GetPrefs(profile);
[email protected]99922662010-08-17 16:24:2544 EXPECT_TRUE(pref->HasKey(UTF16ToUTF8(appid)));
[email protected]398206c2010-06-21 01:46:0845 DictionaryValue* value;
[email protected]90018542010-08-14 01:49:1446 pref->GetDictionaryWithoutPathExpansion(UTF16ToUTF8(appid), &value);
[email protected]398206c2010-06-21 01:46:0847 std::string url;
[email protected]90018542010-08-14 01:49:1448 value->GetString("url", &url);
[email protected]398206c2010-06-21 01:46:0849 return url;
50 }
51
52 scoped_ptr<CommandLine> command_line_;
53};
54
55class MockBackgroundContents : public BackgroundContents {
56 public:
57 explicit MockBackgroundContents(Profile* profile)
58 : appid_(ASCIIToUTF16("app_id")),
59 profile_(profile) {
60 }
61 MockBackgroundContents(Profile* profile, const std::string& id)
62 : appid_(ASCIIToUTF16(id)),
63 profile_(profile) {
64 }
65
[email protected]da58f5b12010-11-10 19:31:1266 void SendOpenedNotification(BackgroundContentsService* service) {
[email protected]398206c2010-06-21 01:46:0867 string16 frame_name = ASCIIToUTF16("background");
68 BackgroundContentsOpenedDetails details = {
69 this, frame_name, appid_ };
[email protected]da58f5b12010-11-10 19:31:1270 service->BackgroundContentsOpened(&details);
[email protected]398206c2010-06-21 01:46:0871 }
72
[email protected]3bf7b362010-08-04 17:47:0673 virtual void Navigate(GURL url) {
[email protected]398206c2010-06-21 01:46:0874 url_ = url;
75 NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:2776 chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED,
[email protected]398206c2010-06-21 01:46:0877 Source<Profile>(profile_),
78 Details<BackgroundContents>(this));
79 }
80 virtual const GURL& GetURL() const { return url_; }
81
82 void MockClose(Profile* profile) {
83 NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:2784 chrome::NOTIFICATION_BACKGROUND_CONTENTS_CLOSED,
[email protected]398206c2010-06-21 01:46:0885 Source<Profile>(profile),
86 Details<BackgroundContents>(this));
87 delete this;
88 }
89
90 ~MockBackgroundContents() {
91 NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:2792 chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED,
[email protected]398206c2010-06-21 01:46:0893 Source<Profile>(profile_),
94 Details<BackgroundContents>(this));
95 }
96
97 const string16& appid() { return appid_; }
98
99 private:
100 GURL url_;
101
102 // The ID of our parent application
103 string16 appid_;
104
105 // Parent profile
106 Profile* profile_;
107};
108
109TEST_F(BackgroundContentsServiceTest, Create) {
110 // Check for creation and leaks.
111 TestingProfile profile;
112 BackgroundContentsService service(&profile, command_line_.get());
113}
114
115TEST_F(BackgroundContentsServiceTest, BackgroundContentsCreateDestroy) {
116 TestingProfile profile;
117 BackgroundContentsService service(&profile, command_line_.get());
[email protected]398206c2010-06-21 01:46:08118 MockBackgroundContents* contents = new MockBackgroundContents(&profile);
119 EXPECT_FALSE(service.IsTracked(contents));
[email protected]da58f5b12010-11-10 19:31:12120 contents->SendOpenedNotification(&service);
[email protected]398206c2010-06-21 01:46:08121 EXPECT_TRUE(service.IsTracked(contents));
122 delete contents;
[email protected]398206c2010-06-21 01:46:08123 EXPECT_FALSE(service.IsTracked(contents));
124}
125
126TEST_F(BackgroundContentsServiceTest, BackgroundContentsUrlAdded) {
127 TestingProfile profile;
[email protected]f33bee52011-03-31 09:18:43128 ClearPrefs(&profile);
[email protected]398206c2010-06-21 01:46:08129 BackgroundContentsService service(&profile, command_line_.get());
130 GURL orig_url;
131 GURL url("http://a/");
132 GURL url2("http://a/");
133 {
134 scoped_ptr<MockBackgroundContents> contents(
135 new MockBackgroundContents(&profile));
136 EXPECT_EQ(0U, GetPrefs(&profile)->size());
[email protected]da58f5b12010-11-10 19:31:12137 contents->SendOpenedNotification(&service);
[email protected]398206c2010-06-21 01:46:08138
139 contents->Navigate(url);
140 EXPECT_EQ(1U, GetPrefs(&profile)->size());
141 EXPECT_EQ(url.spec(), GetPrefURLForApp(&profile, contents->appid()));
142
143 // Navigate the contents to a new url, should not change url.
144 contents->Navigate(url2);
145 EXPECT_EQ(1U, GetPrefs(&profile)->size());
146 EXPECT_EQ(url.spec(), GetPrefURLForApp(&profile, contents->appid()));
[email protected]398206c2010-06-21 01:46:08147 }
148 // Contents are deleted, url should persist.
149 EXPECT_EQ(1U, GetPrefs(&profile)->size());
150}
151
152TEST_F(BackgroundContentsServiceTest, BackgroundContentsUrlAddedAndClosed) {
153 TestingProfile profile;
[email protected]f33bee52011-03-31 09:18:43154 ClearPrefs(&profile);
[email protected]398206c2010-06-21 01:46:08155 BackgroundContentsService service(&profile, command_line_.get());
156 GURL url("http://a/");
157 MockBackgroundContents* contents = new MockBackgroundContents(&profile);
158 EXPECT_EQ(0U, GetPrefs(&profile)->size());
[email protected]da58f5b12010-11-10 19:31:12159 contents->SendOpenedNotification(&service);
[email protected]398206c2010-06-21 01:46:08160 contents->Navigate(url);
161 EXPECT_EQ(1U, GetPrefs(&profile)->size());
162 EXPECT_EQ(url.spec(), GetPrefURLForApp(&profile, contents->appid()));
163
164 // Fake a window closed by script.
165 contents->MockClose(&profile);
166 EXPECT_EQ(0U, GetPrefs(&profile)->size());
167}
168
169// Test what happens if a BackgroundContents shuts down (say, due to a renderer
170// crash) then is restarted. Should not persist URL twice.
171TEST_F(BackgroundContentsServiceTest, RestartBackgroundContents) {
172 TestingProfile profile;
[email protected]f33bee52011-03-31 09:18:43173 ClearPrefs(&profile);
[email protected]398206c2010-06-21 01:46:08174 BackgroundContentsService service(&profile, command_line_.get());
175 GURL url("http://a/");
176 {
177 scoped_ptr<MockBackgroundContents> contents(new MockBackgroundContents(
178 &profile, "appid"));
[email protected]da58f5b12010-11-10 19:31:12179 contents->SendOpenedNotification(&service);
[email protected]398206c2010-06-21 01:46:08180 contents->Navigate(url);
181 EXPECT_EQ(1U, GetPrefs(&profile)->size());
182 EXPECT_EQ(url.spec(), GetPrefURLForApp(&profile, contents->appid()));
183 }
184 // Contents deleted, url should be persisted.
185 EXPECT_EQ(1U, GetPrefs(&profile)->size());
186
187 {
188 // Reopen the BackgroundContents to the same URL, we should not register the
189 // URL again.
190 scoped_ptr<MockBackgroundContents> contents(new MockBackgroundContents(
191 &profile, "appid"));
[email protected]da58f5b12010-11-10 19:31:12192 contents->SendOpenedNotification(&service);
[email protected]398206c2010-06-21 01:46:08193 contents->Navigate(url);
194 EXPECT_EQ(1U, GetPrefs(&profile)->size());
195 }
196}
197
198// Ensures that BackgroundContentsService properly tracks the association
199// between a BackgroundContents and its parent extension, including
200// unregistering the BC when the extension is uninstalled.
201TEST_F(BackgroundContentsServiceTest, TestApplicationIDLinkage) {
202 TestingProfile profile;
203 BackgroundContentsService service(&profile, command_line_.get());
[email protected]f33bee52011-03-31 09:18:43204 ClearPrefs(&profile);
[email protected]398206c2010-06-21 01:46:08205
206 EXPECT_EQ(NULL, service.GetAppBackgroundContents(ASCIIToUTF16("appid")));
207 MockBackgroundContents* contents = new MockBackgroundContents(&profile,
208 "appid");
209 scoped_ptr<MockBackgroundContents> contents2(
210 new MockBackgroundContents(&profile, "appid2"));
[email protected]da58f5b12010-11-10 19:31:12211 contents->SendOpenedNotification(&service);
[email protected]398206c2010-06-21 01:46:08212 EXPECT_EQ(contents, service.GetAppBackgroundContents(contents->appid()));
[email protected]da58f5b12010-11-10 19:31:12213 contents2->SendOpenedNotification(&service);
[email protected]398206c2010-06-21 01:46:08214 EXPECT_EQ(contents2.get(), service.GetAppBackgroundContents(
215 contents2->appid()));
216 EXPECT_EQ(0U, GetPrefs(&profile)->size());
217
218 // Navigate the contents, then make sure the one associated with the extension
219 // is unregistered.
220 GURL url("http://a/");
221 GURL url2("http://b/");
222 contents->Navigate(url);
223 EXPECT_EQ(1U, GetPrefs(&profile)->size());
224 contents2->Navigate(url2);
225 EXPECT_EQ(2U, GetPrefs(&profile)->size());
226 service.ShutdownAssociatedBackgroundContents(ASCIIToUTF16("appid"));
227 EXPECT_FALSE(service.IsTracked(contents));
228 EXPECT_EQ(NULL, service.GetAppBackgroundContents(ASCIIToUTF16("appid")));
229 EXPECT_EQ(1U, GetPrefs(&profile)->size());
230 EXPECT_EQ(url2.spec(), GetPrefURLForApp(&profile, contents2->appid()));
231}