github.com/luciferinlove/gqlgen@v0.17.16-bzc.1/codegen/testserver/followschema/nulls_test.go (about)

     1  package followschema
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/luciferinlove/gqlgen/client"
     8  	"github.com/luciferinlove/gqlgen/graphql/handler"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestNullBubbling(t *testing.T) {
    13  	resolvers := &Stub{}
    14  	resolvers.QueryResolver.Valid = func(ctx context.Context) (s string, e error) {
    15  		return "Ok", nil
    16  	}
    17  	resolvers.QueryResolver.Errors = func(ctx context.Context) (errors *Errors, e error) {
    18  		return &Errors{}, nil
    19  	}
    20  	resolvers.QueryResolver.ErrorBubble = func(ctx context.Context) (i *Error, e error) {
    21  		return &Error{ID: "E1234"}, nil
    22  	}
    23  	resolvers.QueryResolver.ErrorBubbleList = func(ctx context.Context) (i []*Error, e error) {
    24  		return []*Error{{ID: "1"}, nil, nil}, nil
    25  	}
    26  	resolvers.QueryResolver.ErrorList = func(ctx context.Context) (i []*Error, e error) {
    27  		return []*Error{nil}, nil
    28  	}
    29  
    30  	c := client.New(handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers})))
    31  
    32  	t.Run("when function errors on non required field", func(t *testing.T) {
    33  		var resp struct {
    34  			Valid       string
    35  			ErrorBubble *struct {
    36  				Id                      string
    37  				ErrorOnNonRequiredField *string
    38  			}
    39  		}
    40  		err := c.Post(`query { valid, errorBubble { id, errorOnNonRequiredField } }`, &resp)
    41  
    42  		require.EqualError(t, err, `[{"message":"boom","path":["errorBubble","errorOnNonRequiredField"]}]`)
    43  		require.Equal(t, "E1234", resp.ErrorBubble.Id)
    44  		require.Nil(t, resp.ErrorBubble.ErrorOnNonRequiredField)
    45  		require.Equal(t, "Ok", resp.Valid)
    46  	})
    47  
    48  	t.Run("when function errors", func(t *testing.T) {
    49  		var resp struct {
    50  			Valid       string
    51  			ErrorBubble *struct {
    52  				NilOnRequiredField string
    53  			}
    54  		}
    55  		err := c.Post(`query { valid, errorBubble { id, errorOnRequiredField } }`, &resp)
    56  
    57  		require.EqualError(t, err, `[{"message":"boom","path":["errorBubble","errorOnRequiredField"]}]`)
    58  		require.Nil(t, resp.ErrorBubble)
    59  		require.Equal(t, "Ok", resp.Valid)
    60  	})
    61  
    62  	t.Run("when user returns null on required field", func(t *testing.T) {
    63  		var resp struct {
    64  			Valid       string
    65  			ErrorBubble *struct {
    66  				NilOnRequiredField string
    67  			}
    68  		}
    69  		err := c.Post(`query { valid, errorBubble { id, nilOnRequiredField } }`, &resp)
    70  
    71  		require.EqualError(t, err, `[{"message":"the requested element is null which the schema does not allow","path":["errorBubble","nilOnRequiredField"]}]`)
    72  		require.Nil(t, resp.ErrorBubble)
    73  		require.Equal(t, "Ok", resp.Valid)
    74  	})
    75  
    76  	t.Run("when list element is null", func(t *testing.T) {
    77  		var resp struct {
    78  			Valid     string
    79  			ErrorList []*struct{}
    80  		}
    81  		err := c.Post(`query { valid, errorList { id } }`, &resp)
    82  
    83  		require.Nil(t, err)
    84  		require.Equal(t, len(resp.ErrorList), 1)
    85  		require.Nil(t, resp.ErrorList[0])
    86  		require.Equal(t, "Ok", resp.Valid)
    87  	})
    88  
    89  	t.Run("when non-null list element is null", func(t *testing.T) {
    90  		var resp struct {
    91  			Valid           string
    92  			ErrorBubbleList []*struct{}
    93  		}
    94  		err := c.Post(`query { valid, errorBubbleList { id } }`, &resp)
    95  
    96  		require.Contains(t, err.Error(), `{"message":"the requested element is null which the schema does not allow","path":["errorBubbleList",2]}`)
    97  		require.Contains(t, err.Error(), `{"message":"the requested element is null which the schema does not allow","path":["errorBubbleList",1]}`)
    98  		require.Nil(t, resp.ErrorBubbleList)
    99  		require.Equal(t, "Ok", resp.Valid)
   100  	})
   101  
   102  	t.Run("null args", func(t *testing.T) {
   103  		var resp struct {
   104  			NullableArg *string
   105  		}
   106  		resolvers.QueryResolver.NullableArg = func(ctx context.Context, arg *int) (i *string, e error) {
   107  			v := "Ok"
   108  			return &v, nil
   109  		}
   110  
   111  		err := c.Post(`query { nullableArg(arg: null) }`, &resp)
   112  		require.Nil(t, err)
   113  		require.Equal(t, "Ok", *resp.NullableArg)
   114  	})
   115  
   116  	t.Run("concurrent null detection", func(t *testing.T) {
   117  		var resp interface{}
   118  		resolvers.ErrorsResolver.A = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil }
   119  		resolvers.ErrorsResolver.B = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil }
   120  		resolvers.ErrorsResolver.C = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil }
   121  		resolvers.ErrorsResolver.D = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil }
   122  		resolvers.ErrorsResolver.E = func(ctx context.Context, obj *Errors) (i *Error, e error) { return nil, nil }
   123  
   124  		err := c.Post(`{ errors {
   125  			a { id },
   126  			b { id },
   127  			c { id },
   128  			d { id },
   129  			e { id },
   130  		} }`, &resp)
   131  
   132  		require.Error(t, err)
   133  		require.Contains(t, err.Error(), "the requested element is null which the schema does not allow")
   134  	})
   135  }