diff --git a/app/graphql/api/v2/stored_query.rb b/app/graphql/api/v2/stored_query.rb index 9a8631bbe..72c49381e 100644 --- a/app/graphql/api/v2/stored_query.rb +++ b/app/graphql/api/v2/stored_query.rb @@ -338,7 +338,7 @@ class API::V2::StoredQuery expert { email } - attachment { + attachments { ...FileFragment } } @@ -348,7 +348,7 @@ class API::V2::StoredQuery email body createdAt - attachment { + attachments { ...FileFragment } } @@ -423,7 +423,7 @@ class API::V2::StoredQuery values } ... on PieceJustificativeChamp { - file { + files { ...FileFragment } } diff --git a/app/graphql/extensions/attachment.rb b/app/graphql/extensions/attachment.rb index bb2da9c90..987c61f31 100644 --- a/app/graphql/extensions/attachment.rb +++ b/app/graphql/extensions/attachment.rb @@ -35,13 +35,18 @@ module Extensions if value.respond_to?(:map) attachments = value.map { after_resolve_attachment(_1) } - if options[:flat_first] + if options[:as] == :single attachments.first else attachments end else - after_resolve_attachment(value) + attachment = after_resolve_attachment(value) + if options[:as] == :multiple + [attachment] + else + attachment + end end end diff --git a/app/graphql/schema.graphql b/app/graphql/schema.graphql index 768c4561a..b2c3b7b52 100644 --- a/app/graphql/schema.graphql +++ b/app/graphql/schema.graphql @@ -112,7 +112,8 @@ type Association { } type Avis { - attachment: File + attachment: File @deprecated(reason: "Utilisez le champ `attachments` à la place.") + attachments: [File!]! claimant: Profile dateQuestion: ISO8601DateTime! dateReponse: ISO8601DateTime @@ -1754,7 +1755,8 @@ type LinkedDropDownListChamp implements Champ { } type Message { - attachment: File + attachment: File @deprecated(reason: "Utilisez le champ `attachments` à la place.") + attachments: [File!]! body: String! createdAt: ISO8601DateTime! email: String! @@ -2029,7 +2031,7 @@ type PersonnePhysique implements Demandeur { type PieceJustificativeChamp implements Champ { file: File @deprecated(reason: "Utilisez le champ `files` à la place.") - files: [File!] + files: [File!]! id: ID! """ @@ -2430,4 +2432,4 @@ type ValidationError { A description of the error """ message: String! -} \ No newline at end of file +} diff --git a/app/graphql/types/avis_type.rb b/app/graphql/types/avis_type.rb index a3a27d1be..b2620374d 100644 --- a/app/graphql/types/avis_type.rb +++ b/app/graphql/types/avis_type.rb @@ -7,9 +7,12 @@ module Types field :date_question, GraphQL::Types::ISO8601DateTime, null: false, method: :created_at field :date_reponse, GraphQL::Types::ISO8601DateTime, null: true, method: :updated_at - field :attachment, Types::File, null: true, extensions: [ + field :attachment, Types::File, null: true, deprecation_reason: "Utilisez le champ `attachments` à la place.", extensions: [ { Extensions::Attachment => { attachment: :piece_justificative_file } } ] + field :attachments, [Types::File], null: false, extensions: [ + { Extensions::Attachment => { attachment: :piece_justificative_file, as: :multiple } } + ] field :instructeur, Types::ProfileType, null: false, method: :claimant, deprecation_reason: "Utilisez le champ `claimant` à la place." field :claimant, Types::ProfileType, null: true diff --git a/app/graphql/types/champs/piece_justificative_champ_type.rb b/app/graphql/types/champs/piece_justificative_champ_type.rb index e06e588fb..b3fef620a 100644 --- a/app/graphql/types/champs/piece_justificative_champ_type.rb +++ b/app/graphql/types/champs/piece_justificative_champ_type.rb @@ -3,10 +3,10 @@ module Types::Champs implements Types::ChampType field :file, Types::File, null: true, deprecation_reason: "Utilisez le champ `files` à la place.", extensions: [ - { Extensions::Attachment => { attachments: :piece_justificative_file, flat_first: true } } + { Extensions::Attachment => { attachments: :piece_justificative_file, as: :single } } ] - field :files, [Types::File], null: true, extensions: [ + field :files, [Types::File], null: false, extensions: [ { Extensions::Attachment => { attachments: :piece_justificative_file } } ] end diff --git a/app/graphql/types/message_type.rb b/app/graphql/types/message_type.rb index 59f2332b9..1bf29a3cd 100644 --- a/app/graphql/types/message_type.rb +++ b/app/graphql/types/message_type.rb @@ -4,9 +4,12 @@ module Types field :email, String, null: false field :body, String, null: false field :created_at, GraphQL::Types::ISO8601DateTime, null: false - field :attachment, Types::File, null: true, extensions: [ + field :attachment, Types::File, null: true, deprecation_reason: "Utilisez le champ `attachments` à la place.", extensions: [ { Extensions::Attachment => { attachment: :piece_jointe } } ] + field :attachments, [Types::File], null: false, extensions: [ + { Extensions::Attachment => { attachment: :piece_jointe, as: :multiple } } + ] def body object.body.nil? ? "" : object.body diff --git a/spec/controllers/api/v2/graphql_controller_spec.rb b/spec/controllers/api/v2/graphql_controller_spec.rb index a746a4b24..f7e21ec82 100644 --- a/spec/controllers/api/v2/graphql_controller_spec.rb +++ b/spec/controllers/api/v2/graphql_controller_spec.rb @@ -871,282 +871,6 @@ describe API::V2::GraphqlController do end end - describe 'stored queries' do - let(:procedure) { create(:procedure, :published, :for_individual, administrateurs: [admin]) } - let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) } - let(:query_id) { 'ds-query-v2' } - - context 'not found operation id' do - let(:query_id) { 'ds-query-v0' } - - it { - expect(gql_errors.first[:message]).to eq('No query with id "ds-query-v0"') - } - end - - context 'not found operation name' do - let(:operation_name) { 'getStuff' } - - it { - expect(gql_errors.first[:message]).to eq('No operation named "getStuff"') - } - end - - context 'getDossier' do - let(:variables) { { dossierNumber: dossier.id } } - let(:operation_name) { 'getDossier' } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:dossier][:id]).to eq(dossier.to_typed_id) - } - end - - context 'getDemarche' do - let(:variables) { { demarcheNumber: procedure.id } } - let(:operation_name) { 'getDemarche' } - - before { dossier } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id) - expect(gql_data[:demarche][:dossiers]).to be_nil - } - - context 'include Dossiers' do - let(:variables) { { demarcheNumber: procedure.id, includeDossiers: true } } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id) - expect(gql_data[:demarche][:dossiers][:nodes].size).to eq(1) - } - end - end - - context 'getGroupeInstructeur' do - let(:groupe_instructeur) { procedure.groupe_instructeurs.first } - let(:variables) { { groupeInstructeurNumber: groupe_instructeur.id } } - let(:operation_name) { 'getGroupeInstructeur' } - - before { dossier } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:groupeInstructeur][:id]).to eq(groupe_instructeur.to_typed_id) - expect(gql_data[:groupeInstructeur][:dossiers]).to be_nil - } - - context 'include Dossiers' do - let(:variables) { { groupeInstructeurNumber: groupe_instructeur.id, includeDossiers: true } } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:groupeInstructeur][:id]).to eq(groupe_instructeur.to_typed_id) - expect(gql_data[:groupeInstructeur][:dossiers][:nodes].size).to eq(1) - } - end - end - - context 'getDemarcheDescriptor' do - let(:operation_name) { 'getDemarcheDescriptor' } - - context 'find by number' do - let(:variables) { { demarche: { number: procedure.id } } } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:demarcheDescriptor][:id]).to eq(procedure.to_typed_id) - } - end - - context 'find by id' do - let(:variables) { { demarche: { id: procedure.to_typed_id } } } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:demarcheDescriptor][:id]).to eq(procedure.to_typed_id) - } - end - - context 'not opendata' do - let(:variables) { { demarche: { id: procedure.to_typed_id } } } - - before { procedure.update(opendata: false) } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:demarcheDescriptor][:id]).to eq(procedure.to_typed_id) - } - end - - context 'without authorization token' do - let(:authorization_header) { nil } - - context 'opendata' do - let(:variables) { { demarche: { id: procedure.to_typed_id } } } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:demarcheDescriptor][:id]).to eq(procedure.to_typed_id) - } - end - - context 'not opendata' do - let(:variables) { { demarche: { id: procedure.to_typed_id } } } - - before { procedure.update(opendata: false) } - - it { - expect(gql_errors).not_to be_nil - expect(gql_errors.first[:message]).to eq('An object of type DemarcheDescriptor was hidden due to permissions') - } - end - end - end - - context 'mutation' do - let(:query_id) { 'ds-mutation-v2' } - - context 'not found operation name' do - let(:operation_name) { 'dossierStuff' } - - it { - expect(gql_errors.first[:message]).to eq('No operation named "dossierStuff"') - } - end - - context 'dossierArchiver' do - let(:dossier) { create(:dossier, :refuse, :with_individual, procedure: procedure) } - let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } } - let(:operation_name) { 'dossierArchiver' } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:dossierArchiver][:errors]).to be_nil - expect(gql_data[:dossierArchiver][:dossier][:id]).to eq(dossier.to_typed_id) - expect(gql_data[:dossierArchiver][:dossier][:archived]).to be_truthy - } - end - - context 'dossierPasserEnInstruction' do - let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) } - let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } } - let(:operation_name) { 'dossierPasserEnInstruction' } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:dossierPasserEnInstruction][:errors]).to be_nil - expect(gql_data[:dossierPasserEnInstruction][:dossier][:id]).to eq(dossier.to_typed_id) - expect(gql_data[:dossierPasserEnInstruction][:dossier][:state]).to eq('en_instruction') - } - end - - context 'dossierRepasserEnConstruction' do - let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) } - let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } } - let(:operation_name) { 'dossierRepasserEnConstruction' } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:dossierRepasserEnConstruction][:errors]).to be_nil - expect(gql_data[:dossierRepasserEnConstruction][:dossier][:id]).to eq(dossier.to_typed_id) - expect(gql_data[:dossierRepasserEnConstruction][:dossier][:state]).to eq('en_construction') - } - end - - context 'dossierRepasserEnInstruction' do - let(:dossier) { create(:dossier, :refuse, :with_individual, procedure: procedure) } - let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } } - let(:operation_name) { 'dossierRepasserEnInstruction' } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:dossierRepasserEnInstruction][:errors]).to be_nil - expect(gql_data[:dossierRepasserEnInstruction][:dossier][:id]).to eq(dossier.to_typed_id) - expect(gql_data[:dossierRepasserEnInstruction][:dossier][:state]).to eq('en_instruction') - } - end - - context 'dossierAccepter' do - let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) } - let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } } - let(:operation_name) { 'dossierAccepter' } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:dossierAccepter][:errors]).to be_nil - expect(gql_data[:dossierAccepter][:dossier][:id]).to eq(dossier.to_typed_id) - expect(gql_data[:dossierAccepter][:dossier][:state]).to eq('accepte') - } - end - - context 'dossierRefuser' do - let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) } - let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id, motivation: 'yolo' } } } - let(:operation_name) { 'dossierRefuser' } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:dossierRefuser][:errors]).to be_nil - expect(gql_data[:dossierRefuser][:dossier][:id]).to eq(dossier.to_typed_id) - expect(gql_data[:dossierRefuser][:dossier][:state]).to eq('refuse') - } - end - - context 'dossierClasserSansSuite' do - let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) } - let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id, motivation: 'yolo' } } } - let(:operation_name) { 'dossierClasserSansSuite' } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:dossierClasserSansSuite][:errors]).to be_nil - expect(gql_data[:dossierClasserSansSuite][:dossier][:id]).to eq(dossier.to_typed_id) - expect(gql_data[:dossierClasserSansSuite][:dossier][:state]).to eq('sans_suite') - } - end - - context 'groupeInstructeurModifier' do - let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) } - let(:variables) { { input: { groupeInstructeurId: dossier.groupe_instructeur.to_typed_id, label: 'nouveau groupe instructeur' } } } - let(:operation_name) { 'groupeInstructeurModifier' } - - it { - expect(gql_errors).to be_nil - expect(gql_data[:groupeInstructeurModifier][:errors]).to be_nil - expect(gql_data[:groupeInstructeurModifier][:groupeInstructeur][:id]).to eq(dossier.groupe_instructeur.to_typed_id) - expect(dossier.groupe_instructeur.reload.label).to eq('nouveau groupe instructeur') - } - - context 'close groupe instructeur' do - let(:variables) { { input: { groupeInstructeurId: dossier.groupe_instructeur.to_typed_id, closed: true } } } - - context 'with multiple groupes' do - before do - create(:groupe_instructeur, procedure: procedure) - end - - it { - expect(gql_errors).to be_nil - expect(gql_data[:groupeInstructeurModifier][:errors]).to be_nil - expect(gql_data[:groupeInstructeurModifier][:groupeInstructeur][:id]).to eq(dossier.groupe_instructeur.to_typed_id) - expect(dossier.groupe_instructeur.reload.closed).to be_truthy - } - end - - context 'validation error' do - it { - expect(gql_errors).to be_nil - expect(gql_data[:groupeInstructeurModifier][:errors].first[:message]).to eq('Il doit y avoir au moins un groupe instructeur actif sur chaque démarche') - } - end - end - end - end - end - describe "mutations" do describe 'dossierEnvoyerMessage' do let(:query) do diff --git a/spec/controllers/api/v2/graphql_controller_stored_queries_spec.rb b/spec/controllers/api/v2/graphql_controller_stored_queries_spec.rb new file mode 100644 index 000000000..674670b0e --- /dev/null +++ b/spec/controllers/api/v2/graphql_controller_stored_queries_spec.rb @@ -0,0 +1,305 @@ +describe API::V2::GraphqlController do + let(:admin) { create(:administrateur) } + let(:token) { admin.renew_api_token } + let(:legacy_token) { APIToken.new(token).token } + let(:procedure) { create(:procedure, :published, :for_individual, :with_service, administrateurs: [admin]) } + let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) } + let(:dossier1) { create(:dossier, :en_construction, :with_individual, procedure: procedure, en_construction_at: 1.day.ago) } + let(:dossier2) { create(:dossier, :en_construction, :with_individual, :archived, procedure: procedure, en_construction_at: 3.days.ago) } + let(:dossiers) { [dossier] } + let(:instructeur) { create(:instructeur, followed_dossiers: dossiers) } + let(:authorization_header) { ActionController::HttpAuthentication::Token.encode_credentials(token) } + + before do + instructeur.assign_to_procedure(procedure) + end + + let(:query_id) { nil } + let(:variables) { {} } + let(:operation_name) { nil } + let(:body) { JSON.parse(subject.body, symbolize_names: true) } + let(:gql_data) { body[:data] } + let(:gql_errors) { body[:errors] } + + subject { post :execute, params: { queryId: query_id, variables: variables, operationName: operation_name }.compact, as: :json } + + before do + request.env['HTTP_AUTHORIZATION'] = authorization_header + end + + describe 'ds-query-v2' do + let(:procedure) { create(:procedure, :published, :for_individual, administrateurs: [admin]) } + let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) } + let(:query_id) { 'ds-query-v2' } + + context 'not found operation id' do + let(:query_id) { 'ds-query-v0' } + + it { + expect(gql_errors.first[:message]).to eq('No query with id "ds-query-v0"') + } + end + + context 'not found operation name' do + let(:operation_name) { 'getStuff' } + + it { + expect(gql_errors.first[:message]).to eq('No operation named "getStuff"') + } + end + + context 'getDossier' do + let(:variables) { { dossierNumber: dossier.id } } + let(:operation_name) { 'getDossier' } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:dossier][:id]).to eq(dossier.to_typed_id) + } + end + + context 'getDemarche' do + let(:variables) { { demarcheNumber: procedure.id } } + let(:operation_name) { 'getDemarche' } + + before { dossier } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id) + expect(gql_data[:demarche][:dossiers]).to be_nil + } + + context 'include Dossiers' do + let(:variables) { { demarcheNumber: procedure.id, includeDossiers: true } } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id) + expect(gql_data[:demarche][:dossiers][:nodes].size).to eq(1) + } + end + end + + context 'getGroupeInstructeur' do + let(:groupe_instructeur) { procedure.groupe_instructeurs.first } + let(:variables) { { groupeInstructeurNumber: groupe_instructeur.id } } + let(:operation_name) { 'getGroupeInstructeur' } + + before { dossier } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:groupeInstructeur][:id]).to eq(groupe_instructeur.to_typed_id) + expect(gql_data[:groupeInstructeur][:dossiers]).to be_nil + } + + context 'include Dossiers' do + let(:variables) { { groupeInstructeurNumber: groupe_instructeur.id, includeDossiers: true } } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:groupeInstructeur][:id]).to eq(groupe_instructeur.to_typed_id) + expect(gql_data[:groupeInstructeur][:dossiers][:nodes].size).to eq(1) + } + end + end + + context 'getDemarcheDescriptor' do + let(:operation_name) { 'getDemarcheDescriptor' } + + context 'find by number' do + let(:variables) { { demarche: { number: procedure.id } } } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:demarcheDescriptor][:id]).to eq(procedure.to_typed_id) + } + end + + context 'find by id' do + let(:variables) { { demarche: { id: procedure.to_typed_id } } } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:demarcheDescriptor][:id]).to eq(procedure.to_typed_id) + } + end + + context 'not opendata' do + let(:variables) { { demarche: { id: procedure.to_typed_id } } } + + before { procedure.update(opendata: false) } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:demarcheDescriptor][:id]).to eq(procedure.to_typed_id) + } + end + + context 'without authorization token' do + let(:authorization_header) { nil } + + context 'opendata' do + let(:variables) { { demarche: { id: procedure.to_typed_id } } } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:demarcheDescriptor][:id]).to eq(procedure.to_typed_id) + } + end + + context 'not opendata' do + let(:variables) { { demarche: { id: procedure.to_typed_id } } } + + before { procedure.update(opendata: false) } + + it { + expect(gql_errors).not_to be_nil + expect(gql_errors.first[:message]).to eq('An object of type DemarcheDescriptor was hidden due to permissions') + } + end + end + end + end + + describe 'ds-mutation-v2' do + let(:query_id) { 'ds-mutation-v2' } + + context 'not found operation name' do + let(:operation_name) { 'dossierStuff' } + + it { + expect(gql_errors.first[:message]).to eq('No operation named "dossierStuff"') + } + end + + context 'dossierArchiver' do + let(:dossier) { create(:dossier, :refuse, :with_individual, procedure: procedure) } + let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } } + let(:operation_name) { 'dossierArchiver' } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:dossierArchiver][:errors]).to be_nil + expect(gql_data[:dossierArchiver][:dossier][:id]).to eq(dossier.to_typed_id) + expect(gql_data[:dossierArchiver][:dossier][:archived]).to be_truthy + } + end + + context 'dossierPasserEnInstruction' do + let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) } + let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } } + let(:operation_name) { 'dossierPasserEnInstruction' } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:dossierPasserEnInstruction][:errors]).to be_nil + expect(gql_data[:dossierPasserEnInstruction][:dossier][:id]).to eq(dossier.to_typed_id) + expect(gql_data[:dossierPasserEnInstruction][:dossier][:state]).to eq('en_instruction') + } + end + + context 'dossierRepasserEnConstruction' do + let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) } + let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } } + let(:operation_name) { 'dossierRepasserEnConstruction' } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:dossierRepasserEnConstruction][:errors]).to be_nil + expect(gql_data[:dossierRepasserEnConstruction][:dossier][:id]).to eq(dossier.to_typed_id) + expect(gql_data[:dossierRepasserEnConstruction][:dossier][:state]).to eq('en_construction') + } + end + + context 'dossierRepasserEnInstruction' do + let(:dossier) { create(:dossier, :refuse, :with_individual, procedure: procedure) } + let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } } + let(:operation_name) { 'dossierRepasserEnInstruction' } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:dossierRepasserEnInstruction][:errors]).to be_nil + expect(gql_data[:dossierRepasserEnInstruction][:dossier][:id]).to eq(dossier.to_typed_id) + expect(gql_data[:dossierRepasserEnInstruction][:dossier][:state]).to eq('en_instruction') + } + end + + context 'dossierAccepter' do + let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) } + let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } } + let(:operation_name) { 'dossierAccepter' } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:dossierAccepter][:errors]).to be_nil + expect(gql_data[:dossierAccepter][:dossier][:id]).to eq(dossier.to_typed_id) + expect(gql_data[:dossierAccepter][:dossier][:state]).to eq('accepte') + } + end + + context 'dossierRefuser' do + let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) } + let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id, motivation: 'yolo' } } } + let(:operation_name) { 'dossierRefuser' } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:dossierRefuser][:errors]).to be_nil + expect(gql_data[:dossierRefuser][:dossier][:id]).to eq(dossier.to_typed_id) + expect(gql_data[:dossierRefuser][:dossier][:state]).to eq('refuse') + } + end + + context 'dossierClasserSansSuite' do + let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) } + let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id, motivation: 'yolo' } } } + let(:operation_name) { 'dossierClasserSansSuite' } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:dossierClasserSansSuite][:errors]).to be_nil + expect(gql_data[:dossierClasserSansSuite][:dossier][:id]).to eq(dossier.to_typed_id) + expect(gql_data[:dossierClasserSansSuite][:dossier][:state]).to eq('sans_suite') + } + end + + context 'groupeInstructeurModifier' do + let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) } + let(:variables) { { input: { groupeInstructeurId: dossier.groupe_instructeur.to_typed_id, label: 'nouveau groupe instructeur' } } } + let(:operation_name) { 'groupeInstructeurModifier' } + + it { + expect(gql_errors).to be_nil + expect(gql_data[:groupeInstructeurModifier][:errors]).to be_nil + expect(gql_data[:groupeInstructeurModifier][:groupeInstructeur][:id]).to eq(dossier.groupe_instructeur.to_typed_id) + expect(dossier.groupe_instructeur.reload.label).to eq('nouveau groupe instructeur') + } + + context 'close groupe instructeur' do + let(:variables) { { input: { groupeInstructeurId: dossier.groupe_instructeur.to_typed_id, closed: true } } } + + context 'with multiple groupes' do + before do + create(:groupe_instructeur, procedure: procedure) + end + + it { + expect(gql_errors).to be_nil + expect(gql_data[:groupeInstructeurModifier][:errors]).to be_nil + expect(gql_data[:groupeInstructeurModifier][:groupeInstructeur][:id]).to eq(dossier.groupe_instructeur.to_typed_id) + expect(dossier.groupe_instructeur.reload.closed).to be_truthy + } + end + + context 'validation error' do + it { + expect(gql_errors).to be_nil + expect(gql_data[:groupeInstructeurModifier][:errors].first[:message]).to eq('Il doit y avoir au moins un groupe instructeur actif sur chaque démarche') + } + end + end + end + end +end