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