View Source PhoenixApiToolkit.TestHelpers (Phoenix API Toolkit v3.1.2)

Various helper functions for writing tests.

Link to this section Summary

Types

Defaults for use by gen_jwt/2

Options for use by gen_jwt/2

Functions

Put request header "content-type: application/json" on the conn.

Remove volatile fields from maps in the data. Volatile fields like "id" mess up test comparisons. Recursively cleans maps and lists.

Generate a JSON Web Key for testing purposes. See gen_jwt/2 for details.

Generate a JSON Web Signature for testing purposes. See gen_jwt/2 for details.

Generate a JSON Web Token for testing purposes, with an "exp" claim 5 minutes in the future. It is possible to override parts of the signing key, payload and signature to test with different scopes, expiration times, issuers, key ID's etc, override the entire signing key, payload or signature. The defaults should generate a valid JWT. For use with endpoints secured with PhoenixApiToolkit.Security.Oauth2Plug.

Generate a JSON Web Token payload for testing purposes. See gen_jwt/2 for details.

Sets the request header "x-csrf-token", to comply with PhoenixApiToolkit.Security.Plugs.ajax_csrf_protect()

Adds a HMAC-SHA256 signature to the connection's authorization header for the request body. Use create_hmac_plug_body/4 to generate a valid body. For use with endpoints secured with PhoenixApiToolkit.Security.HmacPlug.

Add JWT to the conn. A valid, signed JWT can be generated by gen_jwt/2.

Put a whole map (or keyword list) of query params on a %Conn{}.

Put a raw request body in conn.assigns.raw_body for testing purposes.

Returns an example jwks for use by gen_jwt/2, as base64-encoded JSON.

Converts a map with atoms in it as keys or values to a map with just strings. Works on nested maps as well.

Link to this section Types

@type gen_jwt_defaults() :: %{jwk: map(), payload: map(), jws: map()}

Defaults for use by gen_jwt/2

@type gen_jwt_opts() :: [jwk: map(), payload: map(), jws: map()]

Options for use by gen_jwt/2

Link to this section Functions

@spec application_json(Plug.Conn.t()) :: Plug.Conn.t()

Put request header "content-type: application/json" on the conn.

examples

Examples

use Plug.Test

iex> conn(:post, "/") |> application_json() |> get_req_header("content-type")
["application/json"]
Link to this function

clean_volatile_fields(data)

View Source
@spec clean_volatile_fields(any()) :: any()

Remove volatile fields from maps in the data. Volatile fields like "id" mess up test comparisons. Recursively cleans maps and lists.

examples

Examples

iex> my_data = [
...>   %{
...>     "updated_at" => 12345
...>   },
...>   %{
...>     "some_thing" => [
...>       %{
...>         "id" => 1
...>       },
...>       12345
...>     ]
...>   }
...> ]
iex> clean_volatile_fields(my_data)
[%{}, %{"some_thing" => [%{}, 12345]}]
Link to this function

create_hmac_plug_body(path, method, contents \\ %{}, timestamp \\ DateTime.utc_now() |> DateTime.to_unix(:second))

View Source
@spec create_hmac_plug_body(binary(), binary(), any(), integer()) :: binary()

Generate a request body for an endpoint secured with PhoenixApiToolkit.Security.HmacPlug. Use put_hmac/3 to generate a valid signature.

It is possible to override the timestamp set in the request body. The default generates a valid request body, so overrides are not necessary unless you wish to test the HMAC verification itself.

examples

Examples

iex> create_hmac_plug_body("/hello", "GET", %{hello: "world"}, 12345) |> Jason.decode!()
%{
  "contents" => %{"hello" => "world"},
  "method" => "GET",
  "path" => "/hello",
  "timestamp" => 12345
}
Link to this function

gen_jwk(overrides \\ [])

View Source
@spec gen_jwk(map() | keyword()) :: map()

Generate a JSON Web Key for testing purposes. See gen_jwt/2 for details.

The default is the first key of test_jwks/0.

examples

Examples

iex> gen_jwk()["kid"]
"my_test_key"

iex> gen_jwk(kid: "other key")["kid"]
"other key"
Link to this function

gen_jws(overrides \\ [])

View Source
@spec gen_jws(map() | keyword()) :: map()

Generate a JSON Web Signature for testing purposes. See gen_jwt/2 for details.

The defaults are the "alg" and "kid" values of the first key of test_jwks/0.

examples

Examples

iex> gen_jws() %{"alg" => "RS256", "kid" => "my_test_key"}

iex> gen_jws(alg: "RS512")["alg"] "RS512"

Link to this function

gen_jwt(defaults, overrides \\ [])

View Source
@spec gen_jwt(gen_jwt_defaults(), gen_jwt_opts()) :: binary()

Generate a JSON Web Token for testing purposes, with an "exp" claim 5 minutes in the future. It is possible to override parts of the signing key, payload and signature to test with different scopes, expiration times, issuers, key ID's etc, override the entire signing key, payload or signature. The defaults should generate a valid JWT. For use with endpoints secured with PhoenixApiToolkit.Security.Oauth2Plug.

examples

Examples

@jwt_defaults %{
  jwk: gen_jwk(),
  jws: gen_jws(),
  payload: gen_payload(iss: "http://my-oauth2-provider")
}

# the defaults as created above generate a valid JWT, provided that the claims match those verified
# the header, payload and signature can be inspected using JOSE.JWS.peek* functions
iex> jwt = gen_jwt(@jwt_defaults)
iex> jwt |> JOSE.JWS.peek_protected() |> Jason.decode!()
%{"alg" => "RS256", "kid" => "my_test_key", "typ" => "JWT"}
iex> jwt |> JOSE.JWS.peek_payload() |> Jason.decode!() |> Map.drop(["exp"])
%{"iss" => "http://my-oauth2-provider"}

# parts of the jwk, payload and jws can be overridden for testing purposes
iex> gen_jwt(@jwt_defaults, payload: [iss: "boom"]) |> JOSE.JWS.peek_payload() |> Jason.decode!() |> Map.drop(["exp"])
%{"iss" => "boom"}
iex> gen_jwt(@jwt_defaults, jws: [kid: "other key"]) |> JOSE.JWS.peek_protected() |> Jason.decode!()
%{"alg" => "RS256", "kid" => "other key", "typ" => "JWT"}
iex> gen_jwt(@jwt_defaults, payload: [exp: 12345]) |> JOSE.JWS.peek_payload() |> Jason.decode!() |> Map.get("exp")
12345
Link to this function

gen_payload(overrides \\ [])

View Source
@spec gen_payload(map() | keyword()) :: map()

Generate a JSON Web Token payload for testing purposes. See gen_jwt/2 for details.

The default payload is empty.

examples

Examples

iex> gen_payload()
%{}

iex> gen_payload(iss: "something")["iss"]
"something"
Link to this function

put_ajax_csrf_header(conn)

View Source
@spec put_ajax_csrf_header(Plug.Conn.t()) :: Plug.Conn.t()

Sets the request header "x-csrf-token", to comply with PhoenixApiToolkit.Security.Plugs.ajax_csrf_protect()

examples-doctests

Examples / doctests

iex> conn(:post, "/") |> put_ajax_csrf_header() |> Map.get(:req_headers)
[{"x-csrf-token", "anything"}]
Link to this function

put_hmac(conn, body, secret)

View Source
@spec put_hmac(Plug.Conn.t(), binary(), binary()) :: Plug.Conn.t()

Adds a HMAC-SHA256 signature to the connection's authorization header for the request body. Use create_hmac_plug_body/4 to generate a valid body. For use with endpoints secured with PhoenixApiToolkit.Security.HmacPlug.

It is possible to override the HMAC secret. The default generates a valid signature, so overrides are not necessary unless you wish to test the HMAC verification itself.

examples

Examples

use Plug.Test

iex> body = %{greeting: "world"} |> Jason.encode!()
iex> conn = conn(:post, "/hello", body)
iex> put_hmac(conn, body, "supersecretkey") |> get_req_header("authorization")
["oseq9TrQc/cyOBU7ujrkKM07tFewcVoaLRK0MgslSos="]
@spec put_jwt(Plug.Conn.t(), binary()) :: Plug.Conn.t()

Add JWT to the conn. A valid, signed JWT can be generated by gen_jwt/2.

examples

Examples

use Plug.Test

iex> conn(:get, "/") |> put_jwt("my_jwt") |> get_req_header("authorization")
["Bearer: my_jwt"]
Link to this function

put_query_params(conn, params)

View Source
@spec put_query_params(Plug.Conn.t(), map() | keyword()) :: Plug.Conn.t()

Put a whole map (or keyword list) of query params on a %Conn{}.

examples

Examples

use Plug.Test

iex> conn(:get, "/") |> put_query_params(user: "Peter") |> Map.get(:query_params)
%{user: "Peter"}
Link to this function

put_raw_body(conn, raw_body)

View Source
@spec put_raw_body(Plug.Conn.t(), binary()) :: Plug.Conn.t()

Put a raw request body in conn.assigns.raw_body for testing purposes.

examples

Examples

use Plug.Test

iex> body = %{hello: "world"}
iex> raw_body = body |> Jason.encode!()
iex> conn = conn(:post, "/") |> put_raw_body(raw_body)
iex> conn.adapter |> elem(1) |> Map.get(:req_body) |> Jason.decode!()
%{"hello" => "world"}
@spec test_jwks() :: binary()

Returns an example jwks for use by gen_jwt/2, as base64-encoded JSON.

examples

Examples

# the keyset is returned as base64-encoded JSON string with a list of keys
iex> test_jwks() |> Base.decode64!() |> Jason.decode!() |> List.first() |> Map.get("kid")
"my_test_key"
@spec to_string_map(map()) :: map()

Converts a map with atoms in it as keys or values to a map with just strings. Works on nested maps as well.

examples

Examples

iex> %{first_name: "Peter", stuff: %{"things" => :indeed}} |> to_string_map()
%{"first_name" => "Peter", "stuff" => %{"things" => "indeed"}}