Apply modified action schema
authorChanggyu Choi <changyu.choi@samsung.com>
Sun, 27 Apr 2025 08:43:59 +0000 (17:43 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Mon, 28 Apr 2025 07:01:13 +0000 (16:01 +0900)
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
src/action/action_request_handler.cc
src/action/utils/action_model_converter.cc
src/action/utils/action_validator.cc
src/common/action_parameter.h
src/common/action_schema.cc
src/common/action_schema.h
src/pkgmgr_plugin_parser/json_action_schema_parser.cc
test/unit_tests/action_model_converter_test.cc
test/unit_tests/action_schema_test.cc

index 71249e00b5ef6b2392d216489d14f55208a56429..a5b8bab9834ae05829579f68ebc1e1086deb4e79 100755 (executable)
@@ -92,9 +92,9 @@ bool CheckPrivileges(pid_t pid, uid_t uid,
 //     return common::ParameterType::IntType;
 //   else if (type.compare("string") == 0)
 //     return common::ParameterType::StringType;
-//   else if (type.compare("double") == 0)
-//     return common::ParameterType::DoubleType;
-//   else if (type.compare("bool") == 0)
+//   else if (type.compare("number") == 0)
+//     return common::ParameterType::NumberType;
+//   else if (type.compare("boolean") == 0)
 //     return common::ParameterType::BoolType;
 
 //   return common::ParameterType::InvalidType;
@@ -107,10 +107,10 @@ std::string GetStringFromParameterType(common::ParameterType type) {
     return "integer";
   else if (type == common::ParameterType::StringType)
     return "string";
-  else if (type == common::ParameterType::DoubleType)
-    return "double";
+  else if (type == common::ParameterType::NumberType)
+    return "number";
   else if (type == common::ParameterType::BoolType)
-    return "bool";
+    return "boolean";
 
   return "";
 }
@@ -122,9 +122,6 @@ void FillActionModelInfo(common::ActionModel& model,
     case common::ActionType::AppControl:
       model.SetExtraInfo(schema.GetAppId());
       break;
-    case common::ActionType::Plugin:
-      model.SetExtraInfo("plugin-path");  // TODO: Set plugin path
-      break;
     default:
       break;
   }
index 27c39b363324bb32ceb2ce7507f801e6033d818e..41dbe0ed080b211ecf7acd124338be9dc9ac7adc 100644 (file)
@@ -18,7 +18,7 @@ plugin_proxy::ActionModel ActionModelConverter::ConvertToAction(
 std::string ActionModelConverter::ActionTypeToString(common::ActionType type) {
   switch (type) {
   case common::ActionType::AppControl:
-    return "app_control";
+    return "appControl";
   case common::ActionType::Plugin:
     return "plugin";
   default:
@@ -33,10 +33,14 @@ std::string ActionModelConverter::ActionParameterTypeToString(
     return "integer";
   case common::ParameterType::StringType:
     return "string";
-  case common::ParameterType::DoubleType:
-    return "double";
+  case common::ParameterType::NumberType:
+    return "number";
   case common::ParameterType::BoolType:
-    return "bool";
+    return "boolean";
+  case common::ParameterType::ObjectType:
+    return "object";
+  case common::ParameterType::ArrayType:
+    return "array";
   default:
     return "InvalidType";
   }
index eb93c8d3f16bb81ba3469ec329fab6fff213835e..2b91b529c3df7e3491cf1d969dcc4efdc14a07d8 100644 (file)
@@ -52,13 +52,13 @@ bool ActionValidator::CheckModelValid(const std::string& schemajson,
           int value = model.get<int>({"params", key});
         } else if (type == "string") {
           std::string value = model.get<std::string>({"params", key});
-        } else if (type == "bool") {  // TODO: change to boolean
+        } else if (type == "boolean") {
           bool value = model.get<bool>({"params", key});
         } else if (type == "array") {
           auto value = model.array({"params", key});
         } else if (type == "object") {
           auto value = model.members({"params", key});
-        } else if (type == "double") {  // TODO: change to number
+        } else if (type == "number") {
           double value = model.get<double>({"params", key});
         } else {
           LOG(ERROR) << "Unknown type: " << type;
index 85b0f216e6d77c9b72bffbb385e79fb6d8641376..1d0a9ca43fda705098a4f7a58fc931a0f1576d41 100644 (file)
@@ -24,9 +24,10 @@ namespace common {
 enum class ParameterType {
   IntType = 0,
   StringType = 1,
-  DoubleType = 2,
+  NumberType = 2,
   BoolType = 3,
-  JsonType = 4,
+  ObjectType = 4,
+  ArrayType = 5,
   InvalidType = 100
 };
 
index 58955791b418e2b5e43394b27a51cfb576b0654b..cfab45082e775e6930543c5d79c1757a4fa12da4 100644 (file)
@@ -27,9 +27,10 @@ namespace {
 std::map<std::string, common::ParameterType> kTypeMap = {
     {"integer", common::ParameterType::IntType},
     {"string", common::ParameterType::StringType},
-    {"double", common::ParameterType::DoubleType},
-    {"bool", common::ParameterType::BoolType},
-    {"json", common::ParameterType::JsonType},
+    {"number", common::ParameterType::NumberType},
+    {"boolean", common::ParameterType::BoolType},
+    {"object", common::ParameterType::ObjectType},
+    {"array", common::ParameterType::ArrayType}
 };
 
 common::ParameterType ConvertStringToParameterType(const std::string& type) {
@@ -42,7 +43,7 @@ common::ParameterType ConvertStringToParameterType(const std::string& type) {
 }
 
 common::ActionType GetActionTypeFromString(const std::string& type) {
-  if (type.compare("app_control") == 0)
+  if (type.compare("appControl") == 0)
     return common::ActionType::AppControl;
   else if (type.compare("plugin") == 0)
     return common::ActionType::Plugin;
@@ -59,7 +60,6 @@ ActionSchema::ActionSchema(const std::string& json_str) {
   try {
     SafeJson root(json_str);
     action_id_ = root.get<std::string>("name");
-    appid_ = root.get<std::string>("appId");  // TODO: Change to details::appId
     try {
       category_ = root.get<std::string>("category");
     } catch (...) {
@@ -90,8 +90,20 @@ ActionSchema::ActionSchema(const std::string& json_str) {
       returns_.emplace_back(name, type, "", description, false);
     }
 
-    for (auto const& it : root.array("required-privileges"))
+    for (auto const& it : root.array("requiredprivileges"))
       privileges_.push_back(it->GetString());
+
+    // details
+    switch (type_) {
+      case ActionType::AppControl:
+        appid_ = root.get<std::string>("details.appid");
+        break;
+      case ActionType::Plugin:
+        plugin_path_ = root.get<std::string>("details.pluginPath");
+        break;
+      default:
+        break;
+    }
   } catch (const std::runtime_error& e) {
     // TODO: how to handle invalid json case?
     LOG(ERROR) << "Failed to parse json string: " << e.what();
@@ -128,6 +140,14 @@ void ActionSchema::SetAppId(std::string appid) {
   appid_ = std::move(appid);
 }
 
+const std::string& ActionSchema::GetPluginPath() const {
+  return plugin_path_;
+}
+
+void ActionSchema::SetPluginPath(std::string plugin_path) {
+  plugin_path_ = std::move(plugin_path);
+}
+
 const std::string& ActionSchema::GetCategory() const {
   return category_;
 }
index ea26e1b238a27f0624c290f8c8a35ad2e85afdab..d06429aa0f10c0bf9ffa6b0d75eeb05a25b4b7b9 100644 (file)
@@ -40,6 +40,9 @@ class ActionSchema {
   const std::string& GetAppId() const;
   void SetAppId(std::string app_id);
 
+  const std::string& GetPluginPath() const;
+  void SetPluginPath(std::string plugin_path);
+
   const std::string& GetCategory() const;
   void SetCategory(std::string category);
 
@@ -61,6 +64,7 @@ class ActionSchema {
  private:
   std::string action_id_;
   std::string appid_;
+  std::string plugin_path_;
   std::string category_;
   ActionType type_ = ActionType::InvalidType;
   std::string description_;
index edb285acfc5578a4a23edfd6a94d46320ac21a08..34464c0233a7095d9d5bb534f42894bfccdb5cb5 100644 (file)
@@ -36,7 +36,7 @@ ActionSchema JsonActionSchemaParser::Parse(const std::string& pkgid,
   common::SafeJson root(json);
   std::string name = root.get<std::string>("name");
   std::string category = root.get<std::string>("category");
-  const auto priv_array = root.array("required-privileges");
+  const auto priv_array = root.array("requiredprivileges");
   std::vector<std::string> privs;
   privs.reserve(priv_array.size());
   std::transform(priv_array.begin(), priv_array.end(),
index f9415f357f51329c39ee2b1b06fd0a43aa575dce..38c18d7ee36e0d83fc927008baca8ab7181b0ef8 100644 (file)
@@ -23,7 +23,7 @@ TEST(ActionModelConverterTest, ConvertToAction) {
 TEST(ActionModelConverterTest, ActionTypeToString) {
   EXPECT_EQ(
       ActionModelConverter().ActionTypeToString(common::ActionType::AppControl),
-      "app_control");
+      "appControl");
   EXPECT_EQ(
       ActionModelConverter().ActionTypeToString(common::ActionType::Plugin),
       "plugin");
@@ -40,11 +40,11 @@ TEST(ActionModelConverterTest, ParameterTypeToString) {
                 common::ParameterType::StringType),
             "string");
   EXPECT_EQ(ActionModelConverter().ActionParameterTypeToString(
-                common::ParameterType::DoubleType),
-            "double");
+                common::ParameterType::NumberType),
+            "number");
   EXPECT_EQ(ActionModelConverter().ActionParameterTypeToString(
                 common::ParameterType::BoolType),
-            "bool");
+            "boolean");
   EXPECT_EQ(ActionModelConverter().ActionParameterTypeToString(
                 static_cast<common::ParameterType>(999)),
             "InvalidType");
index 82ef9e03b75fc9e6aef099265e9f34909483cf7a..f9349d281039a7b3784d25b4beecc0e524da7c6c 100644 (file)
@@ -1,19 +1,18 @@
-#include <gtest/gtest.h>
 #include "common/action_schema.h"
+#include <gtest/gtest.h>
 #include <sstream>
 
 using namespace common;
 
 class ActionSchemaTest : public ::testing::Test {
-protected:
-    void SetUp() override {
-        valid_json_ = R"(
+ protected:
+  void SetUp() override {
+    valid_appcontrol_action_json_ = R"(
         {
           "name": "test_action",
-          "appId": "com.example.app",
           "category": "test_category",
           "desc": "Test action description",
-          "type": "app_control",
+          "type": "appControl",
           "params": {
             "param1": {
               "type": "integer",
@@ -26,86 +25,142 @@ protected:
           },
           "returns": {
             "return1": {
-              "type": "double",
+              "type": "number",
               "desc": "Return 1"
             }
           },
-          "required-privileges": ["priv1", "priv2"]
+          "requiredprivileges": ["priv1", "priv2"],
+          "details": {
+            "appid": "com.example.app"
+          }
         })";
-        invalid_json_ = R"( { "invalid": "json" })";
-    }
+    valid_plugin_action_json_ = R"(
+          {
+            "name": "test_plugin_action",
+            "category": "test_category",
+            "desc": "Test action description",
+            "type": "plugin",
+            "params": {
+              "param1": {
+                "type": "boolean",
+                "desc": "Param 1"
+              },
+              "param2": {
+                "type": "number",
+                "desc": "Param 2"
+              }
+            },
+            "returns": {
+              "return1": {
+                "type": "number",
+                "desc": "Return 1"
+              }
+            },
+            "requiredprivileges": ["priv1", "priv2"],
+            "details": {
+              "pluginPath": "/path/to/plugin"
+            }
+          })";
+    invalid_json_ = R"( { "invalid": "json" })";
+  }
 
-    std::string valid_json_;
-    std::string invalid_json_;
+  std::string valid_appcontrol_action_json_;
+  std::string valid_plugin_action_json_;
+  std::string invalid_json_;
 };
 
-TEST_F(ActionSchemaTest, ValidJsonParsing) {
-    ActionSchema schema(valid_json_);
-    EXPECT_EQ(schema.GetActionId(), "test_action");
-    EXPECT_EQ(schema.GetAppId(), "com.example.app");
-    EXPECT_EQ(schema.GetCategory(), "test_category");
-    EXPECT_EQ(schema.GetDescription(), "Test action description");
-    EXPECT_EQ(schema.GetType(), ActionType::AppControl);
-
-    const auto& params = schema.GetParameters();
-    EXPECT_EQ(params.size(), 2);
-    EXPECT_EQ(params[0].GetName(), "param1");
-    EXPECT_EQ(params[0].GetType(), ParameterType::IntType);
-    EXPECT_EQ(params[1].GetName(), "param2");
-    EXPECT_EQ(params[1].GetType(), ParameterType::StringType);
-
-    const auto& returns = schema.GetReturns();
-    EXPECT_EQ(returns.size(), 1);
-    EXPECT_EQ(returns[0].GetType(), ParameterType::DoubleType);
-
-    const auto& privileges = schema.GetPrivileges();
-    EXPECT_EQ(privileges.size(), 2);
-    EXPECT_EQ(privileges[0], "priv1");
-    EXPECT_EQ(privileges[1], "priv2");
+TEST_F(ActionSchemaTest, ValidAppControlActionJsonParsing) {
+  ActionSchema schema(valid_appcontrol_action_json_);
+  EXPECT_EQ(schema.GetActionId(), "test_action");
+  EXPECT_EQ(schema.GetAppId(), "com.example.app");
+  EXPECT_EQ(schema.GetCategory(), "test_category");
+  EXPECT_EQ(schema.GetDescription(), "Test action description");
+  EXPECT_EQ(schema.GetType(), ActionType::AppControl);
+
+  const auto& params = schema.GetParameters();
+  EXPECT_EQ(params.size(), 2);
+  EXPECT_EQ(params[0].GetName(), "param1");
+  EXPECT_EQ(params[0].GetType(), ParameterType::IntType);
+  EXPECT_EQ(params[1].GetName(), "param2");
+  EXPECT_EQ(params[1].GetType(), ParameterType::StringType);
+
+  const auto& returns = schema.GetReturns();
+  EXPECT_EQ(returns.size(), 1);
+  EXPECT_EQ(returns[0].GetType(), ParameterType::NumberType);
+
+  const auto& privileges = schema.GetPrivileges();
+  EXPECT_EQ(privileges.size(), 2);
+  EXPECT_EQ(privileges[0], "priv1");
+  EXPECT_EQ(privileges[1], "priv2");
+}
+
+TEST_F(ActionSchemaTest, ValidPluginActionJsonParsing) {
+  ActionSchema schema(valid_plugin_action_json_);
+  EXPECT_EQ(schema.GetActionId(), "test_plugin_action");
+  EXPECT_EQ(schema.GetPluginPath(), "/path/to/plugin");
+  EXPECT_EQ(schema.GetCategory(), "test_category");
+  EXPECT_EQ(schema.GetDescription(), "Test action description");
+  EXPECT_EQ(schema.GetType(), ActionType::Plugin);
+
+  const auto& params = schema.GetParameters();
+  EXPECT_EQ(params.size(), 2);
+  EXPECT_EQ(params[0].GetName(), "param1");
+  EXPECT_EQ(params[0].GetType(), ParameterType::BoolType);
+  EXPECT_EQ(params[1].GetName(), "param2");
+  EXPECT_EQ(params[1].GetType(), ParameterType::NumberType);
+
+  const auto& returns = schema.GetReturns();
+  EXPECT_EQ(returns.size(), 1);
+  EXPECT_EQ(returns[0].GetType(), ParameterType::NumberType);
+
+  const auto& privileges = schema.GetPrivileges();
+  EXPECT_EQ(privileges.size(), 2);
+  EXPECT_EQ(privileges[0], "priv1");
+  EXPECT_EQ(privileges[1], "priv2");
 }
 
 TEST_F(ActionSchemaTest, InvalidJsonParsing) {
-    ActionSchema invalid_schema(invalid_json_);
-    EXPECT_EQ(invalid_schema.GetActionId().empty(), true);
-    EXPECT_EQ(invalid_schema.GetAppId().empty(), true);
-    EXPECT_EQ(invalid_schema.GetCategory().empty(), true);
-    EXPECT_EQ(invalid_schema.GetDescription().empty(), true);
-    EXPECT_EQ(invalid_schema.GetType(), ActionType::InvalidType);
+  ActionSchema invalid_schema(invalid_json_);
+  EXPECT_EQ(invalid_schema.GetActionId().empty(), true);
+  EXPECT_EQ(invalid_schema.GetAppId().empty(), true);
+  EXPECT_EQ(invalid_schema.GetCategory().empty(), true);
+  EXPECT_EQ(invalid_schema.GetDescription().empty(), true);
+  EXPECT_EQ(invalid_schema.GetType(), ActionType::InvalidType);
 }
 
 TEST_F(ActionSchemaTest, SettersAndGetters) {
-    ActionSchema schema;
-    schema.SetActionId("new_id");
-    schema.SetAppId("new_package");
-    schema.SetCategory("new_category");
-    schema.SetDescription("new_desc");
-    schema.SetType(ActionType::Plugin);
-
-    EXPECT_EQ(schema.GetActionId(), "new_id");
-    EXPECT_EQ(schema.GetAppId(), "new_package");
-    EXPECT_EQ(schema.GetCategory(), "new_category");
-    EXPECT_EQ(schema.GetDescription(), "new_desc");
-    EXPECT_EQ(schema.GetType(), ActionType::Plugin);
+  ActionSchema schema;
+  schema.SetActionId("new_id");
+  schema.SetAppId("new_package");
+  schema.SetCategory("new_category");
+  schema.SetDescription("new_desc");
+  schema.SetType(ActionType::Plugin);
+
+  EXPECT_EQ(schema.GetActionId(), "new_id");
+  EXPECT_EQ(schema.GetAppId(), "new_package");
+  EXPECT_EQ(schema.GetCategory(), "new_category");
+  EXPECT_EQ(schema.GetDescription(), "new_desc");
+  EXPECT_EQ(schema.GetType(), ActionType::Plugin);
 }
 
 TEST_F(ActionSchemaTest, ParameterTypeConversion) {
-    ActionSchema schema(valid_json_);
-    const auto& params = schema.GetParameters();
-    EXPECT_EQ(params[0].GetType(), ParameterType::IntType);
-    EXPECT_EQ(params[1].GetType(), ParameterType::StringType);
+  ActionSchema schema(valid_appcontrol_action_json_);
+  const auto& params = schema.GetParameters();
+  EXPECT_EQ(params[0].GetType(), ParameterType::IntType);
+  EXPECT_EQ(params[1].GetType(), ParameterType::StringType);
 
-    const auto& returns = schema.GetReturns();
-    EXPECT_EQ(returns[0].GetType(), ParameterType::DoubleType);
+  const auto& returns = schema.GetReturns();
+  EXPECT_EQ(returns[0].GetType(), ParameterType::NumberType);
 }
 
 TEST_F(ActionSchemaTest, DefaultConstructor) {
-    ActionSchema default_schema;
-    EXPECT_TRUE(default_schema.GetActionId().empty());
-    EXPECT_TRUE(default_schema.GetAppId().empty());
-    EXPECT_TRUE(default_schema.GetCategory().empty());
-    EXPECT_TRUE(default_schema.GetDescription().empty());
-    EXPECT_EQ(default_schema.GetType(), ActionType::InvalidType);
-    EXPECT_TRUE(default_schema.GetParameters().empty());
-    EXPECT_TRUE(default_schema.GetReturns().empty());
-    EXPECT_TRUE(default_schema.GetPrivileges().empty());
+  ActionSchema default_schema;
+  EXPECT_TRUE(default_schema.GetActionId().empty());
+  EXPECT_TRUE(default_schema.GetAppId().empty());
+  EXPECT_TRUE(default_schema.GetCategory().empty());
+  EXPECT_TRUE(default_schema.GetDescription().empty());
+  EXPECT_EQ(default_schema.GetType(), ActionType::InvalidType);
+  EXPECT_TRUE(default_schema.GetParameters().empty());
+  EXPECT_TRUE(default_schema.GetReturns().empty());
+  EXPECT_TRUE(default_schema.GetPrivileges().empty());
 }