/* * Copyright 2018 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 #include namespace alexaClientSDK { namespace capabilitiesDelegate { namespace test { using namespace avsCommon::avs; using namespace avsCommon::avs::initialization; using namespace avsCommon::sdkInterfaces; using namespace avsCommon::utils; using namespace avsCommon::utils::configuration; using namespace avsCommon::utils::libcurlUtils; using namespace integration::test; /// Auth token static const std::string AUTH_TOKEN = "testAuthToken"; /// Client Id static const std::string CLIENT_ID = "testClientId"; /// Client Id 2 static const std::string CLIENT_ID_TWO = "testClientId2"; /// Product Id static const std::string PRODUCT_ID = "testProductId"; /// Product Id 2 static const std::string PRODUCT_ID_TWO = "testProductId2"; /// DSN static const std::string DSN = "testDSN"; /// DSN 2 static const std::string DSN_TWO = "testDSN2"; /// Separator between the components that make up a capability key static const std::string CAPABILITY_KEY_SEPARATOR = "."; /// Capabilities key in message body static const std::string CAPABILITIES_KEY = "capabilities"; /// Envelope version key in message body static const std::string ENVELOPE_VERSION_KEY = "envelopeVersion"; /// Envelope version value in message body static const std::string ENVELOPE_VERSION_VALUE = "20160207"; /// Envelope version value 2 static const std::string ENVELOPE_VERSION_VALUE_TWO = "201602072"; /// Interface type static const std::string INTERFACE_TYPE = "testInterfaceType"; /// Interface version static const std::string INTERFACE_VERSION = "testInterfaceVersion"; /// Interface configuration static const std::string INTERFACE_CONFIG = "{\"config\":\"testConfig\"}"; /// Bad interface configuration static const std::string INTERFACE_CONFIG_BAD = "thisIsNotJson"; /// Interface name one static const std::string INTERFACE_NAME_ONE = "testInterfaceNameOne"; /// Interface name two static const std::string INTERFACE_NAME_TWO = "testInterfaceNameTwo"; /// Interface name three static const std::string INTERFACE_NAME_THREE = "testInterfaceNameThree"; /// Constants for the Capabilities API message json /// Content type header key static const std::string CONTENT_TYPE_HEADER_KEY = "Content-Type"; /// Content type header value static const std::string CONTENT_TYPE_HEADER_VALUE = "application/json"; /// Content length header key static const std::string CONTENT_LENGTH_HEADER_KEY = "Content-Length"; /// Auth token header key static const std::string AUTHORIZATION_HEADER_KEY = "x-amz-access-token"; /// Separator between header key and value static const std::string HEADER_KEY_VALUE_SEPARATOR = ":"; /// Constituents of the CAPABILITIES API URL /// Capabilities API endpoint static const std::string CAPABILITIES_API_ENDPOINT = "https://api.amazonalexa.com"; /// Suffix before the device's place in the URL static const std::string CAPABILITIES_API_URL_PRE_DEVICE_SUFFIX = "/v1/devices/"; /// Suffix after the device's place in the URL static const std::string CAPABILITIES_API_URL_POST_DEVICE_SUFFIX = "/capabilities"; /// Device ID for the device that will show up in the URL static const std::string SELF_DEVICE = "@self"; /// Constants for prefixes for DB storage /// Endpoint key static const std::string DB_KEY_ENDPOINT = "endpoint:"; /// Client id key static const std::string DB_KEY_CLIENT_ID = "clientId:"; /// Product id key static const std::string DB_KEY_PRODUCT_ID = "productId:"; /// Envelope version key static const std::string DB_KEY_ENVELOPE_VERSION = "envelopeVersion:"; /// DSN key static const std::string DB_KEY_DSN = "deviceSerialNumber:"; /// Message key static const std::string DB_KEY_PUBLISH_MSG = "publishMsg:"; /// Separator between keys static const std::string DB_KEY_SEPARATOR = ","; /// Component key static const std::string DB_KEY_COMPONENT = "component:"; /// Table key static const std::string DB_KEY_TABLE = "table:"; /// Component name needed for Misc DB static const std::string COMPONENT_NAME = "capabilitiesDelegate"; /// Capabilities API message table static const std::string CAPABILITIES_PUBLISH_TABLE = "capabilitiesPublishMessage"; // clang-format off static const std::string CAPABILITIES_CONFIG_JSON = "{" "\"capabilitiesDelegate\":{" "\"randomKey\":\"randomValue\"" "}" "}"; // clang-format on /** * Test harness for @c CapabilitiesDelegate class. */ class CapabilitiesDelegateTest : public ::testing::Test { public: /** * Constructor. */ CapabilitiesDelegateTest(); /** * Destructor. */ ~CapabilitiesDelegateTest(); /** * Set up the test harness for running a test. */ void SetUp() override; /** * Tear down the test harness for running a test. */ void TearDown() override; /** * Returns a capability's unique key. * * @param capabilityMap The capability map. * @return A key that uniquely represents a capability. */ std::string getCapabilityKey(const std::unordered_map& capabilityMap); /** * Returns a capability's unique key. * * @param interfaceType The interface type of the capability. * @param interfaceName The interface name of the capability. * @return A key that uniquely represents a capability. */ std::string getCapabilityKey(const std::string& interfaceType, const std::string& interfaceName); /** * Returns the URL to which the Capabilities API message is sent. * * @param deviceId The device Id. * @return The URL to which the Capabilities API message is sent. */ std::string getCapabilitiesApiUrl(const std::string& deviceId); /** * Returns the published envelope version given the published Capabilities API message. * * @param publishedMsgStr The published message. * @return The published envelope version. */ std::string getPublishedEnvelopeVersion(const std::string& publishedMsgStr); /** * Returns the published capabilities given the published Capabilities API message. * * @param publishedMsgStr The published message. * @return A map of the capability key and the capability configuration. */ std::unordered_map> getPublishedConfigs( const std::string& publishedMsgStr); protected: /// Auth delegate instance std::shared_ptr m_authDelegate; /// Misc storage instance std::shared_ptr m_miscStorage; /// HTTP put handler std::shared_ptr m_httpPut; /// Device Info instance std::shared_ptr m_deviceInfo; /// Config instance ConfigurationNode m_configRoot; /// The CapabilitiesDelegate instance std::shared_ptr m_capabilitiesDelegate; }; CapabilitiesDelegateTest::CapabilitiesDelegateTest() : m_authDelegate{std::make_shared()}, m_miscStorage{std::make_shared()}, m_httpPut{std::make_shared()}, m_deviceInfo{DeviceInfo::create(CLIENT_ID, PRODUCT_ID, DSN)} { auto inString = std::shared_ptr(new std::istringstream(CAPABILITIES_CONFIG_JSON)); AlexaClientSDKInit::initialize({inString}); m_configRoot = ConfigurationNode::getRoot(); m_authDelegate->setAuthToken(AUTH_TOKEN); } CapabilitiesDelegateTest::~CapabilitiesDelegateTest() { AlexaClientSDKInit::uninitialize(); } void CapabilitiesDelegateTest::SetUp() { m_capabilitiesDelegate = CapabilitiesDelegate::create(m_authDelegate, m_miscStorage, m_httpPut, m_configRoot, m_deviceInfo); ASSERT_NE(m_capabilitiesDelegate, nullptr); m_capabilitiesDelegate->onAuthStateChange( AuthObserverInterface::State::REFRESHED, AuthObserverInterface::Error::SUCCESS); } void CapabilitiesDelegateTest::TearDown() { m_capabilitiesDelegate->shutdown(); } std::string CapabilitiesDelegateTest::getCapabilitiesApiUrl(const std::string& deviceId) { return CAPABILITIES_API_ENDPOINT + CAPABILITIES_API_URL_PRE_DEVICE_SUFFIX + deviceId + CAPABILITIES_API_URL_POST_DEVICE_SUFFIX; } std::string CapabilitiesDelegateTest::getCapabilityKey( const std::unordered_map& capabilityMap) { auto interfaceTypeIterator = capabilityMap.find(CAPABILITY_INTERFACE_TYPE_KEY); if (interfaceTypeIterator == capabilityMap.end()) { return ""; } auto interfaceType = interfaceTypeIterator->second; auto interfaceNameIterator = capabilityMap.find(CAPABILITY_INTERFACE_NAME_KEY); if (interfaceNameIterator == capabilityMap.end()) { return ""; } auto interfaceName = interfaceNameIterator->second; return getCapabilityKey(interfaceType, interfaceName); } std::string CapabilitiesDelegateTest::getCapabilityKey( const std::string& interfaceType, const std::string& interfaceName) { return interfaceType + CAPABILITY_KEY_SEPARATOR + interfaceName; } std::string CapabilitiesDelegateTest::getPublishedEnvelopeVersion(const std::string& publishedMsgStr) { rapidjson::Document publishedMsgJson; publishedMsgJson.Parse(publishedMsgStr); return publishedMsgJson[ENVELOPE_VERSION_KEY].GetString(); } std::unordered_map> CapabilitiesDelegateTest::getPublishedConfigs( const std::string& publishedMsgStr) { std::unordered_map> publishedConfigs; rapidjson::Document publishedMsgJson; publishedMsgJson.Parse(publishedMsgStr); for (rapidjson::SizeType capabilityIndx = 0; capabilityIndx < publishedMsgJson[CAPABILITIES_KEY].Size(); capabilityIndx++) { const rapidjson::Value& capabilityJson = publishedMsgJson[CAPABILITIES_KEY][capabilityIndx]; std::unordered_map capabilityMap; std::string capabilityType = (capabilityJson.FindMember(CAPABILITY_INTERFACE_TYPE_KEY))->value.GetString(); capabilityMap.insert({CAPABILITY_INTERFACE_TYPE_KEY, capabilityType}); std::string capabilityName = (capabilityJson.FindMember(CAPABILITY_INTERFACE_NAME_KEY))->value.GetString(); capabilityMap.insert({CAPABILITY_INTERFACE_NAME_KEY, capabilityName}); std::string capabilityVersion = (capabilityJson.FindMember(CAPABILITY_INTERFACE_VERSION_KEY))->value.GetString(); capabilityMap.insert({CAPABILITY_INTERFACE_VERSION_KEY, capabilityVersion}); if (capabilityJson.HasMember(CAPABILITY_INTERFACE_CONFIGURATIONS_KEY)) { std::string capabilityConfigs = (capabilityJson.FindMember(CAPABILITY_INTERFACE_CONFIGURATIONS_KEY))->value.GetString(); capabilityMap.insert({CAPABILITY_INTERFACE_CONFIGURATIONS_KEY, capabilityConfigs}); } std::string capabilityKey = getCapabilityKey(capabilityMap); publishedConfigs.insert({capabilityKey, std::make_shared(capabilityMap)}); } return publishedConfigs; } /// Test publishing no capabilities TEST_F(CapabilitiesDelegateTest, noCapability) { ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::FATAL_ERROR); ASSERT_TRUE(m_httpPut->getRequestData().empty()); ASSERT_FALSE(m_miscStorage->dataExists(COMPONENT_NAME, CAPABILITIES_PUBLISH_TABLE)); } /// Test publishing capabilities with no errors TEST_F(CapabilitiesDelegateTest, withCapabilitiesHappyCase) { std::shared_ptr capabilityProviderOne = std::make_shared(); capabilityProviderOne->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_ONE, INTERFACE_VERSION); capabilityProviderOne->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_THREE, INTERFACE_VERSION); std::shared_ptr capabilityProviderTwo = std::make_shared(); capabilityProviderTwo->addCapabilityConfiguration( INTERFACE_TYPE, INTERFACE_NAME_TWO, INTERFACE_VERSION, INTERFACE_CONFIG); ASSERT_TRUE(m_capabilitiesDelegate->registerCapability(capabilityProviderOne)); ASSERT_TRUE(m_capabilitiesDelegate->registerCapability(capabilityProviderTwo)); m_httpPut->setResponseCode(HTTPResponseCode::SUCCESS_NO_CONTENT); /// Success ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::SUCCESS); ASSERT_TRUE(m_miscStorage->dataExists(COMPONENT_NAME, CAPABILITIES_PUBLISH_TABLE)); /// Check URL ASSERT_EQ(m_httpPut->getRequestUrl(), getCapabilitiesApiUrl(SELF_DEVICE)); /// Check the body of the HTTP request const std::string publishedMsg = m_httpPut->getRequestData(); std::unordered_map> publishedConfigs = getPublishedConfigs(publishedMsg); std::string publishedEnvelopeVersion = getPublishedEnvelopeVersion(publishedMsg); /// Check envelope version ASSERT_EQ(publishedEnvelopeVersion, ENVELOPE_VERSION_VALUE); /// Check capabilities /// Total of 3 capabilities = 2 capabilties from capabilityProviderOne and 1 from capabilityProviderTwo size_t numOfCapabilties = 3; ASSERT_EQ(publishedConfigs.size(), numOfCapabilties); /// Check if all capabilities in the publish message are what we sent out /// First capability std::string capabilityKey = getCapabilityKey(INTERFACE_TYPE, INTERFACE_NAME_ONE); auto capabilityIterator = publishedConfigs.find(capabilityKey); ASSERT_NE(capabilityIterator, publishedConfigs.end()); std::unordered_map capabilityConfigMap = (capabilityIterator->second)->capabilityConfiguration; auto capabilityConfigIterator = capabilityConfigMap.find(CAPABILITY_INTERFACE_VERSION_KEY); ASSERT_NE(capabilityConfigIterator, capabilityConfigMap.end()); ASSERT_EQ(capabilityConfigIterator->second, INTERFACE_VERSION); /// Second capability capabilityKey = getCapabilityKey(INTERFACE_TYPE, INTERFACE_NAME_TWO); capabilityIterator = publishedConfigs.find(capabilityKey); ASSERT_NE(capabilityIterator, publishedConfigs.end()); capabilityConfigMap = (capabilityIterator->second)->capabilityConfiguration; capabilityConfigIterator = capabilityConfigMap.find(CAPABILITY_INTERFACE_VERSION_KEY); ASSERT_NE(capabilityConfigIterator, capabilityConfigMap.end()); ASSERT_EQ(capabilityConfigIterator->second, INTERFACE_VERSION); capabilityConfigIterator = capabilityConfigMap.find(CAPABILITY_INTERFACE_CONFIGURATIONS_KEY); ASSERT_NE(capabilityConfigIterator, capabilityConfigMap.end()); ASSERT_EQ(capabilityConfigIterator->second, INTERFACE_CONFIG); /// Third capability capabilityKey = getCapabilityKey(INTERFACE_TYPE, INTERFACE_NAME_THREE); capabilityIterator = publishedConfigs.find(capabilityKey); ASSERT_NE(capabilityIterator, publishedConfigs.end()); capabilityConfigMap = (capabilityIterator->second)->capabilityConfiguration; capabilityConfigIterator = capabilityConfigMap.find(CAPABILITY_INTERFACE_VERSION_KEY); ASSERT_NE(capabilityConfigIterator, capabilityConfigMap.end()); ASSERT_EQ(capabilityConfigIterator->second, INTERFACE_VERSION); /// Check the HTTP headers std::vector headers = m_httpPut->getRequestHeaders(); std::unordered_set headersSet(headers.begin(), headers.end()); std::string headerToCheck = CONTENT_TYPE_HEADER_KEY + HEADER_KEY_VALUE_SEPARATOR + CONTENT_TYPE_HEADER_VALUE; ASSERT_NE(headersSet.find(headerToCheck), headersSet.end()); headerToCheck = CONTENT_LENGTH_HEADER_KEY + HEADER_KEY_VALUE_SEPARATOR + std::to_string(publishedMsg.size()); ASSERT_NE(headersSet.find(headerToCheck), headersSet.end()); headerToCheck = AUTHORIZATION_HEADER_KEY + HEADER_KEY_VALUE_SEPARATOR + AUTH_TOKEN; ASSERT_NE(headersSet.find(headerToCheck), headersSet.end()); } /// Test publishing capabilities that returns a fatal error TEST_F(CapabilitiesDelegateTest, publishFatalError) { std::shared_ptr capabilityProvider = std::make_shared(); capabilityProvider->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_ONE, INTERFACE_VERSION); ASSERT_TRUE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); m_httpPut->setResponseCode(HTTPResponseCode::BAD_REQUEST); /// Fatal error ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::FATAL_ERROR); ASSERT_FALSE(m_httpPut->getRequestData().empty()); ASSERT_FALSE(m_miscStorage->dataExists(COMPONENT_NAME, CAPABILITIES_PUBLISH_TABLE)); } /// Test publishing capabilities that returns a retriable error TEST_F(CapabilitiesDelegateTest, publishRetriableError) { std::shared_ptr capabilityProvider = std::make_shared(); capabilityProvider->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_ONE, INTERFACE_VERSION); ASSERT_TRUE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); m_httpPut->setResponseCode(HTTPResponseCode::SERVER_INTERNAL_ERROR); /// Retriable error ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::RETRIABLE_ERROR); ASSERT_FALSE(m_httpPut->getRequestData().empty()); ASSERT_FALSE(m_miscStorage->dataExists(COMPONENT_NAME, CAPABILITIES_PUBLISH_TABLE)); } /// Test republishing capabilities TEST_F(CapabilitiesDelegateTest, republish) { std::shared_ptr capabilityProvider = std::make_shared(); capabilityProvider->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_ONE, INTERFACE_VERSION); /// Publish succeeds the first time ASSERT_TRUE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); m_httpPut->setResponseCode(HTTPResponseCode::SUCCESS_NO_CONTENT); /// Success ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::SUCCESS); ASSERT_FALSE(m_httpPut->getRequestData().empty()); ASSERT_TRUE(m_miscStorage->dataExists(COMPONENT_NAME, CAPABILITIES_PUBLISH_TABLE)); /// Republish with same data will not send again m_httpPut->reset(); m_httpPut->setResponseCode(HTTPResponseCode::SUCCESS_NO_CONTENT); /// Success ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::SUCCESS); ASSERT_TRUE(m_httpPut->getRequestData().empty()); const std::string dbKeysPrefix = DB_KEY_ENDPOINT + CAPABILITIES_API_ENDPOINT + DB_KEY_SEPARATOR; /// Change client id to republish m_httpPut->reset(); m_httpPut->setResponseCode(HTTPResponseCode::SUCCESS_NO_CONTENT); /// Success std::string dbKey = dbKeysPrefix + DB_KEY_CLIENT_ID; m_miscStorage->update(COMPONENT_NAME, CAPABILITIES_PUBLISH_TABLE, dbKey, CLIENT_ID_TWO); ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::SUCCESS); ASSERT_FALSE(m_httpPut->getRequestData().empty()); /// Change product id to republish m_httpPut->reset(); m_httpPut->setResponseCode(HTTPResponseCode::SUCCESS_NO_CONTENT); /// Success dbKey = dbKeysPrefix + DB_KEY_PRODUCT_ID; m_miscStorage->update(COMPONENT_NAME, CAPABILITIES_PUBLISH_TABLE, dbKey, PRODUCT_ID_TWO); ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::SUCCESS); ASSERT_FALSE(m_httpPut->getRequestData().empty()); /// Change DSN to republish m_httpPut->reset(); m_httpPut->setResponseCode(HTTPResponseCode::SUCCESS_NO_CONTENT); /// Success dbKey = dbKeysPrefix + DB_KEY_DSN; m_miscStorage->update(COMPONENT_NAME, CAPABILITIES_PUBLISH_TABLE, dbKey, DSN_TWO); ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::SUCCESS); ASSERT_FALSE(m_httpPut->getRequestData().empty()); /// Change envelope version to republish m_httpPut->reset(); m_httpPut->setResponseCode(HTTPResponseCode::SUCCESS_NO_CONTENT); /// Success dbKey = dbKeysPrefix + DB_KEY_ENVELOPE_VERSION; m_miscStorage->update(COMPONENT_NAME, CAPABILITIES_PUBLISH_TABLE, dbKey, ENVELOPE_VERSION_VALUE_TWO); ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::SUCCESS); ASSERT_FALSE(m_httpPut->getRequestData().empty()); /// Change capabilities to republish m_httpPut->reset(); m_httpPut->setResponseCode(HTTPResponseCode::SUCCESS_NO_CONTENT); /// Success std::shared_ptr capabilityProviderTwo = std::make_shared(); capabilityProviderTwo->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_TWO, INTERFACE_VERSION); ASSERT_TRUE(m_capabilitiesDelegate->registerCapability(capabilityProviderTwo)); ASSERT_EQ( m_capabilitiesDelegate->publishCapabilities(), CapabilitiesDelegate::CapabilitiesPublishReturnCode::SUCCESS); ASSERT_FALSE(m_httpPut->getRequestData().empty()); } /// Tests with registering capabilities TEST_F(CapabilitiesDelegateTest, registerTests) { std::shared_ptr capabilityProvider = std::make_shared(); std::unordered_map capabilityConfigurationMap; /// nullptr register ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(nullptr)); /// No capability in config ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); /// Empty interface type capabilityProvider->clearCapabilityConfigurations(); capabilityProvider->addCapabilityConfiguration("", INTERFACE_NAME_ONE, INTERFACE_VERSION); ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); /// Empty interface name capabilityProvider->clearCapabilityConfigurations(); capabilityProvider->addCapabilityConfiguration(INTERFACE_TYPE, "", INTERFACE_VERSION); ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); /// Empty interface version capabilityProvider->clearCapabilityConfigurations(); capabilityProvider->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_ONE, ""); ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); /// Bad interface config capabilityProvider->clearCapabilityConfigurations(); capabilityProvider->addCapabilityConfiguration( INTERFACE_TYPE, INTERFACE_NAME_ONE, INTERFACE_VERSION, INTERFACE_CONFIG_BAD); ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); /// Null interface type capabilityConfigurationMap.clear(); capabilityConfigurationMap.insert({CAPABILITY_INTERFACE_NAME_KEY, INTERFACE_NAME_ONE}); capabilityConfigurationMap.insert({CAPABILITY_INTERFACE_VERSION_KEY, INTERFACE_VERSION}); auto capabilityConfiguration = std::make_shared(capabilityConfigurationMap); capabilityProvider->clearCapabilityConfigurations(); capabilityProvider->addCapabilityConfiguration(capabilityConfiguration); ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); /// Null interface name capabilityConfigurationMap.clear(); capabilityConfigurationMap.insert({CAPABILITY_INTERFACE_TYPE_KEY, INTERFACE_TYPE}); capabilityConfigurationMap.insert({CAPABILITY_INTERFACE_VERSION_KEY, INTERFACE_VERSION}); capabilityConfiguration = std::make_shared(capabilityConfigurationMap); capabilityProvider->clearCapabilityConfigurations(); capabilityProvider->addCapabilityConfiguration(capabilityConfiguration); ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); /// Null interface version capabilityConfigurationMap.clear(); capabilityConfigurationMap.insert({CAPABILITY_INTERFACE_TYPE_KEY, INTERFACE_TYPE}); capabilityConfigurationMap.insert({CAPABILITY_INTERFACE_NAME_KEY, INTERFACE_NAME_ONE}); capabilityConfiguration = std::make_shared(capabilityConfigurationMap); capabilityProvider->clearCapabilityConfigurations(); capabilityProvider->addCapabilityConfiguration(capabilityConfiguration); ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); /// Some random entry in otherwise ok map capabilityConfigurationMap.clear(); capabilityConfigurationMap.insert({CAPABILITY_INTERFACE_TYPE_KEY, INTERFACE_TYPE}); capabilityConfigurationMap.insert({CAPABILITY_INTERFACE_NAME_KEY, INTERFACE_NAME_ONE}); capabilityConfigurationMap.insert({CAPABILITY_INTERFACE_VERSION_KEY, INTERFACE_VERSION}); capabilityConfigurationMap.insert({"randomKey", "randomValue"}); capabilityConfiguration = std::make_shared(capabilityConfigurationMap); capabilityProvider->clearCapabilityConfigurations(); capabilityProvider->addCapabilityConfiguration(capabilityConfiguration); ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); /// Successful entries capabilityProvider->clearCapabilityConfigurations(); capabilityProvider->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_ONE, INTERFACE_VERSION); capabilityProvider->addCapabilityConfiguration( INTERFACE_TYPE, INTERFACE_NAME_TWO, INTERFACE_VERSION, INTERFACE_CONFIG); ASSERT_TRUE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); /// Can't register same capability again std::shared_ptr capabilityProviderTwo = std::make_shared(); capabilityProvider->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_ONE, INTERFACE_VERSION); ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider)); } } // namespace test } // namespace capabilitiesDelegate } // namespace alexaClientSDK