blob: 31c1db3735a1477c1f17bd84099e4a069ab65e4f [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/sharing/sharing_fcm_handler.h"
#include <memory>
#include "chrome/browser/sharing/sharing_constants.h"
#include "chrome/browser/sharing/sharing_fcm_sender.h"
#include "chrome/browser/sharing/sharing_message_handler.h"
#include "chrome/browser/sharing/sharing_sync_preference.h"
#include "components/gcm_driver/fake_gcm_driver.h"
#include "components/sync_device_info/fake_device_info_sync_service.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using RecipientInfo = chrome_browser_sharing::RecipientInfo;
using SharingMessage = chrome_browser_sharing::SharingMessage;
using namespace testing;
namespace {
const char kTestAppId[] = "test_app_id";
const char kTestMessageId[] = "0:1563805165426489%0bb84dcff9fd7ecd";
const char kTestMessageIdSecondaryUser[] =
"0:1563805165426489%20#0bb84dcff9fd7ecd";
const char kOriginalMessageId[] = "test_original_message_id";
const char kSenderGuid[] = "test_sender_guid";
const char kSenderName[] = "test_sender_name";
const char kFCMToken[] = "test_fcm_token";
const char kP256dh[] = "test_p256_dh";
const char kAuthSecret[] = "test_auth_secret";
class MockSharingMessageHandler : public SharingMessageHandler {
public:
MockSharingMessageHandler() = default;
~MockSharingMessageHandler() override = default;
// SharingMessageHandler implementation:
MOCK_METHOD1(OnMessage, void(const SharingMessage& message));
};
class MockSharingFCMSender : public SharingFCMSender {
public:
MockSharingFCMSender()
: SharingFCMSender(nullptr, nullptr, nullptr, nullptr) {}
~MockSharingFCMSender() override {}
MOCK_METHOD4(SendMessageToDevice,
void(syncer::DeviceInfo::SharingInfo target,
base::TimeDelta time_to_live,
chrome_browser_sharing::SharingMessage message,
SendMessageCallback callback));
};
class SharingFCMHandlerTest : public Test {
protected:
SharingFCMHandlerTest() {
sync_prefs_ = std::make_unique<SharingSyncPreference>(
&prefs_, &fake_device_info_sync_service_);
sharing_fcm_handler_ = std::make_unique<SharingFCMHandler>(
&fake_gcm_driver_, &mock_sharing_fcm_sender_, sync_prefs_.get());
fake_device_info_ = std::make_unique<syncer::DeviceInfo>(
kSenderGuid, kSenderName, "chrome_version", "user_agent",
sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id",
/*last_updated_timestamp=*/base::Time::Now(),
/*send_tab_to_self_receiving_enabled=*/false,
syncer::DeviceInfo::SharingInfo(
kFCMToken, kP256dh, kAuthSecret,
std::set<sync_pb::SharingSpecificFields::EnabledFeatures>()));
SharingSyncPreference::RegisterProfilePrefs(prefs_.registry());
}
// Creates a gcm::IncomingMessage with SharingMessage and defaults.
gcm::IncomingMessage CreateGCMIncomingMessage(
const std::string& message_id,
const SharingMessage& sharing_message) {
gcm::IncomingMessage incoming_message;
incoming_message.message_id = message_id;
sharing_message.SerializeToString(&incoming_message.raw_data);
return incoming_message;
}
NiceMock<MockSharingMessageHandler> mock_sharing_message_handler_;
NiceMock<MockSharingFCMSender> mock_sharing_fcm_sender_;
gcm::FakeGCMDriver fake_gcm_driver_;
std::unique_ptr<SharingFCMHandler> sharing_fcm_handler_;
std::unique_ptr<SharingSyncPreference> sync_prefs_;
sync_preferences::TestingPrefServiceSyncable prefs_;
syncer::FakeDeviceInfoSyncService fake_device_info_sync_service_;
std::unique_ptr<syncer::DeviceInfo> fake_device_info_;
};
} // namespace
MATCHER_P(ProtoEquals, message, "") {
std::string expected_serialized, actual_serialized;
message.SerializeToString(&expected_serialized);
arg.SerializeToString(&actual_serialized);
return expected_serialized == actual_serialized;
}
MATCHER(DeviceMatcher, "") {
return arg.fcm_token == kFCMToken && arg.p256dh == kP256dh &&
arg.auth_secret == kAuthSecret;
}
// Tests handling of SharingMessage with AckMessage payload. This is different
// from other payloads since we need to ensure AckMessage is not sent for
// SharingMessage with AckMessage payload.
TEST_F(SharingFCMHandlerTest, AckMessageHandler) {
SharingMessage sharing_message;
sharing_message.mutable_ack_message()->set_original_message_id(
kOriginalMessageId);
gcm::IncomingMessage incoming_message =
CreateGCMIncomingMessage(kTestMessageId, sharing_message);
EXPECT_CALL(mock_sharing_message_handler_,
OnMessage(ProtoEquals(sharing_message)));
EXPECT_CALL(mock_sharing_fcm_sender_, SendMessageToDevice(_, _, _, _))
.Times(0);
sharing_fcm_handler_->AddSharingHandler(SharingMessage::kAckMessage,
&mock_sharing_message_handler_);
sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message);
}
// Generic test for handling of SharingMessage payload other than AckMessage.
TEST_F(SharingFCMHandlerTest, PingMessageHandler) {
fake_device_info_sync_service_.GetDeviceInfoTracker()->Add(
fake_device_info_.get());
SharingMessage sharing_message;
sharing_message.set_sender_guid(kSenderGuid);
sharing_message.mutable_ping_message();
gcm::IncomingMessage incoming_message =
CreateGCMIncomingMessage(kTestMessageId, sharing_message);
SharingMessage sharing_ack_message;
sharing_ack_message.mutable_ack_message()->set_original_message_id(
kTestMessageId);
// Tests OnMessage flow in SharingFCMHandler when no handler is registered.
EXPECT_CALL(mock_sharing_message_handler_, OnMessage(_)).Times(0);
EXPECT_CALL(mock_sharing_fcm_sender_, SendMessageToDevice(_, _, _, _))
.Times(0);
sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message);
// Tests OnMessage flow in SharingFCMHandler after handler is added.
EXPECT_CALL(mock_sharing_message_handler_,
OnMessage(ProtoEquals(sharing_message)));
EXPECT_CALL(mock_sharing_fcm_sender_,
SendMessageToDevice(DeviceMatcher(), Eq(kAckTimeToLive),
ProtoEquals(sharing_ack_message), _));
sharing_fcm_handler_->AddSharingHandler(SharingMessage::kPingMessage,
&mock_sharing_message_handler_);
sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message);
// Tests OnMessage flow in SharingFCMHandler after registered handler is
// removed.
EXPECT_CALL(mock_sharing_message_handler_, OnMessage(_)).Times(0);
EXPECT_CALL(mock_sharing_fcm_sender_, SendMessageToDevice(_, _, _, _))
.Times(0);
sharing_fcm_handler_->RemoveSharingHandler(SharingMessage::kPingMessage);
sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message);
}
// Test for handling of SharingMessage payload other than AckMessage for
// secondary users in Android.
TEST_F(SharingFCMHandlerTest, PingMessageHandlerSecondaryUser) {
fake_device_info_sync_service_.GetDeviceInfoTracker()->Add(
fake_device_info_.get());
SharingMessage sharing_message;
sharing_message.set_sender_guid(kSenderGuid);
sharing_message.mutable_ping_message();
gcm::IncomingMessage incoming_message =
CreateGCMIncomingMessage(kTestMessageIdSecondaryUser, sharing_message);
SharingMessage sharing_ack_message;
sharing_ack_message.mutable_ack_message()->set_original_message_id(
kTestMessageId);
// Tests OnMessage flow in SharingFCMHandler after handler is added.
EXPECT_CALL(mock_sharing_message_handler_,
OnMessage(ProtoEquals(sharing_message)));
EXPECT_CALL(mock_sharing_fcm_sender_,
SendMessageToDevice(DeviceMatcher(), Eq(kAckTimeToLive),
ProtoEquals(sharing_ack_message), _));
sharing_fcm_handler_->AddSharingHandler(SharingMessage::kPingMessage,
&mock_sharing_message_handler_);
sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message);
}
// Test for handling of SharingMessage payload with RecipientInfo other than
// AckMessage.
TEST_F(SharingFCMHandlerTest, PingMessageHandlerWithRecipientInfo) {
SharingMessage sharing_message;
sharing_message.set_sender_guid(kSenderGuid);
sharing_message.mutable_ping_message();
RecipientInfo* sender_info = sharing_message.mutable_sender_info();
sender_info->set_fcm_token(kFCMToken);
sender_info->set_p256dh(kP256dh);
sender_info->set_auth_secret(kAuthSecret);
gcm::IncomingMessage incoming_message =
CreateGCMIncomingMessage(kTestMessageId, sharing_message);
SharingMessage sharing_ack_message;
sharing_ack_message.mutable_ack_message()->set_original_message_id(
kTestMessageId);
EXPECT_CALL(mock_sharing_message_handler_,
OnMessage(ProtoEquals(sharing_message)));
EXPECT_CALL(mock_sharing_fcm_sender_,
SendMessageToDevice(DeviceMatcher(), Eq(kAckTimeToLive),
ProtoEquals(sharing_ack_message), _));
sharing_fcm_handler_->AddSharingHandler(SharingMessage::kPingMessage,
&mock_sharing_message_handler_);
sharing_fcm_handler_->OnMessage(kTestAppId, incoming_message);
}