Merge pull request #8117 from tchak/graphql-complete-demarche

feat(graphql): expose more information on demarche descriptor
This commit is contained in:
Paul Chavard 2023-01-18 15:50:22 +01:00 committed by GitHub
commit 357290acf7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 1759 additions and 92 deletions

View file

@ -22,11 +22,15 @@ class API::V2::Context < GraphQL::Query::Context
Administrateur.find(self[:administrateur_id])
end
def authorized_demarche?(demarche)
def authorized_demarche?(demarche, opendata: false)
if internal_use?
return true
end
if opendata && demarche.opendata?
return true
end
# We are caching authorization logic because it is called for each node
# of the requested graph and can be expensive. Context is reset per request so it is safe.
self[:authorized] ||= Hash.new do |hash, demarche_id|

View file

@ -75,7 +75,42 @@ class API::V2::Schema < GraphQL::Schema
Types::GeoAreas::ParcelleCadastraleType,
Types::GeoAreas::SelectionUtilisateurType,
Types::PersonneMoraleType,
Types::PersonnePhysiqueType
Types::PersonnePhysiqueType,
Types::Champs::Descriptor::AddressChampDescriptorType,
Types::Champs::Descriptor::AnnuaireEducationChampDescriptorType,
Types::Champs::Descriptor::CarteChampDescriptorType,
Types::Champs::Descriptor::CheckboxChampDescriptorType,
Types::Champs::Descriptor::CiviliteChampDescriptorType,
Types::Champs::Descriptor::CnafChampDescriptorType,
Types::Champs::Descriptor::CommuneChampDescriptorType,
Types::Champs::Descriptor::DateChampDescriptorType,
Types::Champs::Descriptor::DatetimeChampDescriptorType,
Types::Champs::Descriptor::DecimalNumberChampDescriptorType,
Types::Champs::Descriptor::DepartementChampDescriptorType,
Types::Champs::Descriptor::DgfipChampDescriptorType,
Types::Champs::Descriptor::DossierLinkChampDescriptorType,
Types::Champs::Descriptor::DropDownListChampDescriptorType,
Types::Champs::Descriptor::EmailChampDescriptorType,
Types::Champs::Descriptor::ExplicationChampDescriptorType,
Types::Champs::Descriptor::HeaderSectionChampDescriptorType,
Types::Champs::Descriptor::IbanChampDescriptorType,
Types::Champs::Descriptor::IntegerNumberChampDescriptorType,
Types::Champs::Descriptor::LinkedDropDownListChampDescriptorType,
Types::Champs::Descriptor::MesriChampDescriptorType,
Types::Champs::Descriptor::MultipleDropDownListChampDescriptorType,
Types::Champs::Descriptor::NumberChampDescriptorType,
Types::Champs::Descriptor::PaysChampDescriptorType,
Types::Champs::Descriptor::PhoneChampDescriptorType,
Types::Champs::Descriptor::PieceJustificativeChampDescriptorType,
Types::Champs::Descriptor::PoleEmploiChampDescriptorType,
Types::Champs::Descriptor::RegionChampDescriptorType,
Types::Champs::Descriptor::RepetitionChampDescriptorType,
Types::Champs::Descriptor::RNAChampDescriptorType,
Types::Champs::Descriptor::SiretChampDescriptorType,
Types::Champs::Descriptor::TextChampDescriptorType,
Types::Champs::Descriptor::TextareaChampDescriptorType,
Types::Champs::Descriptor::TitreIdentiteChampDescriptorType,
Types::Champs::Descriptor::YesNoChampDescriptorType
def self.unauthorized_object(error)
# Add a top-level error to the response instead of returning nil:

View file

@ -50,7 +50,7 @@ class API::V2::StoredQuery
declarative
dateCreation
dateFermeture
publishedRevision @include(if: $includeRevision) {
activeRevision @include(if: $includeRevision) {
...RevisionFragment
}
groupeInstructeurs @include(if: $includeGroupeInstructeurs) {
@ -305,25 +305,65 @@ class API::V2::StoredQuery
datePublication
champDescriptors {
...ChampDescriptorFragment
champDescriptors {
...ChampDescriptorFragment
... on RepetitionChampDescriptor {
champDescriptors {
...ChampDescriptorFragment
}
}
}
annotationDescriptors {
...ChampDescriptorFragment
champDescriptors {
...ChampDescriptorFragment
... on RepetitionChampDescriptor {
champDescriptors {
...ChampDescriptorFragment
}
}
}
}
fragment ChampDescriptorFragment on ChampDescriptor {
__typename
id
type
label
description
required
options
... on DropDownListChampDescriptor {
options
otherOption
}
... on MultipleDropDownListChampDescriptor {
options
}
... on LinkedDropDownListChampDescriptor {
options
}
... on PieceJustificativeChampDescriptor {
fileTemplate {
...FileFragment
}
}
... on ExplicationChampDescriptor {
collapsibleExplanationEnabled
collapsibleExplanationText
}
... on PaysChampDescriptor {
options {
name
code
}
}
... on RegionChampDescriptor {
options {
name
code
}
}
... on DepartementChampDescriptor {
options {
name
code
}
}
}
fragment AvisFragment on Avis {

View file

@ -3,7 +3,7 @@
module Extensions
class Attachment < GraphQL::Schema::FieldExtension
attr_reader :attachment_assoc
attr_reader :attachment_assoc, :root
def apply
# Here we try to define the ActiveRecord association name:
@ -18,13 +18,14 @@ module Extensions
attachment = field.original_name.to_s.sub(/_url$/, "")
"#{attachment}_attachment"
end
@root = options&.dig(:root) || :object
end
# This method resolves (as it states) the field itself
# (it's the same as defining a method within a type)
def resolve(object:, **_rest)
Loaders::Association.for(
object.object.class,
object.public_send(root).class,
attachment_assoc => :blob
).load(object.object)
end

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,7 @@
module Types
class ChampDescriptorType < Types::BaseObject
module ChampDescriptorType
include Types::BaseInterface
class TypeDeChampType < Types::BaseEnum
TypeDeChamp.type_champs.each do |symbol_name, string_name|
value(string_name,
@ -9,24 +11,107 @@ module Types
end
global_id_field :id
field :type, TypeDeChampType, "Type de la valeur du champ.", null: false, method: :type_champ
field :label, String, "Libellé du champ.", null: false, method: :libelle
field :description, String, "Description du champ.", null: true
field :required, Boolean, "Est-ce que le champ est obligatoire ?", null: false, method: :mandatory?
field :champ_descriptors, [Types::ChampDescriptorType], "Description des champs dun bloc répétable.", null: true
field :options, [String], "List des options dun champ avec selection.", null: true
field :options, [String], "List des options dun champ avec selection.", null: true, deprecation_reason: 'Utilisez le champ `DropDownListChampDescriptor.options` à la place.'
field :champ_descriptors, [Types::ChampDescriptorType], "Description des champs dun bloc répétable.", null: true, deprecation_reason: 'Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.'
field :type, TypeDeChampType, "Type de la valeur du champ.", null: false, method: :type_champ, deprecation_reason: 'Utilisez le champ `__typename` à la place.'
definition_methods do
def resolve_type(object, context)
case object.type_champ
when TypeDeChamp.type_champs.fetch(:text)
Types::Champs::Descriptor::TextChampDescriptorType
when TypeDeChamp.type_champs.fetch(:textarea)
Types::Champs::Descriptor::TextareaChampDescriptorType
when TypeDeChamp.type_champs.fetch(:date)
Types::Champs::Descriptor::DateChampDescriptorType
when TypeDeChamp.type_champs.fetch(:datetime)
Types::Champs::Descriptor::DatetimeChampDescriptorType
when TypeDeChamp.type_champs.fetch(:number)
Types::Champs::Descriptor::NumberChampDescriptorType
when TypeDeChamp.type_champs.fetch(:decimal_number)
Types::Champs::Descriptor::DecimalNumberChampDescriptorType
when TypeDeChamp.type_champs.fetch(:integer_number)
Types::Champs::Descriptor::IntegerNumberChampDescriptorType
when TypeDeChamp.type_champs.fetch(:checkbox)
Types::Champs::Descriptor::CheckboxChampDescriptorType
when TypeDeChamp.type_champs.fetch(:civilite)
Types::Champs::Descriptor::CiviliteChampDescriptorType
when TypeDeChamp.type_champs.fetch(:email)
Types::Champs::Descriptor::EmailChampDescriptorType
when TypeDeChamp.type_champs.fetch(:phone)
Types::Champs::Descriptor::PhoneChampDescriptorType
when TypeDeChamp.type_champs.fetch(:address)
Types::Champs::Descriptor::AddressChampDescriptorType
when TypeDeChamp.type_champs.fetch(:yes_no)
Types::Champs::Descriptor::YesNoChampDescriptorType
when TypeDeChamp.type_champs.fetch(:drop_down_list)
Types::Champs::Descriptor::DropDownListChampDescriptorType
when TypeDeChamp.type_champs.fetch(:multiple_drop_down_list)
Types::Champs::Descriptor::MultipleDropDownListChampDescriptorType
when TypeDeChamp.type_champs.fetch(:linked_drop_down_list)
Types::Champs::Descriptor::LinkedDropDownListChampDescriptorType
when TypeDeChamp.type_champs.fetch(:communes)
Types::Champs::Descriptor::CommuneChampDescriptorType
when TypeDeChamp.type_champs.fetch(:departements)
Types::Champs::Descriptor::DepartementChampDescriptorType
when TypeDeChamp.type_champs.fetch(:regions)
Types::Champs::Descriptor::RegionChampDescriptorType
when TypeDeChamp.type_champs.fetch(:pays)
Types::Champs::Descriptor::PaysChampDescriptorType
when TypeDeChamp.type_champs.fetch(:header_section)
Types::Champs::Descriptor::HeaderSectionChampDescriptorType
when TypeDeChamp.type_champs.fetch(:explication)
Types::Champs::Descriptor::ExplicationChampDescriptorType
when TypeDeChamp.type_champs.fetch(:dossier_link)
Types::Champs::Descriptor::DossierLinkChampDescriptorType
when TypeDeChamp.type_champs.fetch(:piece_justificative)
Types::Champs::Descriptor::PieceJustificativeChampDescriptorType
when TypeDeChamp.type_champs.fetch(:rna)
Types::Champs::Descriptor::RNAChampDescriptorType
when TypeDeChamp.type_champs.fetch(:carte)
Types::Champs::Descriptor::CarteChampDescriptorType
when TypeDeChamp.type_champs.fetch(:repetition)
Types::Champs::Descriptor::RepetitionChampDescriptorType
when TypeDeChamp.type_champs.fetch(:titre_identite)
Types::Champs::Descriptor::TitreIdentiteChampDescriptorType
when TypeDeChamp.type_champs.fetch(:iban)
Types::Champs::Descriptor::IbanChampDescriptorType
when TypeDeChamp.type_champs.fetch(:siret)
Types::Champs::Descriptor::SiretChampDescriptorType
when TypeDeChamp.type_champs.fetch(:annuaire_education)
Types::Champs::Descriptor::AnnuaireEducationChampDescriptorType
when TypeDeChamp.type_champs.fetch(:cnaf)
Types::Champs::Descriptor::CnafChampDescriptorType
when TypeDeChamp.type_champs.fetch(:dgfip)
Types::Champs::Descriptor::DgfipChampDescriptorType
when TypeDeChamp.type_champs.fetch(:pole_emploi)
Types::Champs::Descriptor::PoleEmploiChampDescriptorType
when TypeDeChamp.type_champs.fetch(:mesri)
Types::Champs::Descriptor::MesriChampDescriptorType
end
end
end
def champ_descriptors
if object.type_de_champ.block?
if type_de_champ.block?
Loaders::Association.for(object.class, revision_types_de_champ: :type_de_champ).load(object)
end
end
def options
if object.type_de_champ.drop_down_list?
object.type_de_champ.drop_down_list_options.reject(&:empty?)
if type_de_champ.drop_down_list?
type_de_champ.drop_down_list_options.reject(&:empty?)
end
end
private
def type_de_champ
object.type_de_champ
end
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class AddressChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class AnnuaireEducationChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class CarteChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class CheckboxChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class CiviliteChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class CnafChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class CommuneChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class DateChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class DatetimeChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class DecimalNumberChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,11 @@
module Types::Champs::Descriptor
class DepartementChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
field :options, [Types::Champs::DepartementChampType::DepartementType], "List des departements.", null: true
def options
APIGeoService.departements
end
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class DgfipChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class DossierLinkChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,16 @@
module Types::Champs::Descriptor
class DropDownListChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
field :options, [String], "List des options dun champ avec selection.", null: true
field :other_option, Boolean, "La selection contien loption \"Autre\".", null: true
def other_option
object.type_de_champ.drop_down_other?
end
def options
object.type_de_champ.drop_down_list_options.reject(&:empty?)
end
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class EmailChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,16 @@
module Types::Champs::Descriptor
class ExplicationChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
field :collapsible_explanation_enabled, Boolean, null: true
field :collapsible_explanation_text, String, null: true
def collapsible_explanation_enabled
object.type_de_champ.collapsible_explanation_enabled?
end
def collapsible_explanation_text
object.type_de_champ.collapsible_explanation_text
end
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class HeaderSectionChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class IbanChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class IntegerNumberChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,11 @@
module Types::Champs::Descriptor
class LinkedDropDownListChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
field :options, [String], "List des options dun champ avec selection.", null: true
def options
object.type_de_champ.drop_down_list_options.reject(&:empty?)
end
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class MesriChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,11 @@
module Types::Champs::Descriptor
class MultipleDropDownListChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
field :options, [String], "List des options dun champ avec selection.", null: true
def options
object.type_de_champ.drop_down_list_options.reject(&:empty?)
end
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class NumberChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,11 @@
module Types::Champs::Descriptor
class PaysChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
field :options, [Types::Champs::PaysChampType::PaysType], "List des pays.", null: true
def options
APIGeoService.countries
end
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class PhoneChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,9 @@
module Types::Champs::Descriptor
class PieceJustificativeChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
field :file_template, Types::File, "Modèle de la pièce justificative.", null: true, extensions: [
{ Extensions::Attachment => { attachment: :piece_justificative_template, root: :type_de_champ } }
]
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class PoleEmploiChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,11 @@
module Types::Champs::Descriptor
class RegionChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
field :options, [Types::Champs::RegionChampType::RegionType], "List des regions.", null: true
def options
APIGeoService.regions
end
end
end

View file

@ -0,0 +1,11 @@
module Types::Champs::Descriptor
class RepetitionChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
field :champ_descriptors, [Types::ChampDescriptorType], "Description des champs dun bloc répétable.", null: true
def champ_descriptors
Loaders::Association.for(object.class, revision_types_de_champ: :type_de_champ).load(object)
end
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class RNAChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class SiretChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class TextChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class TextareaChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class TitreIdentiteChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class YesNoChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end

View file

@ -25,11 +25,24 @@ Cela évite laccès récursif aux dossiers."
field :date_depublication, GraphQL::Types::ISO8601DateTime, "Date de la dépublication.", null: true
field :date_fermeture, GraphQL::Types::ISO8601DateTime, "Date de la fermeture.", null: true
field :duree_conservation_dossiers, Int, "Durée de conservation des dossiers en mois.", null: false
field :demarche_url, String, null: true
field :site_web_url, String, null: true
field :dpo_url, String, null: true
field :notice_url, String, null: true
field :cadre_juridique_url, String, null: true
field :opendata, Boolean, null: false
field :tags, [String], null: false
field :zones, [String], null: false
field :revision, Types::RevisionType, null: false
field :service, Types::ServiceType, null: true
field :cadre_juridique, String, null: true
field :deliberation, String, null: true
field :logo, Types::File, null: true, extensions: [{ Extensions::Attachment => { root: :procedure } }]
field :notice, Types::File, null: true, extensions: [{ Extensions::Attachment => { root: :procedure } }]
field :deliberation, Types::File, null: true, extensions: [{ Extensions::Attachment => { root: :procedure } }]
field :dossiers_count, Int, null: false, internal: true
@ -38,25 +51,51 @@ Cela évite laccès récursif aux dossiers."
end
def revision
object.is_a?(ProcedureRevision) ? object : object.active_revision
if object.is_a?(ProcedureRevision)
object
else
object.active_revision
end
end
def procedure
if object.is_a?(ProcedureRevision)
object.procedure
else
object
end
end
def dossiers_count
object.dossiers.count
end
def deliberation
Rails.application.routes.url_helpers.url_for(procedure.deliberation) if procedure.deliberation.attached?
procedure.dossiers.visible_by_administration.count
end
def state
procedure.aasm.current_state
end
def cadre_juridique
delegate :description, :opendata, :tags, to: :procedure
def demarche_url
procedure.lien_demarche
end
def dpo_url
procedure.lien_dpo
end
def notice_url
procedure.lien_notice
end
def cadre_juridique_url
procedure.cadre_juridique
end
def site_web_url
procedure.lien_site_web
end
def number
procedure.id
end
@ -65,10 +104,6 @@ Cela évite laccès récursif aux dossiers."
procedure.libelle
end
def description
procedure.description
end
def declarative
procedure.declarative_with_state
end
@ -93,15 +128,17 @@ Cela évite laccès récursif aux dossiers."
procedure.closed_at
end
def self.authorized?(object, context)
procedure = object.is_a?(ProcedureRevision) ? object.procedure : object
procedure.opendata? || context.authorized_demarche?(procedure)
def duree_conservation_dossiers
procedure.duree_conservation_dossiers_dans_ds
end
private
def zones
procedure.zones.map(&:current_label)
end
def procedure
revision.procedure
def self.authorized?(object, context)
procedure = object.is_a?(ProcedureRevision) ? object.procedure : object
context.authorized_demarche?(procedure, opendata: true)
end
end
end

View file

@ -12,7 +12,11 @@ module Types
end
def annotation_descriptors
Loaders::Association.for(object.class, revision_types_de_champ_private: :type_de_champ).load(object)
if context.authorized_demarche?(object.procedure, opendata: true)
Loaders::Association.for(object.class, revision_types_de_champ_private: :type_de_champ).load(object)
else
[]
end
end
end
end

View file

@ -303,16 +303,18 @@ class SerializerService
}
fragment ChampDescriptorFragment on ChampDescriptor {
type
__typename
label
description
required
options
champDescriptors {
type
label
description
required
... on DropDownListChampDescriptor {
options
otherOption
}
... on MultipleDropDownListChampDescriptor {
options
}
... on LinkedDropDownListChampDescriptor {
options
}
}
@ -321,13 +323,28 @@ class SerializerService
number
title
description
tags
zones
datePublication
service { nom organisme typeOrganisme }
cadreJuridique
deliberation
demarcheUrl
dpoUrl
noticeUrl
siteWebUrl
cadreJuridiqueUrl
logo { ...FileFragment }
notice { ...FileFragment }
deliberation { ...FileFragment }
dossiersCount
revision {
champDescriptors { ...ChampDescriptorFragment }
champDescriptors {
...ChampDescriptorFragment
... on RepetitionChampDescriptor {
champDescriptors {
...ChampDescriptorFragment
}
}
}
}
}
GRAPHQL

View file

@ -67,7 +67,7 @@ describe API::V2::GraphqlController do
publishedRevision {
id
champDescriptors {
type
__typename
}
}
service {
@ -76,16 +76,26 @@ describe API::V2::GraphqlController do
organisme
}
champDescriptors {
__typename
id
type
label
description
required
champDescriptors {
id
type
... on RepetitionChampDescriptor {
champDescriptors {
__typename
id
}
}
... on DropDownListChampDescriptor {
options
}
... on MultipleDropDownListChampDescriptor {
options
}
... on LinkedDropDownListChampDescriptor {
options
}
options
}
dossiers {
nodes {
@ -157,9 +167,13 @@ describe API::V2::GraphqlController do
describe "query a demarche" do
let(:procedure) { create(:procedure, :published, :for_individual, :with_service, :with_all_champs, :with_all_annotations, administrateurs: [admin]) }
def format_type_champ(type_champ)
"#{type_champ.gsub('regions', 'region').gsub('departements', 'departement').gsub('communes', 'commune').camelcase}ChampDescriptor"
end
it "returns the demarche" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(demarche: {
expect(gql_data).to include(demarche: {
id: procedure.to_typed_id,
number: procedure.id,
title: procedure.libelle,
@ -174,15 +188,11 @@ describe API::V2::GraphqlController do
label: "défaut"
}
],
revisions: procedure.revisions.map { |revision| { id: revision.to_typed_id } },
revisions: procedure.revisions.map { { id: _1.to_typed_id } },
draftRevision: { id: procedure.draft_revision.to_typed_id },
publishedRevision: {
id: procedure.published_revision.to_typed_id,
champDescriptors: procedure.published_revision.types_de_champ_public.map do |tdc|
{
type: tdc.type_champ
}
end
champDescriptors: procedure.published_revision.types_de_champ_public.map { { __typename: format_type_champ(_1.type_champ) } }
},
service: {
nom: procedure.service.nom,
@ -193,15 +203,15 @@ describe API::V2::GraphqlController do
{
id: tdc.to_typed_id,
label: tdc.libelle,
type: tdc.type_champ,
__typename: format_type_champ(tdc.type_champ),
description: tdc.description,
required: tdc.mandatory?,
champDescriptors: tdc.repetition? ? procedure.active_revision.children_of(tdc.reload).map { |tdc| { id: tdc.to_typed_id, type: tdc.type_champ } } : nil,
champDescriptors: tdc.repetition? ? procedure.active_revision.children_of(tdc.reload).map { { id: _1.to_typed_id, __typename: format_type_champ(_1.type_champ) } } : nil,
options: tdc.drop_down_list? ? tdc.drop_down_list_options.reject(&:empty?) : nil
}
}.compact
end,
dossiers: {
nodes: dossiers.map { |dossier| { id: dossier.to_typed_id } }
nodes: dossiers.map { { id: _1.to_typed_id } }
}
})
end

View file

@ -79,6 +79,16 @@ describe API::V2::GraphqlController do
expect(gql_data[:demarche][:dossiers][:nodes].size).to eq(1)
}
end
context 'include Revision' do
let(:variables) { { demarcheNumber: procedure.id, includeRevision: true } }
it {
expect(gql_errors).to be_nil
expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id)
expect(gql_data[:demarche][:activeRevision]).not_to be_nil
}
end
end
context 'getGroupeInstructeur' do

View file

@ -5,9 +5,9 @@ FactoryBot.define do
labels { [{ designated_on: '1981-05-08', name: "Ministère de l'Education Populaire" }] }
end
after(:create) do |zone, evaluator|
after(:build) do |zone, evaluator|
evaluator.labels.each do |label|
zone.labels.create(designated_on: label[:designated_on], name: label[:name])
zone.labels.build(designated_on: label[:designated_on], name: label[:name])
end
end
end

View file

@ -1,6 +1,6 @@
describe DemarchesPubliquesExportService do
let(:procedure) { create(:procedure, :published, :with_service, :with_type_de_champ) }
let!(:dossier) { create(:dossier, procedure: procedure) }
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
let(:gzip_filename) { "demarches.json.gz" }
after { FileUtils.rm(gzip_filename) }
@ -16,19 +16,25 @@ describe DemarchesPubliquesExportService do
organisme: "organisme",
typeOrganisme: "association"
},
cadreJuridique: "un cadre juridique important",
cadreJuridiqueUrl: "un cadre juridique important",
demarcheUrl: nil,
dpoUrl: nil,
noticeUrl: nil,
siteWebUrl: "https://mon-site.gouv",
logo: nil,
notice: nil,
deliberation: nil,
datePublication: procedure.published_at.iso8601,
zones: ["Ministère de l'Education Populaire"],
tags: [],
dossiersCount: 1,
revision: {
champDescriptors: [
{
description: procedure.active_revision.types_de_champ_public.first.description,
label: procedure.active_revision.types_de_champ_public.first.libelle,
options: nil,
required: false,
type: "text",
champDescriptors: nil
__typename: "TextChampDescriptor"
}
]
}