View Source PlugLimit.Test (PlugLimit v0.1.0)

Conveniences for testing endpoints protected with PlugLimit rate limiters.

Unit testing endpoints protected with rate limiters might provide unexpected results because after exceeding requests limit during consecutive tests given endpoint will respond with 429 status code.

PlugLimit.Test can help to avoid unexpected 429 responses by adding following code to your test cases:

use PlugLimit.Test, redis_flushdb?: true

Using this module with :redis_flushdb? set to true will flush Redis database with redis_flushdb/1 function executed inside ExUnit.Callbacks.setup/1. Required by redis_flushdb/1 Redis command function is taken from :plug_limit :cmd key defined for testing environment, for example:

# config/test.exs
config :plug_limit, cmd: {MyApp.Redis, :command, []}

Please refer to PlugLimit module documentation for detailed :cmd setting description.

PlugLimit.Test has one configuration setting :redis_flushdb?, set to false by default. When using :redis_flushdb? you might consider setting separate Redis database (e.g.: redis://localhost:6379/15) for PlugLimit to avoid interference with other parts of your application during testing.

Alternatively to :redis_flushdb? you can use redis_del_keys/2.

Link to this section Summary

Functions

Gets x-ratelimit-remaining header from conn and parses it to integer.

Same as get_remaining/1 but for x-ratelimit-reset header.

Checks for IETF recommended x-ratelimit-* http response headers in conn.

Deletes all keys with the names matching pattern given by key from the Redis DB selected with {m, f, a} Redis command function.

Deletes all keys from the Redis DB selected with {m, f, a} Redis command function.

Link to this section Functions

@spec get_remaining(conn :: Plug.Conn.t()) :: integer() | String.t()

Gets x-ratelimit-remaining header from conn and parses it to integer.

Returns x-ratelimit-remaining header as an integer or string message if invalid or missing header.

Example:


test "x-ratelimit-remaining is correct", %{conn: conn} do
  conn = get(conn, "/")
  assert PlugLimit.Test.get_remaining(conn) == 60
end
iex> PlugLimit.Test.get_remaining(conn_invalid_header)
"Invalid, non-standard or missing x-ratelimit-remaining header."
@spec get_reset(conn :: Plug.Conn.t()) :: integer()

Same as get_remaining/1 but for x-ratelimit-reset header.

@spec headers_exist?(conn :: Plug.Conn.t()) :: boolean()

Checks for IETF recommended x-ratelimit-* http response headers in conn.

Checks if basic rate limiting http response headers complying with "RateLimit Fields for HTTP" IETF specification are added to Plug.Conn.t().

Required rate limiting http response headers:

  • x-ratelimit-limit,
  • x-ratelimit-remaining,
  • x-ratelimit-reset.

Returns true if above headers are present and false otherwise.

Example:

test "it is protected by rate limiter", %{conn: conn} do
  conn = get(conn, "/")
  assert PlugLimit.Test.headers_exist?(conn)
end
Link to this function

redis_del_keys(redis_command_function, key)

View Source
@spec redis_del_keys({m :: module(), f :: atom(), [a :: any()]}, key :: String.t()) ::
  :ok | any()

Deletes all keys with the names matching pattern given by key from the Redis DB selected with {m, f, a} Redis command function.

{m, f, a} usually should be consistent with a value given in :plug_limit :cmd configuration key. Returns :ok on success or any() on error.

Function should not be used to delete large numbers of Redis keys.

Example:

setup do
  :ok = PlugLimit.Test.redis_del_keys({MyApp.Redis, :command, []}, "my_key:*")
end
Link to this function

redis_flushdb(redis_command_function)

View Source
@spec redis_flushdb({m :: module(), f :: atom(), [a :: any()]}) :: :ok | any()

Deletes all keys from the Redis DB selected with {m, f, a} Redis command function.

{m, f, a} usually should be consistent with a value given in :plug_limit :cmd configuration key. Returns :ok on success or any() on error.

Redis command which is used to delete keys: FLUSHDB SYNC.

Example:

iex> PlugLimit.Test.redis_flushdb({MyApp.Redis, :command, []})
:ok