ash_graphql/test/read_test.exs

1380 lines
32 KiB
Elixir

defmodule AshGraphql.ReadTest do
use ExUnit.Case, async: false
require Ash.Query
setup do
on_exit(fn ->
AshGraphql.TestHelpers.stop_ets()
end)
end
test "float fields works correctly" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "foo", published: true, score: 9.8)
|> Ash.create!()
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "bar", published: true, score: 9.85)
|> Ash.create!()
resp =
"""
query PostScore($score: Float) {
postScore(score: $score) {
text
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"score" => 9.8
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{data: %{"postScore" => [%{"text" => "foo"}]}} = result
end
test "union fields works correctly" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "foo", published: true, simple_union: 10)
|> Ash.create!()
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "bar", published: true, simple_union: "foo")
|> Ash.create!()
resp =
"""
query postLibrary {
postLibrary {
text
simpleUnion {
... on SimpleUnionString {
value
}
... on SimpleUnionInt {
value
}
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok,
%{
data: %{
"postLibrary" => [
%{"simpleUnion" => %{"value" => value1}},
%{"simpleUnion" => %{"value" => value2}}
]
}
}} = resp
assert Enum.sort([10, "foo"]) == Enum.sort([value1, value2])
end
test "metadata fields are rendered" do
AshGraphql.Test.User
|> Ash.Changeset.for_create(:create,
name: "My Name"
)
|> Ash.create!()
resp =
"""
query CurrentUserWithMetadata {
currentUserWithMetadata {
bar
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{data: %{"currentUserWithMetadata" => %{"bar" => "bar"}}} = result
end
test "forbidden fields show errors" do
user =
AshGraphql.Test.User
|> Ash.Changeset.for_create(:create,
name: "My Name"
)
|> Ash.create!()
resp =
"""
query CurrentUserWithMetadata {
currentUserWithMetadata {
bar
secret
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema, context: %{actor: user})
assert {:ok, result} = resp
assert %{
data: %{"currentUserWithMetadata" => nil},
errors: [%{code: "forbidden_field"}]
} = result
end
test "loading relationships with fragment works" do
user =
AshGraphql.Test.User
|> Ash.Changeset.for_create(:create, %{name: "My Name"})
|> Ash.create!()
post =
AshGraphql.Test.Post
|> Ash.Changeset.for_create(
:create,
%{
author_id: user.id,
text: "a",
published: true
}
)
|> Ash.create!()
post
|> Ash.Changeset.for_update(
:update_with_comments,
%{
comments: [%{text: "comment", author_id: user.id}]
}
)
|> Ash.update!()
resp =
"""
query postLibrary {
postLibrary(sort: {field: TEXT}) {
id
comments {
...User
}
}
}
fragment User on Comment {
id
author {
name
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"postLibrary" => [
%{
"comments" => [
%{
"author" => %{"name" => "My Name"}
}
]
}
]
}
} = result
end
test "a read with arguments works" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "foo", published: true)
|> Ash.create!()
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "bar", published: false)
|> Ash.create!()
resp =
"""
query PostLibrary($published: Boolean) {
postLibrary(published: $published) {
text
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"published" => true
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{data: %{"postLibrary" => [%{"text" => "foo"}]}} = result
end
test "a read with custom set types works" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "foo",
integer_as_string_in_domain: 1,
published: true
)
|> Ash.create!()
resp =
"""
query PostLibrary {
postLibrary {
text
integerAsStringInDomain
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{data: %{"postLibrary" => [%{"integerAsStringInDomain" => "1"}]}} = result
end
test "reading relationships works, without selecting the id field" do
post =
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "foo", published: true)
|> Ash.create!()
AshGraphql.Test.Comment
|> Ash.Changeset.for_create(:create, %{text: "stuff"})
|> Ash.Changeset.force_change_attribute(:post_id, post.id)
|> Ash.create!()
resp =
"""
query PostLibrary($published: Boolean) {
postLibrary(published: $published) {
text
comments{
text
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"published" => true
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{data: %{"postLibrary" => [%{"text" => "foo", "comments" => [%{"text" => "stuff"}]}]}} =
result
end
test "reading relationships works with fragments, without selecting the id field" do
post =
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "foo", published: true)
|> Ash.create!()
AshGraphql.Test.Comment
|> Ash.Changeset.for_create(:create, %{text: "stuff"})
|> Ash.Changeset.force_change_attribute(:post_id, post.id)
|> Ash.create!()
resp =
"""
query PostLibrary($published: Boolean) {
postLibrary(published: $published) {
text
id
...PostFragment
}
}
fragment PostFragment on Post {
comments{
id
text
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"published" => true
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{data: %{"postLibrary" => [%{"text" => "foo", "comments" => [%{"text" => "stuff"}]}]}} =
result
end
test "the same relationship can be fetched with different parameters" do
post =
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "foo", published: true)
|> Ash.create!()
for _ <- 0..1 do
AshGraphql.Test.Comment
|> Ash.Changeset.for_create(:create, %{text: "stuff"})
|> Ash.Changeset.force_change_attribute(:post_id, post.id)
|> Ash.create!()
end
resp =
"""
query PostLibrary($published: Boolean) {
postLibrary(published: $published) {
text
foo: comments(limit: 1){
text
}
bar: comments(limit: 2){
text
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"published" => true
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"postLibrary" => [
%{
"text" => "foo",
"foo" => [%{"text" => "stuff"}],
"bar" => [%{"text" => "stuff"}, %{"text" => "stuff"}]
}
]
}
} = result
end
test "complexity is calculated for relationships" do
query = """
query PostLibrary {
paginatedPosts(limit: 2) {
results{
text
comments(limit: 2){
text
post {
comments(limit: 2) {
text
post {
text
}
}
}
}
}
}
}
"""
query
|> Absinthe.run(AshGraphql.Test.Schema,
analyze_complexity: true,
max_complexity: 36
)
resp =
query
|> Absinthe.run(AshGraphql.Test.Schema,
analyze_complexity: true,
max_complexity: 35
)
assert {:ok, %{errors: errors}} = resp
assert errors |> Enum.map(& &1.message) |> Enum.sort() == [
"Field paginatedPosts is too complex: complexity is 36 and maximum is 35",
"Operation PostLibrary is too complex: complexity is 36 and maximum is 35"
]
end
test "a read with a loaded field works" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "bar", published: true)
|> Ash.create!()
resp =
"""
query PostLibrary($published: Boolean) {
postLibrary(published: $published) {
text
staticCalculation
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"published" => true
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{data: %{"postLibrary" => [%{"text" => "bar", "staticCalculation" => "static"}]}} =
result
end
test "the same calculation can be loaded twice with different arguments via aliases" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "bar", text1: "1", text2: "2", published: true)
|> Ash.create!()
resp =
"""
query PostLibrary($published: Boolean) {
postLibrary(published: $published) {
foo: text1And2(separator: "foo")
bar: text1And2(separator: "bar")
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{data: %{"postLibrary" => [%{"foo" => "1foo2", "bar" => "1bar2"}]}} = result
end
test "the same calculation can be sorted on twice with different arguments via aliases" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "bar", text1: "1", text2: "2", published: true)
|> Ash.create!()
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "bar", text1: "1", text2: "2", published: true)
|> Ash.create!()
resp =
"""
query PostLibrary($published: Boolean) {
postLibrary(published: $published, sort: [{field: TEXT1_AND2, order: DESC, text1And2Input: {separator: "a"}}, {field: TEXT1_AND2, order: DESC, text1And2Input: {separator: "b"}}]) {
a: text1And2(separator: "a")
b: text1And2(separator: "b")
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"postLibrary" => [%{"a" => "1a2", "b" => "1b2"}, %{"a" => "1a2", "b" => "1b2"}]
}
} = result
end
test "a read with a non-id primary key fills in the id field" do
record =
AshGraphql.Test.NonIdPrimaryKey
|> Ash.Changeset.for_create(:create, %{})
|> Ash.create!()
resp =
"""
query GetNonIdPrimaryKey($id: ID!) {
getNonIdPrimaryKey(id: $id) {
id
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"id" => record.other
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
id = record.other
assert %{data: %{"getNonIdPrimaryKey" => %{"id" => ^id}}} = result
end
test "get requests against non-encoded primary key fields accept both fields and display both fields" do
record =
AshGraphql.Test.CompositePrimaryKeyNotEncoded
|> Ash.Changeset.for_create(:create, %{})
|> Ash.create!()
resp =
"""
query GetCompositePrimaryKeyNotEncoded($first: ID!, $second: ID!) {
getCompositePrimaryKeyNotEncoded(first: $first, second: $second) {
first
second
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"first" => record.first,
"second" => record.second
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
first = record.first
second = record.second
assert %{
data: %{
"getCompositePrimaryKeyNotEncoded" => %{"first" => ^first, "second" => ^second}
}
} = result
end
test "a read with a composite primary key fills in the id field" do
record =
AshGraphql.Test.CompositePrimaryKey
|> Ash.Changeset.for_create(:create, %{})
|> Ash.create!()
resp =
"""
query GetCompositePrimaryKey($id: ID!) {
getCompositePrimaryKey(id: $id) {
id
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"id" => AshGraphql.Resource.encode_primary_key(record)
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
id = AshGraphql.Resource.encode_primary_key(record)
assert %{data: %{"getCompositePrimaryKey" => %{"id" => ^id}}} = result
end
test "aggregate of a calculation" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "foo",
published: true,
score: 9.8
)
|> Ash.create!()
post =
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "foo", published: true)
|> Ash.create!()
AshGraphql.Test.Comment
|> Ash.Changeset.for_create(:create, %{text: "stuff"})
|> Ash.Changeset.force_change_attribute(:post_id, post.id)
|> Ash.create!()
resp =
"""
query Post($id: ID!) {
getPost(id: $id) {
latestCommentAt
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"id" => post.id
}
)
assert {:ok, result} = resp
assert result[:data]["getPost"]["latestCommentAt"]
end
test "a read with custom types works" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "bar",
published: true,
foo: %{foo: "foo", bar: "bar"}
)
|> Ash.create!()
resp =
"""
query PostLibrary($published: Boolean) {
postLibrary(published: $published) {
text
staticCalculation
foo{
foo
bar
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"published" => true
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"postLibrary" => [
%{
"text" => "bar",
"staticCalculation" => "static",
"foo" => %{"foo" => "foo", "bar" => "bar"}
}
]
}
} = result
end
test "a read without an argument works" do
user =
AshGraphql.Test.User
|> Ash.Changeset.for_create(:create,
name: "My Name"
)
|> Ash.create!()
doc = """
query CurrentUser {
currentUser {
name
}
}
"""
assert {:ok,
%{
data: %{
"currentUser" => %{
"name" => "My Name"
}
}
}} == Absinthe.run(doc, AshGraphql.Test.Schema, context: %{actor: user})
end
test "a multitenant object can be read if tenant is set" do
tenant = "Some Tenant"
tag =
AshGraphql.Test.MultitenantTag
|> Ash.Changeset.for_create(
:create,
[name: "My Tag1"],
tenant: tenant
)
|> Ash.create!()
doc = """
query MultitenantTag($id: ID!) {
getMultitenantTag(id: $id) {
name
}
}
"""
assert {:ok,
%{
data: %{
"getMultitenantTag" => %{
"name" => "My Tag1"
}
}
}} ==
Absinthe.run(doc, AshGraphql.Test.Schema,
context: %{tenant: tenant},
variables: %{"id" => tag.id}
)
end
test "a multitenant relation can be read if tenant is set" do
tenant = "Some Tenant"
tag =
AshGraphql.Test.MultitenantTag
|> Ash.Changeset.for_create(
:create,
[name: "My Tag"],
tenant: tenant
)
|> Ash.create!()
post =
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "foo", published: true)
|> Ash.Changeset.manage_relationship(
:multitenant_tags,
[tag],
on_no_match: {:create, :create_action},
on_lookup: :relate
)
|> Ash.create!()
doc = """
query MultitenantPostTag($id: ID!) {
getPost(id: $id) {
text
published
multitenantTags {
name
}
}
}
"""
assert {:ok,
%{
data: %{
"getPost" => %{
"published" => true,
"text" => "foo",
"multitenantTags" => [
%{
"name" => "My Tag"
}
]
}
}
}} ==
Absinthe.run(doc, AshGraphql.Test.Schema,
context: %{tenant: tenant},
variables: %{"id" => post.id}
)
end
test "manual relationships can be read" do
tag =
AshGraphql.Test.Tag
|> Ash.Changeset.for_create(
:create,
name: "My Tag"
)
|> Ash.create!()
post_1 =
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "foo", published: true)
|> Ash.Changeset.manage_relationship(
:tags,
[tag],
on_no_match: {:create, :create_action},
on_lookup: :relate
)
|> Ash.create!()
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create, text: "bar", published: true)
|> Ash.Changeset.manage_relationship(
:tags,
[tag],
on_no_match: {:create, :create_action},
on_lookup: :relate
)
|> Ash.create!()
doc = """
query ($id: ID!) {
getPost(id: $id) {
text
relatedPosts {
text
}
}
}
"""
assert {:ok,
%{
data: %{
"getPost" => %{
"relatedPosts" => [%{"text" => "bar"}],
"text" => "foo"
}
}
}} ==
Absinthe.run(doc, AshGraphql.Test.Schema, variables: %{"id" => post_1.id})
end
describe "loading through types" do
test "loading through an embed works" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
embed_foo: %{foo: "fred"},
published: true
)
|> Ash.create!()
resp =
"""
query postLibrary {
postLibrary {
embedFoo{
alwaysTrue
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"postLibrary" => [
%{
"embedFoo" => %{
"alwaysTrue" => true
}
}
]
}
} = result
end
test "loading through a union works" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "a",
embed_union_new_type: %{type: :foo, foo: "fred"},
published: true
)
|> Ash.create!()
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "b",
embed_union_new_type: %{type: :bar, bar: "george"},
published: true
)
|> Ash.create!()
resp =
"""
query postLibrary {
postLibrary(sort: {field: TEXT}) {
embedUnionNewType{
...on EmbedUnionNewTypeFoo {
value {
alwaysNil
}
}
...on EmbedUnionNewTypeBar {
value {
alwaysFalse
}
}
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"postLibrary" => [
%{
"embedUnionNewType" => %{
"value" => %{
"alwaysNil" => nil
}
}
},
%{
"embedUnionNewType" => %{
"value" => %{
"alwaysFalse" => false
}
}
}
]
}
} = result
end
test "loading through an unnested union works" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "a",
embed_union_unnested: %{type: :foo, foo: "fred"},
published: true
)
|> Ash.create!()
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "b",
embed_union_unnested: %{type: :bar, bar: "george"},
published: true
)
|> Ash.create!()
resp =
"""
query postLibrary {
postLibrary(sort: {field: TEXT}) {
embedUnionUnnested{
...on FooEmbed {
alwaysNil
}
...on BarEmbed {
alwaysFalse
}
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"postLibrary" => [
%{
"embedUnionUnnested" => %{
"alwaysNil" => nil
}
},
%{
"embedUnionUnnested" => %{
"alwaysFalse" => false
}
}
]
}
} = result
end
test "loading through a list of unnested union with aliases works" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "a",
embed_union_new_type_list: [%{type: :foo, foo: "fred"}],
published: true
)
|> Ash.create!()
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "b",
embed_union_new_type_list: [%{type: :bar, bar: "george"}],
published: true
)
|> Ash.create!()
resp =
"""
query postLibrary {
postLibrary(sort: {field: TEXT}) {
foo: embedUnionNewTypeList{
...on FooEmbed {
alwaysNil
}
...on BarEmbed {
alwaysFalse
}
}
bar: embedUnionNewTypeList{
...on FooEmbed {
alwaysTrue
}
...on BarEmbed {
alwaysTrue
}
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"postLibrary" => [
%{
"bar" => [%{"alwaysTrue" => true}],
"foo" => [%{"alwaysNil" => nil}]
},
%{
"bar" => [%{"alwaysTrue" => true}],
"foo" => [%{"alwaysFalse" => false}]
}
]
}
}
end
test "loading through an unnested union with aliases works" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "a",
embed_union_unnested: %{type: :foo, foo: "fred"},
published: true
)
|> Ash.create!()
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "b",
embed_union_unnested: %{type: :bar, bar: "george"},
published: true
)
|> Ash.create!()
resp =
"""
query postLibrary {
postLibrary(sort: {field: TEXT}) {
foo: embedUnionUnnested{
...on FooEmbed {
alwaysNil
}
...on BarEmbed {
alwaysFalse
}
}
bar: embedUnionUnnested{
...on FooEmbed {
alwaysTrue
}
...on BarEmbed {
alwaysTrue
}
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"postLibrary" => [
%{
"bar" => %{"alwaysTrue" => true},
"foo" => %{"alwaysNil" => nil}
},
%{
"bar" => %{"alwaysTrue" => true},
"foo" => %{"alwaysFalse" => false}
}
]
}
} = result
end
test "loading through an unnested union with aliases works when one is nil" do
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "a",
embed_union_unnested: %{type: :foo, foo: "fred"},
published: true
)
|> Ash.create!()
AshGraphql.Test.Post
|> Ash.Changeset.for_create(:create,
text: "b",
published: true
)
|> Ash.create!()
resp =
"""
query postLibrary {
postLibrary(sort: {field: TEXT}) {
foo: embedUnionUnnested{
...on FooEmbed {
alwaysNil
}
...on BarEmbed {
alwaysFalse
}
}
bar: embedUnionUnnested{
...on FooEmbed {
alwaysTrue
}
...on BarEmbed {
alwaysTrue
}
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"postLibrary" => [
%{
"bar" => %{"alwaysTrue" => true},
"foo" => %{"alwaysNil" => nil}
},
%{
"bar" => nil,
"foo" => nil
}
]
}
} = result
end
test "loading relationships through a union with fragments works" do
user1 =
AshGraphql.Test.User
|> Ash.Changeset.for_create(:create, %{name: "fred"})
|> Ash.create!(authorize?: false)
user2 =
AshGraphql.Test.User
|> Ash.Changeset.for_create(:create, %{name: "barney"})
|> Ash.create!(authorize?: false)
post1 =
AshGraphql.Test.Post
|> Ash.Changeset.for_create(
:create,
%{
author_id: user1.id,
text: "a",
published: true
}
)
|> Ash.create!()
post1 =
post1
|> Ash.Changeset.for_update(
:update_with_comments,
%{
comments: [%{text: "comment", author_id: user2.id}],
sponsored_comments: [%{text: "sponsored"}]
}
)
|> Ash.update!()
resp =
"""
query postLibrary {
getPost(id: "#{post1.id}") {
postComments {
...on Comment {
__typename
post {
...Author
}
}
}
}
}
fragment Author on Post {
author {
name
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"getPost" => %{
"postComments" => [
%{},
%{"__typename" => "Comment", "post" => %{"author" => %{"name" => "fred"}}}
]
}
}
} = result
end
test "loading relationships through an unnested union with aliases works" do
user =
AshGraphql.Test.User
|> Ash.Changeset.for_create(:create, %{name: "My Name"})
|> Ash.create!()
post =
AshGraphql.Test.Post
|> Ash.Changeset.for_create(
:create,
%{
author_id: user.id,
text: "a",
published: true
}
)
|> Ash.create!()
post =
post
|> Ash.Changeset.for_update(
:update_with_comments,
%{
comments: [%{text: "comment", author_id: user.id}],
sponsored_comments: [%{text: "sponsored"}]
}
)
|> Ash.update!()
resp =
"""
query postLibrary {
postLibrary(sort: {field: TEXT}) {
postComments {
...on Comment {
__typename
text
author {
name
}
}
...on SponsoredComment {
__typename
text
p: post {
id
user: author {
name
posts {
id
}
}
}
}
}
bar: postComments {
...on Comment {
__typename
text
author {
name
}
}
...on SponsoredComment {
__typename
text
post {
id
}
}
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
post_id = post.id
assert %{
data: %{
"postLibrary" => [
%{
"postComments" => [
%{
"__typename" => "SponsoredComment",
"text" => "sponsored",
"p" => %{"id" => ^post_id, "user" => %{"name" => "My Name"}}
},
%{
"__typename" => "Comment",
"text" => "comment",
"author" => %{"name" => "My Name"}
}
],
"bar" => [
%{
"__typename" => "SponsoredComment",
"text" => "sponsored",
"post" => %{"id" => ^post_id}
},
%{
"__typename" => "Comment",
"text" => "comment",
"author" => %{"name" => "My Name"}
}
]
}
]
}
} = result
end
end
end