ash_graphql/test/create_test.exs

697 lines
15 KiB
Elixir
Raw Normal View History

2020-12-02 18:07:15 +13:00
defmodule AshGraphql.CreateTest do
use ExUnit.Case, async: false
setup do
on_exit(fn ->
Application.delete_env(:ash_graphql, AshGraphql.Test.Api)
2022-09-28 19:28:44 +13:00
AshGraphql.TestHelpers.stop_ets()
end)
end
2020-12-02 18:07:15 +13:00
test "metadata is in the result" do
resp =
"""
mutation SimpleCreatePost($input: SimpleCreatePostInput) {
simpleCreatePost(input: $input) {
result{
text
comments(sort:{field:TEXT}){
text
}
}
metadata{
foo
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{"input" => %{"text" => "foobar"}}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"simpleCreatePost" => %{
"result" => %{
"text" => "foobar"
},
"metadata" => %{
"foo" => "bar"
}
}
}
} = result
end
test "a create with a managed relationship works" do
resp =
"""
mutation CreatePostWithComments($input: CreatePostWithCommentsInput) {
createPostWithComments(input: $input) {
result{
text
comments(sort:{field:TEXT}){
text
}
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text" => "foobar",
"comments" => [
%{"text" => "foobar"},
%{"text" => "barfoo"}
]
}
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"createPostWithComments" => %{
"result" => %{
"text" => "foobar",
"comments" => [%{"text" => "barfoo"}, %{"text" => "foobar"}]
}
}
}
} = result
end
test "a union type can be written to" do
resp =
"""
mutation SimpleCreatePost($input: SimpleCreatePostInput) {
simpleCreatePost(input: $input) {
result{
text1
simpleUnion {
... on PostSimpleUnionString {
value
}
... on PostSimpleUnionInt {
value
}
}
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text1" => "foo",
"simpleUnion" => %{
"int" => 10
}
}
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"simpleCreatePost" => %{
"result" => %{
"simpleUnion" => %{
"value" => 10
}
}
}
}
} = result
end
test "an embedded union type can be written to" do
resp =
"""
mutation SimpleCreatePost($input: SimpleCreatePostInput) {
simpleCreatePost(input: $input) {
result{
text1
embedUnion {
... on PostEmbedUnionFoo {
value {
foo
}
}
... on PostEmbedUnionBar {
value {
bar
}
}
}
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text1" => "foo",
"embedUnion" => %{
"foo" => %{
"foo" => "10"
}
}
}
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"simpleCreatePost" => %{
"result" => %{
"embedUnion" => %{
"value" => %{
"foo" => "10"
}
}
}
}
}
} = result
end
test "a create can load a calculation without selecting the fields the calculation needs" do
resp =
"""
mutation SimpleCreatePost($input: SimpleCreatePostInput) {
simpleCreatePost(input: $input) {
result{
text1
fullText
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{"input" => %{"text1" => "foo", "text2" => "bar"}}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"simpleCreatePost" => %{
"result" => %{
"fullText" => "foobar"
}
}
}
} = result
end
test "a create can use custom input types" do
resp =
"""
mutation SimpleCreatePost($input: SimpleCreatePostInput) {
simpleCreatePost(input: $input) {
result{
text1
integerAsStringInApi
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{"input" => %{"text1" => "foo", "integerAsStringInApi" => "1"}}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"simpleCreatePost" => %{
"result" => %{
"integerAsStringInApi" => "1"
}
}
}
} = result
end
test "a create can load a calculation on a related belongs_to record" do
author = AshGraphql.Test.Api.create!(Ash.Changeset.new(AshGraphql.Test.User, name: "bob"))
resp =
"""
mutation SimpleCreatePost($input: SimpleCreatePostInput) {
simpleCreatePost(input: $input) {
result{
text1
fullText
author {
nameTwice
}
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{"input" => %{"text1" => "foo", "text2" => "bar", "authorId" => author.id}}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"simpleCreatePost" => %{
"result" => %{
"fullText" => "foobar",
"author" => %{
"nameTwice" => "bob bob"
}
}
}
}
} = result
end
test "a create with a managed relationship works with many_to_many and [on_lookup: :relate, on_match: :relate]" do
resp =
"""
mutation CreatePostWithCommentsAndTags($input: CreatePostWithCommentsAndTagsInput) {
createPostWithCommentsAndTags(input: $input) {
result{
text
comments(sort:{field:TEXT}){
text
}
tags(sort:{field:NAME}){
name
}
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text" => "foobar",
"comments" => [
%{"text" => "foobar"},
%{"text" => "barfoo"}
],
"tags" => [%{"name" => "test"}, %{"name" => "tag"}]
}
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"createPostWithCommentsAndTags" => %{
"result" => %{
"text" => "foobar",
"comments" => [%{"text" => "barfoo"}, %{"text" => "foobar"}],
"tags" => [%{"name" => "tag"}, %{"name" => "test"}]
}
}
}
} = result
end
2020-12-02 18:07:15 +13:00
test "a create with arguments works" do
resp =
"""
mutation CreatePost($input: CreatePostInput) {
createPost(input: $input) {
result{
text
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text" => "foobar",
"confirmation" => "foobar"
}
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{data: %{"createPost" => %{"result" => %{"text" => "foobar"}}}} = result
end
test "a create with a fragment works" do
resp =
"""
fragment comparisonFields on Post {
text
}
mutation CreatePost($input: CreatePostInput) {
createPost(input: $input) {
result{
...comparisonFields
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text" => "foobar",
"confirmation" => "foobar"
}
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{data: %{"createPost" => %{"result" => %{"text" => "foobar"}}}} = result
end
test "an upsert works" do
post =
AshGraphql.Test.Post
|> Ash.Changeset.new(text: "foobar")
|> AshGraphql.Test.Api.create!()
resp =
"""
mutation CreatePost($input: UpsertPostInput) {
upsertPost(input: $input) {
result{
text
id
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"id" => post.id,
"text" => "foobar"
}
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
post_id = post.id
2021-04-17 05:49:51 +12:00
assert %{data: %{"upsertPost" => %{"result" => %{"text" => "foobar", "id" => ^post_id}}}} =
result
end
2020-12-02 18:07:15 +13:00
test "arguments are threaded properly" do
resp =
"""
mutation CreatePost($input: CreatePostInput) {
createPost(input: $input) {
result{
text
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text" => "foobar",
"confirmation" => "foobar2"
}
}
)
assert {:ok, result} = resp
assert %{data: %{"createPost" => %{"result" => nil, "errors" => [%{"message" => message}]}}} =
result
assert message =~ "Confirmation did not match value"
2020-12-02 18:07:15 +13:00
end
defmodule ErrorHandler do
def handle_error(error, _context) do
%{error | message: "replaced!"}
end
end
test "errors can be intercepted" do
Application.put_env(:ash_graphql, AshGraphql.Test.Api,
graphql: [
error_handler: {ErrorHandler, :handle_error, []}
]
)
resp =
"""
mutation CreatePost($input: CreatePostWithRequiredErrorInput) {
createPostWithRequiredError(input: $input) {
result{
text
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{}
}
)
assert {:ok, result} = resp
assert %{
data: %{
"createPostWithRequiredError" => %{
"result" => nil,
"errors" => [%{"message" => message}]
}
}
} = result
assert message =~ "replaced!"
end
2021-09-12 17:02:08 +12:00
test "root level error" do
Application.put_env(:ash_graphql, AshGraphql.Test.Api,
2021-09-12 17:02:08 +12:00
graphql: [show_raised_errors?: true, root_level_errors?: true]
)
resp =
"""
mutation CreatePost($input: CreatePostInput) {
createPost(input: $input) {
result{
text
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text" => "foobar",
"confirmation" => "foobar2"
}
}
)
assert {:ok, result} = resp
assert %{errors: [%{message: message}]} = result
assert message =~ "Confirmation did not match value"
end
test "custom input types are used" do
resp =
"""
mutation CreatePost($input: CreatePostInput) {
createPost(input: $input) {
result{
text
foo{
foo
bar
}
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text" => "foobar",
"confirmation" => "foobar",
"foo" => %{
"foo" => "foo",
"bar" => "bar"
}
}
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"createPost" => %{
"result" => %{"text" => "foobar", "foo" => %{"foo" => "foo", "bar" => "bar"}}
}
}
} = result
end
2021-03-29 08:46:23 +13:00
test "standard enums are used" do
resp =
"""
mutation CreatePost($input: CreatePostInput) {
createPost(input: $input) {
result{
text
statusEnum
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text" => "foobar",
"confirmation" => "foobar",
"statusEnum" => "OPEN"
}
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"createPost" => %{
"result" => %{"text" => "foobar", "statusEnum" => "OPEN"}
}
}
} = result
end
2021-03-29 08:46:23 +13:00
test "custom enums are used" do
resp =
"""
mutation CreatePost($input: CreatePostInput) {
createPost(input: $input) {
result{
text
status
}
errors{
message
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{
"input" => %{
"text" => "foobar",
"confirmation" => "foobar",
"status" => "OPEN"
}
}
)
assert {:ok, result} = resp
refute Map.has_key?(result, :errors)
assert %{
data: %{
"createPost" => %{
"result" => %{"text" => "foobar", "status" => "OPEN"}
}
}
} = result
end
2020-12-02 18:07:15 +13:00
end