From 88a16bb9fcd1f80b8a2634e815cb855d3a8346ee Mon Sep 17 00:00:00 2001 From: Alexander Strizhakov Date: Mon, 6 Jan 2020 14:05:32 +0300 Subject: [PATCH] deep merge in config update --- lib/pleroma/web/admin_api/config.ex | 2 +- .../admin_api/admin_api_controller_test.exs | 50 +++++++++++++++++++ test/web/admin_api/config_test.exs | 20 ++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/web/admin_api/config.ex b/lib/pleroma/web/admin_api/config.ex index b55851602..a01c28716 100644 --- a/lib/pleroma/web/admin_api/config.ex +++ b/lib/pleroma/web/admin_api/config.ex @@ -81,7 +81,7 @@ def update_or_create(params) 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] -> diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 55a4055a7..ebd9054e3 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -2204,6 +2204,56 @@ test "saving config with partial update", %{conn: conn} 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", %{ diff --git a/test/web/admin_api/config_test.exs b/test/web/admin_api/config_test.exs index cc4c903bf..2c0601b56 100644 --- a/test/web/admin_api/config_test.exs +++ b/test/web/admin_api/config_test.exs @@ -68,6 +68,26 @@ test "partial update" 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))