OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_gcm_app_handler.h" | 5 #include "chrome/browser/extensions/extension_gcm_app_handler.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/file_util.h" | |
12 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
14 #include "base/files/scoped_temp_dir.h" | |
13 #include "base/location.h" | 15 #include "base/location.h" |
14 #include "base/logging.h" | 16 #include "base/logging.h" |
15 #include "base/memory/ref_counted.h" | 17 #include "base/memory/ref_counted.h" |
16 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
19 #include "base/path_service.h" | |
17 #include "base/prefs/pref_service.h" | 20 #include "base/prefs/pref_service.h" |
18 #include "base/run_loop.h" | 21 #include "base/run_loop.h" |
19 #include "base/values.h" | 22 #include "base/values.h" |
23 #include "chrome/browser/chrome_notification_types.h" | |
20 #include "chrome/browser/extensions/extension_service.h" | 24 #include "chrome/browser/extensions/extension_service.h" |
21 #include "chrome/browser/extensions/test_extension_service.h" | 25 #include "chrome/browser/extensions/test_extension_service.h" |
22 #include "chrome/browser/extensions/test_extension_system.h" | 26 #include "chrome/browser/extensions/test_extension_system.h" |
23 #include "chrome/browser/profiles/profile.h" | 27 #include "chrome/browser/profiles/profile.h" |
24 #include "chrome/browser/services/gcm/fake_signin_manager.h" | 28 #include "chrome/browser/services/gcm/fake_signin_manager.h" |
25 #include "chrome/browser/services/gcm/gcm_profile_service.h" | 29 #include "chrome/browser/services/gcm/gcm_profile_service.h" |
26 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" | 30 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" |
27 #include "chrome/browser/signin/signin_manager_factory.h" | 31 #include "chrome/browser/signin/signin_manager_factory.h" |
32 #include "chrome/common/chrome_paths.h" | |
28 #include "chrome/common/pref_names.h" | 33 #include "chrome/common/pref_names.h" |
29 #include "chrome/test/base/testing_profile.h" | 34 #include "chrome/test/base/testing_profile.h" |
30 #include "components/gcm_driver/fake_gcm_app_handler.h" | 35 #include "components/gcm_driver/fake_gcm_app_handler.h" |
31 #include "components/gcm_driver/fake_gcm_client.h" | 36 #include "components/gcm_driver/fake_gcm_client.h" |
32 #include "components/gcm_driver/fake_gcm_client_factory.h" | 37 #include "components/gcm_driver/fake_gcm_client_factory.h" |
33 #include "components/gcm_driver/gcm_client_factory.h" | 38 #include "components/gcm_driver/gcm_client_factory.h" |
34 #include "components/gcm_driver/gcm_driver.h" | 39 #include "components/gcm_driver/gcm_driver.h" |
35 #include "components/keyed_service/core/keyed_service.h" | 40 #include "components/keyed_service/core/keyed_service.h" |
36 #include "content/public/browser/browser_context.h" | 41 #include "content/public/browser/browser_context.h" |
37 #include "content/public/browser/browser_thread.h" | 42 #include "content/public/browser/browser_thread.h" |
38 #include "content/public/test/test_browser_thread_bundle.h" | 43 #include "content/public/test/test_browser_thread_bundle.h" |
44 #include "content/public/test/test_utils.h" | |
39 #include "extensions/browser/extension_system.h" | 45 #include "extensions/browser/extension_system.h" |
40 #include "extensions/common/extension.h" | 46 #include "extensions/common/extension.h" |
41 #include "extensions/common/manifest.h" | 47 #include "extensions/common/manifest.h" |
42 #include "extensions/common/manifest_constants.h" | 48 #include "extensions/common/manifest_constants.h" |
43 #include "extensions/common/permissions/api_permission.h" | 49 #include "extensions/common/permissions/api_permission.h" |
44 #include "extensions/common/permissions/permissions_data.h" | 50 #include "extensions/common/permissions/permissions_data.h" |
45 #include "testing/gtest/include/gtest/gtest.h" | 51 #include "testing/gtest/include/gtest/gtest.h" |
46 | 52 |
47 #if !defined(OS_ANDROID) | 53 #if !defined(OS_ANDROID) |
48 #include "chrome/browser/extensions/api/gcm/gcm_api.h" | 54 #include "chrome/browser/extensions/api/gcm/gcm_api.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
124 scoped_ptr<base::RunLoop> run_loop_; | 130 scoped_ptr<base::RunLoop> run_loop_; |
125 | 131 |
126 DISALLOW_COPY_AND_ASSIGN(Waiter); | 132 DISALLOW_COPY_AND_ASSIGN(Waiter); |
127 }; | 133 }; |
128 | 134 |
129 class FakeExtensionGCMAppHandler : public ExtensionGCMAppHandler { | 135 class FakeExtensionGCMAppHandler : public ExtensionGCMAppHandler { |
130 public: | 136 public: |
131 FakeExtensionGCMAppHandler(Profile* profile, Waiter* waiter) | 137 FakeExtensionGCMAppHandler(Profile* profile, Waiter* waiter) |
132 : ExtensionGCMAppHandler(profile), | 138 : ExtensionGCMAppHandler(profile), |
133 waiter_(waiter), | 139 waiter_(waiter), |
134 unregistration_result_(gcm::GCMClient::UNKNOWN_ERROR) { | 140 unregistration_result_(gcm::GCMClient::UNKNOWN_ERROR), |
141 add_count_(0), | |
142 remove_count_(0) { | |
135 } | 143 } |
136 | 144 |
137 virtual ~FakeExtensionGCMAppHandler() { | 145 virtual ~FakeExtensionGCMAppHandler() { |
138 } | 146 } |
139 | 147 |
140 virtual void OnMessage( | 148 virtual void OnMessage( |
141 const std::string& app_id, | 149 const std::string& app_id, |
142 const gcm::GCMClient::IncomingMessage& message) OVERRIDE { | 150 const gcm::GCMClient::IncomingMessage& message) OVERRIDE { |
143 } | 151 } |
144 | 152 |
145 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE { | 153 virtual void OnMessagesDeleted(const std::string& app_id) OVERRIDE { |
146 } | 154 } |
147 | 155 |
148 virtual void OnSendError( | 156 virtual void OnSendError( |
149 const std::string& app_id, | 157 const std::string& app_id, |
150 const gcm::GCMClient::SendErrorDetails& send_error_details) OVERRIDE { | 158 const gcm::GCMClient::SendErrorDetails& send_error_details) OVERRIDE { |
151 } | 159 } |
152 | 160 |
153 virtual void OnUnregisterCompleted(const std::string& app_id, | 161 virtual void OnUnregisterCompleted(const std::string& app_id, |
154 gcm::GCMClient::Result result) OVERRIDE { | 162 gcm::GCMClient::Result result) OVERRIDE { |
155 unregistration_result_ = result; | 163 unregistration_result_ = result; |
156 waiter_->SignalCompleted(); | 164 waiter_->SignalCompleted(); |
157 } | 165 } |
158 | 166 |
167 virtual void AddAppHandler(const std::string& app_id) OVERRIDE { | |
fgorski
2014/06/12 21:38:32
There is a DCHECK for not adding duplicates in GCM
jianli
2014/06/12 21:48:31
Then it will get caught by the DCHECK assert. Here
fgorski
2014/06/13 15:20:21
Let's discuss it today.
| |
168 size_t old_size = GetGCMDriver()->app_handlers().size(); | |
169 ExtensionGCMAppHandler::AddAppHandler(app_id); | |
170 if (old_size < GetGCMDriver()->app_handlers().size()) | |
171 add_count_++; | |
172 } | |
173 | |
174 virtual void RemoveAppHandler(const std::string& app_id) OVERRIDE{ | |
175 size_t old_size = GetGCMDriver()->app_handlers().size(); | |
176 ExtensionGCMAppHandler::RemoveAppHandler(app_id); | |
177 if (old_size > GetGCMDriver()->app_handlers().size()) | |
178 remove_count_++; | |
179 } | |
180 | |
159 gcm::GCMClient::Result unregistration_result() const { | 181 gcm::GCMClient::Result unregistration_result() const { |
160 return unregistration_result_; | 182 return unregistration_result_; |
161 } | 183 } |
184 int add_count() const { return add_count_; } | |
185 int remove_count() const { return remove_count_; } | |
162 | 186 |
163 private: | 187 private: |
164 Waiter* waiter_; | 188 Waiter* waiter_; |
165 gcm::GCMClient::Result unregistration_result_; | 189 gcm::GCMClient::Result unregistration_result_; |
190 int add_count_; | |
191 int remove_count_; | |
166 | 192 |
167 DISALLOW_COPY_AND_ASSIGN(FakeExtensionGCMAppHandler); | 193 DISALLOW_COPY_AND_ASSIGN(FakeExtensionGCMAppHandler); |
168 }; | 194 }; |
169 | 195 |
170 class ExtensionGCMAppHandlerTest : public testing::Test { | 196 class ExtensionGCMAppHandlerTest : public testing::Test { |
171 public: | 197 public: |
172 static KeyedService* BuildGCMProfileService( | 198 static KeyedService* BuildGCMProfileService( |
173 content::BrowserContext* context) { | 199 content::BrowserContext* context) { |
174 return new gcm::GCMProfileService( | 200 return new gcm::GCMProfileService( |
175 Profile::FromBrowserContext(context), | 201 Profile::FromBrowserContext(context), |
176 scoped_ptr<gcm::GCMClientFactory>(new gcm::FakeGCMClientFactory( | 202 scoped_ptr<gcm::GCMClientFactory>(new gcm::FakeGCMClientFactory( |
177 gcm::FakeGCMClient::NO_DELAY_START, | 203 gcm::FakeGCMClient::NO_DELAY_START, |
178 content::BrowserThread::GetMessageLoopProxyForThread( | 204 content::BrowserThread::GetMessageLoopProxyForThread( |
179 content::BrowserThread::UI), | 205 content::BrowserThread::UI), |
180 content::BrowserThread::GetMessageLoopProxyForThread( | 206 content::BrowserThread::GetMessageLoopProxyForThread( |
181 content::BrowserThread::IO)))); | 207 content::BrowserThread::IO)))); |
182 } | 208 } |
183 | 209 |
184 ExtensionGCMAppHandlerTest() | 210 ExtensionGCMAppHandlerTest() |
185 : extension_service_(NULL), | 211 : extension_service_(NULL), |
186 registration_result_(gcm::GCMClient::UNKNOWN_ERROR), | 212 registration_result_(gcm::GCMClient::UNKNOWN_ERROR), |
187 unregistration_result_(gcm::GCMClient::UNKNOWN_ERROR) { | 213 unregistration_result_(gcm::GCMClient::UNKNOWN_ERROR) { |
188 } | 214 } |
189 | 215 |
190 virtual ~ExtensionGCMAppHandlerTest() { | 216 virtual ~ExtensionGCMAppHandlerTest() { |
191 } | 217 } |
192 | 218 |
193 // Overridden from test::Test: | 219 // Overridden from test::Test: |
194 virtual void SetUp() OVERRIDE { | 220 virtual void SetUp() OVERRIDE { |
221 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
222 | |
195 // Make BrowserThread work in unittest. | 223 // Make BrowserThread work in unittest. |
196 thread_bundle_.reset(new content::TestBrowserThreadBundle( | 224 thread_bundle_.reset(new content::TestBrowserThreadBundle( |
197 content::TestBrowserThreadBundle::REAL_IO_THREAD)); | 225 content::TestBrowserThreadBundle::REAL_IO_THREAD)); |
198 | 226 |
227 // Allow extension update to unpack crx in process. | |
228 in_process_utility_thread_helper_.reset( | |
229 new content::InProcessUtilityThreadHelper); | |
230 | |
199 // This is needed to create extension service under CrOS. | 231 // This is needed to create extension service under CrOS. |
200 #if defined(OS_CHROMEOS) | 232 #if defined(OS_CHROMEOS) |
201 test_user_manager_.reset(new chromeos::ScopedTestUserManager()); | 233 test_user_manager_.reset(new chromeos::ScopedTestUserManager()); |
202 #endif | 234 #endif |
203 | 235 |
204 // Create a new profile. | 236 // Create a new profile. |
205 TestingProfile::Builder builder; | 237 TestingProfile::Builder builder; |
206 builder.AddTestingFactory(SigninManagerFactory::GetInstance(), | 238 builder.AddTestingFactory(SigninManagerFactory::GetInstance(), |
207 gcm::FakeSigninManager::Build); | 239 gcm::FakeSigninManager::Build); |
208 profile_ = builder.Build(); | 240 profile_ = builder.Build(); |
209 signin_manager_ = static_cast<gcm::FakeSigninManager*>( | 241 signin_manager_ = static_cast<gcm::FakeSigninManager*>( |
210 SigninManagerFactory::GetInstance()->GetForProfile(profile_.get())); | 242 SigninManagerFactory::GetInstance()->GetForProfile(profile_.get())); |
211 | 243 |
212 // Create extension service in order to uninstall the extension. | 244 // Create extension service in order to uninstall the extension. |
213 TestExtensionSystem* extension_system( | 245 TestExtensionSystem* extension_system( |
214 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile()))); | 246 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile()))); |
247 base::FilePath extensions_install_dir = | |
248 temp_dir_.path().Append(FILE_PATH_LITERAL("Extensions")); | |
215 extension_system->CreateExtensionService( | 249 extension_system->CreateExtensionService( |
216 CommandLine::ForCurrentProcess(), base::FilePath(), false); | 250 CommandLine::ForCurrentProcess(), extensions_install_dir, false); |
217 extension_service_ = extension_system->Get(profile())->extension_service(); | 251 extension_service_ = extension_system->Get(profile())->extension_service(); |
252 extension_service_->set_extensions_enabled(true); | |
253 extension_service_->set_show_extensions_prompts(false); | |
254 extension_service_->set_install_updates_when_idle_for_test(false); | |
218 | 255 |
219 // Enable GCM such that tests could be run on all channels. | 256 // Enable GCM such that tests could be run on all channels. |
220 profile()->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true); | 257 profile()->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true); |
221 | 258 |
222 // Create GCMProfileService that talks with fake GCMClient. | 259 // Create GCMProfileService that talks with fake GCMClient. |
223 gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse( | 260 gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
224 profile(), &ExtensionGCMAppHandlerTest::BuildGCMProfileService); | 261 profile(), &ExtensionGCMAppHandlerTest::BuildGCMProfileService); |
225 | 262 |
226 // Create a fake version of ExtensionGCMAppHandler. | 263 // Create a fake version of ExtensionGCMAppHandler. |
227 gcm_app_handler_.reset(new FakeExtensionGCMAppHandler(profile(), &waiter_)); | 264 gcm_app_handler_.reset(new FakeExtensionGCMAppHandler(profile(), &waiter_)); |
228 } | 265 } |
229 | 266 |
230 virtual void TearDown() OVERRIDE { | 267 virtual void TearDown() OVERRIDE { |
231 #if defined(OS_CHROMEOS) | 268 #if defined(OS_CHROMEOS) |
232 test_user_manager_.reset(); | 269 test_user_manager_.reset(); |
233 #endif | 270 #endif |
234 | 271 |
235 waiter_.PumpUILoop(); | 272 waiter_.PumpUILoop(); |
236 } | 273 } |
237 | 274 |
238 // Returns a barebones test extension. | 275 // Returns a barebones test extension. |
239 scoped_refptr<Extension> CreateExtension() { | 276 scoped_refptr<Extension> CreateExtension() { |
240 #if defined(OS_WIN) | |
241 base::FilePath path(FILE_PATH_LITERAL("c:\\foo")); | |
242 #elif defined(OS_POSIX) | |
243 base::FilePath path(FILE_PATH_LITERAL("/foo")); | |
244 #endif | |
245 | |
246 base::DictionaryValue manifest; | 277 base::DictionaryValue manifest; |
247 manifest.SetString(manifest_keys::kVersion, "1.0.0.0"); | 278 manifest.SetString(manifest_keys::kVersion, "1.0.0.0"); |
248 manifest.SetString(manifest_keys::kName, kTestExtensionName); | 279 manifest.SetString(manifest_keys::kName, kTestExtensionName); |
249 base::ListValue* permission_list = new base::ListValue; | 280 base::ListValue* permission_list = new base::ListValue; |
250 permission_list->Append(base::Value::CreateStringValue("gcm")); | 281 permission_list->Append(base::Value::CreateStringValue("gcm")); |
251 manifest.Set(manifest_keys::kPermissions, permission_list); | 282 manifest.Set(manifest_keys::kPermissions, permission_list); |
252 | 283 |
253 std::string error; | 284 std::string error; |
254 scoped_refptr<Extension> extension = Extension::Create( | 285 scoped_refptr<Extension> extension = Extension::Create( |
255 path.AppendASCII(kTestExtensionName), | 286 temp_dir_.path(), |
256 Manifest::INVALID_LOCATION, | 287 Manifest::UNPACKED, |
257 manifest, | 288 manifest, |
258 Extension::NO_FLAGS, | 289 Extension::NO_FLAGS, |
290 "ldnnhddmnhbkjipkidpdiheffobcpfmf", | |
259 &error); | 291 &error); |
260 EXPECT_TRUE(extension.get()) << error; | 292 EXPECT_TRUE(extension.get()) << error; |
261 EXPECT_TRUE( | 293 EXPECT_TRUE( |
262 extension->permissions_data()->HasAPIPermission(APIPermission::kGcm)); | 294 extension->permissions_data()->HasAPIPermission(APIPermission::kGcm)); |
263 | 295 |
264 return extension; | 296 return extension; |
265 } | 297 } |
266 | 298 |
267 void LoadExtension(const Extension* extension) { | 299 void LoadExtension(const Extension* extension) { |
268 extension_service_->AddExtension(extension); | 300 extension_service_->AddExtension(extension); |
269 } | 301 } |
270 | 302 |
303 static bool IsCrxInstallerDone(extensions::CrxInstaller** installer, | |
304 const content::NotificationSource& source, | |
305 const content::NotificationDetails& details) { | |
306 return content::Source<extensions::CrxInstaller>(source).ptr() == | |
307 *installer; | |
308 } | |
309 | |
310 void UpdateExtension(const Extension* extension) { | |
311 base::FilePath data_dir; | |
312 if (!PathService::Get(chrome::DIR_TEST_DATA, &data_dir)) { | |
313 ADD_FAILURE(); | |
314 return; | |
315 } | |
316 data_dir = data_dir.AppendASCII("extensions"); | |
317 data_dir = data_dir.AppendASCII("gcm2.crx"); | |
318 | |
319 base::FilePath path = temp_dir_.path(); | |
320 path = path.Append(data_dir.BaseName()); | |
321 ASSERT_TRUE(base::CopyFile(data_dir, path)); | |
322 | |
323 extensions::CrxInstaller* installer = NULL; | |
324 content::WindowedNotificationObserver observer( | |
325 chrome::NOTIFICATION_CRX_INSTALLER_DONE, | |
326 base::Bind(&IsCrxInstallerDone, &installer)); | |
327 extension_service_->UpdateExtension( | |
328 extension->id(), path, true, &installer); | |
329 | |
330 if (installer) | |
331 observer.Wait(); | |
332 } | |
333 | |
271 void DisableExtension(const Extension* extension) { | 334 void DisableExtension(const Extension* extension) { |
272 extension_service_->DisableExtension( | 335 extension_service_->DisableExtension( |
273 extension->id(), Extension::DISABLE_USER_ACTION); | 336 extension->id(), Extension::DISABLE_USER_ACTION); |
274 } | 337 } |
275 | 338 |
276 void EnableExtension(const Extension* extension) { | 339 void EnableExtension(const Extension* extension) { |
277 extension_service_->EnableExtension(extension->id()); | 340 extension_service_->EnableExtension(extension->id()); |
278 } | 341 } |
279 | 342 |
280 void UninstallExtension(const Extension* extension) { | 343 void UninstallExtension(const Extension* extension) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
321 } | 384 } |
322 gcm::GCMClient::Result registration_result() const { | 385 gcm::GCMClient::Result registration_result() const { |
323 return registration_result_; | 386 return registration_result_; |
324 } | 387 } |
325 gcm::GCMClient::Result unregistration_result() const { | 388 gcm::GCMClient::Result unregistration_result() const { |
326 return unregistration_result_; | 389 return unregistration_result_; |
327 } | 390 } |
328 | 391 |
329 private: | 392 private: |
330 scoped_ptr<content::TestBrowserThreadBundle> thread_bundle_; | 393 scoped_ptr<content::TestBrowserThreadBundle> thread_bundle_; |
394 scoped_ptr<content::InProcessUtilityThreadHelper> | |
395 in_process_utility_thread_helper_; | |
331 scoped_ptr<TestingProfile> profile_; | 396 scoped_ptr<TestingProfile> profile_; |
332 ExtensionService* extension_service_; // Not owned. | 397 ExtensionService* extension_service_; // Not owned. |
333 gcm::FakeSigninManager* signin_manager_; // Not owned. | 398 gcm::FakeSigninManager* signin_manager_; // Not owned. |
399 base::ScopedTempDir temp_dir_; | |
334 | 400 |
335 // This is needed to create extension service under CrOS. | 401 // This is needed to create extension service under CrOS. |
336 #if defined(OS_CHROMEOS) | 402 #if defined(OS_CHROMEOS) |
337 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; | 403 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; |
338 chromeos::ScopedTestCrosSettings test_cros_settings_; | 404 chromeos::ScopedTestCrosSettings test_cros_settings_; |
339 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_; | 405 scoped_ptr<chromeos::ScopedTestUserManager> test_user_manager_; |
340 #endif | 406 #endif |
341 | 407 |
342 Waiter waiter_; | 408 Waiter waiter_; |
343 scoped_ptr<FakeExtensionGCMAppHandler> gcm_app_handler_; | 409 scoped_ptr<FakeExtensionGCMAppHandler> gcm_app_handler_; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
393 // Unregistration should be triggered when the extension is uninstalled. | 459 // Unregistration should be triggered when the extension is uninstalled. |
394 UninstallExtension(extension); | 460 UninstallExtension(extension); |
395 waiter()->WaitUntilCompleted(); | 461 waiter()->WaitUntilCompleted(); |
396 EXPECT_EQ(gcm::GCMClient::SUCCESS, | 462 EXPECT_EQ(gcm::GCMClient::SUCCESS, |
397 gcm_app_handler()->unregistration_result()); | 463 gcm_app_handler()->unregistration_result()); |
398 | 464 |
399 // Clean up. | 465 // Clean up. |
400 GetGCMDriver()->RemoveAppHandler("Foo"); | 466 GetGCMDriver()->RemoveAppHandler("Foo"); |
401 } | 467 } |
402 | 468 |
469 TEST_F(ExtensionGCMAppHandlerTest, UpdateExtension) { | |
470 scoped_refptr<Extension> extension(CreateExtension()); | |
471 | |
472 // App handler is added when extension is loaded. | |
473 LoadExtension(extension); | |
474 waiter()->PumpUILoop(); | |
475 EXPECT_TRUE(HasAppHandlers(extension->id())); | |
476 EXPECT_EQ(1, gcm_app_handler()->add_count()); | |
477 EXPECT_EQ(0, gcm_app_handler()->remove_count()); | |
478 | |
479 // App handler is not affected when extension is updated. | |
480 UpdateExtension(extension); | |
481 waiter()->PumpUILoop(); | |
482 EXPECT_TRUE(HasAppHandlers(extension->id())); | |
483 EXPECT_EQ(1, gcm_app_handler()->add_count()); | |
484 EXPECT_EQ(0, gcm_app_handler()->remove_count()); | |
485 } | |
486 | |
403 } // namespace extensions | 487 } // namespace extensions |
OLD | NEW |