Chromium Code Reviews| Index: chrome/browser/push_messaging/push_messaging_browsertest.cc |
| diff --git a/chrome/browser/push_messaging/push_messaging_browsertest.cc b/chrome/browser/push_messaging/push_messaging_browsertest.cc |
| index 024accdb7bb1a361dfd5708353fbac0ca04492bf..8dcc74eca05c071b2f1c956e1bf9fef186e8af0c 100644 |
| --- a/chrome/browser/push_messaging/push_messaging_browsertest.cc |
| +++ b/chrome/browser/push_messaging/push_messaging_browsertest.cc |
| @@ -26,6 +26,8 @@ |
| #include "chrome/browser/engagement/site_engagement_service.h" |
| #include "chrome/browser/gcm/fake_gcm_profile_service.h" |
| #include "chrome/browser/gcm/gcm_profile_service_factory.h" |
| +#include "chrome/browser/gcm/instance_id/instance_id_profile_service.h" |
| +#include "chrome/browser/gcm/instance_id/instance_id_profile_service_factory.h" |
| #include "chrome/browser/lifetime/keep_alive_registry.h" |
| #include "chrome/browser/lifetime/keep_alive_types.h" |
| #include "chrome/browser/notifications/message_center_display_service.h" |
| @@ -49,6 +51,7 @@ |
| #include "components/gcm_driver/common/gcm_messages.h" |
| #include "components/gcm_driver/gcm_client.h" |
| #include "components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h" |
| +#include "components/gcm_driver/instance_id/instance_id_driver.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/content_switches.h" |
| #include "content/public/common/push_subscription_options.h" |
| @@ -108,6 +111,14 @@ void DidRegister(base::Closure done_callback, |
| done_callback.Run(); |
| } |
| +void InstanceIDResultCallback(base::Closure done_callback, |
| + instance_id::InstanceID::Result* out_result, |
| + instance_id::InstanceID::Result result) { |
| + if (out_result) |
|
Peter Beverloo
2017/03/20 23:50:13
if -> DCHECK, it's always given
johnme
2017/03/30 18:36:38
Done.
|
| + *out_result = result; |
| + done_callback.Run(); |
| +} |
| + |
| } // namespace |
| class PushMessagingBrowserTest : public InProcessBrowserTest { |
| @@ -241,6 +252,11 @@ class PushMessagingBrowserTest : public InProcessBrowserTest { |
| bool standard_protocol = true, |
| std::string* out_token = nullptr); |
| + // Deletes an Instance ID from the GCM Store but keeps the push subscription |
| + // stored in the PushMessagingAppIdentifier map and Service Worker DB. |
| + // Calls should be wrapped in the ASSERT_NO_FATAL_FAILURE() macro. |
| + void DeleteInstanceIDAsIfGCMStoreReset(const std::string& app_id); |
| + |
| PushMessagingAppIdentifier GetAppIdentifierForServiceWorkerRegistration( |
| int64_t service_worker_registration_id); |
| @@ -378,8 +394,8 @@ void PushMessagingBrowserTest::LegacySubscribeSuccessfully( |
| GURL requesting_origin = https_server()->GetURL("/").GetOrigin(); |
| int64_t service_worker_registration_id = 0LL; |
| PushMessagingAppIdentifier app_identifier = |
| - PushMessagingAppIdentifier::Generate(requesting_origin, |
| - service_worker_registration_id); |
| + PushMessagingAppIdentifier::LegacyGenerateForTesting( |
| + requesting_origin, service_worker_registration_id); |
| push_service_->IncreasePushSubscriptionCount(1, true /* is_pending */); |
| std::string subscription_id; |
| @@ -436,6 +452,31 @@ PushMessagingBrowserTest::GetAppIdentifierForServiceWorkerRegistration( |
| return app_identifier; |
| } |
| +void PushMessagingBrowserTest::DeleteInstanceIDAsIfGCMStoreReset( |
| + const std::string& app_id) { |
| + // Delete the Instance ID directly, keeping the push subscription stored in |
| + // the PushMessagingAppIdentifier map and the Service Worker database. This |
| + // simulates the GCM Store getting reset but failing to clear push |
| + // subscriptions, either because the store got reset before |
| + // 93ec793ac69a542b2213297737178a55d069fd0d (Chrome 56), or because a race |
| + // condition (e.g. shutdown) prevents PushMessagingServiceImpl::OnStoreReset |
| + // from clearing all subscriptions. |
| + instance_id::InstanceIDProfileService* instance_id_profile_service = |
| + instance_id::InstanceIDProfileServiceFactory::GetForProfile( |
| + GetBrowser()->profile()); |
| + DCHECK(instance_id_profile_service); |
| + instance_id::InstanceIDDriver* instance_id_driver = |
| + instance_id_profile_service->driver(); |
| + DCHECK(instance_id_driver); |
| + instance_id::InstanceID::Result delete_result = |
| + instance_id::InstanceID::UNKNOWN_ERROR; |
| + base::RunLoop run_loop; |
| + instance_id_driver->GetInstanceID(app_id)->DeleteID(base::Bind( |
| + &InstanceIDResultCallback, run_loop.QuitClosure(), &delete_result)); |
| + run_loop.Run(); |
| + ASSERT_EQ(instance_id::InstanceID::SUCCESS, delete_result); |
| +} |
| + |
| void PushMessagingBrowserTest::SendMessageAndWaitUntilHandled( |
| const PushMessagingAppIdentifier& app_identifier, |
| const gcm::IncomingMessage& message) { |
| @@ -1752,6 +1793,93 @@ IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, |
| } |
| IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, |
| + InvalidGetSubscriptionUnsubscribes) { |
| + std::string script_result; |
| + |
| + ASSERT_NO_FATAL_FAILURE(SubscribeSuccessfully()); |
| + |
| + GURL origin = https_server()->GetURL("/").GetOrigin(); |
| + PushMessagingAppIdentifier app_identifier1 = |
| + PushMessagingAppIdentifier::FindByServiceWorker( |
| + GetBrowser()->profile(), origin, |
| + 0LL /* service_worker_registration_id */); |
| + ASSERT_FALSE(app_identifier1.is_null()); |
| + |
| + ASSERT_NO_FATAL_FAILURE( |
| + DeleteInstanceIDAsIfGCMStoreReset(app_identifier1.app_id())); |
| + |
| + // Push messaging should not yet be aware of the InstanceID being deleted. |
| + histogram_tester_.ExpectTotalCount("PushMessaging.UnregistrationReason", 0); |
| + // We should still be able to look up the app id. |
| + PushMessagingAppIdentifier app_identifier2 = |
| + PushMessagingAppIdentifier::FindByServiceWorker( |
| + GetBrowser()->profile(), origin, |
| + 0LL /* service_worker_registration_id */); |
| + EXPECT_FALSE(app_identifier2.is_null()); |
| + EXPECT_EQ(app_identifier1.app_id(), app_identifier2.app_id()); |
| + |
| + // Now call PushManager.getSubscription(). It should return null. |
| + ASSERT_TRUE(RunScript("hasSubscription()", &script_result)); |
| + EXPECT_EQ("false - not subscribed", script_result); |
| + |
| + // This should have unsubscribed the push subscription. |
| + histogram_tester_.ExpectUniqueSample( |
| + "PushMessaging.UnregistrationReason", |
| + content::PUSH_UNREGISTRATION_REASON_GET_SUBSCRIPTION_STORAGE_CORRUPT, 1); |
| + // We should no longer be able to look up the app id. |
| + PushMessagingAppIdentifier app_identifier3 = |
| + PushMessagingAppIdentifier::FindByServiceWorker( |
| + GetBrowser()->profile(), origin, |
| + 0LL /* service_worker_registration_id */); |
| + EXPECT_TRUE(app_identifier3.is_null()); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, InvalidSubscribeUnsubscribes) { |
| + std::string script_result; |
| + |
| + std::string token1; |
| + ASSERT_NO_FATAL_FAILURE(SubscribeSuccessfully(true /* use_key */, &token1)); |
| + |
| + GURL origin = https_server()->GetURL("/").GetOrigin(); |
| + PushMessagingAppIdentifier app_identifier1 = |
| + PushMessagingAppIdentifier::FindByServiceWorker( |
| + GetBrowser()->profile(), origin, |
| + 0LL /* service_worker_registration_id */); |
| + ASSERT_FALSE(app_identifier1.is_null()); |
| + |
| + ASSERT_NO_FATAL_FAILURE( |
| + DeleteInstanceIDAsIfGCMStoreReset(app_identifier1.app_id())); |
| + |
| + // Push messaging should not yet be aware of the InstanceID being deleted. |
| + histogram_tester_.ExpectTotalCount("PushMessaging.UnregistrationReason", 0); |
| + // We should still be able to look up the app id. |
| + PushMessagingAppIdentifier app_identifier2 = |
| + PushMessagingAppIdentifier::FindByServiceWorker( |
| + GetBrowser()->profile(), origin, |
| + 0LL /* service_worker_registration_id */); |
| + EXPECT_FALSE(app_identifier2.is_null()); |
| + EXPECT_EQ(app_identifier1.app_id(), app_identifier2.app_id()); |
| + |
| + // Now call PushManager.subscribe() again. It should succeed, but with a |
| + // *different* token, indicating that it unsubscribed and re-subscribed. |
| + std::string token2; |
| + ASSERT_NO_FATAL_FAILURE(SubscribeSuccessfully(true /* use_key */, &token2)); |
| + EXPECT_NE(token1, token2); |
| + |
| + // This should have unsubscribed the original push subscription. |
| + histogram_tester_.ExpectUniqueSample( |
| + "PushMessaging.UnregistrationReason", |
| + content::PUSH_UNREGISTRATION_REASON_SUBSCRIBE_STORAGE_CORRUPT, 1); |
| + // Looking up the app id should return a different id. |
| + PushMessagingAppIdentifier app_identifier3 = |
| + PushMessagingAppIdentifier::FindByServiceWorker( |
| + GetBrowser()->profile(), origin, |
| + 0LL /* service_worker_registration_id */); |
| + EXPECT_FALSE(app_identifier3.is_null()); |
| + EXPECT_NE(app_identifier2.app_id(), app_identifier3.app_id()); |
| +} |
| + |
| +IN_PROC_BROWSER_TEST_F(PushMessagingBrowserTest, |
| GlobalResetPushPermissionUnsubscribes) { |
| std::string script_result; |