Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(GraphQL): Unions #6722

Merged
merged 15 commits into from
Oct 19, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
tests
abhimanyusinghgaur committed Oct 14, 2020
commit 7c33f237f49c2f2fc468e09069c8d028d9f7cbc8
1 change: 1 addition & 0 deletions graphql/e2e/common/common.go
Original file line number Diff line number Diff line change
@@ -388,6 +388,7 @@ func RunAll(t *testing.T) {
t.Run("fragment in mutation", fragmentInMutation)
t.Run("fragment in query", fragmentInQuery)
t.Run("fragment in query on Interface", fragmentInQueryOnInterface)
t.Run("fragment in query on union", fragmentInQueryOnUnion)
t.Run("fragment in query on Object", fragmentInQueryOnObject)
}

117 changes: 117 additions & 0 deletions graphql/e2e/common/fragment.go
Original file line number Diff line number Diff line change
@@ -21,6 +21,8 @@ import (
"fmt"
"testing"

"github.com/dgraph-io/dgraph/testutil"

"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/stretchr/testify/require"
@@ -310,6 +312,121 @@ func fragmentInQueryOnInterface(t *testing.T) {
deleteThingTwo(t, thingTwoId)
}

func fragmentInQueryOnUnion(t *testing.T) {
newStarship := addStarship(t)
humanID := addHuman(t, newStarship.ID)
homeId, dogId, parrotId, plantId := addHome(t, humanID)

queryHomeParams := &GraphQLParams{
Query: `query {
queryHome {
members {
__typename
... on Animal {
category
}
... on Dog {
id
breed
}
... on Parrot {
repeatsWords
}
... on Employee {
ename
}
... on Character {
id
}
... on Human {
name
}
... on Plant {
id
}
}
}
qh: queryHome {
members {
... on Animal {
__typename
}
... on Dog {
breed
}
... on Human {
name
}
... on Plant {
breed
}
}
}
}
`,
}

gqlResponse := queryHomeParams.ExecuteAsPost(t, GraphqlURL)
RequireNoGQLErrors(t, gqlResponse)

queryHomeExpected := fmt.Sprintf(`
{
"queryHome": [
{
"members": [
{
"__typename": "Human",
"ename": "Han_employee",
"id": "%s",
"name": "Han"
},
{
"__typename": "Dog",
"category": "Mammal",
"id": "%s",
"breed": "German Shephard"
},
{
"__typename": "Parrot",
"category": "Bird",
"repeatsWords": [
"Good Morning!",
"squawk"
]
},
{
"__typename": "Plant",
"id": "%s"
}
]
}
],
"qh": [
{
"members": [
{
"name": "Han"
},
{
"__typename": "Dog",
"breed": "German Shephard"
},
{
"__typename": "Parrot"
},
{
"breed": "Flower"
}
]
}
]
}`, humanID, dogId, plantId)
testutil.CompareJSON(t, queryHomeExpected, string(gqlResponse.Data))

cleanupStarwars(t, newStarship.ID, humanID, "")
deleteHome(t, homeId, dogId, parrotId, plantId)
}

func fragmentInQueryOnObject(t *testing.T) {
newStarship := addStarship(t)
humanID := addHuman(t, newStarship.ID)
113 changes: 109 additions & 4 deletions graphql/e2e/common/mutation.go
Original file line number Diff line number Diff line change
@@ -2376,7 +2376,7 @@ func addDroid(t *testing.T) string {
}

func addThingOne(t *testing.T) string {
addDroidParams := &GraphQLParams{
addThingOneParams := &GraphQLParams{
Query: `mutation addThingOne($input: AddThingOneInput!) {
addThingOne(input: [$input]) {
thingOne {
@@ -2391,7 +2391,7 @@ func addThingOne(t *testing.T) string {
}},
}

gqlResponse := addDroidParams.ExecuteAsPost(t, GraphqlURL)
gqlResponse := addThingOneParams.ExecuteAsPost(t, GraphqlURL)
RequireNoGQLErrors(t, gqlResponse)

var result struct {
@@ -2409,7 +2409,7 @@ func addThingOne(t *testing.T) string {
}

func addThingTwo(t *testing.T) string {
addDroidParams := &GraphQLParams{
addThingTwoParams := &GraphQLParams{
Query: `mutation addThingTwo($input: AddThingTwoInput!) {
addThingTwo(input: [$input]) {
thingTwo {
@@ -2424,7 +2424,7 @@ func addThingTwo(t *testing.T) string {
}},
}

gqlResponse := addDroidParams.ExecuteAsPost(t, GraphqlURL)
gqlResponse := addThingTwoParams.ExecuteAsPost(t, GraphqlURL)
RequireNoGQLErrors(t, gqlResponse)

var result struct {
@@ -2441,6 +2441,111 @@ func addThingTwo(t *testing.T) string {
return result.AddThingTwo.ThingTwo[0].ID
}

func addHome(t *testing.T, humanId string) (string, string, string, string) {
addHomeParams := &GraphQLParams{
Query: `mutation addHome($input: AddHomeInput!) {
addHome(input: [$input]) {
home {
id
members {
__typename
... on Animal {
id
}
... on Human {
id
}
... on Plant {
id
}
}
}
}
}`,
Variables: map[string]interface{}{
"input": map[string]interface{}{
"address": "Avenger Street",
"members": []interface{}{
map[string]interface{}{
"dogRef": map[string]interface{}{
"category": "Mammal",
"breed": "German Shephard",
},
},
map[string]interface{}{
"parrotRef": map[string]interface{}{
"category": "Bird",
"repeatsWords": []interface{}{
"squawk",
"Good Morning!",
},
},
},
map[string]interface{}{
"humanRef": map[string]interface{}{
"id": humanId,
},
},
map[string]interface{}{
"plantRef": map[string]interface{}{
"breed": "Flower",
},
},
},
"favouriteMember": map[string]interface{}{
"humanRef": map[string]interface{}{
"id": humanId,
},
},
},
},
}

gqlResponse := addHomeParams.ExecuteAsPost(t, GraphqlURL)
RequireNoGQLErrors(t, gqlResponse)

var result struct {
AddHome struct {
Home []struct {
ID string
Members []struct {
Typename string `json:"__typename"`
ID string
}
}
}
}
err := json.Unmarshal([]byte(gqlResponse.Data), &result)
require.NoError(t, err)

homeId := result.AddHome.Home[0].ID
requireUID(t, homeId)

var dogId, parrotId, plantId string
for _, member := range result.AddHome.Home[0].Members {
switch member.Typename {
case "Dog":
dogId = member.ID
case "Parrot":
parrotId = member.ID
case "Plant":
plantId = member.ID
}
}
return homeId, dogId, parrotId, plantId
}

func deleteHome(t *testing.T, homeId, dogId, parrotId, plantId string) {
homeFilter := map[string]interface{}{"id": []string{homeId}}
deleteGqlType(t, "Home", homeFilter, 1, nil)
dogFilter := map[string]interface{}{"id": []string{dogId}}
deleteGqlType(t, "Dog", dogFilter, 1, nil)
parrotFilter := map[string]interface{}{"id": []string{parrotId}}
deleteGqlType(t, "Parrot", parrotFilter, 1, nil)
plantFilter := map[string]interface{}{"id": []string{plantId}}
deleteGqlType(t, "Plant", plantFilter, 1, nil)
}

func deleteThingOne(t *testing.T, thingOneId string) {
thingOneFilter := map[string]interface{}{"id": []string{thingOneId}}
deleteGqlType(t, "ThingOne", thingOneFilter, 1, nil)
2 changes: 2 additions & 0 deletions graphql/e2e/common/schema.go
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ package common

import (
"context"
"fmt"
"testing"

"github.com/dgraph-io/dgo/v200"
@@ -112,6 +113,7 @@ func SchemaTest(t *testing.T, expectedDgraphSchema string) {
resp, err := client.NewReadOnlyTxn().Query(context.Background(), "schema {}")
require.NoError(t, err)

fmt.Println(string(resp.GetJson()))
testutil.CompareJSON(t, expectedDgraphSchema, string(resp.GetJson()))
}

52 changes: 52 additions & 0 deletions graphql/e2e/directives/schema.graphql
Original file line number Diff line number Diff line change
@@ -184,3 +184,55 @@ type Person1 {
name: String!
friends: [Person1] @hasInverse(field: friends)
}

# union testing - start
enum AnimalCategory {
Fish
Amphibian
Reptile
Bird
Mammal
InVertebrate
}

interface Animal {
id: ID!
category: AnimalCategory @search
}

type Dog implements Animal {
breed: String @search
}

type Parrot implements Animal {
repeatsWords: [String]
}

type Cheetah implements Animal {
speed: Float
}

"""
This type specifically doesn't implement any interface.
We need this to test out all cases with union.
"""
type Plant {
id: ID!
breed: String # field with same name as a field in type Dog
}

union HomeMember = Dog | Parrot | Human | Plant

type Zoo {
id: ID!
animals: [Animal]
city: String
}

type Home {
id: ID!
address: String
members: [HomeMember]
favouriteMember: HomeMember
}
# union testing - end
Loading