1 // Copyright 2014 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.
7 #include "base/compiler_specific.h"
8 #include "components/invalidation/push_client_channel.h"
9 #include "jingle/notifier/listener/fake_push_client.h"
10 #include "jingle/notifier/listener/notification_defines.h"
11 #include "testing/gtest/include/gtest/gtest.h"
16 class PushClientChannelTest
17 : public ::testing::Test
,
18 public SyncNetworkChannel::Observer
{
20 PushClientChannelTest()
21 : fake_push_client_(new notifier::FakePushClient()),
23 scoped_ptr
<notifier::PushClient
>(fake_push_client_
)),
24 last_invalidator_state_(DEFAULT_INVALIDATION_ERROR
) {
25 push_client_channel_
.AddObserver(this);
26 push_client_channel_
.SetMessageReceiver(
27 invalidation::NewPermanentCallback(
28 this, &PushClientChannelTest::OnIncomingMessage
));
29 push_client_channel_
.SetSystemResources(NULL
);
32 ~PushClientChannelTest() override
{
33 push_client_channel_
.RemoveObserver(this);
36 void OnNetworkChannelStateChanged(
37 InvalidatorState invalidator_state
) override
{
38 last_invalidator_state_
= invalidator_state
;
41 void OnIncomingMessage(std::string incoming_message
) {
42 last_message_
= incoming_message
;
45 notifier::FakePushClient
* fake_push_client_
;
46 PushClientChannel push_client_channel_
;
47 std::string last_message_
;
48 InvalidatorState last_invalidator_state_
;
51 const char kMessage
[] = "message";
52 const char kServiceContext
[] = "service context";
53 const int64 kSchedulingHash
= 100;
55 // Make sure the channel subscribes to the correct notifications
56 // channel on construction.
57 TEST_F(PushClientChannelTest
, Subscriptions
) {
58 notifier::Subscription expected_subscription
;
59 expected_subscription
.channel
= "tango_raw";
60 EXPECT_TRUE(notifier::SubscriptionListsEqual(
61 fake_push_client_
->subscriptions(),
62 notifier::SubscriptionList(1, expected_subscription
)));
65 // Call UpdateCredentials on the channel. It should propagate it to
67 TEST_F(PushClientChannelTest
, UpdateCredentials
) {
68 const char kEmail
[] = "foo@bar.com";
69 const char kToken
[] = "token";
70 EXPECT_TRUE(fake_push_client_
->email().empty());
71 EXPECT_TRUE(fake_push_client_
->token().empty());
72 push_client_channel_
.UpdateCredentials(kEmail
, kToken
);
73 EXPECT_EQ(kEmail
, fake_push_client_
->email());
74 EXPECT_EQ(kToken
, fake_push_client_
->token());
77 // Simulate push client state changes on the push client. It should
78 // propagate to the channel.
79 TEST_F(PushClientChannelTest
, OnPushClientStateChange
) {
80 EXPECT_EQ(DEFAULT_INVALIDATION_ERROR
, last_invalidator_state_
);
81 fake_push_client_
->EnableNotifications();
82 EXPECT_EQ(INVALIDATIONS_ENABLED
, last_invalidator_state_
);
83 fake_push_client_
->DisableNotifications(
84 notifier::TRANSIENT_NOTIFICATION_ERROR
);
85 EXPECT_EQ(TRANSIENT_INVALIDATION_ERROR
, last_invalidator_state_
);
86 fake_push_client_
->DisableNotifications(
87 notifier::NOTIFICATION_CREDENTIALS_REJECTED
);
88 EXPECT_EQ(INVALIDATION_CREDENTIALS_REJECTED
, last_invalidator_state_
);
91 // Call SendMessage on the channel. It should propagate it to the
93 TEST_F(PushClientChannelTest
, SendMessage
) {
94 EXPECT_TRUE(fake_push_client_
->sent_notifications().empty());
95 push_client_channel_
.SendMessage(kMessage
);
96 ASSERT_EQ(1u, fake_push_client_
->sent_notifications().size());
97 std::string expected_encoded_message
=
98 PushClientChannel::EncodeMessageForTest(
100 push_client_channel_
.GetServiceContextForTest(),
101 push_client_channel_
.GetSchedulingHashForTest());
102 ASSERT_EQ(expected_encoded_message
,
103 fake_push_client_
->sent_notifications()[0].data
);
106 // Encode a message with some context and then decode it. The decoded info
107 // should match the original info.
108 TEST_F(PushClientChannelTest
, EncodeDecode
) {
109 const std::string
& data
= PushClientChannel::EncodeMessageForTest(
110 kMessage
, kServiceContext
, kSchedulingHash
);
112 std::string service_context
;
113 int64 scheduling_hash
= 0LL;
114 EXPECT_TRUE(PushClientChannel::DecodeMessageForTest(
115 data
, &message
, &service_context
, &scheduling_hash
));
116 EXPECT_EQ(kMessage
, message
);
117 EXPECT_EQ(kServiceContext
, service_context
);
118 EXPECT_EQ(kSchedulingHash
, scheduling_hash
);
121 // Encode a message with no context and then decode it. The decoded message
122 // should match the original message, but the context and hash should be
124 TEST_F(PushClientChannelTest
, EncodeDecodeNoContext
) {
125 const std::string
& data
= PushClientChannel::EncodeMessageForTest(
126 kMessage
, std::string(), kSchedulingHash
);
128 std::string service_context
= kServiceContext
;
129 int64 scheduling_hash
= kSchedulingHash
+ 1;
130 EXPECT_TRUE(PushClientChannel::DecodeMessageForTest(
131 data
, &message
, &service_context
, &scheduling_hash
));
132 EXPECT_EQ(kMessage
, message
);
133 EXPECT_EQ(kServiceContext
, service_context
);
134 EXPECT_EQ(kSchedulingHash
+ 1, scheduling_hash
);
137 // Decode an empty notification. It should result in an empty message
138 // but should leave the context and hash untouched.
139 TEST_F(PushClientChannelTest
, DecodeEmpty
) {
140 std::string message
= kMessage
;
141 std::string service_context
= kServiceContext
;
142 int64 scheduling_hash
= kSchedulingHash
;
143 EXPECT_TRUE(PushClientChannel::DecodeMessageForTest(
144 std::string(), &message
, &service_context
, &scheduling_hash
));
145 EXPECT_TRUE(message
.empty());
146 EXPECT_EQ(kServiceContext
, service_context
);
147 EXPECT_EQ(kSchedulingHash
, scheduling_hash
);
150 // Try to decode a garbage notification. It should leave all its
151 // arguments untouched and return false.
152 TEST_F(PushClientChannelTest
, DecodeGarbage
) {
153 std::string data
= "garbage";
154 std::string message
= kMessage
;
155 std::string service_context
= kServiceContext
;
156 int64 scheduling_hash
= kSchedulingHash
;
157 EXPECT_FALSE(PushClientChannel::DecodeMessageForTest(
158 data
, &message
, &service_context
, &scheduling_hash
));
159 EXPECT_EQ(kMessage
, message
);
160 EXPECT_EQ(kServiceContext
, service_context
);
161 EXPECT_EQ(kSchedulingHash
, scheduling_hash
);
164 // Simulate an incoming notification. It should be decoded properly
166 TEST_F(PushClientChannelTest
, OnIncomingMessage
) {
167 notifier::Notification notification
;
169 PushClientChannel::EncodeMessageForTest(
170 kMessage
, kServiceContext
, kSchedulingHash
);
171 fake_push_client_
->SimulateIncomingNotification(notification
);
173 EXPECT_EQ(kServiceContext
,
174 push_client_channel_
.GetServiceContextForTest());
175 EXPECT_EQ(kSchedulingHash
,
176 push_client_channel_
.GetSchedulingHashForTest());
177 EXPECT_EQ(kMessage
, last_message_
);
180 // Simulate an incoming notification with no receiver. It should be dropped by
182 TEST_F(PushClientChannelTest
, OnIncomingMessageNoReceiver
) {
183 push_client_channel_
.SetMessageReceiver(NULL
);
185 notifier::Notification notification
;
186 notification
.data
= PushClientChannel::EncodeMessageForTest(
187 kMessage
, kServiceContext
, kSchedulingHash
);
188 fake_push_client_
->SimulateIncomingNotification(notification
);
190 EXPECT_TRUE(push_client_channel_
.GetServiceContextForTest().empty());
191 EXPECT_EQ(static_cast<int64
>(0),
192 push_client_channel_
.GetSchedulingHashForTest());
193 EXPECT_TRUE(last_message_
.empty());
196 // Simulate an incoming garbage notification. It should be dropped by
198 TEST_F(PushClientChannelTest
, OnIncomingMessageGarbage
) {
199 notifier::Notification notification
;
200 notification
.data
= "garbage";
201 fake_push_client_
->SimulateIncomingNotification(notification
);
202 EXPECT_TRUE(push_client_channel_
.GetServiceContextForTest().empty());
203 EXPECT_EQ(static_cast<int64
>(0),
204 push_client_channel_
.GetSchedulingHashForTest());
205 EXPECT_TRUE(last_message_
.empty());
208 // Send a message, simulate an incoming message with context, and then
209 // send the same message again. The first sent message should not
210 // have any context, but the second sent message should have the
211 // context from the incoming emssage.
212 TEST_F(PushClientChannelTest
, PersistedMessageState
) {
213 push_client_channel_
.SendMessage(kMessage
);
214 ASSERT_EQ(1u, fake_push_client_
->sent_notifications().size());
217 std::string service_context
;
218 int64 scheduling_hash
= 0LL;
219 EXPECT_TRUE(PushClientChannel::DecodeMessageForTest(
220 fake_push_client_
->sent_notifications()[0].data
,
224 EXPECT_EQ(kMessage
, message
);
225 EXPECT_TRUE(service_context
.empty());
226 EXPECT_EQ(0LL, scheduling_hash
);
229 notifier::Notification notification
;
230 notification
.data
= PushClientChannel::EncodeMessageForTest(
231 kMessage
, kServiceContext
, kSchedulingHash
);
232 fake_push_client_
->SimulateIncomingNotification(notification
);
234 push_client_channel_
.SendMessage(kMessage
);
235 ASSERT_EQ(2u, fake_push_client_
->sent_notifications().size());
238 std::string service_context
;
239 int64 scheduling_hash
= 0LL;
240 EXPECT_TRUE(PushClientChannel::DecodeMessageForTest(
241 fake_push_client_
->sent_notifications()[1].data
,
245 EXPECT_EQ(kMessage
, message
);
246 EXPECT_EQ(kServiceContext
, service_context
);
247 EXPECT_EQ(kSchedulingHash
, scheduling_hash
);
252 } // namespace syncer