line_bot/test/test_helper.exs

242 lines
6.9 KiB
Elixir

Mox.defmock(MockAPIClient, for: HTTPoison.Base)
Mox.defmock(MockTokenServer, for: LineBot.TokenServer.Behaviour)
defmodule LineBot.TestHelpers do
defmacro test_get_with_status(function, uri, args, params, status, status_atom) do
quote do
test "when get response is #{unquote(status)}" do
expect(MockAPIClient, :get, fn unquote(uri), [], params: unquote(params) ->
{:ok, %{status_code: unquote(status), body: "body"}}
end)
assert {unquote(status_atom), "body"} == apply(LineBot, unquote(function), unquote(args))
end
end
end
defmacro test_get_for(function, uri, args, params) do
quote do
describe Atom.to_string(unquote(function)) do
test_get_with_status(
unquote(function),
unquote(uri),
unquote(args),
unquote(params),
200,
:ok
)
test_get_with_status(
unquote(function),
unquote(uri),
unquote(args),
unquote(params),
401,
:unauthorized
)
test_get_with_status(
unquote(function),
unquote(uri),
unquote(args),
unquote(params),
403,
:forbidden
)
test_get_with_status(
unquote(function),
unquote(uri),
unquote(args),
unquote(params),
404,
:not_found
)
test_get_with_status(
unquote(function),
unquote(uri),
unquote(args),
unquote(params),
429,
:too_many_requests
)
test_get_with_status(
unquote(function),
unquote(uri),
unquote(args),
unquote(params),
500,
:server_error
)
test "when error occurs during post" do
error = %HTTPoison.Error{reason: "test error"}
expect(MockAPIClient, :get, fn unquote(uri), [], params: unquote(params) ->
{:error, error}
end)
assert {:error, error} == apply(LineBot, unquote(function), unquote(args))
end
end
end
end
defmacro expect_post_status(uri, status) do
quote do
expect(MockAPIClient, :post, fn unquote(uri), data ->
{:ok, %{status_code: unquote(status), body: data}}
end)
end
end
defmacro test_post_msg_with_status(function, uri, to, status, status_atom) do
quote do
test "when post response is #{unquote(status)}", %{data: data} do
expect_post_status(unquote(uri), unquote(status))
args = [["message"], "disabled"]
args = if unquote(to), do: [unquote(to) | args], else: args
assert {unquote(status_atom), data} == apply(LineBot, unquote(function), args)
end
end
end
defmacro test_post_msg(function, uri, to, data) do
quote do
describe Atom.to_string(unquote(function)) do
setup do
%{data: unquote(data)}
end
test_post_msg_with_status(unquote(function), unquote(uri), unquote(to), 200, :ok)
test_post_msg_with_status(
unquote(function),
unquote(uri),
unquote(to),
401,
:unauthorized
)
test_post_msg_with_status(unquote(function), unquote(uri), unquote(to), 403, :forbidden)
test_post_msg_with_status(unquote(function), unquote(uri), unquote(to), 404, :not_found)
test_post_msg_with_status(
unquote(function),
unquote(uri),
unquote(to),
429,
:too_many_requests
)
test_post_msg_with_status(
unquote(function),
unquote(uri),
unquote(to),
500,
:server_error
)
test "when error occurs during post" do
error = %HTTPoison.Error{reason: "test error"}
expect(MockAPIClient, :post, fn unquote(uri), _data -> {:error, error} end)
args = [["message"], "disabled"]
args = if unquote(to), do: [unquote(to) | args], else: args
assert {:error, error} == apply(LineBot, unquote(function), args)
end
test "notification_disabled defaults to false" do
expect(MockAPIClient, :post, fn unquote(uri), data ->
{:ok, %{status_code: 200, body: data}}
end)
args = [["message"]]
args = if unquote(to), do: [unquote(to) | args], else: args
assert {:ok, %{"notificationDisabled" => false}} =
apply(LineBot, unquote(function), args)
expect(MockAPIClient, :post, fn unquote(uri), data ->
{:ok, %{status_code: 200, body: data}}
end)
args = [["message"], true]
args = if unquote(to), do: [unquote(to) | args], else: args
assert {:ok, %{"notificationDisabled" => true}} =
apply(LineBot, unquote(function), args)
end
test "single message is converted to single-element list" do
expect(MockAPIClient, :post, fn unquote(uri), data ->
{:ok, %{status_code: 200, body: data}}
end)
args = ["message"]
args = if unquote(to), do: [unquote(to) | args], else: args
assert {:ok, %{"messages" => ["message"]}} = apply(LineBot, unquote(function), args)
end
end
end
end
defmacro test_post_uri_with_status(function, uri, arg, status, status_atom) do
quote do
test "when post response is #{unquote(status)}" do
data = %{}
expect_post_status(unquote(uri), unquote(status))
assert {unquote(status_atom), data} == apply(LineBot, unquote(function), [unquote(arg)])
end
end
end
# TODO remove this duplication by refactoring the macro to test try_post behaviour,
# and extracting the surrouding logic
defmacro test_post_uri(function, uri, arg) do
quote do
describe Atom.to_string(unquote(function)) do
test_post_uri_with_status(unquote(function), unquote(uri), unquote(arg), 200, :ok)
test_post_uri_with_status(
unquote(function),
unquote(uri),
unquote(arg),
401,
:unauthorized
)
test_post_uri_with_status(unquote(function), unquote(uri), unquote(arg), 403, :forbidden)
test_post_uri_with_status(unquote(function), unquote(uri), unquote(arg), 404, :not_found)
test_post_uri_with_status(
unquote(function),
unquote(uri),
unquote(arg),
429,
:too_many_requests
)
test_post_uri_with_status(
unquote(function),
unquote(uri),
unquote(arg),
500,
:server_error
)
test "when error occurs during post" do
error = %HTTPoison.Error{reason: "test error"}
expect(MockAPIClient, :post, fn unquote(uri), _data -> {:error, error} end)
assert {:error, error} == apply(LineBot, unquote(function), [unquote(arg)])
end
end
end
end
end
ExUnit.start()