github.com/dgraph-io/dgraph@v1.2.8/graphql/schema/errors_test.go (about)

     1  /*
     2   * Copyright 2019 Dgraph Labs, Inc. and Contributors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package schema
    18  
    19  import (
    20  	"encoding/json"
    21  	"errors"
    22  	"testing"
    23  
    24  	"github.com/dgraph-io/dgraph/x"
    25  	"github.com/stretchr/testify/require"
    26  	"github.com/vektah/gqlparser/gqlerror"
    27  
    28  	"github.com/stretchr/testify/assert"
    29  )
    30  
    31  func TestGQLWrapf_Error(t *testing.T) {
    32  	tests := map[string]struct {
    33  		err  error
    34  		msg  string
    35  		args []interface{}
    36  		req  string
    37  	}{
    38  		"wrap one error": {err: errors.New("An error occurred"),
    39  			msg: "mutation failed",
    40  			req: "mutation failed because An error occurred"},
    41  		"wrap multiple errors": {
    42  			err: GQLWrapf(errors.New("A Dgraph error occurred"), "couldn't check ID type"),
    43  			msg: "delete mutation failed",
    44  			req: "delete mutation failed because couldn't check ID type because " +
    45  				"A Dgraph error occurred"},
    46  		"wrap an x.GqlError": {err: x.GqlErrorf("of bad GraphQL input"),
    47  			msg: "couldn't generate query",
    48  			req: "couldn't generate query because of bad GraphQL input"},
    49  		"wrap and format": {err: errors.New("an error occurred"),
    50  			msg:  "couldn't generate %s for %s",
    51  			args: []interface{}{"query", "you"},
    52  			req:  "couldn't generate query for you because an error occurred"},
    53  		"wrap a list": {
    54  			err: x.GqlErrorList{
    55  				x.GqlErrorf("an error occurred"),
    56  				x.GqlErrorf("something bad happend"),
    57  			},
    58  			msg: "couldn't do it",
    59  			req: "couldn't do it because an error occurred\n" +
    60  				"couldn't do it because something bad happend"},
    61  	}
    62  
    63  	for name, tcase := range tests {
    64  		t.Run(name, func(t *testing.T) {
    65  			assert.Equal(t, tcase.req, GQLWrapf(tcase.err, tcase.msg, tcase.args...).Error())
    66  		})
    67  	}
    68  }
    69  
    70  func TestGQLWrapLocationf_Error(t *testing.T) {
    71  
    72  	tests := map[string]struct {
    73  		err  error
    74  		msg  string
    75  		args []interface{}
    76  		loc  x.Location
    77  		req  string
    78  	}{
    79  		"wrap one error": {err: errors.New("An error occurred"),
    80  			msg: "mutation failed",
    81  			loc: x.Location{Line: 1, Column: 2},
    82  			req: "mutation failed because An error occurred (Locations: [{Line: 1, Column: 2}])"},
    83  		"wrap multiple errors": {
    84  			err: GQLWrapf(errors.New("A Dgraph error occurred"), "couldn't check ID type"),
    85  			msg: "delete mutation failed",
    86  			loc: x.Location{Line: 1, Column: 2},
    87  			req: "delete mutation failed because couldn't check ID type because " +
    88  				"A Dgraph error occurred (Locations: [{Line: 1, Column: 2}])"},
    89  		"wrap an x.GqlError with location": {
    90  			err: x.GqlErrorf("of bad GraphQL input").WithLocations(x.Location{Line: 1, Column: 8}),
    91  			msg: "couldn't generate query",
    92  			loc: x.Location{Line: 1, Column: 2},
    93  			req: "couldn't generate query because of bad GraphQL input " +
    94  				"(Locations: [{Line: 1, Column: 8}, {Line: 1, Column: 2}])"},
    95  		"wrap and format": {err: errors.New("an error occurred"),
    96  			msg:  "couldn't generate %s for %s",
    97  			args: []interface{}{"query", "you"},
    98  			loc:  x.Location{Line: 1, Column: 2},
    99  			req: "couldn't generate query for you because an error occurred " +
   100  				"(Locations: [{Line: 1, Column: 2}])"},
   101  		"wrap a list": {
   102  			err: x.GqlErrorList{
   103  				x.GqlErrorf("an error occurred"),
   104  				x.GqlErrorf("something bad happend").WithLocations(x.Location{Line: 1, Column: 8}),
   105  			},
   106  			msg: "couldn't do it",
   107  			loc: x.Location{Line: 1, Column: 2},
   108  			req: "couldn't do it because an error occurred (Locations: [{Line: 1, Column: 2}])\n" +
   109  				"couldn't do it because something bad happend " +
   110  				"(Locations: [{Line: 1, Column: 8}, {Line: 1, Column: 2}])"},
   111  	}
   112  
   113  	for name, tcase := range tests {
   114  		t.Run(name, func(t *testing.T) {
   115  			assert.Equal(t,
   116  				tcase.req,
   117  				GQLWrapLocationf(tcase.err, tcase.loc, tcase.msg, tcase.args...).Error())
   118  		})
   119  	}
   120  }
   121  
   122  func TestGQLWrapf_nil(t *testing.T) {
   123  	require.Nil(t, GQLWrapf(nil, "nothing"))
   124  }
   125  
   126  func TestAsGQLErrors(t *testing.T) {
   127  	tests := map[string]struct {
   128  		err error
   129  		req string
   130  	}{
   131  		"just an error": {err: errors.New("An error occurred"),
   132  			req: `[{"message": "An error occurred"}]`},
   133  		"wrap an error": {
   134  			err: GQLWrapf(errors.New("A Dgraph error occurred"), "couldn't check ID type"),
   135  			req: `[{"message": "couldn't check ID type because A Dgraph error occurred"}]`},
   136  		"an x.GqlError": {err: x.GqlErrorf("A GraphQL error"),
   137  			req: `[{"message": "A GraphQL error"}]`},
   138  		"an x.GqlError with a location": {err: x.GqlErrorf("A GraphQL error at a location").
   139  			WithLocations(x.Location{Line: 1, Column: 2}),
   140  			req: `[{
   141  				"message": "A GraphQL error at a location", 
   142  				"locations": [{"column":2, "line":1}]}]`},
   143  		"wrap an x.GqlError with a location": {
   144  			err: GQLWrapf(x.GqlErrorf("this error has a location").
   145  				WithLocations(x.Location{Line: 1, Column: 2}), "this error didn't need a location"),
   146  			req: `[{
   147  				"message": "this error didn't need a location because this error has a location",
   148  				"locations": [{"column":2, "line":1}]}]`},
   149  		"GQLWrapLocationf": {err: GQLWrapLocationf(x.GqlErrorf("this error didn't have a location"),
   150  			x.Location{Line: 1, Column: 8},
   151  			"there's one location"),
   152  			req: `[{
   153  				"message": "there's one location because this error didn't have a location",
   154  				"locations": [{"column":8, "line":1}]}]`},
   155  		"GQLWrapLocationf wrapping a location": {
   156  			err: GQLWrapLocationf(x.GqlErrorf("this error also had a location").
   157  				WithLocations(x.Location{Line: 1, Column: 2}), x.Location{Line: 1, Column: 8},
   158  				"there's two locations"),
   159  			req: `[{
   160  				"message": "there's two locations because this error also had a location",
   161  				"locations": [{"column":2, "line":1}, {"column":8, "line":1}]}]`},
   162  		"an x.GqlErrorList": {
   163  			err: x.GqlErrorList{
   164  				x.GqlErrorf("A GraphQL error"),
   165  				x.GqlErrorf("Another GraphQL error").WithLocations(x.Location{Line: 1, Column: 2})},
   166  			req: `[
   167  				{"message":"A GraphQL error"}, 
   168  				{"message":"Another GraphQL error", "locations": [{"column":2, "line":1}]}]`},
   169  		"a gql parser error": {
   170  			err: gqlerror.Errorf("A GraphQL error"),
   171  			req: `[{"message": "A GraphQL error"}]`},
   172  		"a gql parser error with a location": {
   173  			err: &gqlerror.Error{
   174  				Message:   "A GraphQL error",
   175  				Locations: []gqlerror.Location{{Line: 1, Column: 2}}},
   176  			req: `[{"message": "A GraphQL error", "locations": [{"column":2, "line":1}]}]`},
   177  		"a list of gql parser errors": {
   178  			err: gqlerror.List{
   179  				gqlerror.Errorf("A GraphQL error"), gqlerror.Errorf("Another GraphQL error")},
   180  			req: `[{"message":"A GraphQL error"}, {"message":"Another GraphQL error"}]`},
   181  	}
   182  
   183  	for name, tcase := range tests {
   184  		t.Run(name, func(t *testing.T) {
   185  			gqlErrs, err := json.Marshal(AsGQLErrors(tcase.err))
   186  			require.NoError(t, err)
   187  
   188  			assert.JSONEq(t, tcase.req, string(gqlErrs))
   189  		})
   190  	}
   191  }
   192  
   193  func TestAsGQLErrors_nil(t *testing.T) {
   194  	require.Nil(t, AsGQLErrors(nil))
   195  }
   196  
   197  func TestAppendGQLErrs(t *testing.T) {
   198  	tests := map[string]struct {
   199  		err1 error
   200  		err2 error
   201  		req  string
   202  	}{
   203  		"two errors": {
   204  			err1: errors.New("An error occurred"),
   205  			err2: errors.New("Another error"),
   206  			req:  `[{"message": "An error occurred"}, {"message": "Another error"}]`,
   207  		},
   208  		"left nil": {
   209  			err1: nil,
   210  			err2: errors.New("An error occurred"),
   211  			req:  `[{"message": "An error occurred"}]`,
   212  		},
   213  		"right nil": {
   214  			err1: errors.New("An error occurred"),
   215  			err2: nil,
   216  			req:  `[{"message": "An error occurred"}]`,
   217  		},
   218  		"both nil": {
   219  			err1: nil,
   220  			err2: nil,
   221  			req:  "null",
   222  		},
   223  	}
   224  
   225  	for name, tcase := range tests {
   226  		t.Run(name, func(t *testing.T) {
   227  			gqlErrs, err := json.Marshal(AppendGQLErrs(tcase.err1, tcase.err2))
   228  			require.NoError(t, err)
   229  
   230  			assert.JSONEq(t, tcase.req, string(gqlErrs))
   231  		})
   232  	}
   233  }