Skip to content
Merged
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
21 changes: 21 additions & 0 deletions lib/tesla/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@ defmodule Tesla.Client do
unruntime(client.pre)
end

@doc ~S"""
Returns a new client by applying a function to the existing middleware list,
preserving the original adapter.

## Examples

iex> middleware = [{Tesla.Middleware.BaseUrl, "https://api.github.com"}]
iex> client = Tesla.client(middleware)
iex> new_client = Tesla.Client.update_middleware(client, &([Tesla.Middleware.JSON] ++ &1))
iex> Tesla.Client.middleware(new_client)
[Tesla.Middleware.JSON, {Tesla.Middleware.BaseUrl, "https://api.github.com"}]
"""
@spec update_middleware(t(), ([middleware] -> [middleware])) :: t()
def update_middleware(client, fun) do
client
|> middleware()
|> fun.()
|> Tesla.client()
|> Map.put(:adapter, client.adapter)
end

defp unruntime(list) when is_list(list), do: Enum.map(list, &unruntime/1)
defp unruntime({module, :call, [[]]}) when is_atom(module), do: module
defp unruntime({module, :call, [opts]}) when is_atom(module), do: {module, opts}
Expand Down
74 changes: 69 additions & 5 deletions test/tesla/client_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ defmodule Tesla.ClientTest do
use ExUnit.Case
doctest Tesla.Client

alias Tesla.Client

describe "Tesla.Client.adapter/1" do
test "converts atom adapter properly" do
adapter = Tesla.Adapter.Httpc

client = Tesla.client([], adapter)

assert adapter == Tesla.Client.adapter(client)
assert adapter == Client.adapter(client)
end

test "converts tuple adapter properly" do
adapter = {Tesla.Adapter.Hackney, [recv_timeout: 30_000]}

client = Tesla.client([], adapter)

assert adapter == Tesla.Client.adapter(client)
assert adapter == Client.adapter(client)
end

test "converts function adapter properly" do
Expand All @@ -26,14 +28,76 @@ defmodule Tesla.ClientTest do

client = Tesla.client([], adapter)

assert adapter == Tesla.Client.adapter(client)
assert adapter == Client.adapter(client)
end
end

test "converts nil adapter properly" do
client = Tesla.client([])

assert Tesla.Client.adapter(client) == nil
assert Client.adapter(client) == nil
end

describe "update_middleware/2" do
test "prepends middleware" do
client = Tesla.client([FirstMiddleware])

new_client = Client.update_middleware(client, &([SecondMiddleware] ++ &1))

assert Client.middleware(new_client) == [SecondMiddleware, FirstMiddleware]
end

test "appends middleware" do
client = Tesla.client([FirstMiddleware])

new_client = Client.update_middleware(client, &(&1 ++ [SecondMiddleware]))

assert Client.middleware(new_client) == [FirstMiddleware, SecondMiddleware]
end

test "filters middleware" do
client = Tesla.client([FirstMiddleware, SecondMiddleware])

new_client =
Client.update_middleware(client, &Enum.reject(&1, fn m -> m == FirstMiddleware end))

assert Client.middleware(new_client) == [SecondMiddleware]
end

test "preserves atom adapter" do
adapter = Tesla.Adapter.Httpc
client = Tesla.client([FirstMiddleware], adapter)

new_client = Client.update_middleware(client, &(&1 ++ [SecondMiddleware]))

assert Client.adapter(new_client) == adapter
end

test "preserves tuple adapter" do
adapter = {Tesla.Adapter.Hackney, [recv_timeout: 30_000]}
client = Tesla.client([FirstMiddleware], adapter)

new_client = Client.update_middleware(client, &(&1 ++ [SecondMiddleware]))

assert Client.adapter(new_client) == adapter
end

test "preserves function adapter" do
adapter = fn env -> {:ok, env} end
client = Tesla.client([FirstMiddleware], adapter)

new_client = Client.update_middleware(client, &(&1 ++ [SecondMiddleware]))

assert Client.adapter(new_client) == adapter
end

test "preserves nil adapter" do
client = Tesla.client([FirstMiddleware])

new_client = Client.update_middleware(client, &(&1 ++ [SecondMiddleware]))

assert Client.adapter(new_client) == nil
end
end

describe "Tesla.Client.middleware/1" do
Expand All @@ -46,7 +110,7 @@ defmodule Tesla.ClientTest do

client = Tesla.client(middlewares)

assert middlewares == Tesla.Client.middleware(client)
assert middlewares == Client.middleware(client)
end
end
end
Loading