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 "jingle/notifier/listener/non_blocking_push_client.h"
6
7 #include <cstddef>
8 #include <memory>
9
10 #include "base/bind.h"
11 #include "base/compiler_specific.h"
12 #include "base/run_loop.h"
13 #include "base/test/task_environment.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "jingle/notifier/base/fake_base_task.h"
16 #include "jingle/notifier/listener/fake_push_client.h"
17 #include "jingle/notifier/listener/fake_push_client_observer.h"
18 #include "jingle/notifier/listener/push_client_observer.h"
19 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
20 #include "net/url_request/url_request_test_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace notifier {
24
25 namespace {
26
27 class NonBlockingPushClientTest : public testing::Test {
28 protected:
NonBlockingPushClientTest()29 NonBlockingPushClientTest() : fake_push_client_(NULL) {}
30
~NonBlockingPushClientTest()31 ~NonBlockingPushClientTest() override {}
32
SetUp()33 void SetUp() override {
34 push_client_ = std::make_unique<NonBlockingPushClient>(
35 base::ThreadTaskRunnerHandle::Get(),
36 base::BindOnce(&NonBlockingPushClientTest::CreateFakePushClient,
37 base::Unretained(this)));
38 push_client_->AddObserver(&fake_observer_);
39 // Pump message loop to run CreateFakePushClient.
40 base::RunLoop().RunUntilIdle();
41 }
42
TearDown()43 void TearDown() override {
44 // Clear out any pending notifications before removing observers.
45 base::RunLoop().RunUntilIdle();
46 push_client_->RemoveObserver(&fake_observer_);
47 push_client_.reset();
48 // Then pump message loop to run
49 // NonBlockingPushClient::DestroyOnDelegateThread().
50 base::RunLoop().RunUntilIdle();
51 }
52
CreateFakePushClient()53 std::unique_ptr<PushClient> CreateFakePushClient() {
54 if (fake_push_client_) {
55 ADD_FAILURE();
56 return nullptr;
57 }
58 auto client = std::make_unique<FakePushClient>();
59 fake_push_client_ = client.get();
60 return client;
61 }
62
63 base::test::SingleThreadTaskEnvironment task_environment_;
64 FakePushClientObserver fake_observer_;
65 std::unique_ptr<NonBlockingPushClient> push_client_;
66 // Owned by |push_client_|.
67 FakePushClient* fake_push_client_;
68 };
69
70 // Make sure UpdateSubscriptions() gets delegated properly.
TEST_F(NonBlockingPushClientTest,UpdateSubscriptions)71 TEST_F(NonBlockingPushClientTest, UpdateSubscriptions) {
72 SubscriptionList subscriptions(10);
73 subscriptions[0].channel = "channel";
74 subscriptions[9].from = "from";
75
76 push_client_->UpdateSubscriptions(subscriptions);
77 EXPECT_TRUE(fake_push_client_->subscriptions().empty());
78 base::RunLoop().RunUntilIdle();
79 EXPECT_TRUE(
80 SubscriptionListsEqual(
81 fake_push_client_->subscriptions(), subscriptions));
82 }
83
84 // Make sure UpdateCredentials() gets delegated properly.
TEST_F(NonBlockingPushClientTest,UpdateCredentials)85 TEST_F(NonBlockingPushClientTest, UpdateCredentials) {
86 const char kEmail[] = "foo@bar.com";
87 const char kToken[] = "baz";
88
89 push_client_->UpdateCredentials(kEmail, kToken, TRAFFIC_ANNOTATION_FOR_TESTS);
90 EXPECT_TRUE(fake_push_client_->email().empty());
91 EXPECT_TRUE(fake_push_client_->token().empty());
92 base::RunLoop().RunUntilIdle();
93 EXPECT_EQ(kEmail, fake_push_client_->email());
94 EXPECT_EQ(kToken, fake_push_client_->token());
95 }
96
MakeTestNotification()97 Notification MakeTestNotification() {
98 Notification notification;
99 notification.channel = "channel";
100 notification.recipients.resize(10);
101 notification.recipients[0].to = "to";
102 notification.recipients[9].user_specific_data = "user_specific_data";
103 notification.data = "data";
104 return notification;
105 }
106
107 // Make sure SendNotification() gets delegated properly.
TEST_F(NonBlockingPushClientTest,SendNotification)108 TEST_F(NonBlockingPushClientTest, SendNotification) {
109 const Notification notification = MakeTestNotification();
110
111 push_client_->SendNotification(notification);
112 EXPECT_TRUE(fake_push_client_->sent_notifications().empty());
113 base::RunLoop().RunUntilIdle();
114 ASSERT_EQ(1u, fake_push_client_->sent_notifications().size());
115 EXPECT_TRUE(
116 fake_push_client_->sent_notifications()[0].Equals(notification));
117 }
118
119 // Make sure SendPing() gets delegated properly.
TEST_F(NonBlockingPushClientTest,SendPing)120 TEST_F(NonBlockingPushClientTest, SendPing) {
121 push_client_->SendPing();
122 EXPECT_EQ(0, fake_push_client_->sent_pings());
123 base::RunLoop().RunUntilIdle();
124 ASSERT_EQ(1, fake_push_client_->sent_pings());
125 }
126
127 // Make sure notification state changes get propagated back to the
128 // parent.
TEST_F(NonBlockingPushClientTest,NotificationStateChange)129 TEST_F(NonBlockingPushClientTest, NotificationStateChange) {
130 EXPECT_EQ(DEFAULT_NOTIFICATION_ERROR,
131 fake_observer_.last_notifications_disabled_reason());
132 fake_push_client_->EnableNotifications();
133 base::RunLoop().RunUntilIdle();
134 EXPECT_EQ(NO_NOTIFICATION_ERROR,
135 fake_observer_.last_notifications_disabled_reason());
136 fake_push_client_->DisableNotifications(
137 NOTIFICATION_CREDENTIALS_REJECTED);
138 base::RunLoop().RunUntilIdle();
139 EXPECT_EQ(NOTIFICATION_CREDENTIALS_REJECTED,
140 fake_observer_.last_notifications_disabled_reason());
141 }
142
143 // Make sure incoming notifications get propagated back to the parent.
TEST_F(NonBlockingPushClientTest,OnIncomingNotification)144 TEST_F(NonBlockingPushClientTest, OnIncomingNotification) {
145 const Notification notification = MakeTestNotification();
146
147 fake_push_client_->SimulateIncomingNotification(notification);
148 base::RunLoop().RunUntilIdle();
149 EXPECT_TRUE(
150 fake_observer_.last_incoming_notification().Equals(notification));
151 }
152
153 } // namespace
154
155 } // namespace notifier
156