583 lines
27 KiB
C++
583 lines
27 KiB
C++
/*
|
|
* 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 <CapabilitiesDelegate/CapabilitiesDelegate.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <rapidjson/document.h>
|
|
#include <rapidjson/error/en.h>
|
|
|
|
#include <AVSCommon/AVS/Initialization/AlexaClientSDKInit.h>
|
|
#include <AVSCommon/Utils/LibcurlUtils/HttpResponseCodes.h>
|
|
#include <Integration/TestAuthDelegate.h>
|
|
#include <Integration/TestCapabilityProvider.h>
|
|
#include <Integration/TestHttpPut.h>
|
|
#include <Integration/TestMiscStorage.h>
|
|
|
|
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<std::string, std::string>& 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<std::string, std::shared_ptr<CapabilityConfiguration>> getPublishedConfigs(
|
|
const std::string& publishedMsgStr);
|
|
|
|
protected:
|
|
/// Auth delegate instance
|
|
std::shared_ptr<TestAuthDelegate> m_authDelegate;
|
|
/// Misc storage instance
|
|
std::shared_ptr<TestMiscStorage> m_miscStorage;
|
|
/// HTTP put handler
|
|
std::shared_ptr<TestHttpPut> m_httpPut;
|
|
/// Device Info instance
|
|
std::shared_ptr<DeviceInfo> m_deviceInfo;
|
|
/// Config instance
|
|
ConfigurationNode m_configRoot;
|
|
/// The CapabilitiesDelegate instance
|
|
std::shared_ptr<CapabilitiesDelegate> m_capabilitiesDelegate;
|
|
};
|
|
|
|
CapabilitiesDelegateTest::CapabilitiesDelegateTest() :
|
|
m_authDelegate{std::make_shared<TestAuthDelegate>()},
|
|
m_miscStorage{std::make_shared<TestMiscStorage>()},
|
|
m_httpPut{std::make_shared<TestHttpPut>()},
|
|
m_deviceInfo{DeviceInfo::create(CLIENT_ID, PRODUCT_ID, DSN)} {
|
|
auto inString = std::shared_ptr<std::istringstream>(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<std::string, std::string>& 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<std::string, std::shared_ptr<CapabilityConfiguration>> CapabilitiesDelegateTest::getPublishedConfigs(
|
|
const std::string& publishedMsgStr) {
|
|
std::unordered_map<std::string, std::shared_ptr<CapabilityConfiguration>> 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<std::string, std::string> 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<CapabilityConfiguration>(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<TestCapabilityProvider> capabilityProviderOne = std::make_shared<TestCapabilityProvider>();
|
|
capabilityProviderOne->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_ONE, INTERFACE_VERSION);
|
|
capabilityProviderOne->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_THREE, INTERFACE_VERSION);
|
|
|
|
std::shared_ptr<TestCapabilityProvider> capabilityProviderTwo = std::make_shared<TestCapabilityProvider>();
|
|
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<std::string, std::shared_ptr<CapabilityConfiguration>> 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<std::string, std::string> 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<std::string> headers = m_httpPut->getRequestHeaders();
|
|
std::unordered_set<std::string> 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<TestCapabilityProvider> capabilityProvider = std::make_shared<TestCapabilityProvider>();
|
|
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<TestCapabilityProvider> capabilityProvider = std::make_shared<TestCapabilityProvider>();
|
|
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<TestCapabilityProvider> capabilityProvider = std::make_shared<TestCapabilityProvider>();
|
|
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<TestCapabilityProvider> capabilityProviderTwo = std::make_shared<TestCapabilityProvider>();
|
|
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<TestCapabilityProvider> capabilityProvider = std::make_shared<TestCapabilityProvider>();
|
|
std::unordered_map<std::string, std::string> 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<CapabilityConfiguration>(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<CapabilityConfiguration>(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<CapabilityConfiguration>(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<CapabilityConfiguration>(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<TestCapabilityProvider> capabilityProviderTwo = std::make_shared<TestCapabilityProvider>();
|
|
capabilityProvider->addCapabilityConfiguration(INTERFACE_TYPE, INTERFACE_NAME_ONE, INTERFACE_VERSION);
|
|
ASSERT_FALSE(m_capabilitiesDelegate->registerCapability(capabilityProvider));
|
|
}
|
|
|
|
} // namespace test
|
|
} // namespace capabilitiesDelegate
|
|
} // namespace alexaClientSDK
|