root/chrome/browser/extensions/api/push_messaging/push_messaging_apitest.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ExtensionAndSubchannelToObjectId
  2. SetUpCommandLine
  3. SetUp
  4. SetUpOnMainThread
  5. EmitInvalidation
  6. GetAPI
  7. GetEventRouter
  8. IN_PROC_BROWSER_TEST_F
  9. IN_PROC_BROWSER_TEST_F
  10. IN_PROC_BROWSER_TEST_F
  11. IN_PROC_BROWSER_TEST_F
  12. IN_PROC_BROWSER_TEST_F
  13. IN_PROC_BROWSER_TEST_F

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/api/push_messaging/push_messaging_api.h"

#include "apps/launcher.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_handler.h"
#include "chrome/browser/extensions/api/push_messaging/push_messaging_invalidation_mapper.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/invalidation/fake_invalidation_service.h"
#include "chrome/browser/invalidation/invalidation_service.h"
#include "chrome/browser/invalidation/invalidation_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/ui_test_utils.h"
#include "google/cacheinvalidation/types.pb.h"
#include "sync/internal_api/public/base/invalidation.h"
#include "sync/notifier/fake_invalidator.h"
#include "testing/gmock/include/gmock/gmock.h"

using ::testing::SaveArg;
using ::testing::StrictMock;
using ::testing::_;

using invalidation::InvalidationServiceFactory;

namespace extensions {

namespace {

invalidation::ObjectId ExtensionAndSubchannelToObjectId(
    const std::string& extension_id, int subchannel_id) {
  return invalidation::ObjectId(
      ipc::invalidation::ObjectSource::CHROME_PUSH_MESSAGING,
      base::StringPrintf("U/%s/%d", extension_id.c_str(), subchannel_id));
}

class MockInvalidationMapper : public PushMessagingInvalidationMapper {
 public:
  MockInvalidationMapper();
  ~MockInvalidationMapper();

  MOCK_METHOD1(SuppressInitialInvalidationsForExtension,
               void(const std::string&));
  MOCK_METHOD1(RegisterExtension, void(const std::string&));
  MOCK_METHOD1(UnregisterExtension, void(const std::string&));
};

MockInvalidationMapper::MockInvalidationMapper() {}
MockInvalidationMapper::~MockInvalidationMapper() {}

}  // namespace

class PushMessagingApiTest : public ExtensionApiTest {
 public:
  PushMessagingApiTest()
      : fake_invalidation_service_(NULL) {
  }

  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    ExtensionApiTest::SetUpCommandLine(command_line);
  }

  virtual void SetUp() OVERRIDE {
    InvalidationServiceFactory::GetInstance()->RegisterTestingFactory(
        invalidation::FakeInvalidationService::Build);
    ExtensionApiTest::SetUp();
  }

  virtual void SetUpOnMainThread() OVERRIDE {
    ExtensionApiTest::SetUpOnMainThread();
    fake_invalidation_service_ =
        static_cast<invalidation::FakeInvalidationService*>(
            InvalidationServiceFactory::GetInstance()->GetForProfile(
                profile()));
  }

  void EmitInvalidation(
      const invalidation::ObjectId& object_id,
      int64 version,
      const std::string& payload) {
    fake_invalidation_service_->EmitInvalidationForTest(
        syncer::Invalidation::Init(object_id, version, payload));
  }

  PushMessagingAPI* GetAPI() {
    return PushMessagingAPI::Get(profile());
  }

  PushMessagingEventRouter* GetEventRouter() {
    return PushMessagingAPI::Get(profile())->GetEventRouterForTest();
  }

  invalidation::FakeInvalidationService* fake_invalidation_service_;
};

IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, EventDispatch) {
  ResultCatcher catcher;
  catcher.RestrictToProfile(profile());

  const extensions::Extension* extension =
      LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
  ASSERT_TRUE(extension);
  ui_test_utils::NavigateToURL(
      browser(), extension->GetResourceURL("event_dispatch.html"));

  GetEventRouter()->TriggerMessageForTest(extension->id(), 1, "payload");

  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}

// Test that a push introduced into the sync code makes it to the extension
// that we install.
IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, ReceivesPush) {
  ResultCatcher catcher;
  catcher.RestrictToProfile(profile());

  const extensions::Extension* extension =
      LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
  ASSERT_TRUE(extension);
  ui_test_utils::NavigateToURL(
      browser(), extension->GetResourceURL("event_dispatch.html"));

  // PushMessagingInvalidationHandler suppresses the initial invalidation on
  // each subchannel at install, so trigger the suppressions first.
  for (int i = 0; i < 3; ++i) {
    EmitInvalidation(
        ExtensionAndSubchannelToObjectId(extension->id(), i), i, std::string());
  }

  EmitInvalidation(
      ExtensionAndSubchannelToObjectId(extension->id(), 1), 5, "payload");
  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}

// Checks that an extension with the pushMessaging permission gets automatically
// registered for invalidations when it is loaded.
IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, AutoRegistration) {
  scoped_ptr<StrictMock<MockInvalidationMapper> > mapper(
      new StrictMock<MockInvalidationMapper>);
  StrictMock<MockInvalidationMapper>* unsafe_mapper = mapper.get();
  // PushMessagingEventRouter owns the mapper now.
  GetAPI()->SetMapperForTest(
      mapper.PassAs<PushMessagingInvalidationMapper>());

  std::string extension_id1;
  std::string extension_id2;
  EXPECT_CALL(*unsafe_mapper, SuppressInitialInvalidationsForExtension(_))
      .WillOnce(SaveArg<0>(&extension_id1));
  EXPECT_CALL(*unsafe_mapper, RegisterExtension(_))
      .WillOnce(SaveArg<0>(&extension_id2));
  const extensions::Extension* extension =
      LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
  ASSERT_TRUE(extension);
  EXPECT_EQ(extension->id(), extension_id1);
  EXPECT_EQ(extension->id(), extension_id2);
  EXPECT_CALL(*unsafe_mapper, UnregisterExtension(extension->id()));
  UnloadExtension(extension->id());
}

// Tests that we re-register for invalidations on restart for extensions that
// are already installed.
IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, PRE_Restart) {
  PushMessagingInvalidationHandler* handler =
      static_cast<PushMessagingInvalidationHandler*>(
          GetAPI()->GetMapperForTest());
  EXPECT_TRUE(handler->GetRegisteredExtensionsForTest().empty());
  ASSERT_TRUE(InstallExtension(test_data_dir_.AppendASCII("push_messaging"),
                               1 /* new install */));
}

IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, Restart) {
  PushMessagingInvalidationHandler* handler =
      static_cast<PushMessagingInvalidationHandler*>(
          GetAPI()->GetMapperForTest());
  EXPECT_EQ(1U, handler->GetRegisteredExtensionsForTest().size());
}

// Test that GetChannelId fails if no user is signed in.
IN_PROC_BROWSER_TEST_F(PushMessagingApiTest, GetChannelId) {
  ResultCatcher catcher;
  catcher.RestrictToProfile(profile());

  const extensions::Extension* extension =
      LoadExtension(test_data_dir_.AppendASCII("push_messaging"));
  ASSERT_TRUE(extension);
  ui_test_utils::NavigateToURL(
      browser(), extension->GetResourceURL("get_channel_id.html"));

  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}

}  // namespace extensions

/* [<][>][^][v][top][bottom][index][help] */