defmodule Tarakan.RateLimiterTest do
  use Tarakan.DataCase, async: true

  alias Tarakan.RateLimiter

  test "enforces fixed windows per bucket key" do
    key = {:test_limit, System.unique_integer([:positive])}

    assert :ok = RateLimiter.check(key, 2, 60)
    assert :ok = RateLimiter.check(key, 2, 60)
    assert {:error, :rate_limited, retry} = RateLimiter.check(key, 2, 60)
    assert is_integer(retry) and retry > 0
  end

  test "under the sandbox, counts are isolated per transaction" do
    key = {:test_limit, System.unique_integer([:positive])}
    parent = self()

    assert :ok = RateLimiter.check(key, 1, 60)
    assert {:error, :rate_limited, _retry} = RateLimiter.check(key, 1, 60)

    # A process checking out its own sandbox connection - as if it were
    # another test - gets a fresh bucket for the same key.
    spawn(fn -> send(parent, {:other, RateLimiter.check(key, 1, 60)}) end)

    assert_receive {:other, :ok}, 1_000
  end
end
