chore: rename from oauth2_token_manager to oauth2_token_agent to avoid conflict
This commit is contained in:
309
test/oauth2_token_agent/token_agent_test.exs
Normal file
309
test/oauth2_token_agent/token_agent_test.exs
Normal file
@@ -0,0 +1,309 @@
|
||||
defmodule OAuth2TokenAgent.TokenAgentTest do
|
||||
@moduledoc """
|
||||
Tests for TokenAgent, which is used to track token state
|
||||
"""
|
||||
use ExUnit.Case, async: false
|
||||
|
||||
import Mock
|
||||
|
||||
alias OAuth2.{AccessToken, Client}
|
||||
alias OAuth2TokenAgent.{TokenAgent, TokenRefreshStrategy}
|
||||
|
||||
defp test_client do
|
||||
Client.new(
|
||||
strategy: OAuth2.Strategy.ClientCredentials,
|
||||
client_id: "test_client_id",
|
||||
client_secret: "test_client_secret_abc123",
|
||||
site: "http://localhost/"
|
||||
)
|
||||
end
|
||||
|
||||
describe "start_link/1" do
|
||||
test "returns an agent storing the token if successful" do
|
||||
with_mock Client, [:passthrough],
|
||||
get_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "test_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 6000
|
||||
}
|
||||
}}
|
||||
end do
|
||||
{:ok, agent} = TokenAgent.start_link(initial_client: test_client())
|
||||
|
||||
assert TokenAgent.get_access_token(agent) == "test_access_token"
|
||||
|
||||
assert TokenAgent.get_current_client(agent).token.access_token == "test_access_token"
|
||||
end
|
||||
end
|
||||
|
||||
test "returns an error if the initial token retrieval did not succeed" do
|
||||
sample_error = %OAuth2.Error{reason: :econnrefused}
|
||||
|
||||
with_mock Client, [:passthrough], get_token: fn _client -> {:error, sample_error} end do
|
||||
{:error, error} = TokenAgent.start_link(initial_client: test_client())
|
||||
|
||||
assert error == sample_error
|
||||
end
|
||||
end
|
||||
|
||||
test "returns an error if no client is provided" do
|
||||
{:error, ":initial_client required"} = TokenAgent.start_link(name: MyModule.TokenAgent)
|
||||
end
|
||||
|
||||
test "can be provided with an name to refer to the agent" do
|
||||
with_mock Client, [:passthrough],
|
||||
get_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "test_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 6000
|
||||
}
|
||||
}}
|
||||
end do
|
||||
{:ok, _} =
|
||||
TokenAgent.start_link(
|
||||
initial_client: test_client(),
|
||||
inline_refresh_strategy: %TokenRefreshStrategy{},
|
||||
name: MyModule.TokenAgent
|
||||
)
|
||||
|
||||
assert TokenAgent.get_access_token(MyModule.TokenAgent) == "test_access_token"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "refresh_tokens/1" do
|
||||
test "uses the refresh token if available" do
|
||||
with_mock Client, [:passthrough],
|
||||
get_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "test_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 600,
|
||||
refresh_token: "test_refresh_token"
|
||||
}
|
||||
}}
|
||||
end,
|
||||
refresh_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "new_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 600,
|
||||
refresh_token: "new_refresh_token"
|
||||
}
|
||||
}}
|
||||
end do
|
||||
{:ok, agent} = TokenAgent.start_link(initial_client: test_client())
|
||||
TokenAgent.refresh(agent)
|
||||
|
||||
assert TokenAgent.get_access_token(agent) == "new_access_token"
|
||||
end
|
||||
end
|
||||
|
||||
test "uses the initial client to get a new token if the refresh token cannot be used" do
|
||||
with_mock Client, [:passthrough],
|
||||
get_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "test_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 600,
|
||||
refresh_token: "test_refresh_token"
|
||||
}
|
||||
}}
|
||||
end,
|
||||
refresh_token: fn _client -> {:error, %OAuth2.Error{reason: :econnrefused}} end,
|
||||
get_token!: fn client ->
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "new_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 600,
|
||||
refresh_token: "new_refresh_token"
|
||||
}
|
||||
}
|
||||
end do
|
||||
{:ok, agent} = TokenAgent.start_link(initial_client: test_client())
|
||||
TokenAgent.refresh(agent)
|
||||
|
||||
assert TokenAgent.get_access_token(agent) == "new_access_token"
|
||||
|
||||
assert_called(Client.refresh_token(:_))
|
||||
end
|
||||
end
|
||||
|
||||
test "uses the initial client to get a new token if no refresh token is available" do
|
||||
with_mock Client, [:passthrough],
|
||||
get_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "test_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 600
|
||||
}
|
||||
}}
|
||||
end,
|
||||
refresh_token: fn _client -> {:error, %OAuth2.Error{reason: :econnrefused}} end,
|
||||
get_token!: fn client ->
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "new_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 600
|
||||
}
|
||||
}
|
||||
end do
|
||||
{:ok, agent} = TokenAgent.start_link(initial_client: test_client())
|
||||
TokenAgent.refresh(agent)
|
||||
|
||||
assert TokenAgent.get_access_token(agent) == "new_access_token"
|
||||
|
||||
assert_not_called(Client.refresh_token(:_))
|
||||
end
|
||||
end
|
||||
|
||||
test "uses the initial client to get a new token if no token is available" do
|
||||
with_mock Client, [:passthrough],
|
||||
get_token: fn client ->
|
||||
{:ok, client}
|
||||
end,
|
||||
refresh_token: fn _client -> {:error, %OAuth2.Error{reason: :econnrefused}} end,
|
||||
get_token!: fn client ->
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "new_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 600
|
||||
}
|
||||
}
|
||||
end do
|
||||
{:ok, agent} = TokenAgent.start_link(initial_client: test_client())
|
||||
TokenAgent.refresh(agent)
|
||||
|
||||
assert TokenAgent.get_access_token(agent) == "new_access_token"
|
||||
|
||||
assert_not_called(Client.refresh_token(:_))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "inline refresh" do
|
||||
test "triggers during get_access_token if the inline_refresh strategy requires it" do
|
||||
with_mock Client, [:passthrough],
|
||||
get_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "test_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 10,
|
||||
refresh_token: "test_refresh_token"
|
||||
}
|
||||
}}
|
||||
end,
|
||||
refresh_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "new_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 6000,
|
||||
refresh_token: "new_refresh_token"
|
||||
}
|
||||
}}
|
||||
end do
|
||||
{:ok, agent} =
|
||||
TokenAgent.start_link(
|
||||
initial_client: test_client(),
|
||||
inline_refresh_strategy: %TokenRefreshStrategy{
|
||||
seconds_before_expires: 30
|
||||
}
|
||||
)
|
||||
|
||||
assert TokenAgent.get_access_token(agent) == "new_access_token"
|
||||
end
|
||||
end
|
||||
|
||||
test "does not trigger during get_access_token if the inline_refresh strategy does not require it" do
|
||||
with_mock Client, [:passthrough],
|
||||
get_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "test_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 100,
|
||||
refresh_token: "test_refresh_token"
|
||||
}
|
||||
}}
|
||||
end,
|
||||
refresh_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "new_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 6000,
|
||||
refresh_token: "new_refresh_token"
|
||||
}
|
||||
}}
|
||||
end do
|
||||
{:ok, agent} =
|
||||
TokenAgent.start_link(
|
||||
initial_client: test_client(),
|
||||
inline_refresh_strategy: %TokenRefreshStrategy{
|
||||
seconds_before_expires: 30
|
||||
}
|
||||
)
|
||||
|
||||
assert TokenAgent.get_access_token(agent) == "test_access_token"
|
||||
|
||||
assert_not_called(Client.refresh_token(:_))
|
||||
end
|
||||
end
|
||||
|
||||
test "does not trigger during get_access_token if no inline_refresh strategy is set" do
|
||||
with_mock Client, [:passthrough],
|
||||
get_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "test_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 10,
|
||||
refresh_token: "test_refresh_token"
|
||||
}
|
||||
}}
|
||||
end,
|
||||
refresh_token: fn client ->
|
||||
{:ok,
|
||||
%Client{
|
||||
client
|
||||
| token: %AccessToken{
|
||||
access_token: "new_access_token",
|
||||
expires_at: (DateTime.utc_now() |> DateTime.to_unix()) + 6000,
|
||||
refresh_token: "new_refresh_token"
|
||||
}
|
||||
}}
|
||||
end do
|
||||
{:ok, agent} =
|
||||
TokenAgent.start_link(initial_client: test_client(), inline_refresh_strategy: nil)
|
||||
|
||||
assert TokenAgent.get_access_token(agent) == "test_access_token"
|
||||
|
||||
assert_not_called(Client.refresh_token(:_))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
108
test/oauth2_token_agent/token_refresh_strategy_test.exs
Normal file
108
test/oauth2_token_agent/token_refresh_strategy_test.exs
Normal file
@@ -0,0 +1,108 @@
|
||||
defmodule OAuth2TokenAgent.TokenRefreshStrategyTest do
|
||||
@moduledoc """
|
||||
Tests the refresh strategies configured with TokenRefreshStrategy
|
||||
"""
|
||||
|
||||
use ExUnit.Case
|
||||
|
||||
alias OAuth2TokenAgent.TokenRefreshStrategy
|
||||
|
||||
defp seconds_from_now(seconds) do
|
||||
DateTime.utc_now() |> DateTime.add(seconds, :second, Calendar.UTCOnlyTimeZoneDatabase)
|
||||
end
|
||||
|
||||
describe "every_seconds" do
|
||||
test "refresh_now? is true if it has been more than the configured value of seconds since the last refresh" do
|
||||
strategy = %TokenRefreshStrategy{
|
||||
every_seconds: 30
|
||||
}
|
||||
|
||||
assert !TokenRefreshStrategy.refresh_now?(
|
||||
strategy,
|
||||
DateTime.utc_now(),
|
||||
seconds_from_now(300)
|
||||
)
|
||||
|
||||
assert TokenRefreshStrategy.refresh_now?(
|
||||
strategy,
|
||||
seconds_from_now(-30),
|
||||
seconds_from_now(300)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "seconds_before_expires" do
|
||||
test "refresh_now? is true if if the token expires at or before the specified number of seconds" do
|
||||
strategy = %TokenRefreshStrategy{
|
||||
seconds_before_expires: 30
|
||||
}
|
||||
|
||||
assert !TokenRefreshStrategy.refresh_now?(
|
||||
strategy,
|
||||
seconds_from_now(-30),
|
||||
seconds_from_now(60)
|
||||
)
|
||||
|
||||
assert TokenRefreshStrategy.refresh_now?(
|
||||
strategy,
|
||||
seconds_from_now(-30),
|
||||
seconds_from_now(30)
|
||||
)
|
||||
end
|
||||
|
||||
test "refresh_now is false if expires_at is nil" do
|
||||
strategy = %TokenRefreshStrategy{
|
||||
seconds_before_expires: 30
|
||||
}
|
||||
|
||||
assert !TokenRefreshStrategy.refresh_now?(
|
||||
strategy,
|
||||
seconds_from_now(-30),
|
||||
nil
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "refresh_now?" do
|
||||
test "returns true if any of the conditions in the strategy are met" do
|
||||
strategy = %TokenRefreshStrategy{
|
||||
seconds_before_expires: 30,
|
||||
every_seconds: 60
|
||||
}
|
||||
|
||||
assert !TokenRefreshStrategy.refresh_now?(
|
||||
strategy,
|
||||
seconds_from_now(-30),
|
||||
seconds_from_now(60)
|
||||
)
|
||||
|
||||
assert TokenRefreshStrategy.refresh_now?(
|
||||
strategy,
|
||||
seconds_from_now(-60),
|
||||
seconds_from_now(30)
|
||||
)
|
||||
|
||||
assert TokenRefreshStrategy.refresh_now?(
|
||||
strategy,
|
||||
seconds_from_now(-30),
|
||||
seconds_from_now(30)
|
||||
)
|
||||
|
||||
assert TokenRefreshStrategy.refresh_now?(
|
||||
strategy,
|
||||
seconds_from_now(-60),
|
||||
seconds_from_now(60)
|
||||
)
|
||||
end
|
||||
|
||||
test "returns false if none of the conditions in the strategy are specified" do
|
||||
strategy = %TokenRefreshStrategy{}
|
||||
|
||||
assert !TokenRefreshStrategy.refresh_now?(
|
||||
strategy,
|
||||
seconds_from_now(-1),
|
||||
seconds_from_now(1)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user