Add BodyReaderPlugTest and TokenServerTest

This commit is contained in:
Adam Millerchip 2019-09-05 00:17:50 +09:00
parent d5674157ef
commit 1b117f8ce3
5 changed files with 138 additions and 4 deletions

View file

@ -62,7 +62,9 @@ The forwarded URL should be whatever you specified as the callback URI on the Li
For detailed instructions, see `LineBot.Webhook`. You can also check the [sample application](../sample/lib/line_bot_sample/router.ex). For detailed instructions, see `LineBot.Webhook`. You can also check the [sample application](../sample/lib/line_bot_sample/router.ex).
## Not supported ## Not implemented
### Rich Menu API
The [Rich Menu API](https://developers.line.biz/en/reference/messaging-api/#rich-menu) is not currently implemented, although `LineBot.APIClient` can be used to call the API manually. The [Rich Menu API](https://developers.line.biz/en/reference/messaging-api/#rich-menu) is not currently implemented, although `LineBot.APIClient` can be used to call the API manually.
@ -90,6 +92,10 @@ And get like this:
LineBot.APIClient.get("richmenu/list") LineBot.APIClient.get("richmenu/list")
``` ```
### Flex Message Update
Recent additions to the Flex message API have not been added yet. This will be the first feature to be implemented after initial release.
## TODO ## TODO
* [ ] Tests * [ ] Tests

View file

@ -5,7 +5,7 @@ defmodule LineBot.BodyReaderPlug do
@moduledoc false @moduledoc false
@impl true @impl true
def init(_opts), do: nil def init(_opts), do: []
@impl true @impl true
def call(conn, opts) do def call(conn, opts) do

View file

@ -1,4 +1,6 @@
defmodule LineBot.TokenServer do defmodule LineBot.TokenServer do
@http Application.get_env(:line_bot, :api_client, HTTPoison)
defmodule Behaviour do defmodule Behaviour do
@moduledoc false @moduledoc false
@callback get_token() :: binary @callback get_token() :: binary
@ -77,7 +79,7 @@ defmodule LineBot.TokenServer do
%{"access_token" => access_token, "expires_in" => expires_in} = %{"access_token" => access_token, "expires_in" => expires_in} =
"https://api.line.me/v2/oauth/accessToken" "https://api.line.me/v2/oauth/accessToken"
|> HTTPoison.post!({:form, data}, @headers) |> @http.post!({:form, data}, @headers)
|> Map.get(:body) |> Map.get(:body)
|> Jason.decode!() |> Jason.decode!()
@ -85,7 +87,7 @@ defmodule LineBot.TokenServer do
end end
defp post_revoke_token(access_token) do defp post_revoke_token(access_token) do
HTTPoison.post!( @http.post!(
"https://api.line.me/v2/oauth/revoke", "https://api.line.me/v2/oauth/revoke",
{:form, [access_token: access_token]}, {:form, [access_token: access_token]},
@headers @headers

View file

@ -0,0 +1,17 @@
defmodule LineBot.BodyReaderPlugTest do
use ExUnit.Case
use Plug.Test
alias LineBot.BodyReaderPlug
test "call puts body into line_bot_raw_body private field" do
conn = conn(:get, "/", "body")
assert "body" == BodyReaderPlug.call(conn, []).private.line_bot_raw_body
end
test "body greater than :length is not supported" do
conn = conn(:get, "/", "body")
assert %Plug.BadRequestError{} =
catch_error(BodyReaderPlug.call(conn, length: 1).private.line_bot_raw_body)
end
end

View file

@ -0,0 +1,109 @@
defmodule LineBot.TokenServerTest do
use ExUnit.Case
use Plug.Test
import Mox
alias LineBot.TokenServer
@client_id 123_456
@client_secret "test dummy secret"
setup do
%{
state: %{
token: "original token",
expires_on: DateTime.utc_now(),
client_id: @client_id,
client_secret: @client_secret
}
}
end
describe "init" do
setup do
global_client_id = Application.fetch_env!(:line_bot, :client_id)
global_client_secret = Application.fetch_env!(:line_bot, :client_id)
Application.put_env(:line_bot, :client_id, @client_id)
Application.put_env(:line_bot, :client_secret, @client_secret)
on_exit(fn ->
Application.put_env(:line_bot, :client_id, global_client_id)
Application.put_env(:line_bot, :client_secret, global_client_secret)
end)
end
test "sets access tokent to nil" do
assert {:ok, %{token: nil}} = TokenServer.init(nil)
end
test "sets expiry time to now" do
now = DateTime.utc_now()
{:ok, %{expires_on: then}} = TokenServer.init(nil)
assert DateTime.diff(now, then) <= 1
end
test "gets client credentials from application environment" do
assert {:ok, %{client_id: @client_id, client_secret: @client_secret}} =
TokenServer.init(nil)
end
end
describe "handle_token" do
test "when token is not expired, returns current token" do
state = %{
token: "original token",
expires_on: DateTime.add(DateTime.utc_now(), 100_000, :second)
}
assert {:reply, "original token", %{token: "original token"}} =
TokenServer.handle_call(:token, nil, state)
end
test "when token has expired, fetches and returns new token, and adds it to state", %{
state: state
} do
headers = [{"Content-Type", "application/x-www-form-urlencoded"}]
data = [
grant_type: "client_credentials",
client_id: @client_id,
client_secret: @client_secret
]
expect(MockAPIClient, :post!, fn "https://api.line.me/v2/oauth/accessToken",
{:form, ^data},
^headers ->
%{body: ~S'{"access_token":"new token", "expires_in":1000}'}
end)
assert {:reply, "new token", %{token: "new token", expires_on: expires_on}} =
TokenServer.handle_call(:token, nil, state)
assert DateTime.diff(DateTime.utc_now(), expires_on) <= 1
end
end
describe "handle_purge" do
test "sets token to nil and expiry to an expired date", %{state: state} do
assert {:reply, :ok, %{token: nil, expires_on: expires_on}} =
TokenServer.handle_call(:purge, nil, state)
assert DateTime.diff(DateTime.utc_now(), expires_on) <= 0
end
end
describe "handle_revoke" do
test "calls purge API and sets token to nil and expiry to an expired date", %{state: state} do
expect(MockAPIClient, :post!, fn "https://api.line.me/v2/oauth/revoke",
{:form, [access_token: "original token"]},
[{"Content-Type", "application/x-www-form-urlencoded"}] ->
:ok
end)
assert {:reply, :ok, %{token: nil, expires_on: expires_on}} =
TokenServer.handle_call(:revoke, nil, state)
assert DateTime.diff(DateTime.utc_now(), expires_on) <= 0
end
end
end