1 // Copyright 2019 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 "remoting/host/ftl_host_change_notification_listener.h"
6 
7 #include <set>
8 
9 #include "base/bind.h"
10 #include "base/run_loop.h"
11 #include "base/test/task_environment.h"
12 #include "base/threading/sequenced_task_runner_handle.h"
13 #include "remoting/proto/ftl/v1/chromoting_message.pb.h"
14 #include "remoting/proto/ftl/v1/ftl_messages.pb.h"
15 #include "remoting/signaling/mock_signal_strategy.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 using testing::NotNull;
20 using testing::Return;
21 
22 namespace remoting {
23 
24 namespace {
25 
26 const char kTestJid[] = "user@gmail.com/chromoting_ftl_abc123";
27 
ACTION_P(AddListener,list)28 ACTION_P(AddListener, list) {
29   list->insert(arg0);
30 }
31 
ACTION_P(RemoveListener,list)32 ACTION_P(RemoveListener, list) {
33   EXPECT_TRUE(list->find(arg0) != list->end());
34   list->erase(arg0);
35 }
36 
CreateMessageWithDirectoryState(ftl::HostStatusChangeMessage_DirectoryState state)37 ftl::ChromotingMessage CreateMessageWithDirectoryState(
38     ftl::HostStatusChangeMessage_DirectoryState state) {
39   ftl::ChromotingMessage message;
40   message.mutable_status()->set_directory_state(state);
41   return message;
42 }
43 
44 }  // namespace
45 
46 class FtlHostChangeNotificationListenerTest : public testing::Test {
47  protected:
FtlHostChangeNotificationListenerTest()48   FtlHostChangeNotificationListenerTest()
49       : signal_strategy_(SignalingAddress(kTestJid)) {}
50   class MockListener : public FtlHostChangeNotificationListener::Listener {
51    public:
52     MOCK_METHOD0(OnHostDeleted, void());
53   };
54 
SetUp()55   void SetUp() override {
56     EXPECT_CALL(signal_strategy_, AddListener(NotNull()))
57         .WillRepeatedly(AddListener(&signal_strategy_listeners_));
58     EXPECT_CALL(signal_strategy_, RemoveListener(NotNull()))
59         .WillRepeatedly(RemoveListener(&signal_strategy_listeners_));
60 
61     system_sender_id_.set_type(ftl::IdType_Type_SYSTEM);
62     peer_sender_id_.set_type(ftl::IdType_Type_EMAIL);
63     peer_sender_id_.set_id("fake_peer_id");
64 
65     ftl_host_change_notification_listener_ =
66         std::make_unique<FtlHostChangeNotificationListener>(&mock_listener_,
67                                                             &signal_strategy_);
68   }
69 
TearDown()70   void TearDown() override {
71     ftl_host_change_notification_listener_.reset();
72     EXPECT_TRUE(signal_strategy_listeners_.empty());
73   }
74 
75  protected:
76   ftl::Id system_sender_id_;
77   ftl::Id peer_sender_id_;
78 
79   base::test::TaskEnvironment task_environment_;
80 
81   MockListener mock_listener_;
82   MockSignalStrategy signal_strategy_;
83   std::set<SignalStrategy::Listener*> signal_strategy_listeners_;
84   std::unique_ptr<FtlHostChangeNotificationListener>
85       ftl_host_change_notification_listener_;
86 };
87 
TEST_F(FtlHostChangeNotificationListenerTest,ReceiveValidNotification)88 TEST_F(FtlHostChangeNotificationListenerTest, ReceiveValidNotification) {
89   base::RunLoop run_loop;
90   EXPECT_CALL(mock_listener_, OnHostDeleted()).WillOnce([&]() {
91     run_loop.Quit();
92   });
93   bool is_handled =
94       ftl_host_change_notification_listener_->OnSignalStrategyIncomingMessage(
95           system_sender_id_, {},
96           CreateMessageWithDirectoryState(
97               ftl::HostStatusChangeMessage_DirectoryState_DELETED));
98   ASSERT_TRUE(is_handled);
99   run_loop.Run();
100 }
101 
TEST_F(FtlHostChangeNotificationListenerTest,ReceiveNotificationThenDeleteObject_CallbackNotCalled)102 TEST_F(FtlHostChangeNotificationListenerTest,
103        ReceiveNotificationThenDeleteObject_CallbackNotCalled) {
104   EXPECT_CALL(mock_listener_, OnHostDeleted()).Times(0);
105   bool is_handled =
106       ftl_host_change_notification_listener_->OnSignalStrategyIncomingMessage(
107           system_sender_id_, {},
108           CreateMessageWithDirectoryState(
109               ftl::HostStatusChangeMessage_DirectoryState_DELETED));
110   ASSERT_TRUE(is_handled);
111   ftl_host_change_notification_listener_.reset();
112   base::RunLoop run_loop;
113   base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
114                                                    run_loop.QuitClosure());
115   run_loop.Run();
116 }
117 
TEST_F(FtlHostChangeNotificationListenerTest,ReceiveNonSystemNotification_Ignored)118 TEST_F(FtlHostChangeNotificationListenerTest,
119        ReceiveNonSystemNotification_Ignored) {
120   EXPECT_CALL(mock_listener_, OnHostDeleted()).Times(0);
121   bool is_handled =
122       ftl_host_change_notification_listener_->OnSignalStrategyIncomingMessage(
123           peer_sender_id_, "fake_registration_id",
124           CreateMessageWithDirectoryState(
125               ftl::HostStatusChangeMessage_DirectoryState_DELETED));
126   ASSERT_FALSE(is_handled);
127   base::RunLoop run_loop;
128   base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
129                                                    run_loop.QuitClosure());
130   run_loop.Run();
131 }
132 
TEST_F(FtlHostChangeNotificationListenerTest,ReceiveUnknownChromotingMessage_Ignored)133 TEST_F(FtlHostChangeNotificationListenerTest,
134        ReceiveUnknownChromotingMessage_Ignored) {
135   EXPECT_CALL(mock_listener_, OnHostDeleted()).Times(0);
136   bool is_handled =
137       ftl_host_change_notification_listener_->OnSignalStrategyIncomingMessage(
138           system_sender_id_, /* registration_id */ {},
139           /* chromoting_message */ {});
140   ASSERT_FALSE(is_handled);
141   base::RunLoop run_loop;
142   base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
143                                                    run_loop.QuitClosure());
144   run_loop.Run();
145 }
146 
TEST_F(FtlHostChangeNotificationListenerTest,ReceiveUnknownDirectoryState_Ignored)147 TEST_F(FtlHostChangeNotificationListenerTest,
148        ReceiveUnknownDirectoryState_Ignored) {
149   EXPECT_CALL(mock_listener_, OnHostDeleted()).Times(0);
150   bool is_handled =
151       ftl_host_change_notification_listener_->OnSignalStrategyIncomingMessage(
152           system_sender_id_, {},
153           CreateMessageWithDirectoryState(
154               ftl::HostStatusChangeMessage_DirectoryState_NOT_SET));
155   ASSERT_FALSE(is_handled);
156   base::RunLoop run_loop;
157   base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
158                                                    run_loop.QuitClosure());
159   run_loop.Run();
160 }
161 
162 }  // namespace remoting
163