1 // Copyright (c) 2012 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.
5 #include "sync/notifier/push_client_channel.h"
10 #include "base/compiler_specific.h"
11 #include "jingle/notifier/listener/fake_push_client.h"
12 #include "jingle/notifier/listener/notification_defines.h"
13 #include "testing/gtest/include/gtest/gtest.h"
18 class PushClientChannelTest
: public ::testing::Test
{
20 PushClientChannelTest()
21 : fake_push_client_(new notifier::FakePushClient()),
23 scoped_ptr
<notifier::PushClient
>(fake_push_client_
)),
25 push_client_channel_
.SetMessageReceiver(
26 invalidation::NewPermanentCallback(
27 this, &PushClientChannelTest::OnIncomingMessage
));
28 push_client_channel_
.AddNetworkStatusReceiver(
29 invalidation::NewPermanentCallback(
30 this, &PushClientChannelTest::OnNetworkStatusChange
));
31 push_client_channel_
.SetSystemResources(NULL
);
34 virtual ~PushClientChannelTest() {}
36 void OnIncomingMessage(std::string incoming_message
) {
37 last_message_
= incoming_message
;
40 void OnNetworkStatusChange(bool connected
) {
41 connected_
= connected
;
44 notifier::FakePushClient
* fake_push_client_
;
45 PushClientChannel push_client_channel_
;
46 std::string last_message_
;
50 const char kMessage
[] = "message";
51 const char kServiceContext
[] = "service context";
52 const int64 kSchedulingHash
= 100;
54 // Encode a message with some context into a notification and then
55 // decode it. The decoded info should match the original info.
56 TEST_F(PushClientChannelTest
, EncodeDecode
) {
57 const notifier::Notification
& notification
=
58 PushClientChannel::EncodeMessageForTest(
59 kMessage
, kServiceContext
, kSchedulingHash
);
61 std::string service_context
;
62 int64 scheduling_hash
= 0LL;
63 EXPECT_TRUE(PushClientChannel::DecodeMessageForTest(
64 notification
, &message
, &service_context
, &scheduling_hash
));
65 EXPECT_EQ(kMessage
, message
);
66 EXPECT_EQ(kServiceContext
, service_context
);
67 EXPECT_EQ(kSchedulingHash
, scheduling_hash
);
70 // Encode a message with no context into a notification and then
71 // decode it. The decoded message should match the original message,
72 // but the context and hash should be untouched.
73 TEST_F(PushClientChannelTest
, EncodeDecodeNoContext
) {
74 const notifier::Notification
& notification
=
75 PushClientChannel::EncodeMessageForTest(
76 kMessage
, std::string(), kSchedulingHash
);
78 std::string service_context
= kServiceContext
;
79 int64 scheduling_hash
= kSchedulingHash
+ 1;
80 EXPECT_TRUE(PushClientChannel::DecodeMessageForTest(
81 notification
, &message
, &service_context
, &scheduling_hash
));
82 EXPECT_EQ(kMessage
, message
);
83 EXPECT_EQ(kServiceContext
, service_context
);
84 EXPECT_EQ(kSchedulingHash
+ 1, scheduling_hash
);
87 // Decode an empty notification. It should result in an empty message
88 // but should leave the context and hash untouched.
89 TEST_F(PushClientChannelTest
, DecodeEmpty
) {
90 std::string message
= kMessage
;
91 std::string service_context
= kServiceContext
;
92 int64 scheduling_hash
= kSchedulingHash
;
93 EXPECT_TRUE(PushClientChannel::DecodeMessageForTest(
94 notifier::Notification(),
95 &message
, &service_context
, &scheduling_hash
));
96 EXPECT_TRUE(message
.empty());
97 EXPECT_EQ(kServiceContext
, service_context
);
98 EXPECT_EQ(kSchedulingHash
, scheduling_hash
);
101 // Try to decode a garbage notification. It should leave all its
102 // arguments untouched and return false.
103 TEST_F(PushClientChannelTest
, DecodeGarbage
) {
104 notifier::Notification notification
;
105 notification
.data
= "garbage";
106 std::string message
= kMessage
;
107 std::string service_context
= kServiceContext
;
108 int64 scheduling_hash
= kSchedulingHash
;
109 EXPECT_FALSE(PushClientChannel::DecodeMessageForTest(
110 notification
, &message
, &service_context
, &scheduling_hash
));
111 EXPECT_EQ(kMessage
, message
);
112 EXPECT_EQ(kServiceContext
, service_context
);
113 EXPECT_EQ(kSchedulingHash
, scheduling_hash
);
116 // Make sure the channel subscribes to the correct notifications
117 // channel on construction.
118 TEST_F(PushClientChannelTest
, Subscriptions
) {
119 notifier::Subscription expected_subscription
;
120 expected_subscription
.channel
= "tango_raw";
121 EXPECT_TRUE(notifier::SubscriptionListsEqual(
122 fake_push_client_
->subscriptions(),
123 notifier::SubscriptionList(1, expected_subscription
)));
126 // Call UpdateCredentials on the channel. It should propagate it to
128 TEST_F(PushClientChannelTest
, UpdateCredentials
) {
129 const char kEmail
[] = "foo@bar.com";
130 const char kToken
[] = "token";
131 EXPECT_TRUE(fake_push_client_
->email().empty());
132 EXPECT_TRUE(fake_push_client_
->token().empty());
133 push_client_channel_
.UpdateCredentials(kEmail
, kToken
);
134 EXPECT_EQ(kEmail
, fake_push_client_
->email());
135 EXPECT_EQ(kToken
, fake_push_client_
->token());
138 // Call SendMessage on the channel. It should propagate it to the
140 TEST_F(PushClientChannelTest
, SendMessage
) {
141 EXPECT_TRUE(fake_push_client_
->sent_notifications().empty());
142 push_client_channel_
.SendMessage(kMessage
);
143 const notifier::Notification expected_notification
=
144 PushClientChannel::EncodeMessageForTest(
146 push_client_channel_
.GetServiceContextForTest(),
147 push_client_channel_
.GetSchedulingHashForTest());
148 ASSERT_EQ(1u, fake_push_client_
->sent_notifications().size());
150 fake_push_client_
->sent_notifications()[0].Equals(
151 expected_notification
));
154 // Simulate push client state changes on the push client. It should
155 // propagate to the channel.
156 TEST_F(PushClientChannelTest
, OnPushClientStateChange
) {
157 EXPECT_FALSE(connected_
);
158 fake_push_client_
->EnableNotifications();
159 EXPECT_TRUE(connected_
);
160 fake_push_client_
->DisableNotifications(
161 notifier::TRANSIENT_NOTIFICATION_ERROR
);
162 EXPECT_FALSE(connected_
);
163 fake_push_client_
->EnableNotifications();
164 EXPECT_TRUE(connected_
);
165 fake_push_client_
->DisableNotifications(
166 notifier::NOTIFICATION_CREDENTIALS_REJECTED
);
167 EXPECT_FALSE(connected_
);
170 // Simulate an incoming notification. It should be decoded properly
172 TEST_F(PushClientChannelTest
, OnIncomingNotification
) {
173 const notifier::Notification notification
=
174 PushClientChannel::EncodeMessageForTest(
175 kMessage
, kServiceContext
, kSchedulingHash
);
177 fake_push_client_
->SimulateIncomingNotification(notification
);
178 EXPECT_EQ(kServiceContext
,
179 push_client_channel_
.GetServiceContextForTest());
180 EXPECT_EQ(kSchedulingHash
,
181 push_client_channel_
.GetSchedulingHashForTest());
182 EXPECT_EQ(kMessage
, last_message_
);
185 // Simulate an incoming notification with no receiver. It should be
186 // dropped by the channel.
187 TEST_F(PushClientChannelTest
, OnIncomingNotificationNoReceiver
) {
188 const notifier::Notification notification
=
189 PushClientChannel::EncodeMessageForTest(
190 kMessage
, kServiceContext
, kSchedulingHash
);
192 push_client_channel_
.SetMessageReceiver(NULL
);
193 fake_push_client_
->SimulateIncomingNotification(notification
);
194 EXPECT_TRUE(push_client_channel_
.GetServiceContextForTest().empty());
195 EXPECT_EQ(static_cast<int64
>(0),
196 push_client_channel_
.GetSchedulingHashForTest());
197 EXPECT_TRUE(last_message_
.empty());
200 // Simulate an incoming garbage notification. It should be dropped by
202 TEST_F(PushClientChannelTest
, OnIncomingNotificationGarbage
) {
203 notifier::Notification notification
;
204 notification
.data
= "garbage";
206 fake_push_client_
->SimulateIncomingNotification(notification
);
207 EXPECT_TRUE(push_client_channel_
.GetServiceContextForTest().empty());
208 EXPECT_EQ(static_cast<int64
>(0),
209 push_client_channel_
.GetSchedulingHashForTest());
210 EXPECT_TRUE(last_message_
.empty());
213 // Send a message, simulate an incoming message with context, and then
214 // send the same message again. The first sent message should not
215 // have any context, but the second sent message should have the
216 // context from the incoming emssage.
217 TEST_F(PushClientChannelTest
, PersistedMessageState
) {
218 push_client_channel_
.SendMessage(kMessage
);
219 ASSERT_EQ(1u, fake_push_client_
->sent_notifications().size());
222 std::string service_context
;
223 int64 scheduling_hash
= 0LL;
224 EXPECT_TRUE(PushClientChannel::DecodeMessageForTest(
225 fake_push_client_
->sent_notifications()[0],
226 &message
, &service_context
, &scheduling_hash
));
227 EXPECT_EQ(kMessage
, message
);
228 EXPECT_TRUE(service_context
.empty());
229 EXPECT_EQ(0LL, scheduling_hash
);
232 const notifier::Notification notification
=
233 PushClientChannel::EncodeMessageForTest(
234 kMessage
, kServiceContext
, kSchedulingHash
);
235 fake_push_client_
->SimulateIncomingNotification(notification
);
237 push_client_channel_
.SendMessage(kMessage
);
238 ASSERT_EQ(2u, fake_push_client_
->sent_notifications().size());
241 std::string service_context
;
242 int64 scheduling_hash
= 0LL;
243 EXPECT_TRUE(PushClientChannel::DecodeMessageForTest(
244 fake_push_client_
->sent_notifications()[1],
245 &message
, &service_context
, &scheduling_hash
));
246 EXPECT_EQ(kMessage
, message
);
247 EXPECT_EQ(kServiceContext
, service_context
);
248 EXPECT_EQ(kSchedulingHash
, scheduling_hash
);
253 } // namespace syncer