defmodule ExGram.Adapter.Test do
@moduledoc """
HTTP Adapter for testing, it allows you to setup request responses and errors
"""
@behaviour ExGram.Adapter
@name __MODULE__
defstruct calls: [], responses: %{}, errors: %{}
def start_link(opts) do
opts = Keyword.put_new(opts, :name, @name)
GenServer.start_link(__MODULE__, :ok, opts)
end
def init(:ok) do
{:ok, %__MODULE__{}}
end
@impl ExGram.Adapter
def request(verb, path, body, name \\ @name) do
GenServer.call(name, {:request, verb, path, body})
end
def backdoor_request(path, response, name \\ @name) do
GenServer.call(name, {:backdoor, path, response})
end
def backdoor_error(path, error, name \\ @name) do
GenServer.call(name, {:backdoor_error, path, error})
end
def clean(name \\ @name) do
GenServer.call(name, {:clean})
end
def handle_call({:request, verb, path, body}, _, state) do
state = add_call(state, {verb, path, body})
reply = get_response(state, path)
{:reply, reply, state}
end
def handle_call({:backdoor, path, response}, _, %{responses: responses} = state) do
path = clean_path(path)
responses = Map.put(responses, path, response)
{:reply, :ok, %{state | responses: responses}}
end
def handle_call({:backdoor_error, path, error}, _, %{errors: errors} = state) do
path = clean_path(path)
errors = Map.put(errors, path, error)
{:reply, :ok, %{state | errors: errors}}
end
def handle_call({:clean}, _, _) do
{:reply, :ok, %__MODULE__{}}
end
defp add_call(%{calls: calls} = state, data), do: %{state | calls: calls ++ [data]}
defp get_response(%{responses: responses, errors: errors}, path) do
path = clean_path(path)
with {:error, :error} <- {:error, Map.fetch(errors, path)},
{:ok, value} <- Map.fetch(responses, path) do
{:ok, value}
else
{:error, {:ok, value}} -> {:error, value}
_ -> {:error, %ExGram.Error{code: 404}}
end
end
defp clean_path("/bot" <> _ = path),
do: "/" <> (path |> String.split("/") |> Enum.drop(2) |> Enum.join("/"))
defp clean_path(path), do: path
end