1// Copyright (c) 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 "chrome/browser/invalidation/invalidation_service_android.h"
6
7#include "chrome/browser/chrome_notification_types.h"
8#include "chrome/browser/invalidation/invalidation_controller_android.h"
9#include "chrome/test/base/testing_profile.h"
10#include "components/invalidation/fake_invalidation_handler.h"
11#include "components/invalidation/invalidation_service_test_template.h"
12#include "content/public/browser/notification_service.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace invalidation {
16
17class MockInvalidationControllerAndroid : public InvalidationControllerAndroid {
18 public:
19  MockInvalidationControllerAndroid() {}
20  virtual ~MockInvalidationControllerAndroid() {}
21
22  virtual void SetRegisteredObjectIds(const syncer::ObjectIdSet& ids) OVERRIDE {
23    registered_ids_ = ids;
24  }
25
26  syncer::ObjectIdSet registered_ids_;
27};
28
29class InvalidationServiceAndroidTestDelegate {
30 public:
31  InvalidationServiceAndroidTestDelegate() {}
32
33  ~InvalidationServiceAndroidTestDelegate() {}
34
35  void CreateInvalidationService() {
36    profile_.reset(new TestingProfile());
37    invalidation_service_android_.reset(
38        new InvalidationServiceAndroid(
39            profile_.get(),
40            new MockInvalidationControllerAndroid()));
41  }
42
43  InvalidationService* GetInvalidationService() {
44    return invalidation_service_android_.get();
45  }
46
47  void DestroyInvalidationService() {
48    invalidation_service_android_.reset();
49  }
50
51  void TriggerOnInvalidatorStateChange(syncer::InvalidatorState state) {
52    invalidation_service_android_->TriggerStateChangeForTest(state);
53  }
54
55  void TriggerOnIncomingInvalidation(
56      const syncer::ObjectIdInvalidationMap& invalidation_map) {
57    content::NotificationService::current()->Notify(
58        chrome::NOTIFICATION_SYNC_REFRESH_REMOTE,
59        content::Source<Profile>(profile_.get()),
60        content::Details<const syncer::ObjectIdInvalidationMap>(
61            &invalidation_map));
62  }
63
64  scoped_ptr<TestingProfile> profile_;
65  scoped_ptr<InvalidationServiceAndroid> invalidation_service_android_;
66};
67
68INSTANTIATE_TYPED_TEST_CASE_P(
69    AndroidInvalidationServiceTest, InvalidationServiceTest,
70    InvalidationServiceAndroidTestDelegate);
71
72class InvalidationServiceAndroidRegistrationTest : public testing::Test {
73 protected:
74  InvalidationServiceAndroidRegistrationTest()
75      : invalidation_controller_(new MockInvalidationControllerAndroid()),
76        invalidation_service_(&profile_, invalidation_controller_) {}
77
78  virtual ~InvalidationServiceAndroidRegistrationTest() {}
79
80  // Get the invalidation service being tested.
81  InvalidationService& invalidation_service() {
82    return invalidation_service_;
83  }
84
85  // Get the number of objects which are registered.
86  size_t RegisteredObjectCount() {
87    return registered_ids().size();
88  }
89
90  // Determines if the given object id is registered with the invalidation
91  // controller.
92  bool IsRegistered(const invalidation::ObjectId& id) {
93    return registered_ids().find(id) != registered_ids().end();
94  }
95
96 private:
97  // Get the set of objects registered with the invalidation controller.
98  const syncer::ObjectIdSet& registered_ids() {
99    return invalidation_controller_->registered_ids_;
100  }
101
102  TestingProfile profile_;
103  MockInvalidationControllerAndroid* invalidation_controller_;
104  InvalidationServiceAndroid invalidation_service_;
105};
106
107TEST_F(InvalidationServiceAndroidRegistrationTest, NoObjectRegistration) {
108  syncer::FakeInvalidationHandler handler;
109  invalidation_service().RegisterInvalidationHandler(&handler);
110  EXPECT_EQ(0U, RegisteredObjectCount());
111  invalidation_service().UnregisterInvalidationHandler(&handler);
112}
113
114TEST_F(InvalidationServiceAndroidRegistrationTest, UpdateObjectRegistration) {
115  syncer::FakeInvalidationHandler handler;
116  invalidation::ObjectId id1(1, "A");
117  invalidation::ObjectId id2(2, "B");
118  syncer::ObjectIdSet ids;
119  invalidation_service().RegisterInvalidationHandler(&handler);
120
121  // Register for both objects.
122  ids.insert(id1);
123  ids.insert(id2);
124  invalidation_service().UpdateRegisteredInvalidationIds(&handler, ids);
125  EXPECT_EQ(2U, RegisteredObjectCount());
126  EXPECT_TRUE(IsRegistered(id1));
127  EXPECT_TRUE(IsRegistered(id2));
128
129  // Unregister for object 2.
130  ids.erase(id2);
131  invalidation_service().UpdateRegisteredInvalidationIds(&handler, ids);
132  EXPECT_EQ(1U, RegisteredObjectCount());
133  EXPECT_TRUE(IsRegistered(id1));
134
135  // Unregister for object 1.
136  ids.erase(id1);
137  invalidation_service().UpdateRegisteredInvalidationIds(&handler, ids);
138  EXPECT_EQ(0U, RegisteredObjectCount());
139
140  invalidation_service().UnregisterInvalidationHandler(&handler);
141}
142
143#if defined(OS_ANDROID)
144
145class InvalidationServiceAndroidTest : public testing::Test {
146 public:
147  InvalidationServiceAndroidTest()
148      : invalidation_service_(&profile_, new InvalidationControllerAndroid()) {}
149  virtual ~InvalidationServiceAndroidTest() {}
150
151  InvalidationService& invalidation_service() {
152    return invalidation_service_;
153  }
154
155 private:
156  TestingProfile profile_;
157  InvalidationServiceAndroid invalidation_service_;
158};
159
160TEST_F(InvalidationServiceAndroidTest, FetchClientId) {
161  const std::string id1 = invalidation_service().GetInvalidatorClientId();
162  ASSERT_FALSE(id1.empty());
163
164  // If nothing else, the ID should be consistent.
165  const std::string id2 = invalidation_service().GetInvalidatorClientId();
166  ASSERT_EQ(id1, id2);
167}
168
169#endif
170
171}  // namespace invalidation
172