Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions lib/ex_force.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ defmodule ExForce do
end
```

Configure default settings for the Tesla client (currently the only
client supported) in config/config.exs (optional).

```elixir
# config/config.exs

config :ex_force, ExForce.Client.Tesla,
api_version: "43.0",
adapter: {Tesla.Adapter.Hackney, [recv_timeout: 1_000]},
append_middleware: [
Tesla.Middleware.Telemetry,
{Tesla.Middleware.Timeout, timeout: :timer.seconds(1)}
]
```

Check out [Choosing a Tesla Adapter](https://github.com/chulkilee/ex_force/wiki/Choosing-a-Tesla-Adapter).

## Usage
Expand Down
39 changes: 27 additions & 12 deletions lib/ex_force/client/tesla/tesla.ex
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,23 @@ defmodule ExForce.Client.Tesla do
end

def build_client(instance_url, opts) when is_binary(instance_url) do
Tesla.client(
adapter = get_from_opts_or_config(opts, :adapter)
headers = get_headers(opts)

middleware =
[
{ExForce.Client.Tesla.Middleware,
{instance_url, Keyword.get(opts, :api_version, @default_api_version)}},
{instance_url, get_from_opts_or_config(opts, :api_version, @default_api_version)}},
{Tesla.Middleware.Compression, format: "gzip"},
{Tesla.Middleware.JSON, engine: Jason},
{Tesla.Middleware.Headers, get_headers(opts)}
],
Keyword.get(opts, :adapter)
)
{Tesla.Middleware.Headers, headers}
] ++ get_from_opts_or_config(opts, :append_middleware, [])

Tesla.client(middleware, adapter)
end

defp get_headers(opts), do: Keyword.get(opts, :headers, [{"user-agent", @default_user_agent}])
defp get_headers(opts),
do: get_from_opts_or_config(opts, :headers, [{"user-agent", @default_user_agent}])

@doc """
Returns a `Tesla` client for `ExForce.OAuth` functions
Expand All @@ -65,16 +69,18 @@ defmodule ExForce.Client.Tesla do
"""
@impl ExForce.Client
def build_oauth_client(instance_url, opts \\ []) do
Tesla.client(
adapter = get_from_opts_or_config(opts, :adapter)

middleware =
[
{Tesla.Middleware.DecodeJson, engine: Jason},
{Tesla.Middleware.BaseUrl, instance_url},
{Tesla.Middleware.Compression, format: "gzip"},
Tesla.Middleware.FormUrlencoded,
{Tesla.Middleware.DecodeJson, engine: Jason},
{Tesla.Middleware.Headers, get_headers(opts)}
],
Keyword.get(opts, :adapter)
)
] ++ get_from_opts_or_config(opts, :append_middleware, [])

Tesla.client(middleware, adapter)
end

@doc """
Expand All @@ -87,6 +93,15 @@ defmodule ExForce.Client.Tesla do
|> cast_response()
end

defp get_from_opts_or_config(opts, key, default \\ nil) do
from_opts = Keyword.get(opts, key)

app_config = Application.get_env(:ex_force, __MODULE__, [])
from_app_config = Keyword.get(app_config, key)

from_opts || from_app_config || default
end

defp cast_tesla_request(%Request{} = request) do
request
|> convert_struct(Tesla.Env)
Expand Down
59 changes: 59 additions & 0 deletions test/config_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
defmodule ExForce.ConfigTest do
# Must be set to async: false since this is manipulating global application config
use ExUnit.Case, async: false

alias ExForce.{
Client,
Request
}

alias Plug.Conn

test "build_client/2 - custom config" do
bypass = Bypass.open()
bypass_url = "http://127.0.0.1:#{bypass.port}"

api_version = "456.0"

custom_middleware = [
Tesla.Middleware.Telemetry,
{Tesla.Middleware.Timeout, timeout: :timer.seconds(1)}
]

custom_middleware_representation = [
{Tesla.Middleware.Telemetry, :call, [[]]},
{Tesla.Middleware.Timeout, :call, [[timeout: 1000]]}
]

Application.put_env(:ex_force, ExForce.Client.Tesla,
api_version: api_version,
append_middleware: custom_middleware
)

on_exit(fn -> Application.delete_env(:ex_force, ExForce.Client.Tesla) end)

Bypass.expect_once(bypass, "GET", "/foo", fn conn ->
conn
|> Conn.put_resp_content_type("application/json")
|> Conn.resp(200, ~w({"hello": "world"}))
end)

client = ExForce.build_client(bypass_url)

assert %Tesla.Client{
adapter: nil,
fun: nil,
post: [],
pre:
[
{ExForce.Client.Tesla.Middleware, :call, [{^bypass_url, ^api_version}]},
{Tesla.Middleware.Compression, :call, [[format: "gzip"]]},
{Tesla.Middleware.JSON, :call, [[engine: Jason]]},
{Tesla.Middleware.Headers, :call, [[{"user-agent", "ex_force"}]]}
] ++ ^custom_middleware_representation
} = client

assert {:ok, %{status: 200, body: %{"hello" => "world"}}} =
Client.request(client, %Request{url: "/foo", method: :get})
end
end
2 changes: 1 addition & 1 deletion test/ex_force/oauth_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,10 @@ defmodule ExForce.OAuthTest do
fun: nil,
post: [],
pre: [
{Tesla.Middleware.DecodeJson, :call, [[engine: Jason]]},
{Tesla.Middleware.BaseUrl, :call, ["http://257.0.0.0:0"]},
{Tesla.Middleware.Compression, :call, [[format: "gzip"]]},
{Tesla.Middleware.FormUrlencoded, :call, [[]]},
{Tesla.Middleware.DecodeJson, :call, [[engine: Jason]]},
{Tesla.Middleware.Headers, :call, [[{"user-agent", "agent"}]]}
]
}
Expand Down