Improve unit tests coverage 41/246041/3
authorDaehyeon Jung <darrenh.jung@samsung.com>
Thu, 22 Oct 2020 11:33:14 +0000 (20:33 +0900)
committerDaehyeon Jung <darrenh.jung@samsung.com>
Fri, 23 Oct 2020 01:48:08 +0000 (10:48 +0900)
Change-Id: I4066513080098cd8a6cd8fb488d5256e97f0e787

lib/include/shortcut_private.h
lib/src/shortcut_db.c
lib/src/shortcut_internal.c
lib/src/shortcut_manager.c
tests/mock/gio_mock.cc
tests/mock/gio_mock.h
tests/unit_tests/src/test_shortcut_db.cc [new file with mode: 0644]
tests/unit_tests/src/test_shortcut_internal.cc [new file with mode: 0644]
tests/unit_tests/src/test_shortcut_manager.cc

index 3a62cff..69a0ff1 100644 (file)
@@ -42,6 +42,8 @@ extern FILE *__file_log_fp;
 extern "C" {
 #endif /* __cplusplus */
 
+int shortcut_set_db_path(const char *db_path);
+
 #define SHORTCUT_FEATURE "http://tizen.org/feature/shortcut"
 #define CHECK_SHORTCUT_FEATURE() \
        do { \
index 3d7649a..ea1cc3c 100644 (file)
 
 static bool is_db_corrupted = false;
 
+static const char* _db_path = DB_PATH;
+
+int shortcut_set_db_path(const char *db_path)
+{
+       _db_path = db_path;
+       return 0;
+}
+
 /* LCOV_EXCL_START */
 static int __check_integrity_cb(void *pid, int argc, char **argv, char **notUsed)
 {
@@ -72,14 +80,14 @@ static int __recover_corrupted_db(sqlite3 *db)
        SHORTCUT_INFO("DB is corrupted, start to recover corrupted db");
        if (db)
                sqlite3_close(db);
-       unlink(DB_PATH);
+       unlink(_db_path);
 
-       sql_ret = sqlite3_open_v2(DB_PATH, &db,
+       sql_ret = sqlite3_open_v2(_db_path, &db,
                                SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE,
                                NULL);
        if (sql_ret != SQLITE_OK) {
                SHORTCUT_ERR("Failed to open db[%d]", sql_ret);
-               unlink(DB_PATH);
+               unlink(_db_path);
                ret = SHORTCUT_ERROR_IO_ERROR;
                goto out;
        }
@@ -106,7 +114,7 @@ EAPI int shortcut_db_init(void)
        sqlite3 *db = NULL;
        char *errmsg = NULL;
 
-       sql_ret = sqlite3_open_v2(DB_PATH, &db,
+       sql_ret = sqlite3_open_v2(_db_path, &db,
                        SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
        if (sql_ret != SQLITE_OK) {
                SHORTCUT_ERR("Failed to open db[%d]", sql_ret);
@@ -144,7 +152,7 @@ out:
 static sqlite3 *_open_db(void)
 {
        int ret;
-       const char *dbfile = DB_PATH;
+       const char *dbfile = _db_path;
        sqlite3 *db = NULL;
 
        ret = db_util_open(dbfile, &db, 0);
index ecb2328..cc2ab65 100644 (file)
@@ -688,7 +688,7 @@ EAPI int shortcut_add_to_home_widget_sync(const char *name,
        }
 
        body = g_variant_new("(sississdi)", request_id, getpid(), widget_id,
-                       name, size, NULL, icon, period, allow_duplicate);
+                       name, size, "", icon, period, allow_duplicate);
 
        ret = _send_sync_shortcut(body, &reply, "add_shortcut_widget");
        if (ret == SHORTCUT_ERROR_NONE) {
index dae74af..1ceb7d4 100644 (file)
@@ -251,7 +251,7 @@ EAPI int shortcut_add_to_home_widget(const char *name, shortcut_widget_size_e si
        item->data = data;
 
        body = g_variant_new("(sississdi)", request_id, getpid(), widget_id,
-                       name, size, NULL, icon, period, allow_duplicate);
+                       name, size, "", icon, period, allow_duplicate);
 
        ret = _send_async_shortcut(body, item, "add_shortcut_widget");
 
index 5d8ed01..4583f50 100644 (file)
@@ -92,3 +92,11 @@ extern "C" void g_dbus_connection_signal_unsubscribe(
   return MOCK_HOOK_P2(GioMock, g_dbus_connection_signal_unsubscribe,
       arg0, arg1);
 }
+
+extern "C" void g_dbus_error_register_error_domain(const gchar* arg0,
+                                    volatile gsize* arg1,
+                                    const GDBusErrorEntry* arg2,
+                                    guint arg3) {
+  return MOCK_HOOK_P4(GioMock, g_dbus_error_register_error_domain,
+      arg0, arg1, arg2, arg3);
+}
index c4bfa32..9898fba 100644 (file)
@@ -53,6 +53,8 @@ class GioMock : public virtual ModuleMock {
   MOCK_METHOD1(g_bus_unwatch_name, void(guint));
   MOCK_METHOD2(g_dbus_connection_signal_unsubscribe,
           void(GDBusConnection*, guint));
+  MOCK_METHOD4(g_dbus_error_register_error_domain,
+      void(const gchar*, volatile gsize*, const GDBusErrorEntry*, guint));
 };
 
 #endif  // MOCK_GIO_MOCK_H_
diff --git a/tests/unit_tests/src/test_shortcut_db.cc b/tests/unit_tests/src/test_shortcut_db.cc
new file mode 100644 (file)
index 0000000..58656c9
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <shortcut_db.h>
+#include <shortcut_private.h>
+#include <gtest/gtest.h>
+
+#include "system_info_mock.h"
+#include "gio_mock.h"
+#include "test_fixture.h"
+
+class Mocks : public ::testing::NiceMock<SystemInfoMock>,
+              public ::testing::NiceMock<GioMock> {};
+
+class ShortcutDbTest : public TestFixture {
+ public:
+  ShortcutDbTest() : TestFixture(std::make_unique<Mocks>()) {}
+  virtual ~ShortcutDbTest() {}
+  virtual void SetUp() {}
+  virtual void TearDown() {}
+};
+
+TEST_F(ShortcutDbTest, Init) {
+    int r = shortcut_db_init();
+    EXPECT_EQ(SHORTCUT_ERROR_IO_ERROR, r);
+
+    GList* list = nullptr;
+    r = shortcut_db_get_list("not_working", &list);
+    EXPECT_EQ(SHORTCUT_ERROR_IO_ERROR, r);
+
+    r = shortcut_set_db_path("./db.db");
+    EXPECT_EQ(SHORTCUT_ERROR_NONE, r);
+
+    r = shortcut_db_init();
+    EXPECT_EQ(SHORTCUT_ERROR_NONE, r);
+
+    r = shortcut_db_get_list("working", &list);
+    EXPECT_EQ(SHORTCUT_ERROR_NONE, r);
+    EXPECT_EQ(nullptr, list);
+}
diff --git a/tests/unit_tests/src/test_shortcut_internal.cc b/tests/unit_tests/src/test_shortcut_internal.cc
new file mode 100644 (file)
index 0000000..a42e106
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <shortcut_internal.h>
+#include <shortcut_private.h>
+#include <gtest/gtest.h>
+
+#include "system_info_mock.h"
+#include "gio_mock.h"
+#include "test_fixture.h"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::SaveArg;
+
+class Mocks : public ::testing::NiceMock<SystemInfoMock>,
+              public ::testing::NiceMock<GioMock> {};
+
+class ShortcutInternalTest : public TestFixture {
+ public:
+  ShortcutInternalTest() : TestFixture(std::make_unique<Mocks>()) {}
+  virtual ~ShortcutInternalTest() {}
+  virtual void SetUp() {}
+  virtual void TearDown() {}
+};
+
+TEST_F(ShortcutInternalTest, shortcut_add_to_home_sync) {
+  int ret;
+  bool is_supported = true;
+  GDBusConnection* _conn = (GDBusConnection*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg3 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg4 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GVariant* reply_body;
+
+  EXPECT_CALL(GetMock<SystemInfoMock>(),
+      system_info_get_platform_bool(_, _)).
+      WillOnce(DoAll(SetArgPointee<1>(is_supported),
+                            Return(0)));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_bus_get_sync(_, _, _)).
+      WillOnce(Return(_conn));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_new_method_call(_, _, _, _)).
+      WillOnce(Return(_msg)).
+      WillOnce(Return(_msg2));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_connection_send_message_with_reply_sync(
+        _, _, _, _, _, _, _)).
+      WillOnce(Return(_msg3)).
+      WillOnce(Return(_msg4));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_to_gerror(_, _)).
+      WillOnce(Return(FALSE)).
+      WillOnce(Return(FALSE));
+
+  reply_body = g_variant_new("(i)", 0);
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_get_body(_)).
+      WillOnce(Return(g_variant_ref(reply_body)));
+
+  ret = shortcut_add_to_home_sync("test_name", LAUNCH_BY_URI, "test_uri", "test_icon", 0);
+
+  EXPECT_EQ(ret, SHORTCUT_ERROR_NONE);
+  g_variant_unref(reply_body);
+}
+
+TEST_F(ShortcutInternalTest, shortcut_add_to_home_widget_sync) {
+  int ret;
+  bool is_supported = true;
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg3 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg4 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GVariant* reply_body;
+
+  EXPECT_CALL(GetMock<SystemInfoMock>(),
+      system_info_get_platform_bool(_, _)).
+      WillOnce(DoAll(SetArgPointee<1>(is_supported),
+                            Return(0)));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_new_method_call(_, _, _, _)).
+      WillOnce(Return(_msg)).
+      WillOnce(Return(_msg2));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_connection_send_message_with_reply_sync(
+        _, _, _, _, _, _, _)).
+      WillOnce(Return(_msg3)).
+      WillOnce(Return(_msg4));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_to_gerror(_, _)).
+      WillOnce(Return(FALSE)).
+      WillOnce(Return(FALSE));
+
+  reply_body = g_variant_new("(i)", 0);
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_get_body(_)).
+      WillOnce(Return(g_variant_ref(reply_body)));
+
+  ret = shortcut_add_to_home_widget_sync("test_name", WIDGET_SIZE_DEFAULT, "test_id", "test_icon",
+                            0, 0);
+
+  EXPECT_EQ(ret, SHORTCUT_ERROR_NONE);
+  g_variant_unref(reply_body);
+}
+
+TEST_F(ShortcutInternalTest, shortcut_remove_from_home_sync) {
+  int ret;
+  bool is_supported = true;
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg3 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg4 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GVariant* reply_body;
+
+  EXPECT_CALL(GetMock<SystemInfoMock>(),
+      system_info_get_platform_bool(_, _)).
+      WillOnce(DoAll(SetArgPointee<1>(is_supported),
+                            Return(0)));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_new_method_call(_, _, _, _)).
+      WillOnce(Return(_msg)).
+      WillOnce(Return(_msg2));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_connection_send_message_with_reply_sync(
+        _, _, _, _, _, _, _)).
+      WillOnce(Return(_msg3)).
+      WillOnce(Return(_msg4));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_to_gerror(_, _)).
+      WillOnce(Return(FALSE)).
+      WillOnce(Return(FALSE));
+
+  reply_body = g_variant_new("(i)", 0);
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_get_body(_)).
+      WillOnce(Return(g_variant_ref(reply_body)));
+
+  ret = shortcut_remove_from_home_sync("test_name");
+
+  EXPECT_EQ(ret, SHORTCUT_ERROR_NONE);
+  g_variant_unref(reply_body);
+}
+
+TEST_F(ShortcutInternalTest, Callback) {
+  GDBusSignalCallback callback;
+  gpointer callback_data;
+
+  EXPECT_CALL(GetMock<GioMock>(),
+    g_dbus_connection_signal_subscribe(_, _, _, _, _, _, _, _, _, _)).
+    WillOnce(DoAll(SaveArg<7>(&callback), SaveArg<8>(&callback_data), Return(0)));
+
+  _dbus_signal_init();
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_new_method_call(_, _, _, "send_return_value")).
+      Times(3);
+
+  GVariant* add_var = g_variant_new("(sississi)", "request_id", 0, "appid", "name",
+      0, "uri", "icon", 0);
+  callback(nullptr, nullptr, nullptr, nullptr, "add_shortcut_notify", add_var, callback_data);
+
+  GVariant* add_widget_var = g_variant_new("(sississdi)", "request_id", 0, "widget_id",
+      "name", 0, "content", "icon", 0, 0);
+  callback(nullptr, nullptr, nullptr, nullptr, "add_shortcut_widget_notify", add_widget_var, callback_data);
+
+  GVariant* remove_var = g_variant_new("(siss)", "request_id", 0, "appid", "name");
+  callback(nullptr, nullptr, nullptr, nullptr, "remove_shortcut_notify", remove_var, callback_data);
+
+}
index 95a32f1..94f3242 100644 (file)
 #include "system_info_mock.h"
 #include "gio_mock.h"
 #include "test_fixture.h"
+#include <glib.h>
 
 using ::testing::_;
 using ::testing::DoAll;
 using ::testing::Return;
 using ::testing::SetArgPointee;
+using ::testing::SaveArg;
 
 class Mocks : public ::testing::NiceMock<SystemInfoMock>,
               public ::testing::NiceMock<GioMock> {};
@@ -48,10 +50,14 @@ class ShortcutTest : public TestFixture {
 TEST_F(ShortcutTest, shortcut_add_to_home) {
   int ret;
   bool is_supported = true;
-  GDBusConnection* _conn = (GDBusConnection*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg3 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
+  GDBusConnection* _conn = (GDBusConnection*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg3 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg4 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GVariant* reply_body;
+  GAsyncReadyCallback async_cb;
+  gpointer async_cb_data;
 
   EXPECT_CALL(GetMock<SystemInfoMock>(),
       system_info_get_platform_bool(_, _)).
@@ -59,10 +65,6 @@ TEST_F(ShortcutTest, shortcut_add_to_home) {
                             Return(0)));
 
   EXPECT_CALL(GetMock<GioMock>(),
-      g_bus_get_sync(_, _, _)).
-      WillOnce(Return(_conn));
-
-  EXPECT_CALL(GetMock<GioMock>(),
       g_dbus_message_new_method_call(_, _, _, _)).
       WillOnce(Return(_msg)).
       WillOnce(Return(_msg2));
@@ -75,24 +77,47 @@ TEST_F(ShortcutTest, shortcut_add_to_home) {
   EXPECT_CALL(GetMock<GioMock>(),
       g_dbus_connection_send_message_with_reply(
         _, _, _, _, _, _, _, _)).
-      Times(1);
+      WillOnce(DoAll(SaveArg<6>(&async_cb), SaveArg<7>(&async_cb_data)));
 
   EXPECT_CALL(GetMock<GioMock>(),
       g_dbus_message_to_gerror(_, _)).
       WillOnce(Return(FALSE));
 
   ret = shortcut_add_to_home("test_name", LAUNCH_BY_URI, "test_uri", "test_icon",
-                            0, NULL, NULL);
+                            0, nullptr, nullptr);
 
   EXPECT_EQ(ret, SHORTCUT_ERROR_NONE);
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_connection_send_message_with_reply_finish(_, _, _)).
+      WillOnce(Return(_msg4));
+
+  reply_body = g_variant_new("(i)", 0);
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_get_body(_)).
+      WillOnce(Return(g_variant_ref(reply_body)));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_to_gerror(_, _)).
+      WillOnce(Return(FALSE));
+
+  async_cb((GObject*)_conn, nullptr, async_cb_data);
+
+  g_variant_unref(reply_body);
 }
 
 TEST_F(ShortcutTest, shortcut_remove_from_home) {
   int ret;
   bool is_supported = true;
-  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg3 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
+  GDBusConnection* _conn = (GDBusConnection*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg3 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg4 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GVariant* reply_body;
+  GAsyncReadyCallback async_cb;
+  gpointer async_cb_data;
 
   EXPECT_CALL(GetMock<SystemInfoMock>(),
       system_info_get_platform_bool(_, _)).
@@ -112,7 +137,7 @@ TEST_F(ShortcutTest, shortcut_remove_from_home) {
   EXPECT_CALL(GetMock<GioMock>(),
       g_dbus_connection_send_message_with_reply(
         _, _, _, _, _, _, _, _)).
-      Times(1);
+      WillOnce(DoAll(SaveArg<6>(&async_cb), SaveArg<7>(&async_cb_data)));
 
   EXPECT_CALL(GetMock<GioMock>(),
       g_dbus_message_to_gerror(_, _)).
@@ -121,9 +146,27 @@ TEST_F(ShortcutTest, shortcut_remove_from_home) {
   ret = shortcut_remove_from_home("test_name",
           [](int ret, void* user_data) -> int {
             return 0;
-          } ,NULL);
+          } ,nullptr);
 
   EXPECT_EQ(ret, SHORTCUT_ERROR_NONE);
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_connection_send_message_with_reply_finish(_, _, _)).
+      WillOnce(Return(_msg4));
+
+  reply_body = g_variant_new("(i)", 0);
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_get_body(_)).
+      WillOnce(Return(g_variant_ref(reply_body)));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_to_gerror(_, _)).
+      WillOnce(Return(FALSE));
+
+  async_cb((GObject*)_conn, nullptr, async_cb_data);
+
+  g_variant_unref(reply_body);
 }
 
 TEST_F(ShortcutTest, shortcut_get_list) {
@@ -132,8 +175,8 @@ TEST_F(ShortcutTest, shortcut_get_list) {
   GVariantBuilder *builder;
   GVariant* body;
   GVariant* reply_body;
-  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
 
   body = g_variant_new("(sssss)",
           "test_pkg", "test_icon", "test_name", "test_extra", "");
@@ -170,7 +213,7 @@ TEST_F(ShortcutTest, shortcut_get_list) {
               const char* name, const char* extra_key,
               const char* extra_data, void* user_data) -> int {
             return 0;
-          }, NULL);
+          }, nullptr);
 
   g_variant_builder_unref(builder);
   g_variant_unref(body);
@@ -181,8 +224,8 @@ TEST_F(ShortcutTest, shortcut_get_list) {
 TEST_F(ShortcutTest, shortcut_set_request_cb) {
   int ret;
   bool is_supported = true;
-  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
 
   EXPECT_CALL(GetMock<SystemInfoMock>(),
       system_info_get_platform_bool(_, _)).
@@ -218,15 +261,15 @@ TEST_F(ShortcutTest, shortcut_set_request_cb) {
               int pid, double period, int allow_duplicate,
               void* user_data) -> int {
             return 0;
-          } ,NULL);
+          } ,nullptr);
 
   EXPECT_EQ(ret, SHORTCUT_ERROR_NONE);
 }
 
 TEST_F(ShortcutTest, shortcut_unset_request_cb) {
   bool is_supported = true;
-  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
 
   EXPECT_CALL(GetMock<SystemInfoMock>(),
       system_info_get_platform_bool(_, _)).
@@ -254,9 +297,9 @@ TEST_F(ShortcutTest, shortcut_unset_request_cb) {
 TEST_F(ShortcutTest, shortcut_set_remove_cb) {
   int ret;
   bool is_supported = true;
-  GDBusConnection* _conn = (GDBusConnection*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
+  GDBusConnection* _conn = (GDBusConnection*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
 
   EXPECT_CALL(GetMock<SystemInfoMock>(),
       system_info_get_platform_bool(_, _)).
@@ -294,15 +337,15 @@ TEST_F(ShortcutTest, shortcut_set_remove_cb) {
           [](const char* package_name, const char* name,
               int sender_pid, void* user_data) -> int {
             return 0;
-          } ,NULL);
+          } ,nullptr);
 
   EXPECT_EQ(ret, SHORTCUT_ERROR_NONE);
 }
 
 TEST_F(ShortcutTest, shortcut_unset_remove_cb) {
   bool is_supported = true;
-  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
-  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, NULL);
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
 
   EXPECT_CALL(GetMock<SystemInfoMock>(),
       system_info_get_platform_bool(_, _)).
@@ -326,3 +369,67 @@ TEST_F(ShortcutTest, shortcut_unset_remove_cb) {
 
   EXPECT_EQ(get_last_result(), SHORTCUT_ERROR_NONE);
 }
+
+TEST_F(ShortcutTest, shortcut_add_to_home_widget) {
+  int ret;
+  bool is_supported = true;
+  GDBusConnection* _conn = (GDBusConnection*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg2 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg3 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GDBusMessage* _msg4 = (GDBusMessage*)g_object_new(G_TYPE_OBJECT, nullptr);
+  GVariant* reply_body;
+  GAsyncReadyCallback async_cb;
+  gpointer async_cb_data;
+
+  EXPECT_CALL(GetMock<SystemInfoMock>(),
+      system_info_get_platform_bool(_, _)).
+      WillOnce(DoAll(SetArgPointee<1>(is_supported),
+                            Return(0)));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_bus_get_sync(_, _, _)).
+      WillOnce(Return(_conn));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_new_method_call(_, _, _, _)).
+      WillOnce(Return(_msg)).
+      WillOnce(Return(_msg2));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_connection_send_message_with_reply_sync(
+        _, _, _, _, _, _, _)).
+      WillOnce(Return(_msg3));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_connection_send_message_with_reply(
+        _, _, _, _, _, _, _, _)).
+      WillOnce(DoAll(SaveArg<6>(&async_cb), SaveArg<7>(&async_cb_data)));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_to_gerror(_, _)).
+      WillOnce(Return(FALSE));
+
+  ret = shortcut_add_to_home_widget("test_name", WIDGET_SIZE_DEFAULT, "test_id", "test_icon",
+                            0, 0, nullptr, nullptr);
+
+  EXPECT_EQ(ret, SHORTCUT_ERROR_NONE);
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_connection_send_message_with_reply_finish(_, _, _)).
+      WillOnce(Return(_msg4));
+
+  reply_body = g_variant_new("(i)", 0);
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_get_body(_)).
+      WillOnce(Return(g_variant_ref(reply_body)));
+
+  EXPECT_CALL(GetMock<GioMock>(),
+      g_dbus_message_to_gerror(_, _)).
+      WillOnce(Return(FALSE));
+
+  async_cb((GObject*)_conn, nullptr, async_cb_data);
+
+  g_variant_unref(reply_body);
+}