Skip to content

Instantly share code, notes, and snippets.

Created March 7, 2016 16:31
Show Gist options
  • Save anonymous/cb37bb65b144a7a7f6b3 to your computer and use it in GitHub Desktop.
Save anonymous/cb37bb65b144a7a7f6b3 to your computer and use it in GitHub Desktop.
Application.ensure_all_started(:hound)
ExUnit.start
Mix.Task.run "ecto.create", ~w(-r PatronLeague.Repo --quiet)
Mix.Task.run "ecto.migrate", ~w(-r PatronLeague.Repo --quiet)
Ecto.Adapters.SQL.begin_test_transaction(PatronLeague.Repo)
defmodule ApiHelper do
use ExUnit.Case, async: false
use PatronLeague.ConnCase
def test_api(method, url, opts \\ [], auth)
def test_api(method, url, [headers: headers, params: p, body_params: bp], auth) do
response = conn(method, url) |> send_request(headers, p, bp, auth)
## Check the body only if the page exists, otherwise Phoenix informs not existing entry in HTML
{response.status, (unless response.status == 404, do: (Poison.decode! response.resp_body), else: %{})}
end
def test_api(method, url, opts, auth) do
test_api method, url, [
headers: opts[:headers] || [],
params: opts[:params] || %{},
body_params: opts[:body_params] || %{}
], auth
end
def parse(conn, opts \\ []) do
opts = Keyword.put_new(opts, :parsers, [Plug.Parsers.URLENCODED, Plug.Parsers.MULTIPART])
Plug.Parsers.call(conn, Plug.Parsers.init(opts))
end
defp send_request(conn, headers, params, body_params, auth) do
conn
|> with_session
|> with_auth(auth)
|> with_headers(headers)
|> with_params(params, body_params)
#|> put_private(:plug_skip_csrf_protection, true)
|> PatronLeague.Endpoint.call([])
end
def with_auth(conn, {:none, _}), do: conn
def with_auth(conn, {level, auth}) do
conn
|> Guardian.Plug.sign_in(auth.user, :token, perms: %{default: Guardian.Permissions.available(level)})
end
def with_headers(conn, headers) do
Enum.reduce headers, conn, fn {k, v}, conn -> put_req_header(conn, k, v) end
end
def with_params(conn, params, body_params) do
parse(%{conn | body_params: body_params, params: params})
end
def with_session(conn) do
session_opts = Plug.Session.init(store: :cookie, key: "_app",
encryption_salt: "abc", signing_salt: "abc")
conn
|> Map.put(:secret_key_base, String.duplicate("abcdefgh", 8))
|> Plug.Session.call(session_opts)
|> Plug.Conn.fetch_session()
|> Plug.Conn.fetch_query_params()
end
defmacro api(method, url, opts \\ []) do
Agent.start_link(fn -> 0 end, name: :counter)
counter = Agent.get_and_update :counter, fn a -> {a, a+1} end
method = to_string(method) |> String.upcase
matcher = opts[:returns]
tag = opts[:as] || :none
info = opts[:info]
quote do
@tag as: unquote(tag)
test "API - #{unquote(method)} #{unquote(url)} as #{unquote(tag)} ##{unquote(counter)} #{unquote(info) || ""}", %{:auth => auth} do
result = ApiHelper.test_api(unquote(method), unquote(url), unquote(opts), auth)
try do
unquote(matcher).(result)
rescue
FunctionClauseError -> raise "Got #{inspect(result, [pretty: true])}"
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment