Merge pull request #5767 from tchak/graphql-modifier-annotation-privee

[GraphQL] modifier annotation
This commit is contained in:
Paul Chavard 2021-02-11 18:40:54 +01:00 committed by GitHub
commit cb2a93a605
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 628 additions and 6 deletions

View file

@ -9,10 +9,10 @@ class API::V2::GraphqlController < API::V2::BaseController
render json: result
rescue => exception
if Rails.env.development?
handle_error_in_development(exception)
else
if Rails.env.production?
handle_error_in_production(exception)
else
handle_error_in_development(exception)
end
end

View file

@ -0,0 +1,66 @@
module Mutations
class DossierModifierAnnotation < Mutations::BaseMutation
argument :dossier_id, ID, "Dossier ID", required: true, loads: Types::DossierType
argument :instructeur_id, ID, "Instructeur qui demande la modification.", required: true, loads: Types::ProfileType
argument :annotation_id, ID, "Annotation ID", required: true
field :annotation, Types::ChampType, null: true
field :errors, [Types::ValidationErrorType], null: true
def resolve_with_type(type, dossier, annotation_id, instructeur, value)
annotation = find_annotation(dossier, type, annotation_id)
if block_given?
annotation.value = yield annotation.type_champ, value
else
annotation.value = value
end
if annotation.save
dossier.log_modifier_annotation!(annotation, instructeur)
{ annotation: annotation }
else
{ errors: annotation.errors.full_messages }
end
end
def authorized?(dossier:, instructeur:, **args)
dossier_authorized_for?(dossier, instructeur)
end
private
def find_annotation(dossier, type, annotation_id)
_, stable_id = GraphQL::Schema::UniqueWithinType.decode(annotation_id)
dossier.champs_private
.joins(:type_de_champ)
.find_by!(types_de_champ: {
type_champ: annotation_type_champ(type),
stable_id: stable_id
})
end
def annotation_type_champ(type)
case type
when :text
[
TypeDeChamp.type_champs.fetch(:text),
TypeDeChamp.type_champs.fetch(:textarea)
]
when :checkbox
[
TypeDeChamp.type_champs.fetch(:checkbox),
TypeDeChamp.type_champs.fetch(:yes_no),
TypeDeChamp.type_champs.fetch(:engagement)
]
when :date
TypeDeChamp.type_champs.fetch(:date)
when :datetime
TypeDeChamp.type_champs.fetch(:datetime)
when :integer_number
TypeDeChamp.type_champs.fetch(:integer_number)
end
end
end
end

View file

@ -0,0 +1,23 @@
module Mutations
class DossierModifierAnnotationCheckbox < Mutations::DossierModifierAnnotation
description "Modifier lannotation au format oui/non."
argument :value, Boolean, required: true
def resolve(dossier:, annotation_id:, instructeur:, value:)
resolve_with_type(
:checkbox,
dossier,
annotation_id,
instructeur,
value
) do |type_champ, value|
if type_champ == TypeDeChamp.type_champs.fetch(:yes_no)
value ? 'true' : 'false'
else
value ? 'on' : 'off'
end
end
end
end
end

View file

@ -0,0 +1,17 @@
module Mutations
class DossierModifierAnnotationDate < Mutations::DossierModifierAnnotation
description "Modifier lannotation au format date."
argument :value, GraphQL::Types::ISO8601Date, required: true
def resolve(dossier:, annotation_id:, instructeur:, value:)
resolve_with_type(
:date,
dossier,
annotation_id,
instructeur,
value
)
end
end
end

View file

@ -0,0 +1,17 @@
module Mutations
class DossierModifierAnnotationDatetime < Mutations::DossierModifierAnnotation
description "Modifier lannotation au format date et heure."
argument :value, GraphQL::Types::ISO8601DateTime, required: true
def resolve(dossier:, annotation_id:, instructeur:, value:)
resolve_with_type(
:datetime,
dossier,
annotation_id,
instructeur,
value
)
end
end
end

View file

@ -0,0 +1,17 @@
module Mutations
class DossierModifierAnnotationIntegerNumber < Mutations::DossierModifierAnnotation
description "Modifier lannotation au format nombre entier."
argument :value, Int, required: true
def resolve(dossier:, annotation_id:, instructeur:, value:)
resolve_with_type(
:integer_number,
dossier,
annotation_id,
instructeur,
value
)
end
end
end

View file

@ -0,0 +1,17 @@
module Mutations
class DossierModifierAnnotationText < Mutations::DossierModifierAnnotation
description "Modifier lannotation au format text."
argument :value, String, required: true
def resolve(dossier:, annotation_id:, instructeur:, value:)
resolve_with_type(
:text,
dossier,
annotation_id,
instructeur,
value
)
end
end
end

View file

@ -685,6 +685,201 @@ type DossierLinkChamp implements Champ {
stringValue: String
}
"""
Autogenerated input type of DossierModifierAnnotationCheckbox
"""
input DossierModifierAnnotationCheckboxInput {
"""
Annotation ID
"""
annotationId: ID!
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Dossier ID
"""
dossierId: ID!
"""
Instructeur qui demande la modification.
"""
instructeurId: ID!
value: Boolean!
}
"""
Autogenerated return type of DossierModifierAnnotationCheckbox
"""
type DossierModifierAnnotationCheckboxPayload {
annotation: Champ
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
errors: [ValidationError!]
}
"""
Autogenerated input type of DossierModifierAnnotationDate
"""
input DossierModifierAnnotationDateInput {
"""
Annotation ID
"""
annotationId: ID!
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Dossier ID
"""
dossierId: ID!
"""
Instructeur qui demande la modification.
"""
instructeurId: ID!
value: ISO8601Date!
}
"""
Autogenerated return type of DossierModifierAnnotationDate
"""
type DossierModifierAnnotationDatePayload {
annotation: Champ
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
errors: [ValidationError!]
}
"""
Autogenerated input type of DossierModifierAnnotationDatetime
"""
input DossierModifierAnnotationDatetimeInput {
"""
Annotation ID
"""
annotationId: ID!
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Dossier ID
"""
dossierId: ID!
"""
Instructeur qui demande la modification.
"""
instructeurId: ID!
value: ISO8601DateTime!
}
"""
Autogenerated return type of DossierModifierAnnotationDatetime
"""
type DossierModifierAnnotationDatetimePayload {
annotation: Champ
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
errors: [ValidationError!]
}
"""
Autogenerated input type of DossierModifierAnnotationIntegerNumber
"""
input DossierModifierAnnotationIntegerNumberInput {
"""
Annotation ID
"""
annotationId: ID!
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Dossier ID
"""
dossierId: ID!
"""
Instructeur qui demande la modification.
"""
instructeurId: ID!
value: Int!
}
"""
Autogenerated return type of DossierModifierAnnotationIntegerNumber
"""
type DossierModifierAnnotationIntegerNumberPayload {
annotation: Champ
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
errors: [ValidationError!]
}
"""
Autogenerated input type of DossierModifierAnnotationText
"""
input DossierModifierAnnotationTextInput {
"""
Annotation ID
"""
annotationId: ID!
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
"""
Dossier ID
"""
dossierId: ID!
"""
Instructeur qui demande la modification.
"""
instructeurId: ID!
value: String!
}
"""
Autogenerated return type of DossierModifierAnnotationText
"""
type DossierModifierAnnotationTextPayload {
annotation: Champ
"""
A unique identifier for the client performing the mutation.
"""
clientMutationId: String
errors: [ValidationError!]
}
"""
Autogenerated input type of DossierPasserEnInstruction
"""
@ -1013,6 +1208,31 @@ type Mutation {
"""
dossierEnvoyerMessage(input: DossierEnvoyerMessageInput!): DossierEnvoyerMessagePayload
"""
Modifier lannotation au format oui/non.
"""
dossierModifierAnnotationCheckbox(input: DossierModifierAnnotationCheckboxInput!): DossierModifierAnnotationCheckboxPayload
"""
Modifier lannotation au format date.
"""
dossierModifierAnnotationDate(input: DossierModifierAnnotationDateInput!): DossierModifierAnnotationDatePayload
"""
Modifier lannotation au format date et heure.
"""
dossierModifierAnnotationDatetime(input: DossierModifierAnnotationDatetimeInput!): DossierModifierAnnotationDatetimePayload
"""
Modifier lannotation au format nombre entier.
"""
dossierModifierAnnotationIntegerNumber(input: DossierModifierAnnotationIntegerNumberInput!): DossierModifierAnnotationIntegerNumberPayload
"""
Modifier lannotation au format text.
"""
dossierModifierAnnotationText(input: DossierModifierAnnotationTextInput!): DossierModifierAnnotationTextPayload
"""
Passer le dossier en instruction.
"""

View file

@ -9,5 +9,11 @@ module Types
field :dossier_accepter, mutation: Mutations::DossierAccepter
field :dossier_archiver, mutation: Mutations::DossierArchiver
field :dossier_changer_groupe_instructeur, mutation: Mutations::DossierChangerGroupeInstructeur
field :dossier_modifier_annotation_text, mutation: Mutations::DossierModifierAnnotationText
field :dossier_modifier_annotation_checkbox, mutation: Mutations::DossierModifierAnnotationCheckbox
field :dossier_modifier_annotation_date, mutation: Mutations::DossierModifierAnnotationDate
field :dossier_modifier_annotation_datetime, mutation: Mutations::DossierModifierAnnotationDatetime
field :dossier_modifier_annotation_integer_number, mutation: Mutations::DossierModifierAnnotationIntegerNumber
end
end

View file

@ -679,6 +679,10 @@ class Dossier < ApplicationRecord
end
end
def log_modifier_annotation!(champ, instructeur)
log_dossier_operation(instructeur, :modifier_annotation, champ)
end
def demander_un_avis!(avis)
log_dossier_operation(avis.claimant, :demander_un_avis, avis)
end

View file

@ -1,11 +1,12 @@
describe API::V2::GraphqlController do
let(:admin) { create(:administrateur) }
let(:token) { admin.renew_api_token }
let(:procedure) { create(:procedure, :published, :for_individual, :with_service, :with_all_champs, administrateurs: [admin]) }
let(:procedure) { create(:procedure, :published, :for_individual, :with_service, :with_all_champs, :with_all_annotations, administrateurs: [admin]) }
let(:dossier) do
dossier = create(:dossier,
:en_construction,
:with_all_champs,
:with_all_annotations,
:with_individual,
procedure: procedure)
create(:commentaire, :with_file, dossier: dossier, email: 'test@test.com')
@ -1117,6 +1118,240 @@ describe API::V2::GraphqlController do
end
end
end
describe 'dossierModifierAnnotation' do
describe 'text' do
let(:query) do
"mutation {
dossierModifierAnnotationText(input: {
dossierId: \"#{dossier.to_typed_id}\",
annotationId: \"#{dossier.champs_private.first.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\",
value: \"hello\"
}) {
annotation {
stringValue
}
errors {
message
}
}
}"
end
context "success" do
it 'should be a success' do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierModifierAnnotationText: {
annotation: {
stringValue: 'hello'
},
errors: nil
})
end
end
end
describe 'checkbox' do
let(:value) { 'true' }
let(:query) do
"mutation {
dossierModifierAnnotationCheckbox(input: {
dossierId: \"#{dossier.to_typed_id}\",
annotationId: \"#{dossier.champs_private.find { |c| c.type_champ == 'checkbox' }.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\",
value: #{value}
}) {
annotation {
stringValue
}
errors {
message
}
}
}"
end
context "success when true" do
it 'should be a success' do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierModifierAnnotationCheckbox: {
annotation: {
stringValue: 'true'
},
errors: nil
})
end
end
context "success when false" do
let(:value) { 'false' }
it 'should be a success' do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierModifierAnnotationCheckbox: {
annotation: {
stringValue: 'false'
},
errors: nil
})
end
end
end
describe 'yes_no' do
let(:value) { 'true' }
let(:query) do
"mutation {
dossierModifierAnnotationCheckbox(input: {
dossierId: \"#{dossier.to_typed_id}\",
annotationId: \"#{dossier.champs_private.find { |c| c.type_champ == 'yes_no' }.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\",
value: #{value}
}) {
annotation {
stringValue
}
errors {
message
}
}
}"
end
context "success when true" do
it 'should be a success' do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierModifierAnnotationCheckbox: {
annotation: {
stringValue: 'true'
},
errors: nil
})
end
end
context "success when false" do
let(:value) { 'false' }
it 'should be a success' do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierModifierAnnotationCheckbox: {
annotation: {
stringValue: 'false'
},
errors: nil
})
end
end
end
describe 'date' do
let(:query) do
"mutation {
dossierModifierAnnotationDate(input: {
dossierId: \"#{dossier.to_typed_id}\",
annotationId: \"#{dossier.champs_private.find { |c| c.type_champ == 'date' }.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\",
value: \"#{1.day.from_now.to_date.iso8601}\"
}) {
annotation {
stringValue
}
errors {
message
}
}
}"
end
context "success" do
it 'should be a success' do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierModifierAnnotationDate: {
annotation: {
stringValue: dossier.reload.champs_private.find { |c| c.type_champ == 'date' }.to_s
},
errors: nil
})
end
end
end
describe 'datetime' do
let(:query) do
"mutation {
dossierModifierAnnotationDatetime(input: {
dossierId: \"#{dossier.to_typed_id}\",
annotationId: \"#{dossier.champs_private.find { |c| c.type_champ == 'datetime' }.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\",
value: \"#{1.day.from_now.iso8601}\"
}) {
annotation {
stringValue
}
errors {
message
}
}
}"
end
context "success" do
it 'should be a success' do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierModifierAnnotationDatetime: {
annotation: {
stringValue: dossier.reload.champs_private.find { |c| c.type_champ == 'datetime' }.to_s
},
errors: nil
})
end
end
end
describe 'integer_number' do
let(:query) do
"mutation {
dossierModifierAnnotationIntegerNumber(input: {
dossierId: \"#{dossier.to_typed_id}\",
annotationId: \"#{dossier.champs_private.find { |c| c.type_champ == 'integer_number' }.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\",
value: 42
}) {
annotation {
stringValue
}
errors {
message
}
}
}"
end
context "success" do
it 'should be a success' do
expect(gql_errors).to eq(nil)
expect(gql_data).to eq(dossierModifierAnnotationIntegerNumber: {
annotation: {
stringValue: '42'
},
errors: nil
})
end
end
end
end
end
end

View file

@ -216,8 +216,8 @@ FactoryBot.define do
trait :with_all_annotations do
after(:create) do |dossier, _evaluator|
dossier.champs = dossier.types_de_champ.map do |type_de_champ|
build(:"champ_#{type_de_champ.type_champ}", dossier: dossier, type_de_champ: type_de_champ)
dossier.champs_private = dossier.types_de_champ_private.map do |type_de_champ|
build(:"champ_#{type_de_champ.type_champ}", private: true, dossier: dossier, type_de_champ: type_de_champ)
end
dossier.save!
end