defmodule GitGud.RateLimitTest do
use ExUnit.Case, async: true
alias GitGud.RateLimit
# Unique keys per test, since the table is shared with the whole suite.
defp key, do: "k-#{System.unique_integer([:positive])}"
test "check counts nothing; record counts; the limit refuses" do
k = key()
{limit, _window} = RateLimit.limits(:login_account)
for _ <- 1..(limit - 1), do: RateLimit.record(:login_account, k)
assert RateLimit.check(:login_account, k) == :ok
assert RateLimit.check(:login_account, k) == :ok
RateLimit.record(:login_account, k)
assert {:error, retry_after} = RateLimit.check(:login_account, k)
assert retry_after in 1..900
end
test "hit lets the limit through and refuses the one after" do
k = key()
{limit, _window} = RateLimit.limits(:email_address)
for _ <- 1..limit, do: assert(RateLimit.hit(:email_address, k) == :ok)
assert {:error, _} = RateLimit.hit(:email_address, k)
end
test "keys and policies are counted apart, and clear forgets" do
k = key()
{limit, _window} = RateLimit.limits(:login_account)
for _ <- 1..limit, do: RateLimit.record(:login_account, k)
assert {:error, _} = RateLimit.check(:login_account, k)
assert RateLimit.check(:login_account, key()) == :ok
assert RateLimit.check(:login_ip, k) == :ok
RateLimit.clear(:login_account, k)
assert RateLimit.check(:login_account, k) == :ok
end
test "minutes rounds up" do
assert RateLimit.minutes(1) == 1
assert RateLimit.minutes(60) == 1
assert RateLimit.minutes(61) == 2
end
test "ip_key is the address, or the /64 for IPv6" do
assert RateLimit.ip_key({203, 0, 113, 7}) == "203.0.113.7"
assert RateLimit.ip_key({0x2001, 0xDB8, 1, 2, 3, 4, 5, 6}) == "2001:db8:1:2::/64"
assert RateLimit.ip_key(nil) == "unknown"
end
end
neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
1.8 KiB · text
History
b868907