- add sources.
[platform/framework/web/crosswalk.git] / src / sync / notifier / push_client_channel_unittest.cc
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.
4
5 #include "sync/notifier/push_client_channel.h"
6
7 #include <cstddef>
8 #include <string>
9
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"
14
15 namespace syncer {
16 namespace {
17
18 class PushClientChannelTest : public ::testing::Test {
19  protected:
20   PushClientChannelTest()
21       : fake_push_client_(new notifier::FakePushClient()),
22         push_client_channel_(
23             scoped_ptr<notifier::PushClient>(fake_push_client_)),
24         connected_(false) {
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);
32   }
33
34   virtual ~PushClientChannelTest() {}
35
36   void OnIncomingMessage(std::string incoming_message) {
37     last_message_ = incoming_message;
38   }
39
40   void OnNetworkStatusChange(bool connected) {
41     connected_ = connected;
42   }
43
44   notifier::FakePushClient* fake_push_client_;
45   PushClientChannel push_client_channel_;
46   std::string last_message_;
47   bool connected_;
48 };
49
50 const char kMessage[] = "message";
51 const char kServiceContext[] = "service context";
52 const int64 kSchedulingHash = 100;
53
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);
60   std::string message;
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);
68 }
69
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);
77   std::string message;
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);
85 }
86
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);
99 }
100
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);
114 }
115
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)));
124 }
125
126 // Call UpdateCredentials on the channel.  It should propagate it to
127 // the push client.
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());
136 }
137
138 // Call SendMessage on the channel.  It should propagate it to the
139 // push client.
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(
145           kMessage,
146           push_client_channel_.GetServiceContextForTest(),
147           push_client_channel_.GetSchedulingHashForTest());
148   ASSERT_EQ(1u, fake_push_client_->sent_notifications().size());
149   EXPECT_TRUE(
150       fake_push_client_->sent_notifications()[0].Equals(
151           expected_notification));
152 }
153
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_);
168 }
169
170 // Simulate an incoming notification.  It should be decoded properly
171 // by the channel.
172 TEST_F(PushClientChannelTest, OnIncomingNotification) {
173   const notifier::Notification notification =
174       PushClientChannel::EncodeMessageForTest(
175           kMessage, kServiceContext, kSchedulingHash);
176
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_);
183 }
184
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);
191
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());
198 }
199
200 // Simulate an incoming garbage notification.  It should be dropped by
201 // the channel.
202 TEST_F(PushClientChannelTest, OnIncomingNotificationGarbage) {
203   notifier::Notification notification;
204   notification.data = "garbage";
205
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());
211 }
212
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());
220   {
221     std::string message;
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);
230   }
231
232   const notifier::Notification notification =
233       PushClientChannel::EncodeMessageForTest(
234           kMessage, kServiceContext, kSchedulingHash);
235   fake_push_client_->SimulateIncomingNotification(notification);
236
237   push_client_channel_.SendMessage(kMessage);
238   ASSERT_EQ(2u, fake_push_client_->sent_notifications().size());
239   {
240     std::string message;
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);
249   }
250 }
251
252 }  // namespace
253 }  // namespace syncer