summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Keeler <jacob.keeler@livioradio.com>2020-06-10 17:12:55 -0400
committerGitHub <noreply@github.com>2020-06-10 17:12:55 -0400
commitef2b88520b4224390ffd332f737fdf5573def60e (patch)
tree15533d732dcccd1682975c9f141c718c4720f314
parent6ebc91a2db98493ac002c56f3555b33a301eee1b (diff)
downloadsdl_core-ef2b88520b4224390ffd332f737fdf5573def60e.tar.gz
Filter unknown enums when removing unknown parameters (#3385)
* Add enum filtering step to applySchema This step is triggered when `remove_unknown_parameters` is enabled * Add unit tests * Pass warning info to message response after processing
-rw-r--r--src/components/application_manager/include/application_manager/commands/command.h12
-rw-r--r--src/components/application_manager/include/application_manager/commands/command_impl.h10
-rw-r--r--src/components/application_manager/include/application_manager/commands/command_request_impl.h2
-rw-r--r--src/components/application_manager/include/application_manager/rpc_handler_impl.h1
-rw-r--r--src/components/application_manager/include/application_manager/rpc_service_impl.h3
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc4
-rw-r--r--src/components/application_manager/src/commands/command_impl.cc8
-rw-r--r--src/components/application_manager/src/commands/command_request_impl.cc20
-rw-r--r--src/components/application_manager/src/rpc_handler_impl.cc27
-rw-r--r--src/components/application_manager/src/rpc_service_impl.cc12
-rw-r--r--src/components/application_manager/test/commands/command_request_impl_test.cc16
-rw-r--r--src/components/application_manager/test/include/application_manager/mock_request.h2
-rw-r--r--src/components/formatters/include/formatters/CSmartFactory.h11
-rw-r--r--src/components/include/application_manager/rpc_service.h6
-rw-r--r--src/components/include/test/application_manager/mock_rpc_service.h5
-rw-r--r--src/components/smart_objects/include/smart_objects/always_false_schema_item.h4
-rw-r--r--src/components/smart_objects/include/smart_objects/always_true_schema_item.h4
-rw-r--r--src/components/smart_objects/include/smart_objects/array_schema_item.h15
-rw-r--r--src/components/smart_objects/include/smart_objects/bool_schema_item.h2
-rw-r--r--src/components/smart_objects/include/smart_objects/default_shema_item.h8
-rw-r--r--src/components/smart_objects/include/smart_objects/enum_schema_item.h47
-rw-r--r--src/components/smart_objects/include/smart_objects/number_schema_item.h19
-rw-r--r--src/components/smart_objects/include/smart_objects/object_schema_item.h32
-rw-r--r--src/components/smart_objects/include/smart_objects/schema_item.h39
-rw-r--r--src/components/smart_objects/include/smart_objects/smart_object.h4
-rw-r--r--src/components/smart_objects/include/smart_objects/smart_schema.h15
-rw-r--r--src/components/smart_objects/include/smart_objects/string_schema_item.h6
-rw-r--r--src/components/smart_objects/src/always_false_schema_item.cc4
-rw-r--r--src/components/smart_objects/src/always_true_schema_item.cc2
-rw-r--r--src/components/smart_objects/src/array_schema_item.cc56
-rw-r--r--src/components/smart_objects/src/bool_schema_item.cc4
-rw-r--r--src/components/smart_objects/src/object_schema_item.cc57
-rw-r--r--src/components/smart_objects/src/schema_item.cc13
-rw-r--r--src/components/smart_objects/src/smart_object.cc5
-rw-r--r--src/components/smart_objects/src/smart_schema.cc14
-rw-r--r--src/components/smart_objects/src/string_schema_item.cc12
-rw-r--r--src/components/smart_objects/test/ArraySchemaItem_test.cc195
-rw-r--r--src/components/smart_objects/test/CObjectSchemaItem_test.cc138
38 files changed, 696 insertions, 138 deletions
diff --git a/src/components/application_manager/include/application_manager/commands/command.h b/src/components/application_manager/include/application_manager/commands/command.h
index 0536c7aee1..a7241ce16d 100644
--- a/src/components/application_manager/include/application_manager/commands/command.h
+++ b/src/components/application_manager/include/application_manager/commands/command.h
@@ -98,6 +98,18 @@ class Command {
*/
virtual WindowID window_id() const = 0;
+ /**
+ * @brief Set warning info string, to be sent on a successful response
+ * @param info Warning info string
+ */
+ virtual void set_warning_info(const std::string info) = 0;
+
+ /**
+ * @brief Returns warning info string
+ * @return Warning info string
+ */
+ virtual std::string warning_info() const = 0;
+
/*
* @brief Function is called by RequestController when request execution time
* has exceed it's limit
diff --git a/src/components/application_manager/include/application_manager/commands/command_impl.h b/src/components/application_manager/include/application_manager/commands/command_impl.h
index 0d8013b639..151c4d7874 100644
--- a/src/components/application_manager/include/application_manager/commands/command_impl.h
+++ b/src/components/application_manager/include/application_manager/commands/command_impl.h
@@ -122,6 +122,10 @@ class CommandImpl : public Command {
*/
WindowID window_id() const OVERRIDE;
+ void set_warning_info(const std::string info) OVERRIDE;
+
+ std::string warning_info() const OVERRIDE;
+
/*
* @brief Function is called by RequestController when request execution time
* has exceed it's limit
@@ -205,6 +209,12 @@ class CommandImpl : public Command {
HMICapabilities& hmi_capabilities_;
policy::PolicyHandlerInterface& policy_handler_;
+ /**
+ * @brief warning_info_ Defines a warning message to send in the case of a
+ * successful response
+ */
+ std::string warning_info_;
+
CommandParametersPermissions parameters_permissions_;
CommandParametersPermissions removed_parameters_permissions_;
diff --git a/src/components/application_manager/include/application_manager/commands/command_request_impl.h b/src/components/application_manager/include/application_manager/commands/command_request_impl.h
index 87008d9439..87c19ca1d1 100644
--- a/src/components/application_manager/include/application_manager/commands/command_request_impl.h
+++ b/src/components/application_manager/include/application_manager/commands/command_request_impl.h
@@ -380,7 +380,7 @@ class CommandRequestImpl : public CommandImpl,
* @param info string with disallowed params enumeration
* @param param disallowed param
*/
- void AddDissalowedParameterToInfoString(std::string& info,
+ void AddDisallowedParameterToInfoString(std::string& info,
const std::string& param) const;
/**
diff --git a/src/components/application_manager/include/application_manager/rpc_handler_impl.h b/src/components/application_manager/include/application_manager/rpc_handler_impl.h
index 11ac1745ee..ab140dbd8a 100644
--- a/src/components/application_manager/include/application_manager/rpc_handler_impl.h
+++ b/src/components/application_manager/include/application_manager/rpc_handler_impl.h
@@ -176,6 +176,7 @@ class RPCHandlerImpl : public RPCHandler,
bool ConvertMessageToSO(const Message& message,
smart_objects::SmartObject& output,
+ std::string& out_warning_info,
const bool allow_unknown_parameters = false,
const bool validate_params = true);
std::shared_ptr<Message> ConvertRawMsgToMessage(
diff --git a/src/components/application_manager/include/application_manager/rpc_service_impl.h b/src/components/application_manager/include/application_manager/rpc_service_impl.h
index 3e3d83a519..289a0bcb66 100644
--- a/src/components/application_manager/include/application_manager/rpc_service_impl.h
+++ b/src/components/application_manager/include/application_manager/rpc_service_impl.h
@@ -122,6 +122,9 @@ class RPCServiceImpl : public RPCService,
bool ManageMobileCommand(const commands::MessageSharedPtr message,
commands::Command::CommandSource source) OVERRIDE;
+ bool ManageMobileCommand(const commands::MessageSharedPtr message,
+ commands::Command::CommandSource source,
+ const std::string warning_info) OVERRIDE;
bool ManageHMICommand(const commands::MessageSharedPtr message,
commands::Command::CommandSource source =
commands::Command::SOURCE_HMI) OVERRIDE;
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc
index 1acb2a7438..3797913f5b 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/subscribe_button_request.cc
@@ -107,8 +107,8 @@ void SubscribeButtonRequest::Run() {
app->SubscribeToButton(static_cast<mobile_apis::ButtonName::eType>(btn_id));
SendSubscribeButtonNotification();
- const bool is_succedeed = true;
- SendResponse(is_succedeed, mobile_apis::Result::SUCCESS);
+ const bool is_succeeded = true;
+ SendResponse(is_succeeded, mobile_apis::Result::SUCCESS);
}
bool SubscribeButtonRequest::Init() {
diff --git a/src/components/application_manager/src/commands/command_impl.cc b/src/components/application_manager/src/commands/command_impl.cc
index 23b14184ad..3872ae45ab 100644
--- a/src/components/application_manager/src/commands/command_impl.cc
+++ b/src/components/application_manager/src/commands/command_impl.cc
@@ -111,6 +111,14 @@ uint32_t CommandImpl::connection_key() const {
return (*message_)[strings::params][strings::connection_key].asUInt();
}
+void CommandImpl::set_warning_info(const std::string info) {
+ warning_info_ = info;
+}
+
+std::string CommandImpl::warning_info() const {
+ return warning_info_;
+}
+
void CommandImpl::onTimeOut() {}
bool CommandImpl::AllowedToTerminate() {
diff --git a/src/components/application_manager/src/commands/command_request_impl.cc b/src/components/application_manager/src/commands/command_request_impl.cc
index e5914e1376..3f279679a3 100644
--- a/src/components/application_manager/src/commands/command_request_impl.cc
+++ b/src/components/application_manager/src/commands/command_request_impl.cc
@@ -298,7 +298,7 @@ void CommandRequestImpl::SendResponse(
response[strings::msg_params] = *response_params;
}
- if (info) {
+ if (info && *info != '\0') {
response[strings::msg_params][strings::info] = std::string(info);
}
@@ -318,7 +318,17 @@ void CommandRequestImpl::SendResponse(
}
response[strings::msg_params][strings::success] = success;
- response[strings::msg_params][strings::result_code] = result_code;
+ if ((result_code == mobile_apis::Result::SUCCESS ||
+ result_code == mobile_apis::Result::WARNINGS) &&
+ !warning_info().empty()) {
+ response[strings::msg_params][strings::info] =
+ (info && *info != '\0') ? std::string(info) + "\n" + warning_info()
+ : warning_info();
+ response[strings::msg_params][strings::result_code] =
+ mobile_apis::Result::WARNINGS;
+ } else {
+ response[strings::msg_params][strings::result_code] = result_code;
+ }
is_success_result_ = success;
@@ -719,7 +729,7 @@ bool CommandRequestImpl::CheckHMICapabilities(
return false;
}
-void CommandRequestImpl::AddDissalowedParameterToInfoString(
+void CommandRequestImpl::AddDisallowedParameterToInfoString(
std::string& info, const std::string& param) const {
// prepare disallowed params enumeration for response info string
if (info.empty()) {
@@ -736,12 +746,12 @@ void CommandRequestImpl::AddDisallowedParametersToInfo(
RPCParams::const_iterator it =
removed_parameters_permissions_.disallowed_params.begin();
for (; it != removed_parameters_permissions_.disallowed_params.end(); ++it) {
- AddDissalowedParameterToInfoString(info, (*it));
+ AddDisallowedParameterToInfoString(info, (*it));
}
it = removed_parameters_permissions_.undefined_params.begin();
for (; it != removed_parameters_permissions_.undefined_params.end(); ++it) {
- AddDissalowedParameterToInfoString(info, (*it));
+ AddDisallowedParameterToInfoString(info, (*it));
}
if (!info.empty()) {
diff --git a/src/components/application_manager/src/rpc_handler_impl.cc b/src/components/application_manager/src/rpc_handler_impl.cc
index 0a62bc8498..bb8e4fc1fb 100644
--- a/src/components/application_manager/src/rpc_handler_impl.cc
+++ b/src/components/application_manager/src/rpc_handler_impl.cc
@@ -108,8 +108,12 @@ void RPCHandlerImpl::ProcessMessageFromMobile(
allow_unknown_parameters = true;
}
- if (!ConvertMessageToSO(
- *message, *so_from_mobile, allow_unknown_parameters, !rpc_passing)) {
+ std::string warning_info;
+ if (!ConvertMessageToSO(*message,
+ *so_from_mobile,
+ warning_info,
+ allow_unknown_parameters,
+ !rpc_passing)) {
LOG4CXX_ERROR(logger_, "Cannot create smart object from message");
return;
}
@@ -131,7 +135,7 @@ void RPCHandlerImpl::ProcessMessageFromMobile(
commands::Command::SOURCE_MOBILE,
message_type)) {
// Since PassThrough failed, refiltering the message
- if (!ConvertMessageToSO(*message, *so_from_mobile)) {
+ if (!ConvertMessageToSO(*message, *so_from_mobile, warning_info)) {
LOG4CXX_ERROR(logger_, "Cannot create smart object from message");
return;
}
@@ -143,7 +147,7 @@ void RPCHandlerImpl::ProcessMessageFromMobile(
#endif // TELEMETRY_MONITOR
if (!app_manager_.GetRPCService().ManageMobileCommand(
- so_from_mobile, commands::Command::SOURCE_MOBILE)) {
+ so_from_mobile, commands::Command::SOURCE_MOBILE, warning_info)) {
LOG4CXX_ERROR(logger_, "Received command didn't run successfully");
}
#ifdef TELEMETRY_MONITOR
@@ -176,7 +180,9 @@ void RPCHandlerImpl::ProcessMessageFromHMI(
allow_unknown_parameters = true;
}
- if (!ConvertMessageToSO(*message, *smart_object, allow_unknown_parameters)) {
+ std::string warning_info;
+ if (!ConvertMessageToSO(
+ *message, *smart_object, warning_info, allow_unknown_parameters)) {
if (application_manager::MessageType::kResponse ==
(*smart_object)[strings::params][strings::message_type].asInt()) {
(*smart_object).erase(strings::msg_params);
@@ -190,6 +196,11 @@ void RPCHandlerImpl::ProcessMessageFromHMI(
}
}
+ if (!warning_info.empty()) {
+ LOG4CXX_WARN(logger_,
+ "Warning while parsing HMI message: " << warning_info);
+ }
+
LOG4CXX_DEBUG(logger_, "Converted message, trying to create hmi command");
if (!app_manager_.GetRPCService().ManageHMICommand(smart_object)) {
LOG4CXX_ERROR(logger_, "Received command didn't run successfully");
@@ -320,6 +331,7 @@ void RPCHandlerImpl::GetMessageVersion(
bool RPCHandlerImpl::ConvertMessageToSO(
const Message& message,
ns_smart_device_link::ns_smart_objects::SmartObject& output,
+ std::string& out_warning_info,
const bool allow_unknown_parameters,
const bool validate_params) {
LOG4CXX_AUTO_TRACE(logger_);
@@ -382,6 +394,9 @@ bool RPCHandlerImpl::ConvertMessageToSO(
"Convertion result for sdl object is true function_id "
<< output[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt());
+ // Populate any warning info generated during the validation process
+ out_warning_info = rpc::PrettyFormat(report);
+
output[strings::params][strings::connection_key] =
message.connection_key();
output[strings::params][strings::protocol_version] =
@@ -534,7 +549,7 @@ bool RPCHandlerImpl::ValidateRpcSO(smart_objects::SmartObject& message,
rpc::ValidationReport& report_out,
bool allow_unknown_parameters) {
if (!mobile_so_factory().attachSchema(
- message, !allow_unknown_parameters, msg_version) ||
+ message, !allow_unknown_parameters, msg_version, &report_out) ||
message.validate(&report_out, msg_version, allow_unknown_parameters) !=
smart_objects::errors::OK) {
LOG4CXX_WARN(logger_, "Failed to parse string to smart object");
diff --git a/src/components/application_manager/src/rpc_service_impl.cc b/src/components/application_manager/src/rpc_service_impl.cc
index 0dc48385b2..d544c3b445 100644
--- a/src/components/application_manager/src/rpc_service_impl.cc
+++ b/src/components/application_manager/src/rpc_service_impl.cc
@@ -112,10 +112,16 @@ EncryptionFlagCheckResult RPCServiceImpl::IsEncryptionRequired(
? EncryptionFlagCheckResult::kSuccess_Protected
: EncryptionFlagCheckResult::kSuccess_NotProtected;
}
-
bool RPCServiceImpl::ManageMobileCommand(
const commands::MessageSharedPtr message,
commands::Command::CommandSource source) {
+ return ManageMobileCommand(message, source, std::string());
+}
+
+bool RPCServiceImpl::ManageMobileCommand(
+ const commands::MessageSharedPtr message,
+ commands::Command::CommandSource source,
+ const std::string warning_info) {
LOG4CXX_AUTO_TRACE(logger_);
if (!message) {
@@ -237,7 +243,6 @@ bool RPCServiceImpl::ManageMobileCommand(
if (message_type == mobile_apis::messageType::request &&
source == commands::Command::CommandSource::SOURCE_MOBILE) {
- // commands will be launched from requesr_ctrl
mobile_apis::HMILevel::eType app_hmi_level =
mobile_apis::HMILevel::INVALID_ENUM;
if (app) {
@@ -245,8 +250,9 @@ bool RPCServiceImpl::ManageMobileCommand(
app->hmi_level(mobile_apis::PredefinedWindows::DEFAULT_WINDOW);
}
- // commands will be launched from request_ctrl
+ command->set_warning_info(warning_info);
+ // commands will be launched from request_ctrl
const request_controller::RequestController::TResult result =
request_ctrl_.addMobileRequest(command, app_hmi_level);
diff --git a/src/components/application_manager/test/commands/command_request_impl_test.cc b/src/components/application_manager/test/commands/command_request_impl_test.cc
index 83b5d7eeb4..9034bf442f 100644
--- a/src/components/application_manager/test/commands/command_request_impl_test.cc
+++ b/src/components/application_manager/test/commands/command_request_impl_test.cc
@@ -543,8 +543,8 @@ TEST_F(CommandRequestImplTest, HashUpdateAllowed_UpdateExpected) {
EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _))
.WillOnce(DoAll(SaveArg<0>(&result), Return(true)));
- const bool is_succedeed = true;
- command->SendResponse(is_succedeed, kMobResultSuccess, NULL, NULL);
+ const bool is_succeeded = true;
+ command->SendResponse(is_succeeded, kMobResultSuccess, NULL, NULL);
MockAppPtr mock_app = CreateMockApp();
EXPECT_CALL(app_mngr_, application(_)).WillOnce(Return(mock_app));
@@ -564,8 +564,8 @@ TEST_F(CommandRequestImplTest, HashUpdateDisallowed_HashUpdateNotExpected) {
EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _))
.WillOnce(DoAll(SaveArg<0>(&result), Return(true)));
- const bool is_succedeed = true;
- command->SendResponse(is_succedeed, kMobResultSuccess, NULL, NULL);
+ const bool is_succeeded = true;
+ command->SendResponse(is_succeeded, kMobResultSuccess, NULL, NULL);
MockAppPtr mock_app = CreateMockApp();
EXPECT_CALL(*mock_app, UpdateHash()).Times(0);
@@ -583,8 +583,8 @@ TEST_F(CommandRequestImplTest, RequestFailed_HashUpdateNotExpected) {
EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _))
.WillOnce(DoAll(SaveArg<0>(&result), Return(true)));
- const bool is_succedeed = false;
- command->SendResponse(is_succedeed, kMobResultSuccess, NULL, NULL);
+ const bool is_succeeded = false;
+ command->SendResponse(is_succeeded, kMobResultSuccess, NULL, NULL);
MockAppPtr mock_app = CreateMockApp();
EXPECT_CALL(*mock_app, UpdateHash()).Times(0);
@@ -602,8 +602,8 @@ TEST_F(CommandRequestImplTest, AppNotFound_HashUpdateNotExpected) {
EXPECT_CALL(mock_rpc_service_, ManageMobileCommand(_, _))
.WillOnce(DoAll(SaveArg<0>(&result), Return(true)));
- const bool is_succedeed = true;
- command->SendResponse(is_succedeed, kMobResultSuccess, NULL, NULL);
+ const bool is_succeeded = true;
+ command->SendResponse(is_succeeded, kMobResultSuccess, NULL, NULL);
MockAppPtr mock_app = CreateMockApp();
EXPECT_CALL(app_mngr_, application(_)).WillOnce(Return(MockAppPtr()));
diff --git a/src/components/application_manager/test/include/application_manager/mock_request.h b/src/components/application_manager/test/include/application_manager/mock_request.h
index 77b5bb7c38..c1cc7f601f 100644
--- a/src/components/application_manager/test/include/application_manager/mock_request.h
+++ b/src/components/application_manager/test/include/application_manager/mock_request.h
@@ -56,6 +56,8 @@ class MockRequest : public application_manager::commands::Command {
MOCK_CONST_METHOD0(default_timeout, uint32_t());
MOCK_CONST_METHOD0(function_id, int32_t());
MOCK_CONST_METHOD0(window_id, application_manager::WindowID());
+ MOCK_METHOD1(set_warning_info, void(const std::string info));
+ MOCK_CONST_METHOD0(warning_info, std::string());
MOCK_METHOD0(onTimeOut, void());
MOCK_METHOD0(AllowedToTerminate, bool());
MOCK_METHOD1(SetAllowedToTerminate, void(bool is_allowed));
diff --git a/src/components/formatters/include/formatters/CSmartFactory.h b/src/components/formatters/include/formatters/CSmartFactory.h
index c384dbf01d..83bcbb770e 100644
--- a/src/components/formatters/include/formatters/CSmartFactory.h
+++ b/src/components/formatters/include/formatters/CSmartFactory.h
@@ -147,16 +147,18 @@ class CSmartFactory {
* @brief Attach schema to the function SmartObject.
*
* @param object SmartObject to attach schema for.
- *
* @param remove_unknown_parameters contains true if need
* to remove fake parameters from smart object otherwise contains false.
+ * @param MessageVersion the version of the schema to be applied
+ * @param report__ object for reporting warnings during schema application
*
* @return True if operation was successful or false otherwise.
*/
bool attachSchema(
ns_smart_device_link::ns_smart_objects::SmartObject& object,
const bool remove_unknown_parameters,
- const utils::SemanticVersion& MessageVersion = utils::SemanticVersion());
+ const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
+ rpc::ValidationReport* report__ = nullptr);
/**
* @brief Attach schema to the struct SmartObject.
@@ -277,7 +279,8 @@ template <class FunctionIdEnum, class MessageTypeEnum, class StructIdEnum>
bool CSmartFactory<FunctionIdEnum, MessageTypeEnum, StructIdEnum>::attachSchema(
ns_smart_device_link::ns_smart_objects::SmartObject& object,
const bool remove_unknown_parameters,
- const utils::SemanticVersion& MessageVersion) {
+ const utils::SemanticVersion& MessageVersion,
+ rpc::ValidationReport* report__) {
if (false == object.keyExists(strings::S_PARAMS))
return false;
if (false == object[strings::S_PARAMS].keyExists(strings::S_MESSAGE_TYPE))
@@ -305,7 +308,7 @@ bool CSmartFactory<FunctionIdEnum, MessageTypeEnum, StructIdEnum>::attachSchema(
object.setSchema(schemaIterator->second);
schemaIterator->second.applySchema(
- object, remove_unknown_parameters, MessageVersion);
+ object, remove_unknown_parameters, MessageVersion, report__);
return true;
}
diff --git a/src/components/include/application_manager/rpc_service.h b/src/components/include/application_manager/rpc_service.h
index 4a80733ee7..f98cd826f9 100644
--- a/src/components/include/application_manager/rpc_service.h
+++ b/src/components/include/application_manager/rpc_service.h
@@ -54,10 +54,16 @@ class RPCService {
* @brief ManageMobileCommand convert message to mobile command and execute it
* @param message pointer to received message
* @param origin origin of command
+ * @param warning_info warning message to send on a successful response. Only
+ * applies to requests from mobile.
* @return true if command is executed, otherwise return false
*/
virtual bool ManageMobileCommand(const commands::MessageSharedPtr message,
commands::Command::CommandSource source) = 0;
+ virtual bool ManageMobileCommand(const commands::MessageSharedPtr message,
+ commands::Command::CommandSource source,
+ const std::string warning_info) = 0;
+
/**
* @brief ManageHMICommand convert message to HMI command and execute it
* @param message pointer to received message
diff --git a/src/components/include/test/application_manager/mock_rpc_service.h b/src/components/include/test/application_manager/mock_rpc_service.h
index ed06b930d8..66de650ab6 100644
--- a/src/components/include/test/application_manager/mock_rpc_service.h
+++ b/src/components/include/test/application_manager/mock_rpc_service.h
@@ -21,6 +21,11 @@ class MockRPCService : public application_manager::rpc_service::RPCService {
ManageMobileCommand,
bool(const application_manager::commands::MessageSharedPtr message,
application_manager::commands::Command::CommandSource origin));
+ MOCK_METHOD3(
+ ManageMobileCommand,
+ bool(const application_manager::commands::MessageSharedPtr message,
+ application_manager::commands::Command::CommandSource origin,
+ const std::string warning_info));
MOCK_METHOD2(SendMessageToMobile,
void(application_manager::commands::MessageSharedPtr, bool));
MOCK_METHOD1(
diff --git a/src/components/smart_objects/include/smart_objects/always_false_schema_item.h b/src/components/smart_objects/include/smart_objects/always_false_schema_item.h
index 05c53ec582..7b92bc9748 100644
--- a/src/components/smart_objects/include/smart_objects/always_false_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/always_false_schema_item.h
@@ -51,7 +51,7 @@ class CAlwaysFalseSchemaItem : public ISchemaItem {
/**
* @brief Validate smart object.
* @param Object Object to validate.
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* @param MessageVersion to check mobile RPC version against RPC Spec History
* @param allow_unknown_enums
* false - unknown enum values (left as string values after applySchema)
@@ -61,7 +61,7 @@ class CAlwaysFalseSchemaItem : public ISchemaItem {
**/
errors::eType validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false) OVERRIDE;
diff --git a/src/components/smart_objects/include/smart_objects/always_true_schema_item.h b/src/components/smart_objects/include/smart_objects/always_true_schema_item.h
index a2d305d0f9..b0bb3f2fa6 100644
--- a/src/components/smart_objects/include/smart_objects/always_true_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/always_true_schema_item.h
@@ -51,7 +51,7 @@ class CAlwaysTrueSchemaItem : public ISchemaItem {
/**
* @brief Validate smart object.
* @param Object Object to validate.
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* @param MessageVersion to check mobile RPC version against RPC Spec History
* @param allow_unknown_enums
* false - unknown enum values (left as string values after applySchema)
@@ -61,7 +61,7 @@ class CAlwaysTrueSchemaItem : public ISchemaItem {
**/
errors::eType validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false) OVERRIDE;
diff --git a/src/components/smart_objects/include/smart_objects/array_schema_item.h b/src/components/smart_objects/include/smart_objects/array_schema_item.h
index 0e19d2237e..8f9a179fff 100644
--- a/src/components/smart_objects/include/smart_objects/array_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/array_schema_item.h
@@ -66,7 +66,7 @@ class CArraySchemaItem : public ISchemaItem {
/**
* @brief Validate smart object.
* @param Object Object to validate.
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* @param MessageVersion to check mobile RPC version against RPC Spec History
* @param allow_unknown_enums
* false - unknown enum values (left as string values after applySchema)
@@ -76,17 +76,21 @@ class CArraySchemaItem : public ISchemaItem {
**/
errors::eType validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false) OVERRIDE;
+ bool filterInvalidEnums(SmartObject& Object,
+ const utils::SemanticVersion& MessageVersion,
+ rpc::ValidationReport* report) OVERRIDE;
+
/**
* @brief Apply schema.
*
* @param Object Object to apply schema.
* @param remove_unknown_parameters contains true if need to remove unknown
- *parameters
- * from smart object otherwise contains false.
+ * parameters from smart object, otherwise contains false.
+ * @param MessageVersion the version of the schema to be applied
**/
void applySchema(SmartObject& Object,
const bool remove_unknown_parameters,
@@ -113,6 +117,8 @@ class CArraySchemaItem : public ISchemaItem {
void BuildObjectBySchema(const SmartObject& pattern_object,
SmartObject& result_object) OVERRIDE;
+ TypeID GetType() OVERRIDE;
+
private:
/**
* @brief Constructor.
@@ -124,6 +130,7 @@ class CArraySchemaItem : public ISchemaItem {
CArraySchemaItem(const ISchemaItemPtr ElementSchemaItem,
const TSchemaItemParameter<size_t>& MinSize,
const TSchemaItemParameter<size_t>& MaxSize);
+
/**
* @brief SchemaItem for array elements.
**/
diff --git a/src/components/smart_objects/include/smart_objects/bool_schema_item.h b/src/components/smart_objects/include/smart_objects/bool_schema_item.h
index 3a9f6c929d..b652799a27 100644
--- a/src/components/smart_objects/include/smart_objects/bool_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/bool_schema_item.h
@@ -51,6 +51,8 @@ class CBoolSchemaItem : public CDefaultSchemaItem<bool> {
const TSchemaItemParameter<bool>& DefaultValue =
TSchemaItemParameter<bool>());
+ TypeID GetType() OVERRIDE;
+
private:
explicit CBoolSchemaItem(const TSchemaItemParameter<bool>& DefaultValue);
SmartType getSmartType() const OVERRIDE;
diff --git a/src/components/smart_objects/include/smart_objects/default_shema_item.h b/src/components/smart_objects/include/smart_objects/default_shema_item.h
index 16dbad4426..bcb610cb33 100644
--- a/src/components/smart_objects/include/smart_objects/default_shema_item.h
+++ b/src/components/smart_objects/include/smart_objects/default_shema_item.h
@@ -51,7 +51,7 @@ class CDefaultSchemaItem : public ISchemaItem {
/**
* @brief Validate smart object.
* @param Object Object to validate.
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* @param MessageVersion to check mobile RPC version against RPC Spec History
* @param allow_unknown_enums
* false - unknown enum values (left as string values after applySchema)
@@ -61,7 +61,7 @@ class CDefaultSchemaItem : public ISchemaItem {
**/
errors::eType validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false) OVERRIDE;
@@ -109,7 +109,7 @@ CDefaultSchemaItem<Type>::CDefaultSchemaItem(const ParameterType& DefaultValue)
template <typename Type>
errors::eType CDefaultSchemaItem<Type>::validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) {
if (getSmartType() != Object.getType()) {
@@ -117,7 +117,7 @@ errors::eType CDefaultSchemaItem<Type>::validate(
"Incorrect type, expected: " +
SmartObject::typeToString(getSmartType()) +
", got: " + SmartObject::typeToString(Object.getType());
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::INVALID_VALUE;
} else {
return errors::OK;
diff --git a/src/components/smart_objects/include/smart_objects/enum_schema_item.h b/src/components/smart_objects/include/smart_objects/enum_schema_item.h
index 7fa5a65b35..836a3faec1 100644
--- a/src/components/smart_objects/include/smart_objects/enum_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/enum_schema_item.h
@@ -106,7 +106,7 @@ class TEnumSchemaItem : public CDefaultSchemaItem<EnumType> {
/**
* @brief Validate smart object.
* @param Object Object to validate.
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* @param MessageVersion to check mobile RPC version against RPC Spec History
* @param allow_unknown_enums
* false - unknown enum values (left as string values after applySchema)
@@ -116,7 +116,7 @@ class TEnumSchemaItem : public CDefaultSchemaItem<EnumType> {
**/
errors::eType validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false) OVERRIDE;
/**
@@ -128,15 +128,17 @@ class TEnumSchemaItem : public CDefaultSchemaItem<EnumType> {
const std::vector<ElementSignature>& signatures,
const utils::SemanticVersion& MessageVersion);
+ bool filterInvalidEnums(SmartObject& Object,
+ const utils::SemanticVersion& MessageVersion,
+ rpc::ValidationReport* report) OVERRIDE;
+
/**
* @brief Apply schema.
- * This implementation checks if enumeration is represented as string
- * and tries to convert it to integer according to element-to-string
- * map.
+ *
* @param Object Object to apply schema.
* @param remove_unknown_parameters contains true if need to remove unknown
- *parameters
- * from smart object otherwise contains false.
+ * parameters from smart object, otherwise contains false.
+ * @param MessageVersion the version of the schema to be applied
**/
void applySchema(SmartObject& Object,
const bool remove_unknown_parameters,
@@ -166,6 +168,7 @@ class TEnumSchemaItem : public CDefaultSchemaItem<EnumType> {
ElementSignatures);
SmartType getSmartType() const OVERRIDE;
EnumType getDefaultValue() const OVERRIDE;
+ TypeID GetType() OVERRIDE;
/**
* @brief Set of allowed enumeration elements.
**/
@@ -315,9 +318,24 @@ const ElementSignature TEnumSchemaItem<EnumType>::getSignature(
}
template <typename EnumType>
+bool TEnumSchemaItem<EnumType>::filterInvalidEnums(
+ SmartObject& Object,
+ const utils::SemanticVersion& MessageVersion,
+ rpc::ValidationReport* report) {
+ rpc::ValidationReport dummy_report("");
+ if (validate(Object, &dummy_report, MessageVersion) != errors::OK) {
+ std::string validation_info =
+ "Ignored invalid value - " + Object.asString();
+ report->set_validation_info(validation_info);
+ return true;
+ }
+ return false;
+}
+
+template <typename EnumType>
errors::eType TEnumSchemaItem<EnumType>::validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) {
if (SmartType_Integer != Object.getType()) {
@@ -333,7 +351,7 @@ errors::eType TEnumSchemaItem<EnumType>::validate(
SmartObject::typeToString(SmartType_Integer) +
" (enum), got: " + SmartObject::typeToString(Object.getType());
}
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::INVALID_VALUE;
}
@@ -344,7 +362,7 @@ errors::eType TEnumSchemaItem<EnumType>::validate(
std::stringstream stream;
stream << "Invalid enum value: " << Object.asInt();
std::string validation_info = stream.str();
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::OUT_OF_RANGE;
}
@@ -361,7 +379,7 @@ errors::eType TEnumSchemaItem<EnumType>::validate(
std::string validation_info = "Enum value : " + Object.asString() +
" removed for SyncMsgVersion " +
MessageVersion.toString();
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::INVALID_VALUE;
} else if (signature.mSince == boost::none &&
signature.mUntil == boost::none) {
@@ -369,7 +387,7 @@ errors::eType TEnumSchemaItem<EnumType>::validate(
std::string validation_info = "Enum value : " + Object.asString() +
" does not exist for SyncMsgVersion " +
MessageVersion.toString();
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::INVALID_VALUE;
}
}
@@ -413,6 +431,11 @@ EnumType TEnumSchemaItem<EnumType>::getDefaultValue() const {
}
template <typename EnumType>
+TypeID TEnumSchemaItem<EnumType>::GetType() {
+ return TYPE_ENUM;
+}
+
+template <typename EnumType>
TEnumSchemaItem<EnumType>::TEnumSchemaItem(
const std::set<EnumType>& AllowedElements,
const TSchemaItemParameter<EnumType>& DefaultValue)
diff --git a/src/components/smart_objects/include/smart_objects/number_schema_item.h b/src/components/smart_objects/include/smart_objects/number_schema_item.h
index c3767e8e48..25b7684829 100644
--- a/src/components/smart_objects/include/smart_objects/number_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/number_schema_item.h
@@ -68,7 +68,7 @@ class TNumberSchemaItem : public CDefaultSchemaItem<NumberType> {
/**
* @brief Validate smart object.
* @param Object Object to validate.
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* @param MessageVersion to check mobile RPC version against RPC Spec History
* @param allow_unknown_enums
* false - unknown enum values (left as string values after applySchema)
@@ -78,10 +78,12 @@ class TNumberSchemaItem : public CDefaultSchemaItem<NumberType> {
**/
errors::eType validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false) OVERRIDE;
+ TypeID GetType() OVERRIDE;
+
private:
/**
* @brief Get smart type for this NumberType.
@@ -142,7 +144,7 @@ bool TNumberSchemaItem<NumberType>::isValidNumberType(SmartType type) {
template <typename NumberType>
errors::eType TNumberSchemaItem<NumberType>::validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) {
if (!isValidNumberType(Object.getType())) {
@@ -152,7 +154,7 @@ errors::eType TNumberSchemaItem<NumberType>::validate(
std::string validation_info =
"Incorrect type, expected: " + SmartObject::typeToString(expectedType) +
", got: " + SmartObject::typeToString(Object.getType());
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::INVALID_VALUE;
}
NumberType value(0);
@@ -176,7 +178,7 @@ errors::eType TNumberSchemaItem<NumberType>::validate(
stream << "Value too small, got: " << value
<< ", minimum allowed: " << rangeLimit;
std::string validation_info = stream.str();
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::OUT_OF_RANGE;
}
@@ -185,13 +187,18 @@ errors::eType TNumberSchemaItem<NumberType>::validate(
stream << "Value too large, got: " << value
<< ", maximum allowed: " << rangeLimit;
std::string validation_info = stream.str();
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::OUT_OF_RANGE;
}
return errors::OK;
}
template <typename NumberType>
+TypeID TNumberSchemaItem<NumberType>::GetType() {
+ return TYPE_NUMBER;
+}
+
+template <typename NumberType>
TNumberSchemaItem<NumberType>::TNumberSchemaItem(
const TSchemaItemParameter<NumberType>& MinValue,
const TSchemaItemParameter<NumberType>& MaxValue,
diff --git a/src/components/smart_objects/include/smart_objects/object_schema_item.h b/src/components/smart_objects/include/smart_objects/object_schema_item.h
index 58e13106d4..d5c8a7f3e9 100644
--- a/src/components/smart_objects/include/smart_objects/object_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/object_schema_item.h
@@ -110,7 +110,7 @@ class CObjectSchemaItem : public ISchemaItem {
/**
* @brief Validate smart object.
* @param Object Object to validate.
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* @param MessageVersion to check mobile RPC version against RPC Spec History
* @param allow_unknown_enums
* false - unknown enum values (left as string values after applySchema)
@@ -120,15 +120,21 @@ class CObjectSchemaItem : public ISchemaItem {
**/
errors::eType validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false) OVERRIDE;
+
+ bool filterInvalidEnums(SmartObject& Object,
+ const utils::SemanticVersion& MessageVersion,
+ rpc::ValidationReport* report) OVERRIDE;
+
/**
* @brief Apply schema.
+ *
* @param Object Object to apply schema.
* @param remove_unknown_parameters contains true if need to remove unknown
- *parameters
- * from smart object otherwise contains false.
+ * parameters from smart object, otherwise contains false.
+ * @param MessageVersion the version of the schema to be applied
**/
void applySchema(SmartObject& Object,
const bool remove_unknown_parameters,
@@ -138,7 +144,7 @@ class CObjectSchemaItem : public ISchemaItem {
* @brief Unapply schema.
* @param Object Object to unapply schema.
* @param remove_unknown_parameters contains true if need to remove unknown
- *parameters
+ * parameters
**/
void unapplySchema(SmartObject& Object,
const bool remove_unknown_parameters) OVERRIDE;
@@ -156,6 +162,8 @@ class CObjectSchemaItem : public ISchemaItem {
*/
size_t GetMemberSize() OVERRIDE;
+ TypeID GetType() OVERRIDE;
+
boost::optional<SMember&> GetMemberSchemaItem(
const std::string& member_key) OVERRIDE;
@@ -171,25 +179,27 @@ class CObjectSchemaItem : public ISchemaItem {
CObjectSchemaItem(const Members& Members);
/**
- * @brief Removes fake parameters from object.
- * @param Object Object to remove fake parameters.
+ * @brief Removes unknown parameters from object.
+ * @param Object Object to remove unknown parameters.
+ * @param MessageVersion The version to check against for which parameters are
+ * unknown.
**/
- void RemoveFakeParams(SmartObject& Object,
- const utils::SemanticVersion& MessageVersion);
+ void RemoveUnknownParams(SmartObject& Object,
+ const utils::SemanticVersion& MessageVersion);
/**
* @brief Returns the correct schema item based on message version.
* @param member Schema member
* @param MessageVersion Semantic Version of mobile message.
* @return Pointer to correct schema item if item found or nullptr, if item
- *was not found.
+ * was not found.
**/
const SMember* GetCorrectMember(const SMember& member,
const utils::SemanticVersion& messageVersion);
/**
* @brief Map of member name to SMember structure describing the object
- *member.
+ * member.
**/
Members mMembers;
DISALLOW_COPY_AND_ASSIGN(CObjectSchemaItem);
diff --git a/src/components/smart_objects/include/smart_objects/schema_item.h b/src/components/smart_objects/include/smart_objects/schema_item.h
index 9c29e66f36..1b1395739b 100644
--- a/src/components/smart_objects/include/smart_objects/schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/schema_item.h
@@ -49,6 +49,16 @@ namespace ns_smart_objects {
class SmartObject;
class SMember;
+enum TypeID {
+ TYPE_NONE,
+ TYPE_OBJECT,
+ TYPE_ARRAY,
+ TYPE_STRING,
+ TYPE_NUMBER,
+ TYPE_ENUM,
+ TYPE_BOOLEAN
+};
+
/**
* @brief Base schema item.
**/
@@ -58,7 +68,7 @@ class ISchemaItem {
* @brief Validate smart object.
*
* @param Object Object to validate.
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* message if an error occurs
* @param MessageVersion to check mobile RPC version against RPC Spec History
* @param allow_unknown_enums
@@ -69,7 +79,7 @@ class ISchemaItem {
**/
virtual errors::eType validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false);
@@ -92,12 +102,26 @@ class ISchemaItem {
virtual bool hasDefaultValue(SmartObject& Object);
/**
+ * @brief Filter invalid enum values
+ *
+ * @param Object Object to check for invalid enum values
+ * @param MessageVersion the version of the schema to use for validation
+ * @param report object for reporting enums which were removed during the
+ * process
+ *
+ * @return true if the value being checked should be filtered, false otherwise
+ **/
+ virtual bool filterInvalidEnums(SmartObject& Object,
+ const utils::SemanticVersion& MessageVersion,
+ rpc::ValidationReport* report);
+
+ /**
* @brief Apply schema.
*
* @param Object Object to apply schema.
* @param remove_unknown_parameters contains true if need to remove unknown
- *parameters
- * from smart object otherwise contains false.
+ * parameters from smart object, otherwise contains false.
+ * @param MessageVersion the version of the schema to be applied
**/
virtual void applySchema(
ns_smart_device_link::ns_smart_objects::SmartObject& Object,
@@ -143,6 +167,13 @@ class ISchemaItem {
*/
virtual size_t GetMemberSize();
+ /**
+ * @brief Get type ID of schema
+ *
+ * @return The type ID of this schema
+ */
+ virtual TypeID GetType();
+
virtual ~ISchemaItem() {}
};
typedef std::shared_ptr<ISchemaItem> ISchemaItemPtr;
diff --git a/src/components/smart_objects/include/smart_objects/smart_object.h b/src/components/smart_objects/include/smart_objects/smart_object.h
index f3aab0fc1e..6ce9f96d8b 100644
--- a/src/components/smart_objects/include/smart_objects/smart_object.h
+++ b/src/components/smart_objects/include/smart_objects/smart_object.h
@@ -674,7 +674,7 @@ class SmartObject FINAL {
/**
* @brief Validates object according to attached schema.
*
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* @param messageVersion of the mobile app to check against RPC Spec Schema
* @param allow_unknown_enums
* false - unknown enum values (left as string values after applySchema)
@@ -683,7 +683,7 @@ class SmartObject FINAL {
* @return Result of validation.
*/
errors::eType validate(
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false);
diff --git a/src/components/smart_objects/include/smart_objects/smart_schema.h b/src/components/smart_objects/include/smart_objects/smart_schema.h
index 8cbafa53b2..b44ac98afd 100644
--- a/src/components/smart_objects/include/smart_objects/smart_schema.h
+++ b/src/components/smart_objects/include/smart_objects/smart_schema.h
@@ -64,7 +64,7 @@ class CSmartSchema FINAL {
* @brief Validate smart object.
*
* @param Object Object to validate.
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* @param MessageVersion to check mobile RPC version against RPC Spec History
* @param allow_unknown_enums
* false - unknown enum values (left as string values after applySchema)
@@ -74,7 +74,7 @@ class CSmartSchema FINAL {
**/
errors::eType validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& messageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false) const;
@@ -96,22 +96,23 @@ class CSmartSchema FINAL {
* @brief Apply schema.
*
* @param Object Object to apply schema.
- *
* @param remove_unknown_parameters contains true if need to remove unknown
- *parameters
- * from smart object otherwise contains false.
+ * parameters from smart object, otherwise contains false.
+ * @param MessageVersion the version of the schema to be applied
+ * @param report object for reporting warnings during schema application
**/
void applySchema(
SmartObject& Object,
const bool remove_unknown_parameters,
- const utils::SemanticVersion& MessageVersion = utils::SemanticVersion());
+ const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
+ rpc::ValidationReport* report = nullptr);
/**
* @brief The reverse SmartObject conversion using schema.
*
* @param object Object to convert.
* @param remove_unknown_parameters contains true if need to remove unknown
- *parameters
+ * parameters
*/
// TODO(cpplint): Is this a non-const reference?
// If so, make const or use a pointer.
diff --git a/src/components/smart_objects/include/smart_objects/string_schema_item.h b/src/components/smart_objects/include/smart_objects/string_schema_item.h
index 7104ff47a9..8f8f516e38 100644
--- a/src/components/smart_objects/include/smart_objects/string_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/string_schema_item.h
@@ -63,7 +63,7 @@ class CStringSchemaItem : public CDefaultSchemaItem<std::string> {
/**
* @brief Validate smart object.
* @param Object Object to validate.
- * @param report__ object for reporting errors during validation
+ * @param report object for reporting errors during validation
* @param MessageVersion to check mobile RPC version against RPC Spec History
* @param allow_unknown_enums
* false - unknown enum values (left as string values after applySchema)
@@ -73,10 +73,12 @@ class CStringSchemaItem : public CDefaultSchemaItem<std::string> {
**/
errors::eType validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(),
const bool allow_unknown_enums = false) OVERRIDE;
+ TypeID GetType() OVERRIDE;
+
private:
/**
* @brief Constructor.
diff --git a/src/components/smart_objects/src/always_false_schema_item.cc b/src/components/smart_objects/src/always_false_schema_item.cc
index 4f8f4584af..45955c79da 100644
--- a/src/components/smart_objects/src/always_false_schema_item.cc
+++ b/src/components/smart_objects/src/always_false_schema_item.cc
@@ -43,10 +43,10 @@ std::shared_ptr<CAlwaysFalseSchemaItem> CAlwaysFalseSchemaItem::create() {
errors::eType CAlwaysFalseSchemaItem::validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) {
- report__->set_validation_info("Generic error");
+ report->set_validation_info("Generic error");
return errors::ERROR;
}
diff --git a/src/components/smart_objects/src/always_true_schema_item.cc b/src/components/smart_objects/src/always_true_schema_item.cc
index 855bfef2a0..6df8b3a63d 100644
--- a/src/components/smart_objects/src/always_true_schema_item.cc
+++ b/src/components/smart_objects/src/always_true_schema_item.cc
@@ -41,7 +41,7 @@ std::shared_ptr<CAlwaysTrueSchemaItem> CAlwaysTrueSchemaItem::create() {
errors::eType CAlwaysTrueSchemaItem::validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) {
return errors::OK;
diff --git a/src/components/smart_objects/src/array_schema_item.cc b/src/components/smart_objects/src/array_schema_item.cc
index 9420fe020f..3c28396213 100644
--- a/src/components/smart_objects/src/array_schema_item.cc
+++ b/src/components/smart_objects/src/array_schema_item.cc
@@ -29,6 +29,8 @@
// POSSIBILITY OF SUCH DAMAGE.
#include "smart_objects/array_schema_item.h"
+
+#include "smart_objects/enum_schema_item.h"
#include "smart_objects/smart_object.h"
namespace ns_smart_device_link {
@@ -44,7 +46,7 @@ std::shared_ptr<CArraySchemaItem> CArraySchemaItem::create(
errors::eType CArraySchemaItem::validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) {
if (SmartType_Array != Object.getType()) {
@@ -52,7 +54,7 @@ errors::eType CArraySchemaItem::validate(
"Incorrect type, expected: " +
SmartObject::typeToString(SmartType_Array) +
", got: " + SmartObject::typeToString(Object.getType());
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::INVALID_VALUE;
}
size_t sizeLimit;
@@ -63,7 +65,7 @@ errors::eType CArraySchemaItem::validate(
stream << "Got array of size: " << array_len
<< ", minimum allowed: " << sizeLimit;
std::string validation_info = stream.str();
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::OUT_OF_RANGE;
}
if (mMaxSize.getValue(sizeLimit) && (array_len > sizeLimit)) {
@@ -71,18 +73,16 @@ errors::eType CArraySchemaItem::validate(
stream << "Got array of size: " << array_len
<< ", maximum allowed: " << sizeLimit;
std::string validation_info = stream.str();
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::OUT_OF_RANGE;
}
for (size_t i = 0u; i < array_len; ++i) {
- std::stringstream strVal;
- strVal << i;
- const errors::eType result =
- mElementSchemaItem->validate(Object.getElement(i),
- &report__->ReportSubobject(strVal.str()),
- MessageVersion,
- allow_unknown_enums);
+ const errors::eType result = mElementSchemaItem->validate(
+ Object.getElement(i),
+ &report->ReportSubobject(std::to_string(i)),
+ MessageVersion,
+ allow_unknown_enums);
if (errors::OK != result) {
return result;
}
@@ -90,6 +90,36 @@ errors::eType CArraySchemaItem::validate(
return errors::OK;
}
+bool CArraySchemaItem::filterInvalidEnums(
+ SmartObject& Object,
+ const utils::SemanticVersion& MessageVersion,
+ rpc::ValidationReport* report) {
+ if (SmartType_Array != Object.getType()) {
+ return false;
+ }
+
+ int index = 0;
+ auto array = Object.asArray();
+ size_t initial_size = array->size();
+ auto should_erase =
+ [this, MessageVersion, report, &index](SmartObject& element) {
+ // If filterInvalidEnums returns true, the checked element
+ // is now invalid and should be filtered
+ return mElementSchemaItem->filterInvalidEnums(
+ element,
+ MessageVersion,
+ &report->ReportSubobject(std::to_string(index++)));
+ };
+ array->erase(std::remove_if(array->begin(), array->end(), should_erase),
+ array->end());
+
+ // Mark this container as invalid if it is below the minimum size after
+ // filtering one or more elements
+ size_t min_size;
+ return array->size() < initial_size && mMinSize.getValue(min_size) &&
+ array->size() < min_size;
+}
+
void CArraySchemaItem::applySchema(
SmartObject& Object,
const bool remove_unknown_parameters,
@@ -127,6 +157,10 @@ void CArraySchemaItem::BuildObjectBySchema(const SmartObject& pattern_object,
result_object = SmartObject(SmartType_Array);
}
+TypeID CArraySchemaItem::GetType() {
+ return TYPE_ARRAY;
+}
+
CArraySchemaItem::CArraySchemaItem(const ISchemaItemPtr ElementSchemaItem,
const TSchemaItemParameter<size_t>& MinSize,
const TSchemaItemParameter<size_t>& MaxSize)
diff --git a/src/components/smart_objects/src/bool_schema_item.cc b/src/components/smart_objects/src/bool_schema_item.cc
index a4875a1b24..f24d14acc3 100644
--- a/src/components/smart_objects/src/bool_schema_item.cc
+++ b/src/components/smart_objects/src/bool_schema_item.cc
@@ -51,5 +51,9 @@ bool CBoolSchemaItem::getDefaultValue() const {
return false;
}
+TypeID CBoolSchemaItem::GetType() {
+ return TYPE_BOOLEAN;
+}
+
} // namespace ns_smart_objects
} // namespace ns_smart_device_link
diff --git a/src/components/smart_objects/src/object_schema_item.cc b/src/components/smart_objects/src/object_schema_item.cc
index 27c64de7e2..c8eab82e8a 100644
--- a/src/components/smart_objects/src/object_schema_item.cc
+++ b/src/components/smart_objects/src/object_schema_item.cc
@@ -35,6 +35,7 @@
#include "generated_msg_version.h"
#include "smart_objects/always_false_schema_item.h"
+#include "smart_objects/enum_schema_item.h"
#include "smart_objects/smart_object.h"
namespace {
@@ -104,7 +105,7 @@ std::shared_ptr<CObjectSchemaItem> CObjectSchemaItem::create(
errors::eType CObjectSchemaItem::validate(
const SmartObject& object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) {
if (SmartType_Map != object.getType()) {
@@ -112,7 +113,7 @@ errors::eType CObjectSchemaItem::validate(
"Incorrect type, expected: " +
SmartObject::typeToString(SmartType_Map) +
", got: " + SmartObject::typeToString(object.getType());
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::INVALID_VALUE;
}
@@ -129,7 +130,7 @@ errors::eType CObjectSchemaItem::validate(
if (correct_member && correct_member->mIsMandatory == true &&
correct_member->mIsRemoved == false) {
std::string validation_info = "Missing mandatory parameter: " + key;
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::MISSING_MANDATORY_PARAMETER;
}
continue;
@@ -141,7 +142,7 @@ errors::eType CObjectSchemaItem::validate(
if (correct_member) {
result =
correct_member->mSchemaItem->validate(field,
- &report__->ReportSubobject(key),
+ &report->ReportSubobject(key),
MessageVersion,
allow_unknown_enums);
} else {
@@ -157,6 +158,40 @@ errors::eType CObjectSchemaItem::validate(
return errors::OK;
}
+bool CObjectSchemaItem::filterInvalidEnums(
+ SmartObject& Object,
+ const utils::SemanticVersion& MessageVersion,
+ rpc::ValidationReport* report) {
+ bool valid = true;
+ for (const auto& key : Object.enumerate()) {
+ auto members_it = mMembers.find(key);
+ if (mMembers.end() == members_it) {
+ // No members found for this key, skipping over
+ continue;
+ }
+
+ const SMember* member =
+ GetCorrectMember(members_it->second, MessageVersion);
+ // Perform filtering recursively on this field
+ if (member->mSchemaItem->filterInvalidEnums(
+ Object[key], MessageVersion, &report->ReportSubobject(key))) {
+ // Object is no longer valid if the member is mandatory.
+ if (member->mIsMandatory) {
+ valid = false;
+ }
+
+ // The member is safe to filter if it is non-mandatory, only leaf nodes
+ // (individual enum values) should be filtered otherwise.
+ bool should_erase = (member->mSchemaItem->GetType() == TYPE_ENUM ||
+ !member->mIsMandatory);
+ if (should_erase) {
+ Object.erase(key);
+ }
+ }
+ }
+ return !valid;
+}
+
void CObjectSchemaItem::applySchema(
SmartObject& Object,
const bool remove_unknown_parameters,
@@ -165,10 +200,6 @@ void CObjectSchemaItem::applySchema(
return;
}
- if (remove_unknown_parameters) {
- RemoveFakeParams(Object, MessageVersion);
- }
-
SmartObject default_value;
for (const auto& item : mMembers) {
@@ -185,6 +216,10 @@ void CObjectSchemaItem::applySchema(
Object[key], remove_unknown_parameters, MessageVersion);
}
}
+
+ if (remove_unknown_parameters) {
+ RemoveUnknownParams(Object, MessageVersion);
+ }
}
void CObjectSchemaItem::unapplySchema(SmartObject& Object,
@@ -232,6 +267,10 @@ size_t CObjectSchemaItem::GetMemberSize() {
return mMembers.size();
}
+TypeID CObjectSchemaItem::GetType() {
+ return TYPE_OBJECT;
+}
+
boost::optional<SMember&> CObjectSchemaItem::GetMemberSchemaItem(
const std::string& member_key) {
auto it = mMembers.find(member_key);
@@ -250,7 +289,7 @@ void CObjectSchemaItem::AddMemberSchemaItem(const std::string& member_key,
CObjectSchemaItem::CObjectSchemaItem(const Members& members)
: mMembers(members) {}
-void CObjectSchemaItem::RemoveFakeParams(
+void CObjectSchemaItem::RemoveUnknownParams(
SmartObject& Object, const utils::SemanticVersion& MessageVersion) {
for (const auto& key : Object.enumerate()) {
std::map<std::string, SMember>::const_iterator members_it =
diff --git a/src/components/smart_objects/src/schema_item.cc b/src/components/smart_objects/src/schema_item.cc
index 8c40e2c7bd..c05b99f19e 100644
--- a/src/components/smart_objects/src/schema_item.cc
+++ b/src/components/smart_objects/src/schema_item.cc
@@ -37,7 +37,7 @@ namespace ns_smart_objects {
errors::eType ISchemaItem::validate(
const SmartObject& object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) {
return errors::ERROR;
@@ -51,6 +51,13 @@ bool ISchemaItem::hasDefaultValue(SmartObject& Object) {
return false;
}
+bool ISchemaItem::filterInvalidEnums(
+ SmartObject& Object,
+ const utils::SemanticVersion& MessageVersion,
+ rpc::ValidationReport* report) {
+ return false;
+}
+
void ISchemaItem::applySchema(SmartObject& Object,
const bool remove_unknown_parameters,
const utils::SemanticVersion& MessageVersion) {}
@@ -65,5 +72,9 @@ size_t ISchemaItem::GetMemberSize() {
return 0;
}
+TypeID ISchemaItem::GetType() {
+ return TYPE_NONE;
+}
+
} // namespace ns_smart_objects
} // namespace ns_smart_device_link
diff --git a/src/components/smart_objects/src/smart_object.cc b/src/components/smart_objects/src/smart_object.cc
index d13ca87848..a8fc267615 100644
--- a/src/components/smart_objects/src/smart_object.cc
+++ b/src/components/smart_objects/src/smart_object.cc
@@ -892,11 +892,10 @@ bool SmartObject::isValid() const {
}
errors::eType SmartObject::validate(
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) {
- return m_schema.validate(
- *this, report__, MessageVersion, allow_unknown_enums);
+ return m_schema.validate(*this, report, MessageVersion, allow_unknown_enums);
}
void SmartObject::setSchema(const CSmartSchema& schema) {
diff --git a/src/components/smart_objects/src/smart_schema.cc b/src/components/smart_objects/src/smart_schema.cc
index 6107d19266..6deb08da3b 100644
--- a/src/components/smart_objects/src/smart_schema.cc
+++ b/src/components/smart_objects/src/smart_schema.cc
@@ -42,11 +42,11 @@ CSmartSchema::CSmartSchema(const ISchemaItemPtr SchemaItem)
errors::eType CSmartSchema::validate(
const SmartObject& object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) const {
return mSchemaItem->validate(
- object, report__, MessageVersion, allow_unknown_enums);
+ object, report, MessageVersion, allow_unknown_enums);
}
void CSmartSchema::setSchemaItem(const ISchemaItemPtr schemaItem) {
@@ -59,8 +59,16 @@ ISchemaItemPtr CSmartSchema::getSchemaItem() {
void CSmartSchema::applySchema(SmartObject& Object,
const bool remove_unknown_parameters,
- const utils::SemanticVersion& MessageVersion) {
+ const utils::SemanticVersion& MessageVersion,
+ rpc::ValidationReport* report) {
mSchemaItem->applySchema(Object, remove_unknown_parameters, MessageVersion);
+ if (remove_unknown_parameters) {
+ rpc::ValidationReport dummy_report("");
+ if (!report) {
+ report = &dummy_report;
+ }
+ mSchemaItem->filterInvalidEnums(Object, MessageVersion, report);
+ }
}
void CSmartSchema::unapplySchema(SmartObject& Object,
diff --git a/src/components/smart_objects/src/string_schema_item.cc b/src/components/smart_objects/src/string_schema_item.cc
index c4382174d0..907f698545 100644
--- a/src/components/smart_objects/src/string_schema_item.cc
+++ b/src/components/smart_objects/src/string_schema_item.cc
@@ -48,7 +48,7 @@ std::shared_ptr<CStringSchemaItem> CStringSchemaItem::create(
errors::eType CStringSchemaItem::validate(
const SmartObject& Object,
- rpc::ValidationReport* report__,
+ rpc::ValidationReport* report,
const utils::SemanticVersion& MessageVersion,
const bool allow_unknown_enums) {
if (SmartType_String != Object.getType()) {
@@ -56,7 +56,7 @@ errors::eType CStringSchemaItem::validate(
"Incorrect type, expected: " +
SmartObject::typeToString(SmartType_String) +
", got: " + SmartObject::typeToString(Object.getType());
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::INVALID_VALUE;
}
@@ -68,7 +68,7 @@ errors::eType CStringSchemaItem::validate(
stream << "Got string of size: " << value.size()
<< ", minimum allowed: " << length;
std::string validation_info = stream.str();
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::OUT_OF_RANGE;
}
if (mMaxLength.getValue(length) && (value.size() > length)) {
@@ -76,7 +76,7 @@ errors::eType CStringSchemaItem::validate(
stream << "Got string of size: " << value.size()
<< ", maximum allowed: " << length;
std::string validation_info = stream.str();
- report__->set_validation_info(validation_info);
+ report->set_validation_info(validation_info);
return errors::OUT_OF_RANGE;
}
return errors::OK;
@@ -90,6 +90,10 @@ std::string CStringSchemaItem::getDefaultValue() const {
return std::string("");
}
+TypeID CStringSchemaItem::GetType() {
+ return TYPE_STRING;
+}
+
CStringSchemaItem::CStringSchemaItem(
const TSchemaItemParameter<size_t>& MinLength,
const TSchemaItemParameter<size_t>& MaxLength,
diff --git a/src/components/smart_objects/test/ArraySchemaItem_test.cc b/src/components/smart_objects/test/ArraySchemaItem_test.cc
index a22a27399d..b5ba73ea91 100644
--- a/src/components/smart_objects/test/ArraySchemaItem_test.cc
+++ b/src/components/smart_objects/test/ArraySchemaItem_test.cc
@@ -33,8 +33,9 @@
#include <string>
#include "gmock/gmock.h"
-
#include "smart_objects/array_schema_item.h"
+#include "smart_objects/enum_schema_item.h"
+#include "smart_objects/object_schema_item.h"
#include "smart_objects/smart_object.h"
#include "smart_objects/string_schema_item.h"
@@ -42,6 +43,15 @@ namespace test {
namespace components {
namespace smart_object_test {
+namespace ExampleEnum {
+enum eType { INVALID_ENUM = -1, Value0 = 0, Value1, Value2 };
+} // namespace ExampleEnum
+
+namespace Keys {
+const char OPTIONAL_PARAM[] = "optionalParam";
+const char MANDATORY_PARAM[] = "mandatoryParam";
+} // namespace Keys
+
/**
* Test ArraySchemaItem no schema item, no min and max size
**/
@@ -345,6 +355,189 @@ TEST(test_map_validate, test_ArraySchemaItemTest) {
EXPECT_EQ(std::string("Out of array"), obj["array"][4].asString());
}
+TEST(test_array_with_unknown_enum, test_ArraySchemaItemTest) {
+ using namespace ns_smart_device_link::ns_smart_objects;
+ SmartObject obj;
+ std::set<ExampleEnum::eType> enum_values;
+ enum_values.insert(ExampleEnum::Value0);
+ enum_values.insert(ExampleEnum::Value1);
+ enum_values.insert(ExampleEnum::Value2);
+
+ ISchemaItemPtr item = CArraySchemaItem::create(
+ TEnumSchemaItem<ExampleEnum::eType>::create(enum_values),
+ TSchemaItemParameter<size_t>(1));
+
+ obj[0] = "Value0";
+ obj[1] = "Value10";
+ obj[2] = "Value1";
+
+ item->applySchema(obj, true);
+
+ rpc::ValidationReport report("RPC");
+ EXPECT_FALSE(
+ item->filterInvalidEnums(obj, utils::SemanticVersion(), &report));
+ EXPECT_NE(std::string(""), rpc::PrettyFormat(report));
+
+ EXPECT_EQ((size_t)2, obj.length());
+ EXPECT_EQ(0, obj[0].asInt());
+ EXPECT_EQ(1, obj[1].asInt());
+
+ report = rpc::ValidationReport("RPC");
+ EXPECT_EQ(errors::OK, item->validate(obj, &report));
+ EXPECT_EQ(std::string(""), rpc::PrettyFormat(report));
+}
+
+TEST(test_array_with_unknown_enums, test_ArraySchemaItemTest) {
+ using namespace ns_smart_device_link::ns_smart_objects;
+ SmartObject obj;
+ std::set<ExampleEnum::eType> enum_values;
+ enum_values.insert(ExampleEnum::Value0);
+ enum_values.insert(ExampleEnum::Value1);
+ enum_values.insert(ExampleEnum::Value2);
+
+ ISchemaItemPtr item = CArraySchemaItem::create(
+ TEnumSchemaItem<ExampleEnum::eType>::create(enum_values),
+ TSchemaItemParameter<size_t>(1));
+
+ obj[0] = "Value10";
+ obj[1] = "Value11";
+ obj[2] = "Value12";
+
+ item->applySchema(obj, true);
+
+ rpc::ValidationReport report("RPC");
+ EXPECT_TRUE(item->filterInvalidEnums(obj, utils::SemanticVersion(), &report));
+ EXPECT_NE(std::string(""), rpc::PrettyFormat(report));
+
+ EXPECT_EQ((size_t)0, obj.length());
+
+ report = rpc::ValidationReport("RPC");
+ EXPECT_EQ(errors::OUT_OF_RANGE, item->validate(obj, &report));
+ EXPECT_NE(std::string(""), rpc::PrettyFormat(report));
+}
+
+TEST(test_array_of_objects_with_unknown_enum, test_ArraySchemaItemTest) {
+ using namespace ns_smart_device_link::ns_smart_objects;
+ SmartObject obj;
+ std::set<ExampleEnum::eType> enum_values;
+ enum_values.insert(ExampleEnum::Value0);
+ enum_values.insert(ExampleEnum::Value1);
+ enum_values.insert(ExampleEnum::Value2);
+
+ Members structMembersMap;
+ structMembersMap[Keys::OPTIONAL_PARAM] =
+ SMember(TEnumSchemaItem<ExampleEnum::eType>::create(enum_values), false);
+ structMembersMap[Keys::MANDATORY_PARAM] =
+ SMember(TEnumSchemaItem<ExampleEnum::eType>::create(enum_values), true);
+
+ ISchemaItemPtr item =
+ CArraySchemaItem::create(CObjectSchemaItem::create(structMembersMap),
+ TSchemaItemParameter<size_t>(1));
+
+ SmartObject struct1;
+ struct1[Keys::MANDATORY_PARAM] = "Value0";
+ SmartObject struct2;
+ struct2[Keys::MANDATORY_PARAM] = "Value11";
+ SmartObject struct3;
+ struct3[Keys::MANDATORY_PARAM] = "Value2";
+ obj[0] = struct1;
+ obj[1] = struct2;
+ obj[2] = struct3;
+
+ item->applySchema(obj, true);
+
+ rpc::ValidationReport report("RPC");
+ EXPECT_FALSE(
+ item->filterInvalidEnums(obj, utils::SemanticVersion(), &report));
+ EXPECT_NE(std::string(""), rpc::PrettyFormat(report));
+
+ EXPECT_EQ((size_t)2, obj.length());
+ EXPECT_EQ(0, obj[0][Keys::MANDATORY_PARAM].asInt());
+ EXPECT_EQ(2, obj[1][Keys::MANDATORY_PARAM].asInt());
+
+ report = rpc::ValidationReport("RPC");
+ EXPECT_EQ(errors::OK, item->validate(obj, &report));
+ EXPECT_EQ(std::string(""), rpc::PrettyFormat(report));
+}
+
+TEST(test_array_of_objects_with_unknown_optional_enums,
+ test_ArraySchemaItemTest) {
+ using namespace ns_smart_device_link::ns_smart_objects;
+ SmartObject obj;
+ std::set<ExampleEnum::eType> enum_values;
+ enum_values.insert(ExampleEnum::Value0);
+ enum_values.insert(ExampleEnum::Value1);
+ enum_values.insert(ExampleEnum::Value2);
+
+ Members structMembersMap;
+ structMembersMap[Keys::OPTIONAL_PARAM] =
+ SMember(TEnumSchemaItem<ExampleEnum::eType>::create(enum_values), false);
+ structMembersMap[Keys::MANDATORY_PARAM] =
+ SMember(TEnumSchemaItem<ExampleEnum::eType>::create(enum_values), true);
+
+ ISchemaItemPtr item =
+ CArraySchemaItem::create(CObjectSchemaItem::create(structMembersMap),
+ TSchemaItemParameter<size_t>(1));
+
+ SmartObject struct1;
+ struct1[Keys::OPTIONAL_PARAM] = "Value10";
+ struct1[Keys::MANDATORY_PARAM] = "Value0";
+ SmartObject struct2;
+ struct2[Keys::OPTIONAL_PARAM] = "Value0";
+ struct2[Keys::MANDATORY_PARAM] = "Value1";
+ SmartObject struct3;
+ struct3[Keys::OPTIONAL_PARAM] = "Value12";
+ struct3[Keys::MANDATORY_PARAM] = "Value2";
+ obj[0] = struct1;
+ obj[1] = struct2;
+ obj[2] = struct3;
+
+ item->applySchema(obj, true);
+
+ rpc::ValidationReport report("RPC");
+ EXPECT_FALSE(
+ item->filterInvalidEnums(obj, utils::SemanticVersion(), &report));
+ EXPECT_NE(std::string(""), rpc::PrettyFormat(report));
+
+ // Unknown sub-parameter values should be filtered, but not array elements
+ EXPECT_EQ((size_t)3, obj.length());
+ EXPECT_EQ(0, obj[0][Keys::MANDATORY_PARAM].asInt());
+ EXPECT_FALSE(obj[0].keyExists(Keys::OPTIONAL_PARAM));
+ EXPECT_EQ(1, obj[1][Keys::MANDATORY_PARAM].asInt());
+ EXPECT_EQ(0, obj[1][Keys::OPTIONAL_PARAM].asInt());
+ EXPECT_EQ(2, obj[2][Keys::MANDATORY_PARAM].asInt());
+ EXPECT_FALSE(obj[2].keyExists(Keys::OPTIONAL_PARAM));
+
+ report = rpc::ValidationReport("RPC");
+ EXPECT_EQ(errors::OK, item->validate(obj, &report));
+ EXPECT_EQ(std::string(""), rpc::PrettyFormat(report));
+}
+
} // namespace smart_object_test
} // namespace components
} // namespace test
+
+namespace ns_smart_device_link {
+namespace ns_smart_objects {
+
+namespace ExampleEnum = test::components::smart_object_test::ExampleEnum;
+typedef EnumConversionHelper<ExampleEnum::eType> EnumConverter;
+
+template <>
+const EnumConverter::EnumToCStringMap EnumConverter::enum_to_cstring_map_ =
+ EnumConverter::InitEnumToCStringMap();
+
+template <>
+const EnumConverter::CStringToEnumMap EnumConverter::cstring_to_enum_map_ =
+ EnumConverter::InitCStringToEnumMap();
+
+template <>
+const char* const EnumConverter::cstring_values_[] = {
+ "Value0", "Value1", "Value2"};
+
+template <>
+const ExampleEnum::eType EnumConverter::enum_values_[] = {
+ ExampleEnum::Value0, ExampleEnum::Value1, ExampleEnum::Value2};
+
+} // namespace ns_smart_objects
+} // namespace ns_smart_device_link
diff --git a/src/components/smart_objects/test/CObjectSchemaItem_test.cc b/src/components/smart_objects/test/CObjectSchemaItem_test.cc
index 8a7d09f31e..477d950257 100644
--- a/src/components/smart_objects/test/CObjectSchemaItem_test.cc
+++ b/src/components/smart_objects/test/CObjectSchemaItem_test.cc
@@ -89,6 +89,9 @@ namespace Keys {
const char RESULT_CODE[] = "resultCode";
const char INFO[] = "info";
const char SUCCESS[] = "success";
+const char STRUCT[] = "struct";
+const char OPTIONAL_PARAM[] = "optionalParam";
+const char MANDATORY_PARAM[] = "mandatoryParam";
} // namespace Keys
class ObjectSchemaItemTest : public ::testing::Test {
@@ -127,6 +130,12 @@ class ObjectSchemaItemTest : public ::testing::Test {
TSchemaItemParameter<int>(2)),
true);
+ Members structMembersMap;
+ structMembersMap[Keys::OPTIONAL_PARAM] = SMember(
+ TEnumSchemaItem<FunctionID::eType>::create(function_values), false);
+ structMembersMap[Keys::MANDATORY_PARAM] = SMember(
+ TEnumSchemaItem<FunctionID::eType>::create(function_values), true);
+
Members schemaMembersMap;
schemaMembersMap[Keys::RESULT_CODE] = SMember(
TEnumSchemaItem<ResultType::eType>::create(resultCode_values), false);
@@ -135,6 +144,8 @@ class ObjectSchemaItemTest : public ::testing::Test {
TSchemaItemParameter<size_t>(10)),
false);
schemaMembersMap[Keys::SUCCESS] = SMember(CBoolSchemaItem::create(), false);
+ schemaMembersMap[Keys::STRUCT] =
+ SMember(CObjectSchemaItem::create(structMembersMap), false);
// Create fake param that has breaking history changes
std::vector<SMember> fake_param_history_vector;
@@ -521,6 +532,97 @@ TEST_F(ObjectSchemaItemTest, test_strings_to_enum_conversion) {
}
}
+TEST_F(ObjectSchemaItemTest, filter_unknown_enums_non_mandatory_param) {
+ SmartObject obj;
+ obj[S_PARAMS][S_FUNCTION_ID] = 1;
+ obj[S_PARAMS][S_CORRELATION_ID] = 0xFF;
+ obj[S_PARAMS][S_PROTOCOL_VERSION] = 2;
+ obj[S_MSG_PARAMS][Keys::RESULT_CODE] = "FUTURE";
+ obj[S_MSG_PARAMS][Keys::INFO] = "0123456789";
+
+ schema_item->applySchema(obj, false);
+ rpc::ValidationReport report("RPC");
+ EXPECT_FALSE(
+ schema_item->filterInvalidEnums(obj, utils::SemanticVersion(), &report));
+ EXPECT_NE(std::string(""), rpc::PrettyFormat(report));
+
+ // The unknown enum value was filtered. Validation should pass in this case.
+ EXPECT_FALSE(obj[S_MSG_PARAMS].keyExists(Keys::RESULT_CODE));
+ report = rpc::ValidationReport("RPC");
+ EXPECT_EQ(errors::OK, schema_item->validate(obj, &report));
+ EXPECT_EQ(std::string(""), rpc::PrettyFormat(report));
+}
+
+TEST_F(ObjectSchemaItemTest, filter_unknown_enums_mandatory) {
+ SmartObject obj;
+ obj[S_PARAMS][S_FUNCTION_ID] = "FUTURE";
+ obj[S_PARAMS][S_CORRELATION_ID] = 0xFF;
+ obj[S_PARAMS][S_PROTOCOL_VERSION] = 2;
+ obj[S_MSG_PARAMS][Keys::RESULT_CODE] = 2;
+ obj[S_MSG_PARAMS][Keys::INFO] = "0123456789";
+
+ schema_item->applySchema(obj, false);
+ rpc::ValidationReport report("RPC");
+ EXPECT_TRUE(
+ schema_item->filterInvalidEnums(obj, utils::SemanticVersion(), &report));
+ EXPECT_NE(std::string(""), rpc::PrettyFormat(report));
+
+ EXPECT_FALSE(obj[S_PARAMS].keyExists(S_FUNCTION_ID));
+ report = rpc::ValidationReport("RPC");
+ EXPECT_EQ(errors::MISSING_MANDATORY_PARAMETER,
+ schema_item->validate(obj, &report));
+ EXPECT_NE(std::string(""), rpc::PrettyFormat(report));
+}
+
+TEST_F(ObjectSchemaItemTest, filter_unknown_enums_non_mandatory_subparam) {
+ SmartObject obj;
+ obj[S_PARAMS][S_FUNCTION_ID] = 1;
+ obj[S_PARAMS][S_CORRELATION_ID] = 0xFF;
+ obj[S_PARAMS][S_PROTOCOL_VERSION] = 2;
+ obj[S_MSG_PARAMS][Keys::STRUCT][Keys::OPTIONAL_PARAM] = "FUTURE";
+ obj[S_MSG_PARAMS][Keys::STRUCT][Keys::MANDATORY_PARAM] = 1;
+ obj[S_MSG_PARAMS][Keys::RESULT_CODE] = 2;
+ obj[S_MSG_PARAMS][Keys::INFO] = "0123456789";
+
+ schema_item->applySchema(obj, false);
+ rpc::ValidationReport report("RPC");
+ EXPECT_FALSE(
+ schema_item->filterInvalidEnums(obj, utils::SemanticVersion(), &report));
+ EXPECT_NE(std::string(""), rpc::PrettyFormat(report));
+
+ // The unknown enum value was filtered.
+ // Validation should pass in this case.
+ ASSERT_TRUE(obj[S_MSG_PARAMS].keyExists(Keys::STRUCT));
+ EXPECT_FALSE(obj[S_MSG_PARAMS][Keys::STRUCT].keyExists(Keys::OPTIONAL_PARAM));
+ EXPECT_TRUE(obj[S_MSG_PARAMS][Keys::STRUCT].keyExists(Keys::MANDATORY_PARAM));
+ report = rpc::ValidationReport("RPC");
+ EXPECT_EQ(errors::OK, schema_item->validate(obj, &report));
+ EXPECT_EQ(std::string(""), rpc::PrettyFormat(report));
+}
+
+TEST_F(ObjectSchemaItemTest, filter_unknown_enums_mandatory_subparam) {
+ SmartObject obj;
+ obj[S_PARAMS][S_FUNCTION_ID] = 1;
+ obj[S_PARAMS][S_CORRELATION_ID] = 0xFF;
+ obj[S_PARAMS][S_PROTOCOL_VERSION] = 2;
+ obj[S_MSG_PARAMS][Keys::STRUCT][Keys::MANDATORY_PARAM] = "FUTURE";
+ obj[S_MSG_PARAMS][Keys::RESULT_CODE] = 2;
+ obj[S_MSG_PARAMS][Keys::INFO] = "0123456789";
+
+ schema_item->applySchema(obj, false);
+ rpc::ValidationReport report("RPC");
+ EXPECT_FALSE(
+ schema_item->filterInvalidEnums(obj, utils::SemanticVersion(), &report));
+ EXPECT_NE(std::string(""), rpc::PrettyFormat(report));
+
+ // The struct containing the unknown enum value was filtered.
+ // Validation should pass in this case.
+ EXPECT_FALSE(obj[S_MSG_PARAMS].keyExists(Keys::STRUCT));
+ report = rpc::ValidationReport("RPC");
+ EXPECT_EQ(errors::OK, schema_item->validate(obj, &report));
+ EXPECT_EQ(std::string(""), rpc::PrettyFormat(report));
+}
+
} // namespace smart_object_test
} // namespace components
} // namespace test
@@ -529,20 +631,20 @@ namespace ns_smart_device_link {
namespace ns_smart_objects {
namespace FunctionID = test::components::smart_object_test::FunctionID;
-typedef EnumConversionHelper<FunctionID::eType> FunctionConvertor;
+typedef EnumConversionHelper<FunctionID::eType> FunctionConverter;
template <>
-const FunctionConvertor::EnumToCStringMap
- FunctionConvertor::enum_to_cstring_map_ =
- FunctionConvertor::InitEnumToCStringMap();
+const FunctionConverter::EnumToCStringMap
+ FunctionConverter::enum_to_cstring_map_ =
+ FunctionConverter::InitEnumToCStringMap();
template <>
-const FunctionConvertor::CStringToEnumMap
- FunctionConvertor::cstring_to_enum_map_ =
- FunctionConvertor::InitCStringToEnumMap();
+const FunctionConverter::CStringToEnumMap
+ FunctionConverter::cstring_to_enum_map_ =
+ FunctionConverter::InitCStringToEnumMap();
template <>
-const char* const FunctionConvertor::cstring_values_[] = {"Function0",
+const char* const FunctionConverter::cstring_values_[] = {"Function0",
"Function1",
"Function2",
"Function3",
@@ -551,7 +653,7 @@ const char* const FunctionConvertor::cstring_values_[] = {"Function0",
"Function6"};
template <>
-const FunctionID::eType FunctionConvertor::enum_values_[] = {
+const FunctionID::eType FunctionConverter::enum_values_[] = {
FunctionID::Function0,
FunctionID::Function1,
FunctionID::Function2,
@@ -563,20 +665,20 @@ const FunctionID::eType FunctionConvertor::enum_values_[] = {
// ----------------------------------------------------------------------------
namespace ResultType = test::components::smart_object_test::ResultType;
-typedef EnumConversionHelper<ResultType::eType> ResultTypeConvertor;
+typedef EnumConversionHelper<ResultType::eType> ResultTypeConverter;
template <>
-const ResultTypeConvertor::EnumToCStringMap
- ResultTypeConvertor::enum_to_cstring_map_ =
- ResultTypeConvertor::InitEnumToCStringMap();
+const ResultTypeConverter::EnumToCStringMap
+ ResultTypeConverter::enum_to_cstring_map_ =
+ ResultTypeConverter::InitEnumToCStringMap();
template <>
-const ResultTypeConvertor::CStringToEnumMap
- ResultTypeConvertor::cstring_to_enum_map_ =
- ResultTypeConvertor::InitCStringToEnumMap();
+const ResultTypeConverter::CStringToEnumMap
+ ResultTypeConverter::cstring_to_enum_map_ =
+ ResultTypeConverter::InitCStringToEnumMap();
template <>
-const char* const ResultTypeConvertor::cstring_values_[] = {
+const char* const ResultTypeConverter::cstring_values_[] = {
"APPLICATION_NOT_REGISTERED",
"SUCCESS",
"TOO_MANY_PENDING_REQUESTS",
@@ -589,7 +691,7 @@ const char* const ResultTypeConvertor::cstring_values_[] = {
"DISALLOWED"};
template <>
-const ResultType::eType ResultTypeConvertor::enum_values_[] = {
+const ResultType::eType ResultTypeConverter::enum_values_[] = {
ResultType::APPLICATION_NOT_REGISTERED,
ResultType::SUCCESS,
ResultType::TOO_MANY_PENDING_REQUESTS,