1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string>
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/compiler_specific.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/values.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_listener_map.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions {
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// A simple mock to keep track of listener additions and removals.
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MockEventRouterObserver : public EventRouter::Observer {
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MockEventRouterObserver()
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : listener_added_count_(0),
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        listener_removed_count_(0) {}
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~MockEventRouterObserver() {}
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int listener_added_count() const { return listener_added_count_; }
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int listener_removed_count() const { return listener_removed_count_; }
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const std::string& last_event_name() const { return last_event_name_; }
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Reset() {
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    listener_added_count_ = 0;
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    listener_removed_count_ = 0;
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    last_event_name_.clear();
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // EventRouter::Observer overrides:
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnListenerAdded(const EventListenerInfo& details) OVERRIDE {
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    listener_added_count_++;
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    last_event_name_ = details.event_name;
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE {
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    listener_removed_count_++;
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    last_event_name_ = details.event_name;
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int listener_added_count_;
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int listener_removed_count_;
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string last_event_name_;
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockEventRouterObserver);
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)typedef testing::Test EventRouterTest;
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(EventRouterTest, GetBaseEventName) {
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Normal event names are passed through unchanged.
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar"));
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Sub-events are converted to the part before the slash.
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ("foo.onBar", EventRouter::GetBaseEventName("foo.onBar/123"));
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Tests adding and removing observers from EventRouter.
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(EventRouterTest, EventRouterObserver) {
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EventRouter router(NULL, NULL);
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EventListener listener(
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "event_name", "extension_id", NULL, scoped_ptr<DictionaryValue>());
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Add/remove works without any observers.
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  router.OnListenerAdded(&listener);
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  router.OnListenerRemoved(&listener);
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Register observers that both match and don't match the event above.
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MockEventRouterObserver matching_observer;
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  router.RegisterObserver(&matching_observer, "event_name");
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MockEventRouterObserver non_matching_observer;
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  router.RegisterObserver(&non_matching_observer, "other");
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Adding a listener notifies the appropriate observers.
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  router.OnListenerAdded(&listener);
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1, matching_observer.listener_added_count());
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, non_matching_observer.listener_added_count());
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Removing a listener notifies the appropriate observers.
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  router.OnListenerRemoved(&listener);
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1, matching_observer.listener_removed_count());
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, non_matching_observer.listener_removed_count());
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Adding the listener again notifies again.
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  router.OnListenerAdded(&listener);
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(2, matching_observer.listener_added_count());
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, non_matching_observer.listener_added_count());
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Removing the listener again notifies again.
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  router.OnListenerRemoved(&listener);
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(2, matching_observer.listener_removed_count());
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, non_matching_observer.listener_removed_count());
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Adding a listener with a sub-event notifies the main observer with
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // proper details.
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  matching_observer.Reset();
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EventListener sub_event_listener(
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "event_name/1", "extension_id", NULL, scoped_ptr<DictionaryValue>());
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  router.OnListenerAdded(&sub_event_listener);
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1, matching_observer.listener_added_count());
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, matching_observer.listener_removed_count());
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ("event_name/1", matching_observer.last_event_name());
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Ditto for removing the listener.
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  matching_observer.Reset();
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  router.OnListenerRemoved(&sub_event_listener);
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(0, matching_observer.listener_added_count());
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1, matching_observer.listener_removed_count());
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ("event_name/1", matching_observer.last_event_name());
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace extensions
123