Skip to content

Commit

Permalink
Use system environment when {:system, ...} is set
Browse files Browse the repository at this point in the history
  • Loading branch information
lnikkila committed Mar 7, 2017
1 parent 2929c2b commit b22060e
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 20 deletions.
42 changes: 30 additions & 12 deletions lib/exquickbooks.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,12 @@ defmodule ExQuickBooks do
"""
def backend do
case get_env(@backend_config) do
backend when is_atom(backend) -> backend
nil -> raise_missing(@backend_config)
_ -> raise_invalid(@backend_config)
backend when is_atom(backend) ->
backend
nil ->
raise_missing(@backend_config)
other ->
raise_invalid(@backend_config, other)
end
end

Expand All @@ -42,9 +45,12 @@ defmodule ExQuickBooks do
"""
def callback_url do
case get_env(@callback_config) do
url when is_binary(url) -> url
nil -> raise_missing(@callback_config)
_ -> raise_invalid(@callback_config)
url when is_binary(url) ->
url
nil ->
raise_missing(@callback_config)
other ->
raise_invalid(@callback_config, other)
end
end

Expand All @@ -54,22 +60,34 @@ defmodule ExQuickBooks do
def credentials do
for k <- @credential_config do
case get_env(k) do
v when is_binary(v) -> {k, v}
nil -> raise_missing(k)
_ -> raise_invalid(k)
v when is_binary(v) ->
{k, v}
nil ->
raise_missing(k)
v ->
raise_invalid(k, v)
end
end
end

# Returns a value from the application's environment. If the value matches
# the {:system, ...} syntax, a system environment variable will be retrieved
# instead and parsed.
defp get_env(key, default \\ nil) do
Application.get_env(:exquickbooks, key, default)
with {:system, var} <- Application.get_env(:exquickbooks, key, default) do
case System.get_env(var) do
"true" -> true
"false" -> false
value -> value
end
end
end

defp raise_missing(key) do
raise "ExQuickBooks configuration value '#{key}' is required."
end

defp raise_invalid(key) do
raise "ExQuickBooks configuration value '#{key}' is invalid."
defp raise_invalid(key, value) do
raise "ExQuickBooks configuration value '#{key}' is invalid, got: #{value}"
end
end
51 changes: 43 additions & 8 deletions test/exquickbooks_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ defmodule ExQuickBooksTest do

setup do
old_env = get_all_env()
old_system_env = System.get_env

on_exit fn ->
restore_env(old_env)
restore_system_env(old_system_env)
end
end

Expand All @@ -16,14 +18,14 @@ defmodule ExQuickBooksTest do
end

test "accounting_api/0 returns the sandbox URL by default" do
delete_env(:use_production_api)
delete_env :use_production_api

assert ExQuickBooks.accounting_api |> String.starts_with?("https")
assert ExQuickBooks.accounting_api |> String.contains?("sandbox")
end

test "accounting_api/0 returns the production URL in production" do
put_env(:use_production_api, true)
put_env :use_production_api, true

assert ExQuickBooks.accounting_api |> String.starts_with?("https")
refute ExQuickBooks.accounting_api |> String.contains?("sandbox")
Expand All @@ -35,8 +37,8 @@ defmodule ExQuickBooksTest do
end

test "credentials/0 returns the right credentials" do
put_env(:consumer_key, "key")
put_env(:consumer_secret, "secret")
put_env :consumer_key, "key"
put_env :consumer_secret, "secret"

assert ExQuickBooks.credentials == [
consumer_key: "key",
Expand All @@ -45,19 +47,39 @@ defmodule ExQuickBooksTest do
end

test "credentials/0 raises for missing credentials" do
delete_env(:consumer_key)
delete_env(:consumer_secret)
delete_env :consumer_key
delete_env :consumer_secret

assert_raise RuntimeError, &ExQuickBooks.credentials/0
end

test "credentials/0 raises for invalid credentials" do
put_env(:consumer_key, 42)
put_env(:consumer_secret, 42)
put_env :consumer_key, 42
put_env :consumer_secret, 42

assert_raise RuntimeError, &ExQuickBooks.credentials/0
end

test "{:system, ...} syntax is supported" do
System.put_env %{
"EXQUICKBOOKS_KEY" => "system_key",
"EXQUICKBOOKS_SECRET" => "system_secret",
"EXQUICKBOOKS_USE_PRODUCTION_API" => "true"
}

put_env :consumer_key, {:system, "EXQUICKBOOKS_KEY"}
put_env :consumer_secret, {:system, "EXQUICKBOOKS_SECRET"}
put_env :use_production_api, {:system, "EXQUICKBOOKS_USE_PRODUCTION_API"}

assert ExQuickBooks.credentials == [
consumer_key: "system_key",
consumer_secret: "system_secret"
]

# Production config flag should be parsed as a boolean
refute ExQuickBooks.accounting_api |> String.contains?("sandbox")
end

defp get_all_env do
Application.get_all_env(:exquickbooks)
end
Expand All @@ -82,4 +104,17 @@ defmodule ExQuickBooksTest do
`async: false`.
"""
end

defp restore_system_env(old_env) do
new_env = System.get_env

for {k, _} <- new_env, do: System.delete_env(k)
for {k, v} <- old_env, do: System.put_env(k, v)

System.get_env == old_env || raise """
Could not restore the system's environment. Check that you're not modifying
it simultaneously in other tests. Those tests should specify
`async: false`.
"""
end
end

0 comments on commit b22060e

Please sign in to comment.