deep merge in config update
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Mon, 6 Jan 2020 11:05:32 +0000 (14:05 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Fri, 10 Jan 2020 12:52:02 +0000 (15:52 +0300)
lib/pleroma/web/admin_api/config.ex
test/web/admin_api/admin_api_controller_test.exs
test/web/admin_api/config_test.exs

index b55851602a05609d946a6418b8db59e5532615e5..a01c28716ec4ea629d4e8fa20739be8ca971ffbb 100644 (file)
@@ -81,7 +81,7 @@ defmodule Pleroma.Web.AdminAPI.Config do
          old_value <- from_binary(config.value),
          transformed_value <- do_transform(params[:value]),
          {:can_be_merged, true, config} <- {:can_be_merged, is_list(transformed_value), config},
-         new_value <- Keyword.merge(old_value, transformed_value) do
+         new_value <- DeepMerge.deep_merge(old_value, transformed_value) do
       Config.update(config, %{value: new_value, transformed?: true})
     else
       {reason, false, config} when reason in [:partial_update, :can_be_merged] ->
index 55a4055a7b1cdc8c58abd668e0eee899940bd68c..ebd9054e3390b6e753295a7c851d56dc6f75ff08 100644 (file)
@@ -2204,6 +2204,56 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
              }
     end
 
+    test "saving config with nested merge", %{conn: conn} do
+      config =
+        insert(:config, key: ":key1", value: :erlang.term_to_binary(key1: 1, key2: [k1: 1, k2: 2]))
+
+      conn =
+        post(conn, "/api/pleroma/admin/config", %{
+          configs: [
+            %{
+              group: config.group,
+              key: config.key,
+              value: [
+                %{"tuple" => [":key3", 3]},
+                %{
+                  "tuple" => [
+                    ":key2",
+                    [
+                      %{"tuple" => [":k2", 1]},
+                      %{"tuple" => [":k3", 3]}
+                    ]
+                  ]
+                }
+              ]
+            }
+          ]
+        })
+
+      assert json_response(conn, 200) == %{
+               "configs" => [
+                 %{
+                   "group" => ":pleroma",
+                   "key" => ":key1",
+                   "value" => [
+                     %{"tuple" => [":key1", 1]},
+                     %{"tuple" => [":key3", 3]},
+                     %{
+                       "tuple" => [
+                         ":key2",
+                         [
+                           %{"tuple" => [":k1", 1]},
+                           %{"tuple" => [":k2", 1]},
+                           %{"tuple" => [":k3", 3]}
+                         ]
+                       ]
+                     }
+                   ]
+                 }
+               ]
+             }
+    end
+
     test "saving special atoms", %{conn: conn} do
       conn =
         post(conn, "/api/pleroma/admin/config", %{
index cc4c903bf4311c8f297c5586280e97db8b5b23df..2c0601b568454acad921c320f0eba276fe1b592b 100644 (file)
@@ -68,6 +68,26 @@ defmodule Pleroma.Web.AdminAPI.ConfigTest do
       assert value[:key3] == :val3
     end
 
+    test "deep merge" do
+      config = insert(:config, value: Config.to_binary(key1: "val1", key2: [k1: :v1, k2: "v2"]))
+
+      {:ok, config} =
+        Config.update_or_create(%{
+          group: config.group,
+          key: config.key,
+          value: [key1: :val1, key2: [k2: :v2, k3: :v3], key3: :val3]
+        })
+
+      updated = Config.get_by_params(%{group: config.group, key: config.key})
+
+      assert config.value == updated.value
+
+      value = Config.from_binary(updated.value)
+      assert value[:key1] == :val1
+      assert value[:key2] == [k1: :v1, k2: :v2, k3: :v3]
+      assert value[:key3] == :val3
+    end
+
     test "only full update for some keys" do
       config1 = insert(:config, key: ":ecto_repos", value: Config.to_binary(repo: Pleroma.Repo))
       config2 = insert(:config, group: ":cors_plug", key: ":max_age", value: Config.to_binary(18))