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 }