root/extensions/browser/event_listener_map_unittest.cc

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

DEFINITIONS

This source file includes following definitions.
  1. OnListenerAdded
  2. OnListenerRemoved
  3. process_
  4. CreateHostSuffixFilter
  5. CreateNamedEvent
  6. CreateEvent
  7. TEST_F
  8. TEST_F
  9. TEST_F
  10. TEST_F
  11. TEST_F
  12. TEST_F
  13. TEST_F
  14. TEST_F
  15. TEST_F
  16. TEST_F
  17. TEST_F
  18. TEST_F
  19. TEST_F
  20. TEST_F
  21. TEST_F
  22. TEST_F

// Copyright 2013 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 "extensions/browser/event_listener_map.h"

#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "extensions/browser/event_router.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::DictionaryValue;
using base::ListValue;
using base::StringValue;

namespace extensions {

namespace {

const char kExt1Id[] = "extension_1";
const char kExt2Id[] = "extension_2";
const char kEvent1Name[] = "event1";
const char kEvent2Name[] = "event2";

class EmptyDelegate : public EventListenerMap::Delegate {
  virtual void OnListenerAdded(const EventListener* listener) OVERRIDE {};
  virtual void OnListenerRemoved(const EventListener* listener) OVERRIDE {};
};

class EventListenerMapUnittest : public testing::Test {
 public:
  EventListenerMapUnittest()
    : delegate_(new EmptyDelegate),
      listeners_(new EventListenerMap(delegate_.get())),
      browser_context_(new content::TestBrowserContext),
      process_(new content::MockRenderProcessHost(browser_context_.get())) {
  }

  scoped_ptr<DictionaryValue> CreateHostSuffixFilter(
      const std::string& suffix) {
    scoped_ptr<DictionaryValue> filter(new DictionaryValue);
    scoped_ptr<ListValue> filter_list(new ListValue);
    scoped_ptr<DictionaryValue> filter_dict(new DictionaryValue);

    filter_dict->Set("hostSuffix", new StringValue(suffix));

    filter_list->Append(filter_dict.release());
    filter->Set("url", filter_list.release());
    return filter.Pass();
  }

  scoped_ptr<Event> CreateNamedEvent(const std::string& event_name) {
    return CreateEvent(event_name, GURL());
  }

  scoped_ptr<Event> CreateEvent(const std::string& event_name,
                                const GURL& url) {
    EventFilteringInfo info;
    info.SetURL(url);
    scoped_ptr<Event> result(new Event(event_name,
        make_scoped_ptr(new ListValue()), NULL, GURL(),
        EventRouter::USER_GESTURE_UNKNOWN, info));
    return result.Pass();
  }

 protected:
  scoped_ptr<EventListenerMap::Delegate> delegate_;
  scoped_ptr<EventListenerMap> listeners_;
  scoped_ptr<content::TestBrowserContext> browser_context_;
  scoped_ptr<content::MockRenderProcessHost> process_;
};

TEST_F(EventListenerMapUnittest, UnfilteredEventsGoToAllListeners) {
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, scoped_ptr<DictionaryValue>())));

  scoped_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  ASSERT_EQ(1u, targets.size());
}

TEST_F(EventListenerMapUnittest, FilteredEventsGoToAllMatchingListeners) {
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com"))));
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, scoped_ptr<DictionaryValue>(
      new DictionaryValue))));

  scoped_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  event->filter_info.SetURL(GURL("http://www.google.com"));
  std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  ASSERT_EQ(2u, targets.size());
}

TEST_F(EventListenerMapUnittest, FilteredEventsOnlyGoToMatchingListeners) {
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com"))));
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("yahoo.com"))));

  scoped_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  event->filter_info.SetURL(GURL("http://www.google.com"));
  std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  ASSERT_EQ(1u, targets.size());
}

TEST_F(EventListenerMapUnittest, LazyAndUnlazyListenersGetReturned) {
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com"))));

  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, process_.get(),
      CreateHostSuffixFilter("google.com"))));

  scoped_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  event->filter_info.SetURL(GURL("http://www.google.com"));
  std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  ASSERT_EQ(2u, targets.size());
}

TEST_F(EventListenerMapUnittest, TestRemovingByProcess) {
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com"))));

  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, process_.get(),
      CreateHostSuffixFilter("google.com"))));

  listeners_->RemoveListenersForProcess(process_.get());

  scoped_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  event->filter_info.SetURL(GURL("http://www.google.com"));
  std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  ASSERT_EQ(1u, targets.size());
}

TEST_F(EventListenerMapUnittest, TestRemovingByListener) {
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com"))));

  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, process_.get(),
      CreateHostSuffixFilter("google.com"))));

  scoped_ptr<EventListener> listener(new EventListener(kEvent1Name, kExt1Id,
      process_.get(), CreateHostSuffixFilter("google.com")));
  listeners_->RemoveListener(listener.get());

  scoped_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  event->filter_info.SetURL(GURL("http://www.google.com"));
  std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  ASSERT_EQ(1u, targets.size());
}

TEST_F(EventListenerMapUnittest, TestLazyDoubleAddIsUndoneByRemove) {
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com"))));
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com"))));

  scoped_ptr<EventListener> listener(new EventListener(
        kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com")));
  listeners_->RemoveListener(listener.get());

  scoped_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  event->filter_info.SetURL(GURL("http://www.google.com"));
  std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  ASSERT_EQ(0u, targets.size());
}

TEST_F(EventListenerMapUnittest, HostSuffixFilterEquality) {
  scoped_ptr<DictionaryValue> filter1(CreateHostSuffixFilter("google.com"));
  scoped_ptr<DictionaryValue> filter2(CreateHostSuffixFilter("google.com"));
  ASSERT_TRUE(filter1->Equals(filter2.get()));
}

TEST_F(EventListenerMapUnittest, RemoveLazyListenersForExtension) {
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent1Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com"))));
  listeners_->AddListener(scoped_ptr<EventListener>(new EventListener(
      kEvent2Name, kExt1Id, NULL, CreateHostSuffixFilter("google.com"))));

  listeners_->RemoveLazyListenersForExtension(kExt1Id);

  scoped_ptr<Event> event(CreateNamedEvent(kEvent1Name));
  event->filter_info.SetURL(GURL("http://www.google.com"));
  std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  ASSERT_EQ(0u, targets.size());

  event->event_name = kEvent2Name;
  targets = listeners_->GetEventListeners(*event);
  ASSERT_EQ(0u, targets.size());
}

TEST_F(EventListenerMapUnittest, AddExistingFilteredListener) {
  bool first_new = listeners_->AddListener(scoped_ptr<EventListener>(
      new EventListener(kEvent1Name, kExt1Id, NULL,
                        CreateHostSuffixFilter("google.com"))));
  bool second_new = listeners_->AddListener(scoped_ptr<EventListener>(
      new EventListener(kEvent1Name, kExt1Id, NULL,
                        CreateHostSuffixFilter("google.com"))));

  ASSERT_TRUE(first_new);
  ASSERT_FALSE(second_new);
}

TEST_F(EventListenerMapUnittest, AddExistingUnfilteredListener) {
  bool first_add = listeners_->AddListener(scoped_ptr<EventListener>(
      new EventListener(kEvent1Name, kExt1Id, NULL,
                        scoped_ptr<DictionaryValue>())));
  bool second_add = listeners_->AddListener(scoped_ptr<EventListener>(
      new EventListener(kEvent1Name, kExt1Id, NULL,
                        scoped_ptr<DictionaryValue>())));

  scoped_ptr<EventListener> listener(
        new EventListener(kEvent1Name, kExt1Id, NULL,
                          scoped_ptr<DictionaryValue>()));
  bool first_remove = listeners_->RemoveListener(listener.get());
  bool second_remove = listeners_->RemoveListener(listener.get());

  ASSERT_TRUE(first_add);
  ASSERT_FALSE(second_add);
  ASSERT_TRUE(first_remove);
  ASSERT_FALSE(second_remove);
}

TEST_F(EventListenerMapUnittest, RemovingRouters) {
  listeners_->AddListener(scoped_ptr<EventListener>(
      new EventListener(kEvent1Name, kExt1Id, process_.get(),
                        scoped_ptr<DictionaryValue>())));
  listeners_->RemoveListenersForProcess(process_.get());
  ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent1Name));
}

TEST_F(EventListenerMapUnittest, HasListenerForEvent) {
  ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent1Name));

  listeners_->AddListener(scoped_ptr<EventListener>(
      new EventListener(kEvent1Name, kExt1Id, process_.get(),
                        scoped_ptr<DictionaryValue>())));

  ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent2Name));
  ASSERT_TRUE(listeners_->HasListenerForEvent(kEvent1Name));
  listeners_->RemoveListenersForProcess(process_.get());
  ASSERT_FALSE(listeners_->HasListenerForEvent(kEvent1Name));
}

TEST_F(EventListenerMapUnittest, HasListenerForExtension) {
  ASSERT_FALSE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name));

  // Non-lazy listener.
  listeners_->AddListener(scoped_ptr<EventListener>(
      new EventListener(kEvent1Name, kExt1Id, process_.get(),
                        scoped_ptr<DictionaryValue>())));
  // Lazy listener.
  listeners_->AddListener(scoped_ptr<EventListener>(
      new EventListener(kEvent1Name, kExt1Id, NULL,
                        scoped_ptr<DictionaryValue>())));

  ASSERT_FALSE(listeners_->HasListenerForExtension(kExt1Id, kEvent2Name));
  ASSERT_TRUE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name));
  ASSERT_FALSE(listeners_->HasListenerForExtension(kExt2Id, kEvent1Name));
  listeners_->RemoveListenersForProcess(process_.get());
  ASSERT_TRUE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name));
  listeners_->RemoveLazyListenersForExtension(kExt1Id);
  ASSERT_FALSE(listeners_->HasListenerForExtension(kExt1Id, kEvent1Name));
}

TEST_F(EventListenerMapUnittest, AddLazyListenersFromPreferences) {
  scoped_ptr<DictionaryValue> filter1(CreateHostSuffixFilter("google.com"));
  scoped_ptr<DictionaryValue> filter2(CreateHostSuffixFilter("yahoo.com"));

  DictionaryValue filtered_listeners;
  ListValue* filter_list = new ListValue();
  filtered_listeners.Set(kEvent1Name, filter_list);

  filter_list->Append(filter1.release());
  filter_list->Append(filter2.release());

  listeners_->LoadFilteredLazyListeners(kExt1Id, filtered_listeners);

  scoped_ptr<Event> event(CreateEvent(kEvent1Name,
                          GURL("http://www.google.com")));
  std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  ASSERT_EQ(1u, targets.size());
  scoped_ptr<EventListener> listener(new EventListener(kEvent1Name, kExt1Id,
      NULL, CreateHostSuffixFilter("google.com")));
  ASSERT_TRUE((*targets.begin())->Equals(listener.get()));
}

TEST_F(EventListenerMapUnittest, CorruptedExtensionPrefsShouldntCrash) {
  scoped_ptr<DictionaryValue> filter1(CreateHostSuffixFilter("google.com"));

  DictionaryValue filtered_listeners;
  // kEvent1Name should be associated with a list, not a dictionary.
  filtered_listeners.Set(kEvent1Name, filter1.release());

  listeners_->LoadFilteredLazyListeners(kExt1Id, filtered_listeners);

  scoped_ptr<Event> event(CreateEvent(kEvent1Name,
                          GURL("http://www.google.com")));
  std::set<const EventListener*> targets(listeners_->GetEventListeners(*event));
  ASSERT_EQ(0u, targets.size());
}

}  // namespace

}  // namespace extensions

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