From a72e34fbac50846451b5578967365c029124ac79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Mar=C3=A7al?= Date: Thu, 31 Oct 2019 16:06:04 -0300 Subject: [PATCH 1/2] Remove go tom Issue: #16 --- Gopkg.lock | 441 ----------------------------------------------------- Gopkg.toml | 33 ---- 2 files changed, 474 deletions(-) delete mode 100644 Gopkg.lock delete mode 100644 Gopkg.toml diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index 45bf29b..0000000 --- a/Gopkg.lock +++ /dev/null @@ -1,441 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:f780d408067189c4c42b53f7bb24ebf8fd2a1e4510b813ed6e79dd6563e38cc5" - name = "github.com/ajg/form" - packages = ["."] - pruneopts = "UT" - revision = "5c4e22684113ffc2a77577c178189940925f9aef" - version = "v1.5.1" - -[[projects]] - digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" - name = "github.com/davecgh/go-spew" - packages = ["spew"] - pruneopts = "UT" - revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" - version = "v1.1.1" - -[[projects]] - digest = "1:865079840386857c809b72ce300be7580cb50d3d3129ce11bf9aa6ca2bc1934a" - name = "github.com/fatih/color" - packages = ["."] - pruneopts = "UT" - revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4" - version = "v1.7.0" - -[[projects]] - digest = "1:af43bdaaf86655a2343f113e9b293bbc16b12099eaeb223982bbe4d4c22ba14d" - name = "github.com/fatih/structs" - packages = ["."] - pruneopts = "UT" - revision = "4966fc68f5b7593aafa6cbbba2d65ec6e1416047" - version = "v1.1.0" - -[[projects]] - branch = "master" - digest = "1:b48ef4624ce31088e81b106c90fa290193d728fd2b4afbdc361c6c3e26ffcfaf" - name = "github.com/gavv/monotime" - packages = ["."] - pruneopts = "UT" - revision = "30dba43534243e3484a34676a0f068d12b989f84" - -[[projects]] - digest = "1:e1ff887e232b2d8f4f7c7db15a5fac7be418025afc4dda53c59c765dbb5aa6b4" - name = "github.com/go-playground/locales" - packages = [ - ".", - "currency", - ] - pruneopts = "UT" - revision = "f63010822830b6fe52288ee52d5a1151088ce039" - version = "v0.12.1" - -[[projects]] - digest = "1:e022cf244bcac1b6ef933f1a2e0adcf6a6dfd7b872d8d41e4d4179bb09a87cbc" - name = "github.com/go-playground/universal-translator" - packages = ["."] - pruneopts = "UT" - revision = "b32fa301c9fe55953584134cb6853a13c87ec0a1" - version = "v0.16.0" - -[[projects]] - digest = "1:a63cff6b5d8b95638bfe300385d93b2a6d9d687734b863da8e09dc834510a690" - name = "github.com/google/go-querystring" - packages = ["query"] - pruneopts = "UT" - revision = "44c6ddd0a2342c386950e880b658017258da92fc" - version = "v1.0.0" - -[[projects]] - digest = "1:d16b4a5083138f96d51b2311181713f83b3f75b6fdc782435002a45c8c1b870f" - name = "github.com/graphql-go/graphql" - packages = [ - "language/ast", - "language/kinds", - "language/location", - "language/source", - ] - pruneopts = "UT" - revision = "2b0b7340d2285b861482047fbf5de0488e021bea" - version = "v0.7.8" - -[[projects]] - branch = "master" - digest = "1:59392ed8afb901aab4287d4894df8191722e34f3957716f4350c8c133ce99046" - name = "github.com/hpcloud/tail" - packages = [ - ".", - "ratelimiter", - "util", - "watch", - "winfile", - ] - pruneopts = "UT" - revision = "a1dbeea552b7c8df4b542c66073e393de198a800" - -[[projects]] - digest = "1:a3ce4de79566c21e93cb6934797fdaa587ad3fc6a964708ab77babe54ea67188" - name = "github.com/imkira/go-interpol" - packages = ["."] - pruneopts = "UT" - revision = "5accad8134979a6ac504d456a6c7f1c53da237ca" - version = "v1.1.0" - -[[projects]] - branch = "master" - digest = "1:8b28915d30e068b130e2c86a725d41e8c221cdcb4307c69e67bdc3cf9aabd286" - name = "github.com/jamillosantos/macchiato" - packages = ["."] - pruneopts = "UT" - revision = "3be045cc503344c551700381369b71cf18ca80cf" - -[[projects]] - digest = "1:aaa8e0e7e35d92e21daed3f241832cee73d15ca1cd3302ba3843159a959a7eac" - name = "github.com/klauspost/compress" - packages = [ - "flate", - "gzip", - "zlib", - ] - pruneopts = "UT" - revision = "30be6041bed523c18e269a700ebd9c2ea9328574" - version = "v1.4.1" - -[[projects]] - digest = "1:2d643962fac133904694fffa959bc3c5dcfdcee38c6f5ffdd99a3c93eb9c835c" - name = "github.com/klauspost/cpuid" - packages = ["."] - pruneopts = "UT" - revision = "e7e905edc00ea8827e58662220139109efea09db" - version = "v1.2.0" - -[[projects]] - digest = "1:59e517ff564963129123748a743db6cce363e5ec0fd0dba34abd6aedd4e64cf2" - name = "github.com/lab259/graphql" - packages = ["gqlerrors"] - pruneopts = "UT" - revision = "2b0b7340d2285b861482047fbf5de0488e021bea" - version = "v0.7.8" - -[[projects]] - digest = "1:53bc4cd4914cd7cd52139990d5170d6dc99067ae31c56530621b18b35fc30318" - name = "github.com/lab259/mapstructure" - packages = ["."] - pruneopts = "UT" - revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe" - version = "v1.1.2" - -[[projects]] - digest = "1:c658e84ad3916da105a761660dcaeb01e63416c8ec7bc62256a9b411a05fcd67" - name = "github.com/mattn/go-colorable" - packages = ["."] - pruneopts = "UT" - revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" - version = "v0.0.9" - -[[projects]] - digest = "1:0981502f9816113c9c8c4ac301583841855c8cf4da8c72f696b3ebedf6d0e4e5" - name = "github.com/mattn/go-isatty" - packages = ["."] - pruneopts = "UT" - revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c" - version = "v0.0.4" - -[[projects]] - digest = "1:7aefb397a53fc437c90f0fdb3e1419c751c5a3a165ced52325d5d797edf1aca6" - name = "github.com/moul/http2curl" - packages = ["."] - pruneopts = "UT" - revision = "9ac6cf4d929b2fa8fd2d2e6dec5bb0feb4f4911d" - version = "v1.0.0" - -[[projects]] - digest = "1:5f4b78246f0bcb105b1e3b2b9e22b52a57cd02f57a8078572fe27c62f4a75ff7" - name = "github.com/onsi/ginkgo" - packages = [ - ".", - "config", - "internal/codelocation", - "internal/containernode", - "internal/failer", - "internal/leafnodes", - "internal/remote", - "internal/spec", - "internal/spec_iterator", - "internal/specrunner", - "internal/suite", - "internal/testingtproxy", - "internal/writer", - "reporters", - "reporters/stenographer", - "reporters/stenographer/support/go-colorable", - "reporters/stenographer/support/go-isatty", - "types", - ] - pruneopts = "UT" - revision = "2e1be8f7d90e9d3e3e58b0ce470f2f14d075406f" - version = "v1.7.0" - -[[projects]] - digest = "1:7a137fb7718928e473b7d805434ae563ec41790d3d227cdc64e8b14d1cab8a1f" - name = "github.com/onsi/gomega" - packages = [ - ".", - "format", - "internal/assertion", - "internal/asyncassertion", - "internal/oraclematcher", - "internal/testingtsupport", - "matchers", - "matchers/support/goraph/bipartitegraph", - "matchers/support/goraph/edge", - "matchers/support/goraph/node", - "matchers/support/goraph/util", - "types", - ] - pruneopts = "UT" - revision = "65fb64232476ad9046e57c26cd0bff3d3a8dc6cd" - version = "v1.4.3" - -[[projects]] - digest = "1:40e195917a951a8bf867cd05de2a46aaf1806c50cf92eebf4c16f78cd196f747" - name = "github.com/pkg/errors" - packages = ["."] - pruneopts = "UT" - revision = "645ef00459ed84a119197bfb8d8205042c6df63d" - version = "v0.8.0" - -[[projects]] - digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" - name = "github.com/pmezard/go-difflib" - packages = ["difflib"] - pruneopts = "UT" - revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.0.0" - -[[projects]] - digest = "1:d917313f309bda80d27274d53985bc65651f81a5b66b820749ac7f8ef061fd04" - name = "github.com/sergi/go-diff" - packages = ["diffmatchpatch"] - pruneopts = "UT" - revision = "1744e2970ca51c86172c8190fadad617561ed6e7" - version = "v1.0.0" - -[[projects]] - digest = "1:5da8ce674952566deae4dbc23d07c85caafc6cfa815b0b3e03e41979cedb8750" - name = "github.com/stretchr/testify" - packages = [ - "assert", - "require", - ] - pruneopts = "UT" - revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053" - version = "v1.3.0" - -[[projects]] - digest = "1:c468422f334a6b46a19448ad59aaffdfc0a36b08fdcc1c749a0b29b6453d7e59" - name = "github.com/valyala/bytebufferpool" - packages = ["."] - pruneopts = "UT" - revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7" - version = "v1.0.0" - -[[projects]] - digest = "1:8d6e2d89065f56a560ce647c05cc8add82ca5d214bcb6cc8b3f4e9329fa6898b" - name = "github.com/valyala/fasthttp" - packages = [ - ".", - "fasthttputil", - "stackless", - ] - pruneopts = "UT" - revision = "46469b532d0621287a2184a890564a59a3d528f3" - version = "v1.3.0" - -[[projects]] - branch = "master" - digest = "1:f4e5276a3b356f4692107047fd2890f2fe534f4feeb6b1fd2f6dfbd87f1ccf54" - name = "github.com/xeipuuv/gojsonpointer" - packages = ["."] - pruneopts = "UT" - revision = "4e3ac2762d5f479393488629ee9370b50873b3a6" - -[[projects]] - branch = "master" - digest = "1:dc6a6c28ca45d38cfce9f7cb61681ee38c5b99ec1425339bfc1e1a7ba769c807" - name = "github.com/xeipuuv/gojsonreference" - packages = ["."] - pruneopts = "UT" - revision = "bd5ef7bd5415a7ac448318e64f11a24cd21e594b" - -[[projects]] - digest = "1:1c898ea6c30c16e8d55fdb6fe44c4bee5f9b7d68aa260cfdfc3024491dcc7bea" - name = "github.com/xeipuuv/gojsonschema" - packages = ["."] - pruneopts = "UT" - revision = "f971f3cd73b2899de6923801c147f075263e0c50" - version = "v1.1.0" - -[[projects]] - branch = "master" - digest = "1:ac3d942a027d57fbfc5c13791cfaaa4b30729674fea88f2e03190b777c2b674e" - name = "github.com/yalp/jsonpath" - packages = ["."] - pruneopts = "UT" - revision = "5cc68e5049a040829faef3a44c00ec4332f6dec7" - -[[projects]] - digest = "1:52ccbcf36804b0beb5677a8994bd4ac740b71d1d6fe38c02b113dabdda51bf6d" - name = "github.com/yudai/gojsondiff" - packages = [ - ".", - "formatter", - ] - pruneopts = "UT" - revision = "7b1b7adf999dab73a6eb02669c3d82dbb27a3dd6" - version = "1.0.0" - -[[projects]] - branch = "master" - digest = "1:0d4822d3440c9b5992704bb357061fff7ab60daa85d92dec02b81b78e4908db7" - name = "github.com/yudai/golcs" - packages = ["."] - pruneopts = "UT" - revision = "ecda9a501e8220fae3b4b600c3db4b0ba22cfc68" - -[[projects]] - branch = "master" - digest = "1:80a7ec454d4d84b077f3d44275236ecd797ea84f65c8562051da7cc39c15c559" - name = "golang.org/x/net" - packages = [ - "html", - "html/atom", - "html/charset", - "idna", - "publicsuffix", - ] - pruneopts = "UT" - revision = "351d144fa1fc0bd934e2408202be0c29f25e35a0" - -[[projects]] - branch = "master" - digest = "1:8775d8a768d9e65e8b659172804aac5db1fc8d563ba766470a6c2698c57c61a7" - name = "golang.org/x/sys" - packages = ["unix"] - pruneopts = "UT" - revision = "4ed8d59d0b35e1e29334a206d1b3f38b1e5dfb31" - -[[projects]] - digest = "1:436b24586f8fee329e0dd65fd67c817681420cda1d7f934345c13fe78c212a73" - name = "golang.org/x/text" - packages = [ - "collate", - "collate/build", - "encoding", - "encoding/charmap", - "encoding/htmlindex", - "encoding/internal", - "encoding/internal/identifier", - "encoding/japanese", - "encoding/korean", - "encoding/simplifiedchinese", - "encoding/traditionalchinese", - "encoding/unicode", - "internal/colltab", - "internal/gen", - "internal/tag", - "internal/triegen", - "internal/ucd", - "internal/utf8internal", - "language", - "runes", - "secure/bidirule", - "transform", - "unicode/bidi", - "unicode/cldr", - "unicode/norm", - "unicode/rangetable", - ] - pruneopts = "UT" - revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" - version = "v0.3.0" - -[[projects]] - digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd" - name = "gopkg.in/fsnotify/fsnotify.v1" - packages = ["."] - pruneopts = "UT" - revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" - version = "v1.4.7" - -[[projects]] - digest = "1:03e96b794cbfd4acee01fcd9f69ed6051b8d9cef829d527b4dc13776693ad8d6" - name = "gopkg.in/gavv/httpexpect.v1" - packages = ["."] - pruneopts = "UT" - revision = "db1fd357d58f43e545656a9c6fe74305ccc46873" - version = "v1.0.0" - -[[projects]] - digest = "1:2c6a8f26c364b006a27b8090a9583fcc4b7865583fcf93f99a20fce339e87192" - name = "gopkg.in/go-playground/validator.v9" - packages = ["."] - pruneopts = "UT" - revision = "1fa3c8d6336562f0a3f95c73593ee2b57ff4da11" - version = "v9.23.0" - -[[projects]] - digest = "1:3c839a777de0e6da035c9de900b60cbec463b0a89351192c1ea083eaf9e0fce0" - name = "gopkg.in/tomb.v1" - packages = ["."] - pruneopts = "UT" - revision = "c131134a1947e9afd9cecfe11f4c6dff0732ae58" - -[[projects]] - digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96" - name = "gopkg.in/yaml.v2" - packages = ["."] - pruneopts = "UT" - revision = "51d6538a90f86fe93ac480b35f37b2be17fef232" - version = "v2.2.2" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = [ - "github.com/go-playground/universal-translator", - "github.com/jamillosantos/macchiato", - "github.com/lab259/graphql/gqlerrors", - "github.com/lab259/mapstructure", - "github.com/onsi/ginkgo", - "github.com/onsi/gomega", - "github.com/onsi/gomega/format", - "github.com/pkg/errors", - "github.com/valyala/fasthttp", - "gopkg.in/gavv/httpexpect.v1", - "gopkg.in/go-playground/validator.v9", - ] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100644 index f754e1c..0000000 --- a/Gopkg.toml +++ /dev/null @@ -1,33 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - -[[constraint]] - name = "gopkg.in/go-playground/validator.v9" - version = "9.23.0" - -[prune] - go-tests = true - unused-packages = true From aaa5d95d7c5fe96f12ebc34971faf3a16302161e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eduardo=20Mar=C3=A7al?= Date: Thu, 31 Oct 2019 16:07:30 -0300 Subject: [PATCH 2/2] Unify the gqlerros actions Issue: #16 --- go.mod | 52 +- go.sum | 32 +- gqlerrors/code.go | 25 +- gqlerrors/code_test.go | 381 ++++++++++----- gqlerrors/extensions.go | 39 +- gqlerrors/extensions_code.go | 61 --- gqlerrors/extensions_code_test.go | 180 ------- gqlerrors/extensions_message.go | 81 ---- gqlerrors/extensions_message_test.go | 186 ------- gqlerrors/extensions_module.go | 59 --- gqlerrors/extensions_module_test.go | 185 ------- gqlerrors/extensions_validator.go | 61 --- gqlerrors/extensions_validator_test.go | 122 ----- gqlerrors/gqlerrors.go | 35 +- gqlerrors/message.go | 47 +- gqlerrors/message_test.go | 639 +++++++++++++++---------- gqlerrors/module.go | 25 +- gqlerrors/module_test.go | 386 ++++++++++----- gqlerrors/validator.go | 27 +- gqlerrors/validator_test.go | 337 ++++++++----- 20 files changed, 1307 insertions(+), 1653 deletions(-) delete mode 100644 gqlerrors/extensions_code.go delete mode 100644 gqlerrors/extensions_code_test.go delete mode 100644 gqlerrors/extensions_message.go delete mode 100644 gqlerrors/extensions_message_test.go delete mode 100644 gqlerrors/extensions_module.go delete mode 100644 gqlerrors/extensions_module_test.go delete mode 100644 gqlerrors/extensions_validator.go delete mode 100644 gqlerrors/extensions_validator_test.go diff --git a/go.mod b/go.mod index 528fe07..39cda8e 100644 --- a/go.mod +++ b/go.mod @@ -4,45 +4,37 @@ go 1.12 require ( github.com/99designs/gqlgen v0.9.1 - github.com/ajg/form v1.5.1 - github.com/davecgh/go-spew v1.1.1 - github.com/fatih/color v1.7.0 - github.com/fatih/structs v1.1.0 - github.com/gavv/monotime v0.0.0-20190418164738-30dba4353424 - github.com/go-playground/locales v0.12.1 + github.com/ajg/form v1.5.1 // indirect + github.com/fatih/color v1.7.0 // indirect + github.com/fatih/structs v1.1.0 // indirect + github.com/gavv/monotime v0.0.0-20190418164738-30dba4353424 // indirect + github.com/go-playground/locales v0.12.1 // indirect github.com/go-playground/universal-translator v0.16.0 - github.com/google/go-querystring v1.0.0 + github.com/google/go-querystring v1.0.0 // indirect github.com/graphql-go/graphql v0.7.8 - github.com/hpcloud/tail v1.0.0 - github.com/imkira/go-interpol v1.1.0 + github.com/imkira/go-interpol v1.1.0 // indirect github.com/jamillosantos/macchiato v0.0.0-20171220130318-3be045cc5033 - github.com/klauspost/compress v1.4.1 - github.com/klauspost/cpuid v1.2.0 - github.com/mattn/go-colorable v0.0.9 - github.com/mattn/go-isatty v0.0.4 + github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect + github.com/klauspost/compress v1.4.1 // indirect + github.com/klauspost/cpuid v1.2.0 // indirect + github.com/mattn/go-colorable v0.0.9 // indirect + github.com/mattn/go-isatty v0.0.4 // indirect github.com/mitchellh/mapstructure v1.1.2 - github.com/moul/http2curl v1.0.0 + github.com/moul/http2curl v1.0.0 // indirect github.com/onsi/ginkgo v1.7.0 github.com/onsi/gomega v1.4.3 github.com/pkg/errors v0.8.1 - github.com/pmezard/go-difflib v1.0.0 - github.com/sergi/go-diff v1.0.0 - github.com/stretchr/testify v1.3.0 - github.com/valyala/bytebufferpool v1.0.0 + github.com/smartystreets/goconvey v1.6.4 // indirect github.com/valyala/fasthttp v1.3.0 github.com/vektah/gqlparser v1.1.2 - github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 - github.com/xeipuuv/gojsonschema v1.1.0 - github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 - github.com/yudai/gojsondiff v0.0.0-20170107030110-7b1b7adf999d - github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 - golang.org/x/net v0.0.0-20190311183353-d8887717615a - golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a - golang.org/x/text v0.3.0 - gopkg.in/fsnotify/fsnotify.v1 v1.4.7 + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.1.0 // indirect + github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect + github.com/yudai/gojsondiff v0.0.0-20170107030110-7b1b7adf999d // indirect + github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect + github.com/yudai/pp v2.0.1+incompatible // indirect gopkg.in/gavv/httpexpect.v1 v1.0.0 + gopkg.in/go-playground/assert.v1 v1.2.1 // indirect gopkg.in/go-playground/validator.v9 v9.23.0 - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 - gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index 5ba01de..ff51c81 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,7 @@ github.com/agnivade/levenshtein v1.0.1 h1:3oJU7J3FGFmyhn8KHjmVaZCN5hxTr7GxgRue+s github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -12,6 +13,7 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gavv/monotime v0.0.0-20190418164738-30dba4353424 h1:Vh7rylVZRZCj6W41lRlP17xPk4Nq260H4Xo/DDYmEZk= github.com/gavv/monotime v0.0.0-20190418164738-30dba4353424/go.mod h1:vmp8DIyckQMXOPl0AQVHt+7n5h7Gb7hS6CUydiV8QeA= @@ -21,31 +23,40 @@ github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3yg github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM= github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/graphql-go/graphql v0.7.8 h1:769CR/2JNAhLG9+aa8pfLkKdR0H+r5lsQqling5WwpU= github.com/graphql-go/graphql v0.7.8/go.mod h1:k6yrAYQaSP59DC5UVxbgxESlmVyojThKdORUqGDGmrI= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hpcloud/tail v0.0.0-20180514194441-a1dbeea552b7/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/jamillosantos/macchiato v0.0.0-20171220130318-3be045cc5033 h1:R0efOJW2JdoZ7ValaK6iFhWHrlZFeRvV4alZbHg5hnQ= github.com/jamillosantos/macchiato v0.0.0-20171220130318-3be045cc5033/go.mod h1:JHpPOBFu/UpmWT79z9fw5lQn7Oem6lnkS3jN4ZQdfLQ= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.4.1 h1:8VMb5+0wMgdBykOV96DwNwKFQ+WTI4pzYURP99CcB9E= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -63,8 +74,6 @@ github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -74,6 +83,10 @@ github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= @@ -100,35 +113,36 @@ github.com/yudai/gojsondiff v0.0.0-20170107030110-7b1b7adf999d h1:yJIizrfO599ot2 github.com/yudai/gojsondiff v0.0.0-20170107030110-7b1b7adf999d/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU= -golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd h1:oMEQDWVXVNpceQoVd1JN3CQ7LYJJzs5qWqZIUcxXHHw= golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= gopkg.in/gavv/httpexpect.v1 v1.0.0 h1:qk1STv6i2qMNiujBPiF+EQhB0qxueKXnqw/Pxt5yq+s= gopkg.in/gavv/httpexpect.v1 v1.0.0/go.mod h1:WtiW9ZA1LdaWqtQRo1VbIL/v4XZ8NDta+O/kSpGgVek= +gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v9 v9.23.0 h1:oq297iqu7qsywIbeW5DBUTtV1nV750Y4q+H8MnDh0Yc= gopkg.in/go-playground/validator.v9 v9.23.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= -gopkg.in/tomb.v1 v1.0.0-20140529071818-c131134a1947/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/gqlerrors/code.go b/gqlerrors/code.go index 3a05a64..fb88bae 100644 --- a/gqlerrors/code.go +++ b/gqlerrors/code.go @@ -7,7 +7,6 @@ import ( "github.com/lab259/errors/v2" "github.com/onsi/gomega/format" "github.com/onsi/gomega/types" - "github.com/vektah/gqlparser/gqlerror" ) // HaveCode succeeds if actual is a GraphQL Error that have the @@ -19,22 +18,34 @@ func HaveCode(expected interface{}) types.GomegaMatcher { } type haveCodeMatcher struct { - err gqlerror.Error + err interface{} code string expected interface{} } -func (matcher *haveCodeMatcher) Match(actual interface{}) (bool, error) { +func (matcher *haveCodeMatcher) Match(actual interface{}) (ok bool, err error) { gqlerror, err := prepare("HaveCode", actual) if err != nil { return false, err } - matcher.err = *gqlerror + var code string + if gqlerror.Gqlerror != nil { + code, ok = gqlerror.Gqlerror.Extensions["code"].(string) + if !ok { + return false, fmt.Errorf("Code extension not found in %s", gqlerror) + } + + matcher.err = gqlerror.Gqlerror + } + + if gqlerror.FormattedError != nil { + code, ok = gqlerror.FormattedError.Extensions["code"].(string) + if !ok { + return false, fmt.Errorf("Code extension not found in %s", gqlerror) + } - code, ok := gqlerror.Extensions["code"].(string) - if !ok { - return false, fmt.Errorf("Code extension not found in %s", gqlerror) + matcher.err = gqlerror.FormattedError } switch t := matcher.expected.(type) { diff --git a/gqlerrors/code_test.go b/gqlerrors/code_test.go index 9e55738..04be0ae 100644 --- a/gqlerrors/code_test.go +++ b/gqlerrors/code_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "github.com/99designs/gqlgen/client" + "gopkg.in/gavv/httpexpect.v1" "github.com/lab259/errors/v2" "github.com/lab259/errors/v2/gqlerrors" @@ -15,136 +16,280 @@ import ( var _ = Describe("GraphQL Extensions", func() { Describe("HaveCode", func() { - It("should match", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "code": "validation", - }, - } - - a := gqlerrors.HaveCode("validation") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + When("Gqlerror", func() { + It("should match", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "code": "validation", + }, + } - It("should match using Option", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "code": "validation", - }, - } - - a := gqlerrors.HaveCode(errors.Code("validation")) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + a := gqlerrors.HaveCode("validation") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) - It("should match using ErrorWithCode", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "code": "validation", - }, - } - - a := gqlerrors.HaveCode(errors.Code("validation")(nil)) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + It("should match using Option", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "code": "validation", + }, + } - It("should match (pointer)", func() { - gqlerr := &gqlerror.Error{ - Extensions: map[string]interface{}{ - "code": "validation", - }, - } - - a := gqlerrors.HaveCode("validation") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + a := gqlerrors.HaveCode(errors.Code("validation")) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) - It("should match (json.RawMessage)", func() { - gqlerr := json.RawMessage(`[{"extensions": {"code": "validation"}}]`) - a := gqlerrors.HaveCode("validation") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + It("should match using ErrorWithCode", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "code": "validation", + }, + } - It("should match (client.RawJsonError)", func() { - gqlerr := client.RawJsonError{ - RawMessage: json.RawMessage(`[{"extensions": {"code": "validation"}}]`), - } - a := gqlerrors.HaveCode("validation") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + a := gqlerrors.HaveCode(errors.Code("validation")(nil)) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) - It("should not match", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "code": "validation", - }, - } - - a := gqlerrors.HaveCode("not-found") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).ToNot(HaveOccurred()) - }) + It("should match (pointer)", func() { + gqlerr := &gqlerror.Error{ + Extensions: map[string]interface{}{ + "code": "validation", + }, + } - It("should fail without extensions", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{}, - } + a := gqlerrors.HaveCode("validation") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) - a := gqlerrors.HaveCode("validation") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("Code extension not found in")) - }) + It("should match (json.RawMessage)", func() { + gqlerr := json.RawMessage(`[{"extensions": {"code": "validation"}}]`) + a := gqlerrors.HaveCode("validation") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) - It("should fail with wrong errors.Option", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "code": "validation", - }, - } - - a := gqlerrors.HaveCode(errors.Module("validation")) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("HaveCode matcher only support an `errors.Code` option")) - }) + It("should match (client.RawJsonError)", func() { + gqlerr := client.RawJsonError{ + RawMessage: json.RawMessage(`[{"extensions": {"code": "validation"}}]`), + } + a := gqlerrors.HaveCode("validation") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should not match", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "code": "validation", + }, + } + + a := gqlerrors.HaveCode("not-found") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail without extensions", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{}, + } + + a := gqlerrors.HaveCode("validation") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Code extension not found in")) + }) + + It("should fail with wrong errors.Option", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "code": "validation", + }, + } + + a := gqlerrors.HaveCode(errors.Module("validation")) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("HaveCode matcher only support an `errors.Code` option")) + }) + + It("should fail with wrong actual type", func() { + a := gqlerrors.HaveCode("validation") + ok, err := a.Match(26) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("HaveCode matcher does not know how to handle int")) + }) + + It("should fail with wrong expected type", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "code": "validation", + }, + } - It("should fail with wrong actual type", func() { - a := gqlerrors.HaveCode("validation") - ok, err := a.Match(26) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("HaveCode matcher does not know how to handle int")) + a := gqlerrors.HaveCode(26) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("HaveCode matcher does not know how to assert int")) + }) }) - It("should fail with wrong expected type", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "code": "validation", - }, - } - - a := gqlerrors.HaveCode(26) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("HaveCode matcher does not know how to assert int")) + When("GraphQL", func() { + It("should check the return code", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "code": "validation", + }, + }, + }, + }) + + a := gqlerrors.HaveCode("validation") + ok, err := a.Match(jsonData) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail check the return code when input not object", func() { + a := gqlerrors.HaveCode("validate") + ok, err := a.Match("it is not an object of the type `*httpexpect.Object`") + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("HaveCode matcher does not know how to handle string")) + }) + + It("should fail when not matcher extension error", func() { + m := gqlerrors.HaveCode("validate") + + ok, err := m.Match(&httpexpect.Object{}) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("HaveCode httpexpect.Object not is error *httpexpect.Object")) + }) + + It("should fail checking the return when error not contains code", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "module": "accounts", + }, + }, + }, + }) + + a := gqlerrors.HaveCode("users") + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Code extension not found")) + }) + + It("should fail to decode when error not matcher", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": map[string]interface{}{ + "extensions": map[string]interface{}{ + "code": "invalid-account-id", + }, + }, + }) + + code := errors.Code("invalid-account-id") + a := gqlerrors.HaveCode(code) + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + }) + + It("should fail checking the return when error not matcher code option", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "code": "validation", + }, + }, + }, + }) + + op := errors.Code("new-code") + a := gqlerrors.HaveCode(op) + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail checking the return when error not matcher code option nil", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "code": "validation", + }, + }, + }, + }) + + a := gqlerrors.HaveCode(nil) + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("HaveCode matcher does not know how to assert")) + }) + + It("should fail checking the return when error not matcher code text", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "code": "validation", + }, + }, + }, + }) + + a := gqlerrors.HaveCode("graphql") + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should checking failure message", func() { + code := "graphql" + a := gqlerrors.HaveCode(code) + failureMessage := a.FailureMessage("code") + Expect(failureMessage).To(ContainSubstring("to have Code extension equals to")) + }) + + It("should checking negative failure message", func() { + code := "graphql" + a := gqlerrors.HaveCode(code) + failureMessage := a.NegatedFailureMessage("mutate") + Expect(failureMessage).To(ContainSubstring("to not have Code extension equals to")) + }) }) }) - }) diff --git a/gqlerrors/extensions.go b/gqlerrors/extensions.go index 3895d3b..edcc7ec 100644 --- a/gqlerrors/extensions.go +++ b/gqlerrors/extensions.go @@ -1,20 +1,13 @@ package gqlerrors import ( - "fmt" - + "github.com/graphql-go/graphql/gqlerrors" "github.com/mitchellh/mapstructure" - "gopkg.in/gavv/httpexpect.v1" ) -type FormattedError struct { - Message string `json:"message"` - Extensions map[string]interface{} `json:"extensions,omitempty"` -} - type graphQLError struct { - Data map[string]interface{} `json:"data"` - Errors []*FormattedError `json:"errors"` + Data map[string]interface{} `json:"data"` + Errors []*gqlerrors.FormattedError `json:"errors"` } // decode an objects @@ -30,29 +23,3 @@ func (g *graphQLError) decode(input interface{}) error { return decoder.Decode(input) } - -func prepareFromJSON(mutateOrQuery string, actual interface{}) (*graphQLError, error) { - data, ok := actual.(*httpexpect.Object) - if !ok { - return nil, fmt.Errorf("`actual` is not an json object") - } - - // Decoding GraphQL error - var graphQLError graphQLError - err := graphQLError.decode(data.Raw()) - if err != nil { - return nil, err - } - - if len(graphQLError.Errors) == 0 { - return nil, fmt.Errorf("expected an error is not `%s`", actual) - } - - for key := range graphQLError.Data { - if key != mutateOrQuery { - return nil, fmt.Errorf("expected mutate or query name [%s] not is equal [%s]", key, mutateOrQuery) - } - } - - return &graphQLError, nil -} diff --git a/gqlerrors/extensions_code.go b/gqlerrors/extensions_code.go deleted file mode 100644 index b5834a5..0000000 --- a/gqlerrors/extensions_code.go +++ /dev/null @@ -1,61 +0,0 @@ -package gqlerrors - -import ( - "fmt" - - "github.com/lab259/errors/v2" - "github.com/onsi/gomega/format" -) - -type errWithGraphQLCodeMatcher struct { - Code interface{} - MutateOrQuery string -} - -func (matcher *errWithGraphQLCodeMatcher) Match(actual interface{}) (bool, error) { - graphQLError, err := prepareFromJSON(matcher.MutateOrQuery, actual) - if err != nil { - return false, err - } - - for _, v := range graphQLError.Errors { - code, ok := v.Extensions["code"].(string) - if !ok { - return false, fmt.Errorf("couldn't have key `code` %q", v.Extensions) - } - - switch matcher.Code.(type) { - case errors.Option: - c := matcher.Code.(errors.Option) - cError := c(nil).Error() - if code != cError { - return false, fmt.Errorf("code [%s] not equal [%s]", cError, code) - - } - case string: - if code != matcher.Code { - return false, fmt.Errorf("code [%s] not equal [%s]", matcher.Code, code) - } - case nil: - return false, fmt.Errorf("the code cannot be null") - } - - } - - return true, nil -} - -func (matcher *errWithGraphQLCodeMatcher) FailureMessage(actual interface{}) string { - return format.Message(actual, "to have any code equal field", matcher.Code) -} - -func (matcher *errWithGraphQLCodeMatcher) NegatedFailureMessage(actual interface{}) string { - return format.Message(actual, "to have any code equal field", matcher.Code) -} - -func ErrWithGraphQLCode(mutateOrQueryName string, code interface{}) *errWithGraphQLCodeMatcher { - return &errWithGraphQLCodeMatcher{ - Code: code, - MutateOrQuery: mutateOrQueryName, - } -} diff --git a/gqlerrors/extensions_code_test.go b/gqlerrors/extensions_code_test.go deleted file mode 100644 index 324c41e..0000000 --- a/gqlerrors/extensions_code_test.go +++ /dev/null @@ -1,180 +0,0 @@ -package gqlerrors_test - -import ( - "github.com/lab259/errors/v2" - "github.com/lab259/errors/v2/gqlerrors" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/onsi/gomega/format" - "gopkg.in/gavv/httpexpect.v1" -) - -var _ = Describe("GraphQL Extensions Code", func() { - It("should check the return code", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLCode("mutate", "validation") - ok, err := a.Match(jsonData) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should fail check the return code when input not object", func() { - a := gqlerrors.ErrWithGraphQLCode("mutate", "validate") - ok, err := a.Match("it is not an object of the type `*httpexpect.Object`") - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("`actual` is not an json object")) - }) - - It("should fail when not matcher extension error", func() { - m := gqlerrors.ErrWithGraphQLCode("mutate", "validate") - - ok, err := m.Match(&httpexpect.Object{}) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("expected an error is not `&{{ %!s(bool=false)} map[]}`")) - }) - - It("should fail checking the return code when mutate not matcher", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - }, - }, - }, - }) - - code := errors.Code("invalid") - a := gqlerrors.ErrWithGraphQLCode("mutateInvalid", code) - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("expected mutate or query name [mutate] not is equal [mutateInvalid]")) - }) - - It("should fail checking the return when error not contains code", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "accounts", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLCode("mutate", "users") - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("couldn't have key `code` map[\"module\":\"accounts\"]")) - }) - - It("should fail to decode when error not matcher", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": map[string]interface{}{ - "extensions": map[string]interface{}{ - "code": "invalid-account-id", - }, - }, - }) - - code := errors.Code("invalid-account-id") - a := gqlerrors.ErrWithGraphQLCode("mutate", code) - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - }) - - It("should fail checking the return when error not matcher code option", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - }, - }, - }, - }) - - op := errors.Code("new-code") - a := gqlerrors.ErrWithGraphQLCode("mutate", op) - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("code [new-code] not equal [validation]")) - }) - - It("should fail checking the return when error not matcher code option nil", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLCode("mutate", nil) - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("the code cannot be null")) - }) - - It("should fail checking the return when error not matcher code text", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLCode("mutate", "graphql") - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("code [graphql] not equal [validation]")) - }) - - It("should checking failure message", func() { - mutate := "mutate" - code := "graphql" - a := gqlerrors.ErrWithGraphQLCode(mutate, code) - failureMessage := a.FailureMessage("mutate") - fMessage := format.Message(mutate, "to have any code equal field", code) - Expect(failureMessage).To(Equal(fMessage)) - }) - - It("should checking negative failure message", func() { - mutate := "mutate" - code := "graphql" - a := gqlerrors.ErrWithGraphQLCode(mutate, code) - failureMessage := a.NegatedFailureMessage("mutate") - fMessage := format.Message(mutate, "to have any code equal field", code) - Expect(failureMessage).To(Equal(fMessage)) - }) - -}) diff --git a/gqlerrors/extensions_message.go b/gqlerrors/extensions_message.go deleted file mode 100644 index 7739e8e..0000000 --- a/gqlerrors/extensions_message.go +++ /dev/null @@ -1,81 +0,0 @@ -package gqlerrors - -import ( - "fmt" - "strings" - - "github.com/lab259/errors/v2" - "github.com/onsi/gomega/format" -) - -type errWithGraphQLMessageMatcher struct { - Message interface{} - MutateOrQuery string -} - -func (matcher *errWithGraphQLMessageMatcher) Match(actual interface{}) (bool, error) { - graphQLError, err := prepareFromJSON(matcher.MutateOrQuery, actual) - if err != nil { - return false, err - } - - for _, v := range graphQLError.Errors { - if extMessage, ok := v.Extensions["message"].(string); ok { - switch matcher.Message.(type) { - case errors.Option: - op := matcher.Message.(errors.Option) - message := op(nil).Error() - return matcher.messageOption(extMessage, message) - case string: - message := matcher.Message.(string) - return matcher.messageOption(extMessage, message) - } - } - - if v.Message != "" { - switch matcher.Message.(type) { - case errors.Option: - op := matcher.Message.(errors.Option) - message := op(nil).Error() - return matcher.messageOption(v.Message, message) - case string: - message := matcher.Message.(string) - return matcher.messageOption(v.Message, message) - case error: - message := matcher.Message.(error) - return matcher.messageOption(v.Message, message.Error()) - } - } - } - - return false, fmt.Errorf("the field message not found") -} - -func (matcher *errWithGraphQLMessageMatcher) FailureMessage(actual interface{}) string { - return format.Message(actual, "to have any message equal field", matcher.Message) -} - -func (matcher *errWithGraphQLMessageMatcher) NegatedFailureMessage(actual interface{}) string { - return format.Message(actual, "to have any message equal field", matcher.Message) -} - -func ErrWithGraphQLMessage(mutateOrQueryName string, message interface{}) *errWithGraphQLMessageMatcher { - return &errWithGraphQLMessageMatcher{ - Message: message, - MutateOrQuery: mutateOrQueryName, - } -} - -func (matcher *errWithGraphQLMessageMatcher) messageOption(source, expected string) (bool, error) { - ok := strings.Contains(source, expected) - if !ok { - message := matcher.Message - switch matcher.Message.(type) { - case errors.Option: - op := matcher.Message.(errors.Option) - message = op(nil).Error() - } - return false, fmt.Errorf("message [%s] not equal [%s]", message, source) - } - return true, nil -} diff --git a/gqlerrors/extensions_message_test.go b/gqlerrors/extensions_message_test.go deleted file mode 100644 index 2cd5e4c..0000000 --- a/gqlerrors/extensions_message_test.go +++ /dev/null @@ -1,186 +0,0 @@ -package gqlerrors_test - -import ( - "github.com/lab259/errors/v2" - "github.com/lab259/errors/v2/gqlerrors" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/onsi/gomega/format" - "gopkg.in/gavv/httpexpect.v1" -) - -var _ = Describe("GraphQL Extensions Message", func() { - It("should check the return extension message", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "message": "name is required", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLMessage("mutate", "name is required") - ok, err := a.Match(jsonData) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should check the return message", func() { - message := errors.Message("name is required") - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - }, - "message": "name is required", - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLMessage("mutate", message) - ok, err := a.Match(jsonData) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should check the return message type error", func() { - message := errors.New("name is required") - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - }, - "message": "name is required", - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLMessage("mutate", message) - ok, err := a.Match(jsonData) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should check the return message type string", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - }, - "message": "email is required", - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLMessage("mutate", "email is required") - ok, err := a.Match(jsonData) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should fail checking the return message when mutate not matcher", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "message": "validation", - }, - }, - }, - }) - - message := errors.Message("invalid") - a := gqlerrors.ErrWithGraphQLMessage("mutateInvalid", message) - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("expected mutate or query name [mutate] not is equal [mutateInvalid]")) - }) - - It("should fail checking the return when error not contains message", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "accounts", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLMessage("mutate", "users") - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("the field message not found")) - }) - - It("should fail checking the return when error not matcher message option", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "message": "validation", - }, - }, - }, - }) - - op := errors.Message("new-message") - a := gqlerrors.ErrWithGraphQLMessage("mutate", op) - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("message [new-message] not equal [validation]")) - }) - - It("should fail checking the return when error not matcher message text", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "message": "validation", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLMessage("mutate", "graphql") - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("message [graphql] not equal [validation]")) - }) - - It("should checking failure message", func() { - mutate := "mutate" - message := "graphql" - a := gqlerrors.ErrWithGraphQLMessage(mutate, message) - failureMessage := a.FailureMessage("mutate") - fMessage := format.Message(mutate, "to have any message equal field", message) - Expect(failureMessage).To(Equal(fMessage)) - }) - - It("should checking negative failure message", func() { - mutate := "mutate" - message := "graphql" - a := gqlerrors.ErrWithGraphQLMessage(mutate, message) - failureMessage := a.NegatedFailureMessage("mutate") - fMessage := format.Message(mutate, "to have any message equal field", message) - Expect(failureMessage).To(Equal(fMessage)) - }) - -}) diff --git a/gqlerrors/extensions_module.go b/gqlerrors/extensions_module.go deleted file mode 100644 index d0b271d..0000000 --- a/gqlerrors/extensions_module.go +++ /dev/null @@ -1,59 +0,0 @@ -package gqlerrors - -import ( - "fmt" - "strings" - - "github.com/lab259/errors/v2" - "github.com/onsi/gomega/format" -) - -type errWithGraphQLModuleMatcher struct { - Module interface{} - MutateOrQuery string -} - -func (matcher *errWithGraphQLModuleMatcher) Match(actual interface{}) (bool, error) { - graphQLError, err := prepareFromJSON(matcher.MutateOrQuery, actual) - if err != nil { - return false, err - } - - for _, v := range graphQLError.Errors { - module, ok := v.Extensions["module"].(string) - if !ok { - return false, fmt.Errorf("couldn't have key `module` %v", graphQLError) - } - - switch matcher.Module.(type) { - case errors.Option: - option := matcher.Module.(errors.Option) - mModule := option(nil).Error() - if ok := strings.Contains(mModule, module); !ok { - return false, fmt.Errorf("expected module [%s] not equal [%s]", mModule, module) - } - case string: - expected := matcher.Module.(string) - if module != expected { - return false, fmt.Errorf("expected module [%s] not equal [%s]", module, expected) - } - } - } - - return true, nil -} - -func (matcher *errWithGraphQLModuleMatcher) FailureMessage(actual interface{}) string { - return format.Message(actual, "to have any module equal field", matcher.Module) -} - -func (matcher *errWithGraphQLModuleMatcher) NegatedFailureMessage(actual interface{}) string { - return format.Message(actual, "to have any module equal field", matcher.Module) -} - -func ErrWithGraphQLModule(mutateOrQueryName string, module interface{}) *errWithGraphQLModuleMatcher { - return &errWithGraphQLModuleMatcher{ - Module: module, - MutateOrQuery: mutateOrQueryName, - } -} diff --git a/gqlerrors/extensions_module_test.go b/gqlerrors/extensions_module_test.go deleted file mode 100644 index 3b8c395..0000000 --- a/gqlerrors/extensions_module_test.go +++ /dev/null @@ -1,185 +0,0 @@ -package gqlerrors_test - -import ( - "github.com/lab259/errors/v2" - "github.com/lab259/errors/v2/gqlerrors" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/onsi/gomega/format" - "gopkg.in/gavv/httpexpect.v1" -) - -var _ = Describe("GraphQL Extensions Module", func() { - - It("should check the return extension module", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "users", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLModule("mutate", "users") - ok, err := a.Match(jsonData) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should check the return module", func() { - module := errors.WrapModule(nil, "users") - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - "module": "users", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLModule("mutate", module) - ok, err := a.Match(jsonData) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should check the return module type string", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - "module": "users", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLModule("mutate", "users") - ok, err := a.Match(jsonData) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should fail check the return module empty", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "code": "validation", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLModule("mutate", "users") - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("couldn't have key `module`")) - }) - - It("should fail checking the return module when mutate not matcher", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "validation", - }, - }, - }, - }) - - module := errors.Module("invalid") - a := gqlerrors.ErrWithGraphQLModule("mutateInvalid", module) - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("expected mutate or query name [mutate] not is equal [mutateInvalid]")) - }) - - It("should fail checking the return when error not contains module", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "accounts", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLModule("mutate", "users") - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("expected module [accounts] not equal [users]")) - }) - - It("should fail checking the return when error not matcher module option", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "validation", - }, - }, - }, - }) - - option := errors.Module("new-module") - a := gqlerrors.ErrWithGraphQLModule("mutate", option) - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - }) - - It("should fail checking the return when error not matcher module text", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "validation", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLModule("mutate", "graphql") - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("expected module [validation] not equal [graphql]")) - }) - - It("should checking failure module", func() { - mutate := "mutate" - module := "graphql" - a := gqlerrors.ErrWithGraphQLModule(mutate, module) - failureModule := a.FailureMessage("mutate") - fModule := format.Message(mutate, "to have any module equal field", module) - Expect(failureModule).To(Equal(fModule)) - }) - - It("should checking negative failure module", func() { - mutate := "mutate" - module := "graphql" - a := gqlerrors.ErrWithGraphQLModule(mutate, module) - failureModule := a.NegatedFailureMessage("mutate") - fModule := format.Message(mutate, "to have any module equal field", module) - Expect(failureModule).To(Equal(fModule)) - }) - -}) diff --git a/gqlerrors/extensions_validator.go b/gqlerrors/extensions_validator.go deleted file mode 100644 index 73f3fb9..0000000 --- a/gqlerrors/extensions_validator.go +++ /dev/null @@ -1,61 +0,0 @@ -package gqlerrors - -import ( - "fmt" - - "github.com/onsi/gomega/format" -) - -type errWithGraphQLValidatorMatcher struct { - Field string - Rule string - MutateOrQuery string -} - -func (matcher *errWithGraphQLValidatorMatcher) Match(actual interface{}) (bool, error) { - graphQLError, err := prepareFromJSON(matcher.MutateOrQuery, actual) - if err != nil { - return false, err - } - - for _, v := range graphQLError.Errors { - validation, ok := v.Extensions["errors"].(map[string]interface{}) - if !ok { - return false, fmt.Errorf("couldn't have key `validation` on the %v", graphQLError) - } - - // Matcher field - if !checkFieldsMatcher(matcher, validation) { - return false, fmt.Errorf("errors not containing key [%s] on the %v", matcher.Field, graphQLError.Errors) - } - } - - return true, nil -} - -func (matcher *errWithGraphQLValidatorMatcher) FailureMessage(actual interface{}) string { - return format.Message(actual, "to have any validation equal field [", matcher.Field, "] and rules [", matcher.Rule, "]") -} - -func (matcher *errWithGraphQLValidatorMatcher) NegatedFailureMessage(actual interface{}) string { - return format.Message(actual, "to have any validation equal field [", matcher.Field, "] and rules [", matcher.Rule, "]") -} - -func ErrWithGraphQLValidate(mutateOrQueryName string, field string, rule string) *errWithGraphQLValidatorMatcher { - return &errWithGraphQLValidatorMatcher{ - Field: field, - Rule: rule, - MutateOrQuery: mutateOrQueryName, - } -} - -func checkFieldsMatcher(matcher *errWithGraphQLValidatorMatcher, e map[string]interface{}) bool { - if rules, ok := e[matcher.Field].([]interface{}); ok { - for _, rule := range rules { - if matcher.Rule == rule { - return true - } - } - } - return false -} diff --git a/gqlerrors/extensions_validator_test.go b/gqlerrors/extensions_validator_test.go deleted file mode 100644 index 9c64712..0000000 --- a/gqlerrors/extensions_validator_test.go +++ /dev/null @@ -1,122 +0,0 @@ -package gqlerrors_test - -import ( - "github.com/lab259/errors/v2/gqlerrors" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "github.com/onsi/gomega/format" - "gopkg.in/gavv/httpexpect.v1" -) - -var _ = Describe("GraphQL Extensions Validate", func() { - It("should check the return extension validate", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "users", - "errors": map[string]interface{}{ - "name": []interface{}{ - "required", - }, - }, - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLValidate("mutate", "name", "required") - ok, err := a.Match(jsonData) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should fail checking the return validate when mutate not matcher", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "users", - "errors": map[string]interface{}{ - "name": []interface{}{ - "required", - }, - }, - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLValidate("mutateInvalid", "email", "email") - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(Equal("expected mutate or query name [mutate] not is equal [mutateInvalid]")) - }) - - It("should fail checking the return when error not matcher validate", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "users", - "errors": map[string]interface{}{ - "email": []interface{}{ - "required", - }, - }, - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLValidate("mutate", "email", "email") - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("errors not containing key [email] on the")) - }) - - It("should fail checking the return when error not matcher errors", func() { - jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ - "data": map[string]interface{}{"mutate": nil}, - "errors": []map[string]interface{}{ - { - "extensions": map[string]interface{}{ - "module": "users", - }, - }, - }, - }) - - a := gqlerrors.ErrWithGraphQLValidate("mutate", "name", "required") - ok, err := a.Match(jsonData) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("couldn't have key `validation`")) - }) - - It("should checking failure validate", func() { - mutate := "mutate" - field := "name" - rule := "required" - a := gqlerrors.ErrWithGraphQLValidate(mutate, "name", "required") - failureValidate := a.FailureMessage("mutate") - fValidate := format.Message(mutate, "to have any validation equal field [", field, "] and rules [", rule, "]") - Expect(failureValidate).To(Equal(fValidate)) - }) - - It("should checking negative failure validate", func() { - mutate := "mutate" - field := "name" - rule := "required" - a := gqlerrors.ErrWithGraphQLValidate(mutate, field, rule) - failureValidate := a.NegatedFailureMessage("mutate") - fValidate := format.Message(mutate, "to have any validation equal field [", field, "] and rules [", rule, "]") - Expect(failureValidate).To(Equal(fValidate)) - }) - -}) diff --git a/gqlerrors/gqlerrors.go b/gqlerrors/gqlerrors.go index 5491d75..bc3ab69 100644 --- a/gqlerrors/gqlerrors.go +++ b/gqlerrors/gqlerrors.go @@ -6,23 +6,50 @@ import ( "reflect" "github.com/99designs/gqlgen/client" + "github.com/graphql-go/graphql/gqlerrors" "github.com/vektah/gqlparser/gqlerror" + "gopkg.in/gavv/httpexpect.v1" ) -func prepare(name string, actual interface{}) (*gqlerror.Error, error) { +type errOutput struct { + Gqlerror *gqlerror.Error + FormattedError *gqlerrors.FormattedError +} + +func prepare(name string, actual interface{}) (*errOutput, error) { switch t := actual.(type) { case json.RawMessage: var e gqlerror.List if err := json.Unmarshal(t, &e); err != nil { return nil, fmt.Errorf("Failed to unmarshal: %s", err.Error()) } - return e[0], nil + return &errOutput{ + Gqlerror: e[0], + }, nil case client.RawJsonError: return prepare(name, t.RawMessage) case gqlerror.Error: - return &t, nil + return &errOutput{ + Gqlerror: &t, + }, nil case *gqlerror.Error: - return t, nil + return &errOutput{ + Gqlerror: t, + }, nil + case *httpexpect.Object: + var graphQLError graphQLError + err := graphQLError.decode(t.Raw()) + if err != nil { + return nil, err + } + + if len(graphQLError.Errors) > 0 { + return &errOutput{ + FormattedError: graphQLError.Errors[0], + }, nil + } + + return nil, fmt.Errorf("%s httpexpect.Object not is error %s", name, reflect.TypeOf(actual)) default: return nil, fmt.Errorf("%s matcher does not know how to handle %s", name, reflect.TypeOf(actual)) } diff --git a/gqlerrors/message.go b/gqlerrors/message.go index b72de5a..81e3b73 100644 --- a/gqlerrors/message.go +++ b/gqlerrors/message.go @@ -8,7 +8,6 @@ import ( "github.com/lab259/errors/v2" "github.com/onsi/gomega/format" "github.com/onsi/gomega/types" - "github.com/vektah/gqlparser/gqlerror" ) // HaveMessage succeeds if actual is a GraphQL Error that have the @@ -20,22 +19,34 @@ func HaveMessage(expected interface{}) types.GomegaMatcher { } type haveMessageMatcher struct { - err gqlerror.Error + err interface{} message string expected interface{} } -func (matcher *haveMessageMatcher) Match(actual interface{}) (bool, error) { +func (matcher *haveMessageMatcher) Match(actual interface{}) (ok bool, err error) { gqlerror, err := prepare("HaveMessage", actual) if err != nil { return false, err } - matcher.err = *gqlerror + var message string + if gqlerror.Gqlerror != nil { + message, ok = gqlerror.Gqlerror.Extensions["message"].(string) + if !ok { + return false, fmt.Errorf("Message extension not found in %s", gqlerror) + } + + matcher.err = gqlerror.Gqlerror + } + + if gqlerror.FormattedError != nil { + message, ok = gqlerror.FormattedError.Extensions["message"].(string) + if !ok { + return false, fmt.Errorf("Message extension not found in %s", gqlerror) + } - message, ok := gqlerror.Extensions["message"].(string) - if !ok { - return false, fmt.Errorf("Message extension not found in %s", gqlerror) + matcher.err = gqlerror.FormattedError } switch t := matcher.expected.(type) { @@ -73,22 +84,30 @@ func ContainMessage(expected interface{}) types.GomegaMatcher { } type containMessageMatcher struct { - err gqlerror.Error + err map[string]interface{} message string expected interface{} } -func (matcher *containMessageMatcher) Match(actual interface{}) (bool, error) { +func (matcher *containMessageMatcher) Match(actual interface{}) (ok bool, err error) { gqlerror, err := prepare("ContainMessage", actual) if err != nil { return false, err } - matcher.err = *gqlerror + var message string + if gqlerror.Gqlerror != nil { + message, ok = gqlerror.Gqlerror.Extensions["message"].(string) + if !ok { + message = gqlerror.Gqlerror.Message + } + } - message, ok := gqlerror.Extensions["message"].(string) - if !ok { - message = gqlerror.Message + if gqlerror.FormattedError != nil { + message, ok = gqlerror.FormattedError.Extensions["message"].(string) + if !ok { + message = gqlerror.FormattedError.Message + } } switch t := matcher.expected.(type) { @@ -102,6 +121,8 @@ func (matcher *containMessageMatcher) Match(actual interface{}) (bool, error) { } case string: matcher.message = t + case error: + matcher.message = t.Error() default: return false, fmt.Errorf("ContainMessage matcher does not know how to assert %s", reflect.TypeOf(t)) } diff --git a/gqlerrors/message_test.go b/gqlerrors/message_test.go index 28ec6da..e9d4db1 100644 --- a/gqlerrors/message_test.go +++ b/gqlerrors/message_test.go @@ -9,151 +9,21 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/vektah/gqlparser/gqlerror" + "gopkg.in/gavv/httpexpect.v1" ) var _ = Describe("GraphQL Extensions", func() { Describe("HaveMessage", func() { - It("should match", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", - }, - } - - a := gqlerrors.HaveMessage("name is required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should match using Option", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", - }, - } - - a := gqlerrors.HaveMessage(errors.Message("name is required")) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should match using ErrorWithMessage", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", - }, - } - - a := gqlerrors.HaveMessage(errors.Message("name is required")(nil)) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should match (pointer)", func() { - gqlerr := &gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", - }, - } - - a := gqlerrors.HaveMessage("name is required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should match (json.RawMessage)", func() { - gqlerr := json.RawMessage(`[{"extensions": {"message": "name is required"}}]`) - a := gqlerrors.HaveMessage("name is required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should match (client.RawJsonError)", func() { - gqlerr := client.RawJsonError{ - RawMessage: json.RawMessage(`[{"extensions": {"message": "name is required"}}]`), - } - a := gqlerrors.HaveMessage("name is required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should not match", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", - }, - } - - a := gqlerrors.HaveMessage("not-found") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should fail without extensions", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{}, - } - - a := gqlerrors.HaveMessage("name is required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("Message extension not found in")) - }) - - It("should fail with wrong errors.Option", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", - }, - } - - a := gqlerrors.HaveMessage(errors.Module("name is required")) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("HaveMessage matcher only support an `errors.Message` option")) - }) - - It("should fail with wrong actual type", func() { - a := gqlerrors.HaveMessage("name is required") - ok, err := a.Match(26) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("HaveMessage matcher does not know how to handle int")) - }) + When("Gqlerror", func() { - It("should fail with wrong expected type", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", - }, - } - - a := gqlerrors.HaveMessage(26) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("HaveMessage matcher does not know how to assert int")) - }) - }) - - Describe("ContainMessage", func() { - - When("using error's message", func() { It("should match", func() { gqlerr := gqlerror.Error{ - Message: "error: name is required", + Extensions: map[string]interface{}{ + "message": "name is required", + }, } - a := gqlerrors.ContainMessage("name is required") + a := gqlerrors.HaveMessage("name is required") ok, err := a.Match(gqlerr) Expect(ok).To(BeTrue()) Expect(err).ToNot(HaveOccurred()) @@ -161,10 +31,12 @@ var _ = Describe("GraphQL Extensions", func() { It("should match using Option", func() { gqlerr := gqlerror.Error{ - Message: "error: name is required", + Extensions: map[string]interface{}{ + "message": "name is required", + }, } - a := gqlerrors.ContainMessage(errors.Message("name is required")) + a := gqlerrors.HaveMessage(errors.Message("name is required")) ok, err := a.Match(gqlerr) Expect(ok).To(BeTrue()) Expect(err).ToNot(HaveOccurred()) @@ -172,10 +44,12 @@ var _ = Describe("GraphQL Extensions", func() { It("should match using ErrorWithMessage", func() { gqlerr := gqlerror.Error{ - Message: "error: name is required", + Extensions: map[string]interface{}{ + "message": "name is required", + }, } - a := gqlerrors.ContainMessage(errors.Message("name is required")(nil)) + a := gqlerrors.HaveMessage(errors.Message("name is required")(nil)) ok, err := a.Match(gqlerr) Expect(ok).To(BeTrue()) Expect(err).ToNot(HaveOccurred()) @@ -183,18 +57,20 @@ var _ = Describe("GraphQL Extensions", func() { It("should match (pointer)", func() { gqlerr := &gqlerror.Error{ - Message: "error: name is required", + Extensions: map[string]interface{}{ + "message": "name is required", + }, } - a := gqlerrors.ContainMessage("name is required") + a := gqlerrors.HaveMessage("name is required") ok, err := a.Match(gqlerr) Expect(ok).To(BeTrue()) Expect(err).ToNot(HaveOccurred()) }) It("should match (json.RawMessage)", func() { - gqlerr := json.RawMessage(`[{"message": "name is required"}]`) - a := gqlerrors.ContainMessage("name is required") + gqlerr := json.RawMessage(`[{"extensions": {"message": "name is required"}}]`) + a := gqlerrors.HaveMessage("name is required") ok, err := a.Match(gqlerr) Expect(ok).To(BeTrue()) Expect(err).ToNot(HaveOccurred()) @@ -202,9 +78,9 @@ var _ = Describe("GraphQL Extensions", func() { It("should match (client.RawJsonError)", func() { gqlerr := client.RawJsonError{ - RawMessage: json.RawMessage(`[{"message": "name is required"}]`), + RawMessage: json.RawMessage(`[{"extensions": {"message": "name is required"}}]`), } - a := gqlerrors.ContainMessage("name is required") + a := gqlerrors.HaveMessage("name is required") ok, err := a.Match(gqlerr) Expect(ok).To(BeTrue()) Expect(err).ToNot(HaveOccurred()) @@ -212,180 +88,455 @@ var _ = Describe("GraphQL Extensions", func() { It("should not match", func() { gqlerr := gqlerror.Error{ - Message: "error: name is required", + Extensions: map[string]interface{}{ + "message": "name is required", + }, } - a := gqlerrors.ContainMessage("not-found") + a := gqlerrors.HaveMessage("not-found") ok, err := a.Match(gqlerr) Expect(ok).To(BeFalse()) Expect(err).ToNot(HaveOccurred()) }) + It("should fail without extensions", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{}, + } + + a := gqlerrors.HaveMessage("name is required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Message extension not found in")) + }) + It("should fail with wrong errors.Option", func() { gqlerr := gqlerror.Error{ - Message: "error: name is required", + Extensions: map[string]interface{}{ + "message": "name is required", + }, } - a := gqlerrors.ContainMessage(errors.Module("name is required")) + a := gqlerrors.HaveMessage(errors.Module("name is required")) ok, err := a.Match(gqlerr) Expect(ok).To(BeFalse()) Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("ContainMessage matcher only support an `errors.Message` option")) + Expect(err.Error()).To(ContainSubstring("HaveMessage matcher only support an `errors.Message` option")) }) It("should fail with wrong actual type", func() { - a := gqlerrors.ContainMessage("name is required") + a := gqlerrors.HaveMessage("name is required") ok, err := a.Match(26) Expect(ok).To(BeFalse()) Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("ContainMessage matcher does not know how to handle int")) + Expect(err.Error()).To(ContainSubstring("HaveMessage matcher does not know how to handle int")) }) It("should fail with wrong expected type", func() { gqlerr := gqlerror.Error{ - Message: "error: name is required", + Extensions: map[string]interface{}{ + "message": "name is required", + }, } - a := gqlerrors.ContainMessage(26) + a := gqlerrors.HaveMessage(26) ok, err := a.Match(gqlerr) Expect(ok).To(BeFalse()) Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("ContainMessage matcher does not know how to assert int")) + Expect(err.Error()).To(ContainSubstring("HaveMessage matcher does not know how to assert int")) }) }) - When("using error's extensions", func() { - It("should match", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", - }, - } + Describe("ContainMessage", func() { + + When("using error's message", func() { + It("should match", func() { + gqlerr := gqlerror.Error{ + Message: "error: name is required", + } + + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match using Option", func() { + gqlerr := gqlerror.Error{ + Message: "error: name is required", + } + + a := gqlerrors.ContainMessage(errors.Message("name is required")) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match using ErrorWithMessage", func() { + gqlerr := gqlerror.Error{ + Message: "error: name is required", + } + + a := gqlerrors.ContainMessage(errors.Message("name is required")(nil)) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match (pointer)", func() { + gqlerr := &gqlerror.Error{ + Message: "error: name is required", + } + + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match (json.RawMessage)", func() { + gqlerr := json.RawMessage(`[{"message": "name is required"}]`) + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match (client.RawJsonError)", func() { + gqlerr := client.RawJsonError{ + RawMessage: json.RawMessage(`[{"message": "name is required"}]`), + } + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should not match", func() { + gqlerr := gqlerror.Error{ + Message: "error: name is required", + } + + a := gqlerrors.ContainMessage("not-found") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail with wrong errors.Option", func() { + gqlerr := gqlerror.Error{ + Message: "error: name is required", + } + + a := gqlerrors.ContainMessage(errors.Module("name is required")) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("ContainMessage matcher only support an `errors.Message` option")) + }) + + It("should fail with wrong actual type", func() { + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(26) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("ContainMessage matcher does not know how to handle int")) + }) + + It("should fail with wrong expected type", func() { + gqlerr := gqlerror.Error{ + Message: "error: name is required", + } + + a := gqlerrors.ContainMessage(26) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("ContainMessage matcher does not know how to assert int")) + }) + }) - a := gqlerrors.ContainMessage("name is required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) + When("using error's extensions", func() { + It("should match", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "message": "name is required", + }, + } + + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match using Option", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "message": "name is required", + }, + } + + a := gqlerrors.ContainMessage(errors.Message("name is required")) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match using ErrorWithMessage", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "message": "name is required", + }, + } + + a := gqlerrors.ContainMessage(errors.Message("name is required")(nil)) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match (pointer)", func() { + gqlerr := &gqlerror.Error{ + Extensions: map[string]interface{}{ + "message": "name is required", + }, + } + + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match (json.RawMessage)", func() { + gqlerr := json.RawMessage(`[{"extensions": {"message": "name is required"}}]`) + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match (client.RawJsonError)", func() { + gqlerr := client.RawJsonError{ + RawMessage: json.RawMessage(`[{"extensions": {"message": "name is required"}}]`), + } + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should not match", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "message": "name is required", + }, + } + + a := gqlerrors.ContainMessage("not-found") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail without extensions", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{}, + } + + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail with wrong errors.Option", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "message": "name is required", + }, + } + + a := gqlerrors.ContainMessage(errors.Module("name is required")) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("ContainMessage matcher only support an `errors.Message` option")) + }) + + It("should fail with wrong actual type", func() { + a := gqlerrors.ContainMessage("name is required") + ok, err := a.Match(26) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("ContainMessage matcher does not know how to handle int")) + }) + + It("should fail with wrong expected type", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "message": "name is required", + }, + } + + a := gqlerrors.ContainMessage(26) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("ContainMessage matcher does not know how to assert int")) + }) }) + }) - It("should match using Option", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", + When("GraphQL", func() { + It("should check the return extension message", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "message": "name is required", + }, + }, }, - } + }) - a := gqlerrors.ContainMessage(errors.Message("name is required")) - ok, err := a.Match(gqlerr) + a := gqlerrors.HaveMessage("name is required") + ok, err := a.Match(jsonData) Expect(ok).To(BeTrue()) Expect(err).ToNot(HaveOccurred()) }) - It("should match using ErrorWithMessage", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", + It("should check the return message", func() { + message := errors.Message("name is required") + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "code": "validation", + }, + "message": "name is required", + }, }, - } + }) - a := gqlerrors.ContainMessage(errors.Message("name is required")(nil)) - ok, err := a.Match(gqlerr) + a := gqlerrors.ContainMessage(message) + ok, err := a.Match(jsonData) Expect(ok).To(BeTrue()) Expect(err).ToNot(HaveOccurred()) }) - It("should match (pointer)", func() { - gqlerr := &gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", + It("should check the return message type error", func() { + message := errors.New("name is required") + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "code": "validation", + }, + "message": "name is required", + }, }, - } + }) - a := gqlerrors.ContainMessage("name is required") - ok, err := a.Match(gqlerr) + a := gqlerrors.ContainMessage(message) + ok, err := a.Match(jsonData) Expect(ok).To(BeTrue()) Expect(err).ToNot(HaveOccurred()) }) - It("should match (json.RawMessage)", func() { - gqlerr := json.RawMessage(`[{"extensions": {"message": "name is required"}}]`) - a := gqlerrors.ContainMessage("name is required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + It("should check the return message type string", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "code": "validation", + }, + "message": "email is required", + }, + }, + }) - It("should match (client.RawJsonError)", func() { - gqlerr := client.RawJsonError{ - RawMessage: json.RawMessage(`[{"extensions": {"message": "name is required"}}]`), - } - a := gqlerrors.ContainMessage("name is required") - ok, err := a.Match(gqlerr) + a := gqlerrors.ContainMessage("email is required") + ok, err := a.Match(jsonData) Expect(ok).To(BeTrue()) Expect(err).ToNot(HaveOccurred()) }) - It("should not match", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", + It("should fail checking the return when error not contains message", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "module": "accounts", + }, + }, }, - } + }) - a := gqlerrors.ContainMessage("not-found") - ok, err := a.Match(gqlerr) + a := gqlerrors.HaveMessage("users") + ok, err := a.Match(jsonData) Expect(ok).To(BeFalse()) - Expect(err).ToNot(HaveOccurred()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Message extension not found")) }) - It("should fail without extensions", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{}, - } + It("should fail checking the return when error not matcher message option", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "message": "validation", + }, + }, + }, + }) - a := gqlerrors.ContainMessage("name is required") - ok, err := a.Match(gqlerr) + op := errors.Message("new-message") + a := gqlerrors.HaveMessage(op) + ok, err := a.Match(jsonData) Expect(ok).To(BeFalse()) Expect(err).ToNot(HaveOccurred()) }) - It("should fail with wrong errors.Option", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", + It("should fail checking the return when error not matcher message text", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "message": "validation", + }, + }, }, - } + }) - a := gqlerrors.ContainMessage(errors.Module("name is required")) - ok, err := a.Match(gqlerr) + a := gqlerrors.HaveMessage("graphql") + ok, err := a.Match(jsonData) Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("ContainMessage matcher only support an `errors.Message` option")) + Expect(err).ToNot(HaveOccurred()) }) - It("should fail with wrong actual type", func() { - a := gqlerrors.ContainMessage("name is required") - ok, err := a.Match(26) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("ContainMessage matcher does not know how to handle int")) + It("should checking failure message", func() { + message := "graphql" + a := gqlerrors.HaveMessage(message) + failureMessage := a.FailureMessage("mutate") + Expect(failureMessage).To(ContainSubstring("to have Message extension equals to")) }) - It("should fail with wrong expected type", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "message": "name is required", - }, - } - - a := gqlerrors.ContainMessage(26) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("ContainMessage matcher does not know how to assert int")) + It("should checking negative failure message", func() { + message := "graphql" + a := gqlerrors.HaveMessage(message) + failureMessage := a.NegatedFailureMessage("mutate") + Expect(failureMessage).To(ContainSubstring("to not have Message extension equals to")) }) }) - }) - }) diff --git a/gqlerrors/module.go b/gqlerrors/module.go index 73479d6..50e93fb 100644 --- a/gqlerrors/module.go +++ b/gqlerrors/module.go @@ -7,7 +7,6 @@ import ( "github.com/lab259/errors/v2" "github.com/onsi/gomega/format" "github.com/onsi/gomega/types" - "github.com/vektah/gqlparser/gqlerror" ) // HaveModule succeeds if actual is a GraphQL Error that have the @@ -19,22 +18,34 @@ func HaveModule(expected interface{}) types.GomegaMatcher { } type haveModuleMatcher struct { - err gqlerror.Error + err interface{} module string expected interface{} } -func (matcher *haveModuleMatcher) Match(actual interface{}) (bool, error) { +func (matcher *haveModuleMatcher) Match(actual interface{}) (ok bool, err error) { gqlerror, err := prepare("HaveModule", actual) if err != nil { return false, err } - matcher.err = *gqlerror + var module string + if gqlerror.Gqlerror != nil { + module, ok = gqlerror.Gqlerror.Extensions["module"].(string) + if !ok { + return false, fmt.Errorf("Module extension not found in %s", gqlerror) + } + + matcher.err = gqlerror.Gqlerror + } + + if gqlerror.FormattedError != nil { + module, ok = gqlerror.FormattedError.Extensions["module"].(string) + if !ok { + return false, fmt.Errorf("Module extension not found in %s", gqlerror) + } - module, ok := gqlerror.Extensions["module"].(string) - if !ok { - return false, fmt.Errorf("Module extension not found in %s", gqlerror) + matcher.err = gqlerror.FormattedError } switch t := matcher.expected.(type) { diff --git a/gqlerrors/module_test.go b/gqlerrors/module_test.go index df5a01d..7aeb7fd 100644 --- a/gqlerrors/module_test.go +++ b/gqlerrors/module_test.go @@ -9,140 +9,290 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/vektah/gqlparser/gqlerror" + "gopkg.in/gavv/httpexpect.v1" ) var _ = Describe("GraphQL Extensions", func() { Describe("HaveModule", func() { - It("should match", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "module": "api", - }, - } - - a := gqlerrors.HaveModule("api") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + When("Gqlerror", func() { + It("should match", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "module": "api", + }, + } - It("should match using Option", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "module": "api", - }, - } - - a := gqlerrors.HaveModule(errors.Module("api")) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + a := gqlerrors.HaveModule("api") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) - It("should match using ErrorWithModule", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "module": "api", - }, - } - - a := gqlerrors.HaveModule(errors.Module("api")(nil)) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + It("should match using Option", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "module": "api", + }, + } - It("should match (pointer)", func() { - gqlerr := &gqlerror.Error{ - Extensions: map[string]interface{}{ - "module": "api", - }, - } - - a := gqlerrors.HaveModule("api") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + a := gqlerrors.HaveModule(errors.Module("api")) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) - It("should match (json.RawMessage)", func() { - gqlerr := json.RawMessage(`[{"extensions": {"module": "api"}}]`) - a := gqlerrors.HaveModule("api") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + It("should match using ErrorWithModule", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "module": "api", + }, + } - It("should match (client.RawJsonError)", func() { - gqlerr := client.RawJsonError{ - RawMessage: json.RawMessage(`[{"extensions": {"module": "api"}}]`), - } - a := gqlerrors.HaveModule("api") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) + a := gqlerrors.HaveModule(errors.Module("api")(nil)) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) - It("should not match", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "module": "api", - }, - } - - a := gqlerrors.HaveModule("not-found") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).ToNot(HaveOccurred()) - }) + It("should match (pointer)", func() { + gqlerr := &gqlerror.Error{ + Extensions: map[string]interface{}{ + "module": "api", + }, + } - It("should fail without extensions", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{}, - } + a := gqlerrors.HaveModule("api") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) - a := gqlerrors.HaveModule("api") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("Module extension not found in")) - }) + It("should match (json.RawMessage)", func() { + gqlerr := json.RawMessage(`[{"extensions": {"module": "api"}}]`) + a := gqlerrors.HaveModule("api") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) - It("should fail with wrong errors.Option", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "module": "api", - }, - } - - a := gqlerrors.HaveModule(errors.Code("api")) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("HaveModule matcher only support an `errors.Module` option")) - }) + It("should match (client.RawJsonError)", func() { + gqlerr := client.RawJsonError{ + RawMessage: json.RawMessage(`[{"extensions": {"module": "api"}}]`), + } + a := gqlerrors.HaveModule("api") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should not match", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "module": "api", + }, + } + + a := gqlerrors.HaveModule("not-found") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail without extensions", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{}, + } + + a := gqlerrors.HaveModule("api") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Module extension not found in")) + }) + + It("should fail with wrong errors.Option", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "module": "api", + }, + } + + a := gqlerrors.HaveModule(errors.Code("api")) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("HaveModule matcher only support an `errors.Module` option")) + }) + + It("should fail with wrong actual type", func() { + a := gqlerrors.HaveModule("api") + ok, err := a.Match(26) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("HaveModule matcher does not know how to handle int")) + }) + + It("should fail with wrong expected type", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "module": "api", + }, + } - It("should fail with wrong actual type", func() { - a := gqlerrors.HaveModule("api") - ok, err := a.Match(26) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("HaveModule matcher does not know how to handle int")) + a := gqlerrors.HaveModule(26) + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("HaveModule matcher does not know how to assert int")) + }) }) - It("should fail with wrong expected type", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "module": "api", - }, - } - - a := gqlerrors.HaveModule(26) - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("HaveModule matcher does not know how to assert int")) + When("GraphQL", func() { + + It("should check the return extension module", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "module": "users", + }, + }, + }, + }) + + a := gqlerrors.HaveModule("users") + ok, err := a.Match(jsonData) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should check the return module", func() { + module := errors.WrapModule(nil, "users") + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "code": "validation", + "module": "users", + }, + }, + }, + }) + + a := gqlerrors.HaveModule(module) + ok, err := a.Match(jsonData) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should check the return module type string", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "code": "validation", + "module": "users", + }, + }, + }, + }) + + a := gqlerrors.HaveModule("users") + ok, err := a.Match(jsonData) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail check the return module empty", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "code": "validation", + }, + }, + }, + }) + + a := gqlerrors.HaveModule("users") + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Module extension not found")) + }) + + It("should fail checking the return when error not contains module", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "module": "accounts", + }, + }, + }, + }) + + a := gqlerrors.HaveModule("users") + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail checking the return when error not matcher module option", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "module": "validation", + }, + }, + }, + }) + + option := errors.Module("new-module") + a := gqlerrors.HaveModule(option) + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail checking the return when error not matcher module text", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "module": "validation", + }, + }, + }, + }) + + a := gqlerrors.HaveModule("graphql") + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should checking failure module", func() { + module := "graphql" + a := gqlerrors.HaveModule(module) + failureModule := a.FailureMessage("mutate") + Expect(failureModule).To(ContainSubstring("to have Module extension equals to")) + }) + + It("should checking negative failure module", func() { + module := "graphql" + a := gqlerrors.HaveModule(module) + failureModule := a.NegatedFailureMessage("mutate") + Expect(failureModule).To(ContainSubstring("to not have Module extension equals to")) + }) }) }) - }) diff --git a/gqlerrors/validator.go b/gqlerrors/validator.go index 88de98b..b90540b 100644 --- a/gqlerrors/validator.go +++ b/gqlerrors/validator.go @@ -6,7 +6,6 @@ import ( "github.com/onsi/gomega/format" "github.com/onsi/gomega/types" - "github.com/vektah/gqlparser/gqlerror" ) // HaveValidation succeeds if actual is a GraphQL Error that have the @@ -19,22 +18,38 @@ func HaveValidation(field string, rules ...string) types.GomegaMatcher { } type haveValidationMatcher struct { - err gqlerror.Error + err interface{} errors map[string]interface{} field string rules []string } -func (matcher *haveValidationMatcher) Match(actual interface{}) (bool, error) { +func (matcher *haveValidationMatcher) Match(actual interface{}) (ok bool, err error) { gqlerror, err := prepare("HaveValidation", actual) if err != nil { return false, err } - matcher.err = *gqlerror + var errors map[string]interface{} + if gqlerror.Gqlerror != nil { + errors, ok = gqlerror.Gqlerror.Extensions["errors"].(map[string]interface{}) + if !ok { + return false, fmt.Errorf("Validation extension not found in %s", gqlerror) + } + + matcher.err = gqlerror.Gqlerror + } + + if gqlerror.FormattedError != nil { + errors, ok = gqlerror.FormattedError.Extensions["errors"].(map[string]interface{}) + if !ok { + return false, fmt.Errorf("Validation extension not found in %s", gqlerror) + } + + matcher.err = gqlerror.FormattedError + } - errors, ok := gqlerror.Extensions["errors"].(map[string]interface{}) - if !ok { + if gqlerror.Gqlerror == nil && gqlerror.FormattedError == nil { return false, fmt.Errorf("Validation extension not found in %s", gqlerror) } diff --git a/gqlerrors/validator_test.go b/gqlerrors/validator_test.go index 59c7cf1..24dacfd 100644 --- a/gqlerrors/validator_test.go +++ b/gqlerrors/validator_test.go @@ -8,151 +8,236 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/vektah/gqlparser/gqlerror" + "gopkg.in/gavv/httpexpect.v1" ) var _ = Describe("GraphQL Extensions", func() { Describe("HaveValidation", func() { - It("should match", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "errors": map[string]interface{}{ - "name": []interface{}{ - "required", + + When("Gqlerror", func() { + It("should match", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "errors": map[string]interface{}{ + "name": []interface{}{ + "required", + }, }, }, - }, - } - - a := gqlerrors.HaveValidation("name", "required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should match multiple rules", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "errors": map[string]interface{}{ - "email": []interface{}{ - "required", - "email", - "min=6", + } + + a := gqlerrors.HaveValidation("name", "required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match multiple rules", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "errors": map[string]interface{}{ + "email": []interface{}{ + "required", + "email", + "min=6", + }, }, }, - }, - } - - a := gqlerrors.HaveValidation("email", "required", "email") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should match (pointer)", func() { - gqlerr := &gqlerror.Error{ - Extensions: map[string]interface{}{ - "errors": map[string]interface{}{ - "name": []interface{}{ - "required", + } + + a := gqlerrors.HaveValidation("email", "required", "email") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match (pointer)", func() { + gqlerr := &gqlerror.Error{ + Extensions: map[string]interface{}{ + "errors": map[string]interface{}{ + "name": []interface{}{ + "required", + }, }, }, - }, - } - - a := gqlerrors.HaveValidation("name", "required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should match (json.RawMessage)", func() { - gqlerr := json.RawMessage(`[{"extensions": {"errors": {"name": ["required"]}}}]`) - a := gqlerrors.HaveValidation("name", "required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should match (client.RawJsonError)", func() { - gqlerr := client.RawJsonError{ - RawMessage: json.RawMessage(`[{"extensions": {"errors": {"name": ["required"]}}}]`), - } - a := gqlerrors.HaveValidation("name", "required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeTrue()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should not match", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "errors": map[string]interface{}{ - "name": []interface{}{ - "required", + } + + a := gqlerrors.HaveValidation("name", "required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match (json.RawMessage)", func() { + gqlerr := json.RawMessage(`[{"extensions": {"errors": {"name": ["required"]}}}]`) + a := gqlerrors.HaveValidation("name", "required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should match (client.RawJsonError)", func() { + gqlerr := client.RawJsonError{ + RawMessage: json.RawMessage(`[{"extensions": {"errors": {"name": ["required"]}}}]`), + } + a := gqlerrors.HaveValidation("name", "required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should not match", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "errors": map[string]interface{}{ + "name": []interface{}{ + "required", + }, }, }, - }, - } - - a := gqlerrors.HaveValidation("name", "min") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should not match (field)", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "errors": map[string]interface{}{ - "name": []interface{}{ - "required", + } + + a := gqlerrors.HaveValidation("name", "min") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should not match (field)", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "errors": map[string]interface{}{ + "name": []interface{}{ + "required", + }, }, }, - }, - } - - a := gqlerrors.HaveValidation("age", "required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).ToNot(HaveOccurred()) - }) - - It("should not match (not all rules)", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{ - "errors": map[string]interface{}{ - "name": []interface{}{ - "required", + } + + a := gqlerrors.HaveValidation("age", "required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should not match (not all rules)", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{ + "errors": map[string]interface{}{ + "name": []interface{}{ + "required", + }, }, }, - }, - } - - a := gqlerrors.HaveValidation("name", "required", "min") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).ToNot(HaveOccurred()) + } + + a := gqlerrors.HaveValidation("name", "required", "min") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail without extensions", func() { + gqlerr := gqlerror.Error{ + Extensions: map[string]interface{}{}, + } + + a := gqlerrors.HaveValidation("name", "required") + ok, err := a.Match(gqlerr) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Validation extension not found in")) + }) + + It("should fail with wrong actual type", func() { + a := gqlerrors.HaveValidation("name", "required") + ok, err := a.Match(26) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("HaveValidation matcher does not know how to handle int")) + }) }) - It("should fail without extensions", func() { - gqlerr := gqlerror.Error{ - Extensions: map[string]interface{}{}, - } - - a := gqlerrors.HaveValidation("name", "required") - ok, err := a.Match(gqlerr) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("Validation extension not found in")) - }) - - It("should fail with wrong actual type", func() { - a := gqlerrors.HaveValidation("name", "required") - ok, err := a.Match(26) - Expect(ok).To(BeFalse()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("HaveValidation matcher does not know how to handle int")) + When("GraphQL", func() { + It("should check the return extension validate", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "module": "users", + "errors": map[string]interface{}{ + "name": []interface{}{ + "required", + }, + }, + }, + }, + }, + }) + + a := gqlerrors.HaveValidation("name", "required") + ok, err := a.Match(jsonData) + Expect(ok).To(BeTrue()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail checking the return when error not matcher validate", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "module": "users", + "errors": map[string]interface{}{ + "email": []interface{}{ + "required", + }, + }, + }, + }, + }, + }) + + a := gqlerrors.HaveValidation("email", "email") + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).ToNot(HaveOccurred()) + }) + + It("should fail checking the return when error not matcher errors", func() { + jsonData := httpexpect.NewObject(&httpGomegaFail{}, map[string]interface{}{ + "data": map[string]interface{}{"mutate": nil}, + "errors": []map[string]interface{}{ + { + "extensions": map[string]interface{}{ + "module": "users", + }, + }, + }, + }) + + a := gqlerrors.HaveValidation("name", "required") + ok, err := a.Match(jsonData) + Expect(ok).To(BeFalse()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("Validation extension not found")) + }) + + It("should checking failure validate", func() { + a := gqlerrors.HaveValidation("name", "required") + failureValidate := a.FailureMessage("mutate") + Expect(failureValidate).To(ContainSubstring("to have Validation extension with failures")) + }) + + It("should checking negative failure validate", func() { + field := "name" + rule := "required" + a := gqlerrors.HaveValidation(field, rule) + failureValidate := a.NegatedFailureMessage("mutate") + Expect(failureValidate).To(ContainSubstring("to not have Validation extension with failures")) + }) }) }) })