From 8f1ae99413d51db02351e2505db66d477062d2c5 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 19 Jan 2023 19:37:58 +0100 Subject: [PATCH] fix(graphql): remove deprecated options from introspection query --- app/graphql/api/v2/context.rb | 17 +- app/graphql/api/v2/stored_query.rb | 2 + app/graphql/schema.graphql | 150 ------------------ app/graphql/types/base_field.rb | 22 ++- app/graphql/types/base_interface.rb | 1 + app/graphql/types/base_object.rb | 1 + app/graphql/types/demarche_descriptor_type.rb | 2 - app/graphql/types/query_type.rb | 2 - .../graphql_controller_stored_queries_spec.rb | 13 ++ 9 files changed, 51 insertions(+), 159 deletions(-) diff --git a/app/graphql/api/v2/context.rb b/app/graphql/api/v2/context.rb index c5c82678d..0b23f1212 100644 --- a/app/graphql/api/v2/context.rb +++ b/app/graphql/api/v2/context.rb @@ -1,8 +1,11 @@ class API::V2::Context < GraphQL::Query::Context - # 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. + # 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. If it is an introspection query, we assume all fragments are present. def has_fragment?(fragment_name) + return true if query.nil? + return true if introspection? + self[:has_fragment] ||= Hash.new do |hash, fragment_name| visitor = HasFragment.new(query.document, fragment_name) visitor.visit @@ -11,6 +14,14 @@ class API::V2::Context < GraphQL::Query::Context self[:has_fragment][fragment_name] end + def has_fragments?(fragment_names) + fragment_names.any? { has_fragment?(_1) } + end + + def introspection? + query.selected_operation.name == "IntrospectionQuery" + end + def internal_use? self[:internal_use] end diff --git a/app/graphql/api/v2/stored_query.rb b/app/graphql/api/v2/stored_query.rb index fa0527fc4..a2e39eddf 100644 --- a/app/graphql/api/v2/stored_query.rb +++ b/app/graphql/api/v2/stored_query.rb @@ -5,6 +5,8 @@ class API::V2::StoredQuery QUERY_V2 when 'ds-mutation-v2' MUTATION_V2 + when 'introspection' + GraphQL::Introspection::INTROSPECTION_QUERY else if fallback.nil? raise GraphQL::ExecutionError.new("No query with id \"#{query_id}\"") diff --git a/app/graphql/schema.graphql b/app/graphql/schema.graphql index 1bf7e53f1..bfd90f02f 100644 --- a/app/graphql/schema.graphql +++ b/app/graphql/schema.graphql @@ -97,11 +97,6 @@ type AddressChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -152,11 +147,6 @@ type AnnuaireEducationChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -228,11 +218,6 @@ type CarteChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -275,11 +260,6 @@ interface ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -323,11 +303,6 @@ type CheckboxChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -383,11 +358,6 @@ type CiviliteChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -416,11 +386,6 @@ type CnafChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -473,11 +438,6 @@ type CommuneChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -580,11 +540,6 @@ type DateChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -631,11 +586,6 @@ type DatetimeChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -679,11 +629,6 @@ type DecimalNumberChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -1126,11 +1071,6 @@ type DgfipChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -1501,11 +1441,6 @@ type DossierLinkChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -1987,11 +1922,6 @@ type EmailChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -2067,11 +1997,6 @@ type ExplicationChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -2444,11 +2369,6 @@ type HeaderSectionChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -2487,11 +2407,6 @@ type IbanChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -2535,11 +2450,6 @@ type IntegerNumberChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -2617,11 +2527,6 @@ type MesriChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -2915,11 +2820,6 @@ type NumberChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -3084,11 +2984,6 @@ type PhoneChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -3138,11 +3033,6 @@ type PieceJustificativeChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -3171,11 +3061,6 @@ type PoleEmploiChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -3259,11 +3144,6 @@ type RNAChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -3361,11 +3241,6 @@ type RepetitionChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -3445,11 +3320,6 @@ type SiretChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -3493,11 +3363,6 @@ type TextChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -3526,11 +3391,6 @@ type TextareaChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -3575,11 +3435,6 @@ type TitreIdentiteChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ @@ -3867,11 +3722,6 @@ type YesNoChampDescriptor implements ChampDescriptor { """ label: String! - """ - List des options d’un champ avec selection. - """ - options: [String!] @deprecated(reason: "Utilisez le champ `DropDownListChampDescriptor.options` à la place.") - """ Est-ce que le champ est obligatoire ? """ diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb index a1a6c1365..0e81b53cf 100644 --- a/app/graphql/types/base_field.rb +++ b/app/graphql/types/base_field.rb @@ -5,8 +5,26 @@ module Types super(*args, **kwargs, &block) end - def visible?(ctx) - super && (@internal ? ctx[:internal_use] : true) + def visible?(context) + super && visible_unless_internal?(context) && visible_unless_deprecated?(context) + end + + private + + def visible_unless_internal?(context) + if @internal + context[:internal_use] + else + true + end + end + + def visible_unless_deprecated?(context) + if name == "options" && owner.name == 'Types::ChampDescriptorType' + !context.has_fragments?([:PaysChampDescriptor, :RegionChampDescriptor, :DepartementChampDescriptor]) + else + true + end end end end diff --git a/app/graphql/types/base_interface.rb b/app/graphql/types/base_interface.rb index 69e72dc58..5cc91c240 100644 --- a/app/graphql/types/base_interface.rb +++ b/app/graphql/types/base_interface.rb @@ -1,5 +1,6 @@ module Types module BaseInterface include GraphQL::Schema::Interface + field_class BaseField end end diff --git a/app/graphql/types/base_object.rb b/app/graphql/types/base_object.rb index 40a81ccd2..2d20f1c05 100644 --- a/app/graphql/types/base_object.rb +++ b/app/graphql/types/base_object.rb @@ -1,4 +1,5 @@ module Types class BaseObject < GraphQL::Schema::Object + field_class BaseField end end diff --git a/app/graphql/types/demarche_descriptor_type.rb b/app/graphql/types/demarche_descriptor_type.rb index 847ce7e6a..d0db6991a 100644 --- a/app/graphql/types/demarche_descriptor_type.rb +++ b/app/graphql/types/demarche_descriptor_type.rb @@ -1,7 +1,5 @@ module Types class DemarcheDescriptorType < Types::BaseObject - field_class BaseField - class FindDemarcheInput < Types::BaseInputObject one_of argument :number, Int, "Numero de la démarche.", required: false diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 8aa90e1b0..a070ec088 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -1,7 +1,5 @@ module Types class QueryType < Types::BaseObject - field_class BaseField - field :demarche, DemarcheType, null: false, description: "Informations concernant une démarche." do argument :number, Int, "Numéro de la démarche.", required: true end diff --git a/spec/controllers/api/v2/graphql_controller_stored_queries_spec.rb b/spec/controllers/api/v2/graphql_controller_stored_queries_spec.rb index b3a3e0e1c..3e065f0de 100644 --- a/spec/controllers/api/v2/graphql_controller_stored_queries_spec.rb +++ b/spec/controllers/api/v2/graphql_controller_stored_queries_spec.rb @@ -28,6 +28,19 @@ describe API::V2::GraphqlController do request.env['HTTP_AUTHORIZATION'] = authorization_header end + describe 'introspection' do + let(:query_id) { 'introspection' } + let(:operation_name) { 'IntrospectionQuery' } + let(:champ_descriptor) { gql_data[:__schema][:types].find { _1[:name] == 'ChampDescriptor' } } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:__schema]).not_to be_nil + expect(champ_descriptor).not_to be_nil + expect(champ_descriptor[:fields].find { _1[:name] == 'options' }).to be_nil + } + end + describe 'ds-query-v2' do let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) } let(:query_id) { 'ds-query-v2' }