chore: copy code for release from private repo

This commit is contained in:
Matt Franczak
2023-12-12 16:04:36 -06:00
commit 81db5cdcad
9 changed files with 804 additions and 0 deletions

View File

@@ -0,0 +1,309 @@
defmodule OAuth2TokenManager.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 OAuth2TokenManager.{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

View File

@@ -0,0 +1,108 @@
defmodule OAuth2TokenManager.TokenRefreshStrategyTest do
@moduledoc """
Tests the refresh strategies configured with TokenRefreshStrategy
"""
use ExUnit.Case
alias OAuth2TokenManager.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