Unify Config.get behaviour for atom/list key param
authorRoman Chvanikov <chvanikoff@pm.me>
Tue, 4 Aug 2020 11:35:47 +0000 (14:35 +0300)
committerRoman Chvanikov <chvanikoff@pm.me>
Tue, 4 Aug 2020 11:35:47 +0000 (14:35 +0300)
lib/pleroma/config.ex
test/config_test.exs
test/support/helpers.ex

index cc80deff5f16597c2c10b46cee74b038d97f9115..88d1972ba1bfa28c74e858c57fdc1aca3ab257f8 100644 (file)
@@ -11,13 +11,33 @@ defmodule Pleroma.Config do
 
   def get([key], default), do: get(key, default)
 
-  def get([parent_key | keys], default) do
-    case :pleroma
-         |> Application.get_env(parent_key)
-         |> get_in(keys) do
-      nil -> default
-      any -> any
-    end
+  def get([root_key | keys], default) do
+    # This is to mimic Application.get_env/3 behaviour that returns `nil` if the
+    # actual value is `nil`.
+    Enum.reduce_while(keys, Application.get_env(:pleroma, root_key), fn key, config ->
+      case key do
+        [last_key] when is_map(config) ->
+          {:halt, Map.get(config, last_key, default)}
+
+        [last_key] when is_list(config) ->
+          {:halt, Keyword.get(config, last_key, default)}
+
+        _ ->
+          case config do
+            %{^key => value} ->
+              {:cont, value}
+
+            [_ | _] ->
+              case :lists.keyfind(key, 1, config) do
+                {_, value} -> {:cont, value}
+                _ -> {:halt, default}
+              end
+
+            _ ->
+              {:halt, default}
+          end
+      end
+    end)
   end
 
   def get(key, default) do
index a46ab43023b14443a802870ad6773a2fe5d4a700..3f3da06d00d00053ace197374c61cc29c5aa0f5e 100644 (file)
@@ -28,6 +28,34 @@ defmodule Pleroma.ConfigTest do
     assert Pleroma.Config.get([:azerty, :uiop], true) == true
   end
 
+  describe "nil values" do
+    setup do
+      Pleroma.Config.put(:lorem, nil)
+      Pleroma.Config.put(:ipsum, %{dolor: [sit: nil]})
+      Pleroma.Config.put(:dolor, sit: %{amet: nil})
+
+      on_exit(fn -> Enum.each(~w(lorem ipsum dolor)a, &Pleroma.Config.delete/1) end)
+    end
+
+    test "get/1 with an atom for nil value" do
+      assert Pleroma.Config.get(:lorem) == nil
+    end
+
+    test "get/2 with an atom for nil value" do
+      assert Pleroma.Config.get(:lorem, true) == nil
+    end
+
+    test "get/1 with a list of keys for nil value" do
+      assert Pleroma.Config.get([:ipsum, :dolor, :sit]) == nil
+      assert Pleroma.Config.get([:dolor, :sit, :amet]) == nil
+    end
+
+    test "get/2 with a list of keys for nil value" do
+      assert Pleroma.Config.get([:ipsum, :dolor, :sit], true) == nil
+      assert Pleroma.Config.get([:dolor, :sit, :amet], true) == nil
+    end
+  end
+
   test "get/1 when value is false" do
     Pleroma.Config.put([:instance, :false_test], false)
     Pleroma.Config.put([:instance, :nested], [])
index 5cbf2e29197c14de391dcef39aea3126ef3401d3..7d729541dc3432ec27dc83e8448050cd508a2c74 100644 (file)
@@ -17,9 +17,19 @@ defmodule Pleroma.Tests.Helpers do
 
   defmacro clear_config(config_path, do: yield) do
     quote do
-      initial_setting = Config.get(unquote(config_path))
+      initial_setting = Config.get(unquote(config_path), :__clear_config_absent__)
       unquote(yield)
-      on_exit(fn -> Config.put(unquote(config_path), initial_setting) end)
+
+      on_exit(fn ->
+        case initial_setting do
+          :__clear_config_absent__ ->
+            Config.delete(unquote(config_path))
+
+          _ ->
+            Config.put(unquote(config_path), initial_setting)
+        end
+      end)
+
       :ok
     end
   end