Home | History | Annotate | Download | only in gcm
      1 // Copyright 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 "base/prefs/pref_service.h"
      6 #include "base/run_loop.h"
      7 #include "chrome/browser/extensions/api/gcm/gcm_api.h"
      8 #include "chrome/browser/extensions/extension_apitest.h"
      9 #include "chrome/browser/extensions/extension_gcm_app_handler.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "chrome/browser/services/gcm/fake_gcm_profile_service.h"
     12 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
     13 #include "chrome/common/chrome_switches.h"
     14 #include "chrome/common/pref_names.h"
     15 #include "chrome/test/base/ui_test_utils.h"
     16 
     17 namespace {
     18 
     19 const char kEventsExtension[] = "gcm/events";
     20 
     21 gcm::GCMClient::SendErrorDetails CreateErrorDetails(
     22     const std::string& message_id,
     23     const gcm::GCMClient::Result result,
     24     const std::string& total_messages) {
     25   gcm::GCMClient::SendErrorDetails error;
     26   error.message_id = message_id;
     27   error.result = result;
     28   error.additional_data["expectedMessageId"] = message_id;
     29   switch (result) {
     30     case gcm::GCMClient::ASYNC_OPERATION_PENDING:
     31       error.additional_data["expectedErrorMessage"] =
     32           "Asynchronous operation is pending.";
     33       break;
     34     case gcm::GCMClient::SERVER_ERROR:
     35       error.additional_data["expectedErrorMessage"] = "Server error occurred.";
     36       break;
     37     case gcm::GCMClient::NETWORK_ERROR:
     38       error.additional_data["expectedErrorMessage"] = "Network error occurred.";
     39       break;
     40     case gcm::GCMClient::TTL_EXCEEDED:
     41       error.additional_data["expectedErrorMessage"] = "Time-to-live exceeded.";
     42       break;
     43     case gcm::GCMClient::UNKNOWN_ERROR:
     44     default:  // Default case is the same as UNKNOWN_ERROR
     45       error.additional_data["expectedErrorMessage"] = "Unknown error occurred.";
     46       break;
     47   }
     48   error.additional_data["totalMessages"] = total_messages;
     49   return error;
     50 }
     51 
     52 }  // namespace
     53 
     54 namespace extensions {
     55 
     56 class GcmApiTest : public ExtensionApiTest {
     57  public:
     58   GcmApiTest() : fake_gcm_profile_service_(NULL) {}
     59 
     60  protected:
     61   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE;
     62   virtual void SetUpOnMainThread() OVERRIDE;
     63 
     64   void StartCollecting();
     65 
     66   const Extension* LoadTestExtension(const std::string& extension_path,
     67                                      const std::string& page_name);
     68   gcm::FakeGCMProfileService* service() const;
     69 
     70  private:
     71   gcm::FakeGCMProfileService* fake_gcm_profile_service_;
     72 };
     73 
     74 void GcmApiTest::SetUpCommandLine(CommandLine* command_line) {
     75   // We now always create the GCMProfileService instance in
     76   // ProfileSyncServiceFactory that is called when a profile is being
     77   // initialized. In order to prevent it from being created, we add the switch
     78   // to disable the sync logic.
     79   command_line->AppendSwitch(switches::kDisableSync);
     80 
     81   ExtensionApiTest::SetUpCommandLine(command_line);
     82 }
     83 
     84 void GcmApiTest::SetUpOnMainThread() {
     85   // Enable GCM such that tests could be run on all channels.
     86   browser()->profile()->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true);
     87 
     88   gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactory(
     89       browser()->profile(), &gcm::FakeGCMProfileService::Build);
     90   fake_gcm_profile_service_ = static_cast<gcm::FakeGCMProfileService*>(
     91       gcm::GCMProfileServiceFactory::GetInstance()->GetForProfile(
     92           browser()->profile()));
     93 
     94   ExtensionApiTest::SetUpOnMainThread();
     95 }
     96 
     97 void GcmApiTest::StartCollecting() {
     98   service()->set_collect(true);
     99 }
    100 
    101 gcm::FakeGCMProfileService* GcmApiTest::service() const {
    102   return fake_gcm_profile_service_;
    103 }
    104 
    105 const Extension* GcmApiTest::LoadTestExtension(
    106     const std::string& extension_path,
    107     const std::string& page_name) {
    108   const Extension* extension =
    109       LoadExtension(test_data_dir_.AppendASCII(extension_path));
    110   if (extension) {
    111     ui_test_utils::NavigateToURL(
    112         browser(), extension->GetResourceURL(page_name));
    113   }
    114   return extension;
    115 }
    116 
    117 IN_PROC_BROWSER_TEST_F(GcmApiTest, RegisterValidation) {
    118   ASSERT_TRUE(RunExtensionTest("gcm/functions/register_validation"));
    119 }
    120 
    121 IN_PROC_BROWSER_TEST_F(GcmApiTest, Register) {
    122   StartCollecting();
    123   ASSERT_TRUE(RunExtensionTest("gcm/functions/register"));
    124 
    125   const std::vector<std::string>& sender_ids =
    126       service()->last_registered_sender_ids();
    127   EXPECT_TRUE(std::find(sender_ids.begin(), sender_ids.end(), "Sender1") !=
    128                   sender_ids.end());
    129   EXPECT_TRUE(std::find(sender_ids.begin(), sender_ids.end(), "Sender2") !=
    130                   sender_ids.end());
    131 }
    132 
    133 IN_PROC_BROWSER_TEST_F(GcmApiTest, Unregister) {
    134   service()->AddExpectedUnregisterResponse(gcm::GCMClient::SUCCESS);
    135   service()->AddExpectedUnregisterResponse(gcm::GCMClient::SERVER_ERROR);
    136 
    137   ASSERT_TRUE(RunExtensionTest("gcm/functions/unregister"));
    138 }
    139 
    140 IN_PROC_BROWSER_TEST_F(GcmApiTest, SendValidation) {
    141   ASSERT_TRUE(RunExtensionTest("gcm/functions/send"));
    142 }
    143 
    144 IN_PROC_BROWSER_TEST_F(GcmApiTest, SendMessageData) {
    145   StartCollecting();
    146   ASSERT_TRUE(RunExtensionTest("gcm/functions/send_message_data"));
    147 
    148   EXPECT_EQ("destination-id", service()->last_receiver_id());
    149   const gcm::GCMClient::OutgoingMessage& message =
    150       service()->last_sent_message();
    151   gcm::GCMClient::MessageData::const_iterator iter;
    152 
    153   EXPECT_EQ(100, message.time_to_live);
    154 
    155   EXPECT_TRUE((iter = message.data.find("key1")) != message.data.end());
    156   EXPECT_EQ("value1", iter->second);
    157 
    158   EXPECT_TRUE((iter = message.data.find("key2")) != message.data.end());
    159   EXPECT_EQ("value2", iter->second);
    160 }
    161 
    162 IN_PROC_BROWSER_TEST_F(GcmApiTest, SendMessageDefaultTTL) {
    163   StartCollecting();
    164   ASSERT_TRUE(RunExtensionTest("gcm/functions/send_message_default_ttl"));
    165 
    166   EXPECT_EQ("destination-id", service()->last_receiver_id());
    167   const gcm::GCMClient::OutgoingMessage& message =
    168       service()->last_sent_message();
    169   gcm::GCMClient::MessageData::const_iterator iter;
    170 
    171   EXPECT_EQ(2419200, message.time_to_live);
    172 }
    173 
    174 IN_PROC_BROWSER_TEST_F(GcmApiTest, OnMessagesDeleted) {
    175   ResultCatcher catcher;
    176   catcher.RestrictToProfile(profile());
    177 
    178   const extensions::Extension* extension =
    179       LoadTestExtension(kEventsExtension, "on_messages_deleted.html");
    180   ASSERT_TRUE(extension);
    181 
    182   extensions::ExtensionGCMAppHandler app_handler(profile());
    183   app_handler.OnMessagesDeleted(extension->id());
    184   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    185 }
    186 
    187 IN_PROC_BROWSER_TEST_F(GcmApiTest, OnMessage) {
    188   ResultCatcher catcher;
    189   catcher.RestrictToProfile(profile());
    190 
    191   const extensions::Extension* extension =
    192       LoadTestExtension(kEventsExtension, "on_message.html");
    193   ASSERT_TRUE(extension);
    194 
    195   extensions::ExtensionGCMAppHandler app_handler(profile());
    196 
    197   gcm::GCMClient::IncomingMessage message;
    198   message.data["property1"] = "value1";
    199   message.data["property2"] = "value2";
    200   // First message is sent without a collapse key.
    201   app_handler.OnMessage(extension->id(), message);
    202 
    203   // Second message carries the same data and a collapse key.
    204   message.collapse_key = "collapseKeyValue";
    205   app_handler.OnMessage(extension->id(), message);
    206 
    207   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    208 }
    209 
    210 IN_PROC_BROWSER_TEST_F(GcmApiTest, OnSendError) {
    211   ResultCatcher catcher;
    212   catcher.RestrictToProfile(profile());
    213 
    214   const extensions::Extension* extension =
    215       LoadTestExtension(kEventsExtension, "on_send_error.html");
    216   ASSERT_TRUE(extension);
    217 
    218   std::string total_expected_messages = "5";
    219   extensions::ExtensionGCMAppHandler app_handler(profile());
    220   app_handler.OnSendError(
    221       extension->id(),
    222       CreateErrorDetails("error_message_1",
    223                          gcm::GCMClient::ASYNC_OPERATION_PENDING,
    224                          total_expected_messages));
    225   app_handler.OnSendError(
    226       extension->id(),
    227       CreateErrorDetails("error_message_2",
    228                          gcm::GCMClient::SERVER_ERROR,
    229                          total_expected_messages));
    230   app_handler.OnSendError(
    231       extension->id(),
    232       CreateErrorDetails("error_message_3",
    233                          gcm::GCMClient::NETWORK_ERROR,
    234                          total_expected_messages));
    235   app_handler.OnSendError(
    236       extension->id(),
    237       CreateErrorDetails("error_message_4",
    238                          gcm::GCMClient::UNKNOWN_ERROR,
    239                          total_expected_messages));
    240   app_handler.OnSendError(
    241       extension->id(),
    242       CreateErrorDetails("error_message_5",
    243                          gcm::GCMClient::TTL_EXCEEDED,
    244                          total_expected_messages));
    245 
    246   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    247 }
    248 
    249 IN_PROC_BROWSER_TEST_F(GcmApiTest, Incognito) {
    250   ResultCatcher catcher;
    251   catcher.RestrictToProfile(profile());
    252   ResultCatcher incognito_catcher;
    253   incognito_catcher.RestrictToProfile(profile()->GetOffTheRecordProfile());
    254 
    255   ASSERT_TRUE(RunExtensionTestIncognito("gcm/functions/incognito"));
    256 
    257   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
    258   EXPECT_TRUE(incognito_catcher.GetNextResult()) << incognito_catcher.message();
    259 }
    260 
    261 }  // namespace extensions
    262