Skip to content

Commit

Permalink
improvement: return a map from decode_relay_id/1
Browse files Browse the repository at this point in the history
Slight API improvement over #106.

This makes it more ergonomic to partially match on the return value (and it also
makes it more explicit by explicitly labeling the two parts).

Also add tests for relay id encoding/decoding.
  • Loading branch information
rbino committed Jan 25, 2024
1 parent 365b3ae commit 744af64
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/graphql/resolver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2588,7 +2588,7 @@ defmodule AshGraphql.Graphql.Resolver do

def resolve_node(%{arguments: %{id: id}} = resolution, type_to_api_and_resource_map) do
case AshGraphql.Resource.decode_relay_id(id) do
{:ok, {type, primary_key}} ->
{:ok, %{type: type, id: primary_key}} ->
{api, resource} = Map.fetch!(type_to_api_and_resource_map, type)
# We can be sure this returns something since we check this at compile time
query = AshGraphql.Resource.primary_key_get_query(resource)
Expand Down
4 changes: 2 additions & 2 deletions lib/resource/resource.ex
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ defmodule AshGraphql.Resource do

if relay_ids? do
case decode_relay_id(id) do
{:ok, {^type, primary_key}} ->
{:ok, %{type: ^type, id: primary_key}} ->
decode_primary_key(resource, primary_key)

_ ->
Expand Down Expand Up @@ -474,7 +474,7 @@ defmodule AshGraphql.Resource do

type = String.to_existing_atom(type_string)

{:ok, {type, primary_key}}
{:ok, %{type: type, id: primary_key}}
rescue
_ ->
{:error, Ash.Error.Invalid.InvalidPrimaryKey.exception(resource: nil, value: id)}
Expand Down
32 changes: 32 additions & 0 deletions test/relay_ids_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -225,4 +225,36 @@ defmodule AshGraphql.RelayIdsTest do
assert result[:errors] != nil
end
end

describe "relay ID decoding" do
test "round trips" do
user =
User
|> Ash.Changeset.for_create(:create, %{name: "Fred"})
|> Api.create!()

user_id = user.id
user_type = AshGraphql.Resource.Info.type(User)

user_relay_id = AshGraphql.Resource.encode_relay_id(user)

assert {:ok, %{type: ^user_type, id: ^user_id}} =
AshGraphql.Resource.decode_relay_id(user_relay_id)
end

test "fails for invalid ids" do
assert {:error, %Ash.Error.Invalid.InvalidPrimaryKey{}} =
AshGraphql.Resource.decode_relay_id("notbase64")

assert {:error, %Ash.Error.Invalid.InvalidPrimaryKey{}} =
"non-existing-type:1234"
|> Base.encode64()
|> AshGraphql.Resource.decode_relay_id()

assert {:error, %Ash.Error.Invalid.InvalidPrimaryKey{}} =
"user"
|> Base.encode64()
|> AshGraphql.Resource.decode_relay_id()
end
end
end

0 comments on commit 744af64

Please sign in to comment.