1.6 KiB · text History b868907
defmodule GitGud.Accounts.PersonalAccessTokenTouchTest do
  @moduledoc """
  `last_used_at` is written at most once a minute, so a client polling
  with one token doesn't queue every request on that row's lock.
  """
  use GitGud.DataCase, async: true

  import GitGud.AccountsFixtures

  alias GitGud.Accounts
  alias GitGud.Accounts.PersonalAccessToken

  setup do
    user = user_fixture()
    {:ok, token, plaintext} = Accounts.create_personal_access_token(user, "poller", ["ci:read"])
    {:ok, plaintext: plaintext, token: token}
  end

  defp last_used(token), do: Repo.get!(PersonalAccessToken, token.id).last_used_at

  defp set_last_used(token, at),
    do: token |> Ecto.Changeset.change(last_used_at: at) |> Repo.update!()

  test "the first use is recorded", %{plaintext: plaintext, token: token} do
    assert {:ok, _user, ["ci:read"]} = Accounts.verify_personal_access_token(plaintext)
    assert DateTime.diff(DateTime.utc_now(), last_used(token)) < 5
  end

  test "a use within the minute writes nothing", %{plaintext: plaintext, token: token} do
    recent = DateTime.add(DateTime.utc_now(:second), -10, :second)
    set_last_used(token, recent)

    assert {:ok, _user, _scopes} = Accounts.verify_personal_access_token(plaintext)
    assert last_used(token) == recent
  end

  test "a use after the minute moves it on", %{plaintext: plaintext, token: token} do
    set_last_used(token, DateTime.add(DateTime.utc_now(:second), -120, :second))

    assert {:ok, _user, _scopes} = Accounts.verify_personal_access_token(plaintext)
    assert DateTime.diff(DateTime.utc_now(), last_used(token)) < 5
  end
end