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
|
||||
def has_fragment?(name)
|
||||
if self["has_fragment_#{name}"]
|
||||
true
|
||||
else
|
||||
visitor = HasFragment.new(self.query.selected_operation, name)
|
||||
# This method is used to check if a given fragment is used in the given query.
|
||||
# We need that in order to maintain backward compatibility for Types de Champ
|
||||
# that we extended in later iterations of our schema.
|
||||
def has_fragment?(fragment_name)
|
||||
self[:has_fragment] ||= Hash.new do |hash, fragment_name|
|
||||
visitor = HasFragment.new(query.document, fragment_name)
|
||||
visitor.visit
|
||||
self["has_fragment_#{name}"] = visitor.found
|
||||
self["has_fragment_#{name}"]
|
||||
hash[fragment_name] = visitor.found
|
||||
end
|
||||
self[:has_fragment][fragment_name]
|
||||
end
|
||||
|
||||
def internal_use?
|
||||
|
@ -36,17 +37,28 @@ class API::V2::Context < GraphQL::Query::Context
|
|||
self[:authorized][demarche.id]
|
||||
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
|
||||
def initialize(document, name)
|
||||
def initialize(document, fragment_name)
|
||||
super(document)
|
||||
@name = name.to_s
|
||||
@fragment_name = fragment_name.to_s
|
||||
@found = false
|
||||
end
|
||||
|
||||
attr_reader :found
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
|
|
|
@ -26,6 +26,16 @@ RSpec.describe Types::DossierType, type: :graphql do
|
|||
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
|
||||
query($number: Int!) {
|
||||
dossier(number: $number) {
|
||||
|
@ -48,4 +58,35 @@ RSpec.describe Types::DossierType, type: :graphql do
|
|||
}
|
||||
}
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue