[GraphQL]: add dossier state change mutations

This commit is contained in:
Paul Chavard 2019-11-13 20:01:58 +01:00
parent 120d8abb75
commit e600aceccc
7 changed files with 501 additions and 1 deletions

View file

@ -0,0 +1,29 @@
module Mutations
class DossierAccepter < Mutations::BaseMutation
include DossierHelper
description "Accepter le dossier."
argument :dossier_id, ID, "Dossier ID", required: true, loads: Types::DossierType
argument :instructeur_id, ID, "Instructeur qui prend la décision sur le dossier.", required: true, loads: Types::ProfileType
argument :motivation, String, required: false
argument :justificatif, ID, required: false
field :dossier, Types::DossierType, null: true
field :errors, [Types::ValidationErrorType], null: true
def resolve(dossier:, instructeur:, motivation: nil, justificatif: nil)
if dossier.en_instruction?
dossier.accepter!(instructeur, motivation, justificatif)
{ dossier: dossier }
else
{ errors: ["Le dossier est déjà #{dossier_display_state(dossier, lower: true)}"] }
end
end
def authorized?(dossier:, instructeur:, motivation: nil)
instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id)
end
end
end

View file

@ -0,0 +1,29 @@
module Mutations
class DossierClasserSansSuite < Mutations::BaseMutation
include DossierHelper
description "Classer le dossier sans suite."
argument :dossier_id, ID, "Dossier ID", required: true, loads: Types::DossierType
argument :instructeur_id, ID, "Instructeur qui prend la décision sur le dossier.", required: true, loads: Types::ProfileType
argument :motivation, String, required: true
argument :justificatif, ID, required: false
field :dossier, Types::DossierType, null: true
field :errors, [Types::ValidationErrorType], null: true
def resolve(dossier:, instructeur:, motivation:, justificatif: nil)
if dossier.en_instruction?
dossier.classer_sans_suite!(instructeur, motivation, justificatif)
{ dossier: dossier }
else
{ errors: ["Le dossier est déjà #{dossier_display_state(dossier, lower: true)}"] }
end
end
def authorized?(dossier:, instructeur:, motivation:)
instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id)
end
end
end

View file

@ -0,0 +1,27 @@
module Mutations
class DossierPasserEnInstruction < Mutations::BaseMutation
include DossierHelper
description "Passer le dossier en instruction."
argument :dossier_id, ID, "Dossier ID", required: true, loads: Types::DossierType
argument :instructeur_id, ID, "Instructeur qui prend la décision sur le dossier.", required: true, loads: Types::ProfileType
field :dossier, Types::DossierType, null: true
field :errors, [Types::ValidationErrorType], null: true
def resolve(dossier:, instructeur:)
if dossier.en_construction?
dossier.passer_en_instruction!(instructeur)
{ dossier: dossier }
else
{ errors: ["Le dossier est déjà #{dossier_display_state(dossier, lower: true)}"] }
end
end
def authorized?(dossier:, instructeur:)
instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id)
end
end
end

View file

@ -0,0 +1,29 @@
module Mutations
class DossierRefuser < Mutations::BaseMutation
include DossierHelper
description "Refuser le dossier."
argument :dossier_id, ID, "Dossier ID", required: true, loads: Types::DossierType
argument :instructeur_id, ID, "Instructeur qui prend la décision sur le dossier.", required: true, loads: Types::ProfileType
argument :motivation, String, required: true
argument :justificatif, ID, required: false
field :dossier, Types::DossierType, null: true
field :errors, [Types::ValidationErrorType], null: true
def resolve(dossier:, instructeur:, motivation:, justificatif: nil)
if dossier.en_instruction?
dossier.refuser!(instructeur, motivation, justificatif)
{ dossier: dossier }
else
{ errors: ["Le dossier est déjà #{dossier_display_state(dossier, lower: true)}"] }
end
end
def authorized?(dossier:, instructeur:, motivation:)
instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id)
end
end
end

View file

@ -317,6 +317,74 @@ type Dossier {
usager: Profile!
}
"""
Autogenerated input type of DossierAccepter
"""
input DossierAccepterInput {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Dossier ID
"""
dossierId: ID!
"""
Instructeur qui prend la décision sur le dossier.
"""
instructeurId: ID!
justificatif: ID
motivation: String
}
"""
Autogenerated return type of DossierAccepter
"""
type DossierAccepterPayload {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
dossier: Dossier
errors: [ValidationError!]
}
"""
Autogenerated input type of DossierClasserSansSuite
"""
input DossierClasserSansSuiteInput {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Dossier ID
"""
dossierId: ID!
"""
Instructeur qui prend la décision sur le dossier.
"""
instructeurId: ID!
justificatif: ID
motivation: String!
}
"""
Autogenerated return type of DossierClasserSansSuite
"""
type DossierClasserSansSuitePayload {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
dossier: Dossier
errors: [ValidationError!]
}
"""
The connection type for Dossier.
"""
@ -394,6 +462,72 @@ type DossierLinkChamp implements Champ {
stringValue: String
}
"""
Autogenerated input type of DossierPasserEnInstruction
"""
input DossierPasserEnInstructionInput {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Dossier ID
"""
dossierId: ID!
"""
Instructeur qui prend la décision sur le dossier.
"""
instructeurId: ID!
}
"""
Autogenerated return type of DossierPasserEnInstruction
"""
type DossierPasserEnInstructionPayload {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
dossier: Dossier
errors: [ValidationError!]
}
"""
Autogenerated input type of DossierRefuser
"""
input DossierRefuserInput {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Dossier ID
"""
dossierId: ID!
"""
Instructeur qui prend la décision sur le dossier.
"""
instructeurId: ID!
justificatif: ID
motivation: String!
}
"""
Autogenerated return type of DossierRefuser
"""
type DossierRefuserPayload {
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
dossier: Dossier
errors: [ValidationError!]
}
enum DossierState {
"""
Accepté
@ -523,10 +657,30 @@ type Mutation {
"""
createDirectUpload(input: CreateDirectUploadInput!): CreateDirectUploadPayload
"""
Accepter le dossier.
"""
dossierAccepter(input: DossierAccepterInput!): DossierAccepterPayload
"""
Classer le dossier sans suite.
"""
dossierClasserSansSuite(input: DossierClasserSansSuiteInput!): DossierClasserSansSuitePayload
"""
Envoyer un message à l'usager du dossier.
"""
dossierEnvoyerMessage(input: DossierEnvoyerMessageInput!): DossierEnvoyerMessagePayload
"""
Passer le dossier en instruction.
"""
dossierPasserEnInstruction(input: DossierPasserEnInstructionInput!): DossierPasserEnInstructionPayload
"""
Refuser le dossier.
"""
dossierRefuser(input: DossierRefuserInput!): DossierRefuserPayload
}
enum Order {

View file

@ -3,5 +3,9 @@ module Types
field :create_direct_upload, mutation: Mutations::CreateDirectUpload
field :dossier_envoyer_message, mutation: Mutations::DossierEnvoyerMessage
field :dossier_passer_en_instruction, mutation: Mutations::DossierPasserEnInstruction
field :dossier_classer_sans_suite, mutation: Mutations::DossierClasserSansSuite
field :dossier_refuser, mutation: Mutations::DossierRefuser
field :dossier_accepter, mutation: Mutations::DossierAccepter
end
end

View file

@ -291,7 +291,235 @@ describe API::V2::GraphqlController do
end
end
context 'createDirectUpload' do
describe 'dossierPasserEnInstruction' do
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
let(:query) do
"mutation {
dossierPasserEnInstruction(input: {
dossierId: \"#{dossier.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\"
}) {
dossier {
id
state
motivation
}
errors {
message
}
}
}"
end
context 'success' do
it "should passer en instruction dossier" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierPasserEnInstruction: {
dossier: {
id: dossier.to_typed_id,
state: "en_instruction",
motivation: nil
},
errors: nil
})
end
end
context 'validation error' do
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
it "should fail" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierPasserEnInstruction: {
errors: [{ message: "Le dossier est déjà en instruction" }],
dossier: nil
})
end
end
end
describe 'dossierClasserSansSuite' do
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
let(:query) do
"mutation {
dossierClasserSansSuite(input: {
dossierId: \"#{dossier.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\",
motivation: \"Parce que\"
}) {
dossier {
id
state
motivation
}
errors {
message
}
}
}"
end
context 'success' do
it "should classer sans suite dossier" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierClasserSansSuite: {
dossier: {
id: dossier.to_typed_id,
state: "sans_suite",
motivation: "Parce que"
},
errors: nil
})
end
end
context 'validation error' do
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
it "should fail" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierClasserSansSuite: {
errors: [{ message: "Le dossier est déjà accepté" }],
dossier: nil
})
end
end
end
describe 'dossierRefuser' do
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
let(:query) do
"mutation {
dossierRefuser(input: {
dossierId: \"#{dossier.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\",
motivation: \"Parce que\"
}) {
dossier {
id
state
motivation
}
errors {
message
}
}
}"
end
context 'success' do
it "should refuser dossier" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierRefuser: {
dossier: {
id: dossier.to_typed_id,
state: "refuse",
motivation: "Parce que"
},
errors: nil
})
end
end
context 'validation error' do
let(:dossier) { create(:dossier, :sans_suite, procedure: procedure) }
it "should fail" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierRefuser: {
errors: [{ message: "Le dossier est déjà sans suite" }],
dossier: nil
})
end
end
end
describe 'dossierAccepter' do
let(:dossier) { create(:dossier, :en_instruction, procedure: procedure) }
let(:query) do
"mutation {
dossierAccepter(input: {
dossierId: \"#{dossier.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\",
motivation: \"Parce que\"
}) {
dossier {
id
state
motivation
}
errors {
message
}
}
}"
end
context 'success' do
it "should accepter dossier" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierAccepter: {
dossier: {
id: dossier.to_typed_id,
state: "accepte",
motivation: "Parce que"
},
errors: nil
})
end
end
context 'success without motivation' do
let(:query) do
"mutation {
dossierAccepter(input: {
dossierId: \"#{dossier.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\"
}) {
dossier {
id
state
motivation
}
errors {
message
}
}
}"
end
it "should accepter dossier" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierAccepter: {
dossier: {
id: dossier.to_typed_id,
state: "accepte",
motivation: nil
},
errors: nil
})
end
end
context 'validation error' do
let(:dossier) { create(:dossier, :refuse, procedure: procedure) }
it "should fail" do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierAccepter: {
errors: [{ message: "Le dossier est déjà refusé" }],
dossier: nil
})
end
end
end
describe 'createDirectUpload' do
let(:query) do
"mutation {
createDirectUpload(input: {