| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/system/network/sms_observer.h" |
| |
| #include <memory> |
| #include <optional> |
| |
| #include "ash/constants/ash_features.h" |
| #include "ash/shell.h" |
| #include "ash/test/ash_test_base.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "chromeos/ash/components/network/fake_network_metadata_store.h" |
| #include "chromeos/ash/components/network/metrics/cellular_network_metrics_logger.h" |
| #include "chromeos/ash/components/network/network_handler.h" |
| #include "chromeos/ash/components/network/network_handler_test_helper.h" |
| #include "chromeos/ash/components/network/network_sms_handler.h" |
| #include "chromeos/ash/components/network/text_message_suppression_state.h" |
| #include "components/onc/onc_constants.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/message_center/message_center.h" |
| #include "ui/message_center/notification_list.h" |
| #include "ui/message_center/public/cpp/notification.h" |
| |
| using message_center::MessageCenter; |
| |
| namespace ash { |
| |
| namespace { |
| |
| constexpr char kTestGuid[] = "TestGuid"; |
| |
| std::optional<const std::string> GetStringOptional(const char* text) { |
| if (text) { |
| return std::make_optional<const std::string>(text); |
| } |
| return std::nullopt; |
| } |
| |
| } // namespace |
| |
| struct SmsObserverTestCase { |
| std::string test_name; |
| bool use_suppress_text_message_flag; |
| }; |
| |
| class SmsObserverTest : public AshTestBase { |
| public: |
| SmsObserverTest() = default; |
| |
| SmsObserverTest(const SmsObserverTest&) = delete; |
| SmsObserverTest& operator=(const SmsObserverTest&) = delete; |
| |
| ~SmsObserverTest() override = default; |
| |
| SmsObserver* GetSmsObserver() { return Shell::Get()->sms_observer_.get(); } |
| |
| void SetUp() override { |
| AshTestBase::SetUp(); |
| test_helper_ = std::make_unique<NetworkHandlerTestHelper>(); |
| NetworkHandler::Get()->text_message_provider()->SetNetworkMetadataStore( |
| &network_metadata_store_); |
| } |
| |
| void SimulateMessageReceived( |
| const char* kDefaultMessage = "FakeSMSClient: \xF0\x9F\x98\x8A", |
| const char* kDefaultNumber = "000-000-0000", |
| const char* kDefaultTimestamp = "Fri Jun 8 13:26:04 EDT 2016") { |
| TextMessageData message_data(GetStringOptional(kDefaultNumber), |
| GetStringOptional(kDefaultMessage), |
| GetStringOptional(kDefaultTimestamp)); |
| GetSmsObserver()->MessageReceived(kTestGuid, message_data); |
| } |
| |
| NetworkMetadataStore* network_metadata_store() { |
| return &network_metadata_store_; |
| } |
| |
| ManagedNetworkConfigurationHandler* managed_network_configuration_handler() { |
| return NetworkHandler::Get()->managed_network_configuration_handler(); |
| } |
| |
| private: |
| base::test::ScopedFeatureList features_; |
| std::unique_ptr<NetworkHandlerTestHelper> test_helper_; |
| FakeNetworkMetadataStore network_metadata_store_; |
| }; |
| |
| // Verify if notification is received after receiving a sms message with |
| // number and content. |
| TEST_F(SmsObserverTest, SendTextMessage) { |
| EXPECT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size()); |
| SimulateMessageReceived(); |
| const message_center::NotificationList::Notifications notifications = |
| MessageCenter::Get()->GetVisibleNotifications(); |
| EXPECT_EQ(1u, notifications.size()); |
| |
| EXPECT_EQ(u"000-000-0000", (*notifications.begin())->title()); |
| EXPECT_EQ(u"FakeSMSClient: 😊", (*notifications.begin())->message()); |
| MessageCenter::Get()->RemoveAllNotifications(false /* by_user */, |
| MessageCenter::RemoveType::ALL); |
| EXPECT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size()); |
| } |
| |
| // Verify if no notification is received if phone number is missing in sms |
| // message. |
| TEST_F(SmsObserverTest, TextMessageMissingNumber) { |
| EXPECT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size()); |
| SimulateMessageReceived("FakeSMSClient: Test Message.", nullptr); |
| EXPECT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size()); |
| } |
| |
| // Verify if no notification is received if text body is empty in sms message. |
| TEST_F(SmsObserverTest, TextMessageEmptyText) { |
| EXPECT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size()); |
| SimulateMessageReceived(""); |
| EXPECT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size()); |
| } |
| |
| // Verify if no notification is received if the text is missing in sms message. |
| TEST_F(SmsObserverTest, TextMessageMissingText) { |
| EXPECT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size()); |
| SimulateMessageReceived(""); |
| EXPECT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size()); |
| } |
| |
| // Verify if 2 notification received after receiving 2 sms messages from the |
| // same number. |
| TEST_F(SmsObserverTest, MultipleTextMessages) { |
| EXPECT_EQ(0u, MessageCenter::Get()->GetVisibleNotifications().size()); |
| SimulateMessageReceived("first message"); |
| SimulateMessageReceived("second message"); |
| const message_center::NotificationList::Notifications notifications = |
| MessageCenter::Get()->GetVisibleNotifications(); |
| EXPECT_EQ(2u, notifications.size()); |
| |
| for (message_center::Notification* iter : notifications) { |
| if (iter->id().find("chrome://network/sms1") != std::string::npos) { |
| EXPECT_EQ(u"000-000-0000", iter->title()); |
| EXPECT_EQ(u"first message", iter->message()); |
| } else if (iter->id().find("chrome://network/sms2") != std::string::npos) { |
| EXPECT_EQ(u"000-000-0000", iter->title()); |
| EXPECT_EQ(u"second message", iter->message()); |
| } else { |
| ASSERT_TRUE(false); |
| } |
| } |
| } |
| |
| class SmsObserverSuppressTextMessagesEnabled : public SmsObserverTest { |
| public: |
| void SetUp() override { |
| SmsObserverTest::SetUp(); |
| histogram_tester_ = std::make_unique<base::HistogramTester>(); |
| } |
| void ChangeUserSuppressionState(UserTextMessageSuppressionState state) { |
| network_metadata_store()->SetUserTextMessageSuppressionState(kTestGuid, |
| state); |
| } |
| |
| void ChangePolicySuppressionState(PolicyTextMessageSuppressionState state) { |
| std::string state_onc; |
| switch (state) { |
| case PolicyTextMessageSuppressionState::kUnset: |
| state_onc = ::onc::cellular::kTextMessagesUnset; |
| break; |
| case PolicyTextMessageSuppressionState::kAllow: |
| state_onc = ::onc::cellular::kTextMessagesAllow; |
| break; |
| case PolicyTextMessageSuppressionState::kSuppress: |
| state_onc = ::onc::cellular::kTextMessagesSuppress; |
| break; |
| } |
| |
| base::Value::Dict global_config; |
| global_config.Set(::onc::global_network_config::kAllowTextMessages, |
| state_onc); |
| managed_network_configuration_handler()->SetPolicy( |
| ::onc::ONC_SOURCE_DEVICE_POLICY, /*userhash=*/std::string(), |
| base::Value::List(), global_config); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| void AssertHistogramCounts(size_t user_suppressed_count, |
| size_t policy_suppressed_count, |
| size_t not_suppressed_count) { |
| histogram_tester_->ExpectBucketCount( |
| CellularNetworkMetricsLogger:: |
| kAllowTextMessagesNotificationSuppressionState, |
| CellularNetworkMetricsLogger::NotificationSuppressionState:: |
| kUserSuppressed, |
| /*expected_count=*/user_suppressed_count); |
| |
| histogram_tester_->ExpectBucketCount( |
| CellularNetworkMetricsLogger:: |
| kAllowTextMessagesNotificationSuppressionState, |
| CellularNetworkMetricsLogger::NotificationSuppressionState:: |
| kPolicySuppressed, |
| /*expected_count=*/policy_suppressed_count); |
| |
| histogram_tester_->ExpectBucketCount( |
| CellularNetworkMetricsLogger:: |
| kAllowTextMessagesNotificationSuppressionState, |
| CellularNetworkMetricsLogger::NotificationSuppressionState:: |
| kNotSuppressed, |
| /*expected_count=*/not_suppressed_count); |
| |
| size_t total_count = |
| user_suppressed_count + policy_suppressed_count + not_suppressed_count; |
| histogram_tester_->ExpectTotalCount( |
| CellularNetworkMetricsLogger:: |
| kAllowTextMessagesNotificationSuppressionState, |
| /*expected_count=*/total_count); |
| } |
| |
| private: |
| std::unique_ptr<base::HistogramTester> histogram_tester_; |
| }; |
| |
| TEST_F(SmsObserverSuppressTextMessagesEnabled, SuccessGuardRailMetricsTest) { |
| base::HistogramTester histogram_tester; |
| |
| AssertHistogramCounts(/*user_suppressed_count=*/0u, |
| /*policy_suppressed_count=*/0u, |
| /*not_suppressed_count=*/0u); |
| ChangeUserSuppressionState(UserTextMessageSuppressionState::kAllow); |
| ChangePolicySuppressionState(PolicyTextMessageSuppressionState::kUnset); |
| SimulateMessageReceived(); |
| AssertHistogramCounts(/*user_suppressed_count=*/0u, |
| /*policy_suppressed_count=*/0u, |
| /*not_suppressed_count=*/1u); |
| |
| ChangeUserSuppressionState(UserTextMessageSuppressionState::kSuppress); |
| ChangePolicySuppressionState(PolicyTextMessageSuppressionState::kUnset); |
| SimulateMessageReceived(); |
| AssertHistogramCounts(/*user_suppressed_count=*/1u, |
| /*policy_suppressed_count=*/0u, |
| /*not_suppressed_count=*/1u); |
| |
| ChangeUserSuppressionState(UserTextMessageSuppressionState::kAllow); |
| ChangePolicySuppressionState(PolicyTextMessageSuppressionState::kAllow); |
| SimulateMessageReceived(); |
| AssertHistogramCounts(/*user_suppressed_count=*/1u, |
| /*policy_suppressed_count=*/0u, |
| /*not_suppressed_count=*/2u); |
| |
| ChangeUserSuppressionState(UserTextMessageSuppressionState::kSuppress); |
| ChangePolicySuppressionState(PolicyTextMessageSuppressionState::kAllow); |
| SimulateMessageReceived(); |
| AssertHistogramCounts(/*user_suppressed_count=*/1u, |
| /*policy_suppressed_count=*/0u, |
| /*not_suppressed_count=*/3u); |
| |
| ChangeUserSuppressionState(UserTextMessageSuppressionState::kSuppress); |
| ChangePolicySuppressionState(PolicyTextMessageSuppressionState::kSuppress); |
| SimulateMessageReceived(); |
| AssertHistogramCounts(/*user_suppressed_count=*/1u, |
| /*policy_suppressed_count=*/1u, |
| /*not_suppressed_count=*/3u); |
| |
| ChangeUserSuppressionState(UserTextMessageSuppressionState::kAllow); |
| ChangePolicySuppressionState(PolicyTextMessageSuppressionState::kSuppress); |
| SimulateMessageReceived(); |
| AssertHistogramCounts(/*user_suppressed_count=*/1u, |
| /*policy_suppressed_count=*/2u, |
| /*not_suppressed_count=*/3u); |
| } |
| |
| } // namespace ash |