Skip to content

Commit

Permalink
Validate that interfaces should not have any resolver (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
namenu authored Aug 18, 2024
1 parent 41ef254 commit de9afce
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/tools/graphql/api.clj
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,7 @@
(pcompose [:red "Unreachable input"] " " (name f) (print-loc loc)))
(doseq [[i loc] (validators/unreachable-interfaces schema)]
(pcompose [:red "Unreachable interface"] " " (name i) (print-loc loc)))
(doseq [[i _loc field] (validators/interface-with-resolver schema)]
(pcompose [:red "Interface should not have resolvers"] " " (name i) "." (name field)))
(doseq [m (validators/relay-arguments schema)]
(pcompose [:red "Invalid pagination arguments"] " " (name (:query m)) [:blue " " (:hint m)]))))
1 change: 1 addition & 0 deletions src/tools/graphql/stitch/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
(update :objects dissoc :Query :Mutation :Subscription)))

(defn source-map
"TODO: only support for 1-level map"
[path]
(fn [schema]
(let [embed-loc #(update-vals % (fn [v]
Expand Down
24 changes: 19 additions & 5 deletions src/tools/graphql/validators.clj
Original file line number Diff line number Diff line change
Expand Up @@ -157,23 +157,37 @@
"A field that returns a Connection Type must include forward pagination arguments, backward pagination arguments, or both.")]
(assoc m :hint hint))))))

(guess-connection-direction {:first {:type '(non-null Int)},
:after {:type 'ID},
:orderBy {:type :CommunityPostCommentOrderBy, :default-value :CREATED_AT},
:orderDirection {:type :OrderDirection, :default-value :DESC}})
(defn interface-with-resolver
[schema]
(sort (m/search schema
{:interfaces {?ifc {:fields {?field {:resolve (m/some ?resolver)
:loc ?loc}}}}}
[?ifc ?loc ?field ?resolver])))

(comment

(require '[tools.graphql.stitch.core :refer [read-edn]]
'[clojure.java.io :as io])
(def schema (read-edn (io/file "../farmmorning-backend/bases/core-api/resources/superschema.edn")))
@(def schema (read-edn (io/file "../farmmorning-backend/bases/core-api/resources/superschema.edn")))
(def schema (read-edn (io/resource "unreachable.edn")))
(def schema (read-edn (io/resource "pagination.edn")))

(unreachable-types schema)
(unreachable-input-types schema)
(unreachable-interfaces schema)
(interface-with-resolver schema)

(m/search schema
{:interfaces {?ifc {:loc ?loc
:fields {?field {:resolve ?resolver}}}}}
[?ifc ?loc ?field ?resolver])

(no-root-resolver schema)
(relay-arguments schema)

(guess-connection-direction {:first {:type '(non-null Int)},
:after {:type 'ID},
:orderBy {:type :CommunityPostCommentOrderBy, :default-value :CREATED_AT},
:orderDirection {:type :OrderDirection, :default-value :DESC}})

:rcf)
19 changes: 19 additions & 0 deletions test/tools/graphql/validators_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,25 @@
:Dummy {:fields {:id {:type 'String}}}}}]
(is (= [[:UnusedIf nil]] (v/unreachable-interfaces schema))))))

(deftest interface-with-resolver-test
(testing "interface should not have any resolvers to its fields"
(let [schema {:interfaces {:Node {:fields {:id {:type '(non-null ID)
:description "The id of the object"}}}
:Post {:implements [:Node]
:fields {:id {:type '(non-null ID)
:description "The id of the object"}
:title {:type '(non-null String)
:description "The title of the post"
:resolve (fn [_ _ _] nil)}
:author {:type '(non-null User)
:description "The author of the post"}}}}}
result (v/interface-with-resolver schema)]
(is (= (count result) 1))
(is (let [[ifc _ field resolver] (first result)]
(and (= ifc :Post)
(= field :title)
(some? resolver)))))))

(deftest no-root-resolver
(testing "query or mutation without resolver"
(let [schema {:queries {:user {:type :User}}
Expand Down

0 comments on commit de9afce

Please sign in to comment.