/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0/ * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ #include #include #include #include #include #include #include #include #include namespace alexaClientSDK { namespace settings { namespace test { using namespace testing; /// @defgroup Define initial values for each setting type. /// @{ constexpr auto INIT_ALARM_VOLUME_RAMP = types::AlarmVolumeRampTypes::NONE; constexpr WakeWordConfirmationSettingType INIT_WAKEWORD_CONFIRMATION = WakeWordConfirmationSettingType::NONE; const std::string INIT_TIMEZONE = "Canada/Eastern"; /// @} /// @defgroup Define updated values for each setting type. /// @{ constexpr auto NEW_ALARM_VOLUME_RAMP = types::AlarmVolumeRampTypes::ASCENDING; const std::string NEW_TIMEZONE = "Canada/Pacific"; /// @} /** * Stub a setting for test purpose. * * @tparam SettingT The setting type to be extended. */ template class SettingStub : public SettingT { public: /// Set the value synchronously for simplicity. SetSettingResult setLocalChange(const typename SettingT::ValueType& value); /// Just a stub that doesn't do anything. bool setAvsChange(const typename SettingT::ValueType& value); /// Just a stub that doesn't do anything. bool clearData(const typename SettingT::ValueType& value); /// Build setting object. explicit SettingStub(const typename SettingT::ValueType& value); }; template SetSettingResult SettingStub::setLocalChange(const typename SettingT::ValueType& value) { this->m_value = value; this->notifyObservers(SettingNotifications::LOCAL_CHANGE); return SetSettingResult::ENQUEUED; } template bool SettingStub::setAvsChange(const typename SettingT::ValueType& value) { return false; } template bool SettingStub::clearData(const typename SettingT::ValueType& value) { return true; } template SettingStub::SettingStub(const typename SettingT::ValueType& value) : SettingT{value} { } /** * Test class used to set-up tear down tests. */ class SettingCallbacksTest : public Test { protected: /** * Set up the objects common for most tests. */ void SetUp() override; /** * Tear down the objects common for most tests. */ void TearDown() override; /// The device settings manager. std::shared_ptr m_manager; /// Alarm Volume Ramp setting stub. std::shared_ptr> m_alarmVolumeRamp; /// Wake word confirmation setting stub. std::shared_ptr> m_wwConfirmation; /// Timezone setting stub. std::shared_ptr> m_timezone; }; void SettingCallbacksTest::SetUp() { auto customerDataManager = std::make_shared>(); DeviceSettingManagerSettingConfigurations settingConfigs; m_manager = std::make_shared(customerDataManager, settingConfigs); m_alarmVolumeRamp = std::make_shared>(INIT_ALARM_VOLUME_RAMP); m_wwConfirmation = std::make_shared>(INIT_WAKEWORD_CONFIRMATION); m_timezone = std::make_shared>(INIT_TIMEZONE); ASSERT_TRUE(m_manager->addSetting(m_alarmVolumeRamp)); ASSERT_TRUE(m_manager->addSetting(m_wwConfirmation)); ASSERT_TRUE(m_manager->addSetting(m_timezone)); } void SettingCallbacksTest::TearDown() { m_manager->removeSetting(m_timezone); m_manager->removeSetting(m_wwConfirmation); m_manager->removeSetting(m_alarmVolumeRamp); m_timezone.reset(); m_wwConfirmation.reset(); m_alarmVolumeRamp.reset(); m_manager.reset(); } /// Used to test static callback. std::string globalTimezone = INIT_TIMEZONE; /// Define a static function to be used as callback. static void staticCallback(const std::string& newValue, SettingNotifications notification) { globalTimezone = newValue; EXPECT_EQ(notification, SettingNotifications::LOCAL_CHANGE); } /** * Observer class that register callback member functions. */ class ObserverClass { public: /** * Constructor. * * @param manager The device manager used to register the callbacks. */ explicit ObserverClass(std::shared_ptr& manager); /** * Destructor. */ ~ObserverClass() = default; /** * Callback method for alarm volume ramp. We don't care about the notification type, so we just omit it. * * @param value The new alarm volume ramp value. */ void onAlarmVolumeRamp(const types::AlarmVolumeRampTypes& value); /** * Callback method for wakeword confirmation. We don't care about the notification type, so we just omit it. * * @param value The new wakeword confirmation value. */ void onWakewordConfirmation(const WakeWordConfirmationSettingType& value); /** * Callback method for timezone. We don't care about the notification type, so we just omit it. * * @param value The new timezone value. */ void onTimezone(const std::string& value); /// The device setting manager. std::shared_ptr m_manager; /// The callback wrapper. std::shared_ptr> m_callbacks; /// The alarm volume ramp value. types::AlarmVolumeRampTypes m_alarmVolumeRampValue; /// The wakeword confirmation value. WakeWordConfirmationSettingType m_wakewordConfirmationValue; /// The timezone value. std::string m_timezoneValue; }; ObserverClass::ObserverClass(std::shared_ptr& manager) : m_manager{manager}, m_callbacks{SettingCallbacks::create(manager)}, m_alarmVolumeRampValue{INIT_ALARM_VOLUME_RAMP}, m_wakewordConfirmationValue{INIT_WAKEWORD_CONFIRMATION}, m_timezoneValue{INIT_TIMEZONE} { EXPECT_TRUE((m_callbacks->add( std::bind(&ObserverClass::onAlarmVolumeRamp, this, std::placeholders::_1)))); EXPECT_TRUE((m_callbacks->add( std::bind(&ObserverClass::onWakewordConfirmation, this, std::placeholders::_1)))); EXPECT_TRUE((m_callbacks->add( std::bind(&ObserverClass::onTimezone, this, std::placeholders::_1)))); } void ObserverClass::onAlarmVolumeRamp(const types::AlarmVolumeRampTypes& value) { m_alarmVolumeRampValue = value; } void ObserverClass::onWakewordConfirmation(const WakeWordConfirmationSettingType& value) { m_wakewordConfirmationValue = value; } void ObserverClass::onTimezone(const std::string& value) { m_timezoneValue = value; } /// Test callback for a mix of lambda and static functions. TEST_F(SettingCallbacksTest, test_lambdaAndStaticCallbacks) { auto alarmVolumeRamp = INIT_ALARM_VOLUME_RAMP; auto alarmVolumeRampCallback = [&alarmVolumeRamp]( const types::AlarmVolumeRampTypes& newValue, SettingNotifications) { alarmVolumeRamp = newValue; }; auto callbacks = SettingCallbacks::create(m_manager); callbacks->add(alarmVolumeRampCallback); callbacks->add(staticCallback); m_manager->setValue(NEW_ALARM_VOLUME_RAMP); m_manager->setValue(NEW_TIMEZONE); EXPECT_EQ(globalTimezone, NEW_TIMEZONE); EXPECT_EQ(alarmVolumeRamp, NEW_ALARM_VOLUME_RAMP); } /// Test callback for member functions. TEST_F(SettingCallbacksTest, test_memberCallback) { ObserverClass observer{m_manager}; m_manager->setValue(NEW_ALARM_VOLUME_RAMP); m_manager->setValue(NEW_TIMEZONE); EXPECT_EQ(observer.m_alarmVolumeRampValue, NEW_ALARM_VOLUME_RAMP); EXPECT_EQ(observer.m_wakewordConfirmationValue, INIT_WAKEWORD_CONFIRMATION); EXPECT_EQ(observer.m_timezoneValue, NEW_TIMEZONE); } } // namespace test } // namespace settings } // namespace alexaClientSDK