fix(graphql): detect custom champs in fragment definitions
This commit is contained in:
parent
ac6010da06
commit
b6bb9552e6
2 changed files with 63 additions and 10 deletions
|
@ -1,13 +1,14 @@
|
||||||
class API::V2::Context < GraphQL::Query::Context
|
class API::V2::Context < GraphQL::Query::Context
|
||||||
def has_fragment?(name)
|
# This method is used to check if a given fragment is used in the given query.
|
||||||
if self["has_fragment_#{name}"]
|
# We need that in order to maintain backward compatibility for Types de Champ
|
||||||
true
|
# that we extended in later iterations of our schema.
|
||||||
else
|
def has_fragment?(fragment_name)
|
||||||
visitor = HasFragment.new(self.query.selected_operation, name)
|
self[:has_fragment] ||= Hash.new do |hash, fragment_name|
|
||||||
|
visitor = HasFragment.new(query.document, fragment_name)
|
||||||
visitor.visit
|
visitor.visit
|
||||||
self["has_fragment_#{name}"] = visitor.found
|
hash[fragment_name] = visitor.found
|
||||||
self["has_fragment_#{name}"]
|
|
||||||
end
|
end
|
||||||
|
self[:has_fragment][fragment_name]
|
||||||
end
|
end
|
||||||
|
|
||||||
def internal_use?
|
def internal_use?
|
||||||
|
@ -36,17 +37,28 @@ class API::V2::Context < GraphQL::Query::Context
|
||||||
self[:authorized][demarche.id]
|
self[:authorized][demarche.id]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This is a query AST visitor that we use to check
|
||||||
|
# if a fragment with a given name is used in the given document.
|
||||||
|
# We check for both inline and standalone fragments.
|
||||||
class HasFragment < GraphQL::Language::Visitor
|
class HasFragment < GraphQL::Language::Visitor
|
||||||
def initialize(document, name)
|
def initialize(document, fragment_name)
|
||||||
super(document)
|
super(document)
|
||||||
@name = name.to_s
|
@fragment_name = fragment_name.to_s
|
||||||
@found = false
|
@found = false
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_reader :found
|
attr_reader :found
|
||||||
|
|
||||||
def on_inline_fragment(node, parent)
|
def on_inline_fragment(node, parent)
|
||||||
if node.type.name == @name
|
if node.type.name == @fragment_name
|
||||||
|
@found = true
|
||||||
|
end
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_fragment_definition(node, parent)
|
||||||
|
if node.type.name == @fragment_name
|
||||||
@found = true
|
@found = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,16 @@ RSpec.describe Types::DossierType, type: :graphql do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'dossier with champs' do
|
||||||
|
let(:procedure) { create(:procedure, :published, :with_commune, :with_address) }
|
||||||
|
let(:dossier) { create(:dossier, :accepte, :with_populated_champs, procedure: procedure) }
|
||||||
|
let(:query) { DOSSIER_WITH_CHAMPS_QUERY }
|
||||||
|
let(:variables) { { number: dossier.id } }
|
||||||
|
|
||||||
|
it { expect(data[:dossier][:champs][0][:__typename]).to eq "CommuneChamp" }
|
||||||
|
it { expect(data[:dossier][:champs][1][:__typename]).to eq "AddressChamp" }
|
||||||
|
end
|
||||||
|
|
||||||
DOSSIER_QUERY = <<-GRAPHQL
|
DOSSIER_QUERY = <<-GRAPHQL
|
||||||
query($number: Int!) {
|
query($number: Int!) {
|
||||||
dossier(number: $number) {
|
dossier(number: $number) {
|
||||||
|
@ -48,4 +58,35 @@ RSpec.describe Types::DossierType, type: :graphql do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GRAPHQL
|
GRAPHQL
|
||||||
|
|
||||||
|
DOSSIER_WITH_CHAMPS_QUERY = <<-GRAPHQL
|
||||||
|
query($number: Int!) {
|
||||||
|
dossier(number: $number) {
|
||||||
|
id
|
||||||
|
number
|
||||||
|
champs {
|
||||||
|
id
|
||||||
|
label
|
||||||
|
__typename
|
||||||
|
...CommuneChampFragment
|
||||||
|
... on AddressChamp {
|
||||||
|
address {
|
||||||
|
...AddressFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragment CommuneChampFragment on CommuneChamp {
|
||||||
|
commune {
|
||||||
|
...CommuneFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fragment CommuneFragment on Commune {
|
||||||
|
code
|
||||||
|
}
|
||||||
|
fragment AddressFragment on Address {
|
||||||
|
cityName
|
||||||
|
}
|
||||||
|
GRAPHQL
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue