Merge pull request #4628 from betagouv/dev

2019-12-11-01
This commit is contained in:
Paul Chavard 2019-12-11 14:07:35 +01:00 committed by GitHub
commit c231270e34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 101 additions and 32 deletions

View file

@ -443,7 +443,7 @@ GEM
byebug (~> 10.0) byebug (~> 10.0)
pry (~> 0.10) pry (~> 0.10)
public_suffix (4.0.1) public_suffix (4.0.1)
puma (3.12.0) puma (3.12.2)
pundit (2.0.1) pundit (2.0.1)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
rack (2.0.7) rack (2.0.7)

View file

@ -28,9 +28,9 @@ module Extensions
# This method is called if the result of the `resolve` # This method is called if the result of the `resolve`
# is a lazy value (e.g., a Promise like in our case) # is a lazy value (e.g., a Promise like in our case)
def after_resolve(value:, **_rest) def after_resolve(value:, **_rest)
return if value.nil? if value&.virus_scanner&.safe? || value&.virus_scanner&.pending?
value
Rails.application.routes.url_helpers.url_for(value) end
end end
end end
end end

View file

@ -22,7 +22,7 @@ module Mutations
end end
end end
def authorized?(dossier:, instructeur:, motivation: nil) def authorized?(dossier:, instructeur:, motivation: nil, justificatif: nil)
instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id) instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id)
end end
end end

View file

@ -22,7 +22,7 @@ module Mutations
end end
end end
def authorized?(dossier:, instructeur:, motivation:) def authorized?(dossier:, instructeur:, motivation:, justificatif: nil)
instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id) instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id)
end end
end end

View file

@ -20,7 +20,7 @@ module Mutations
end end
end end
def authorized?(dossier:, instructeur:, body:) def authorized?(dossier:, instructeur:, body:, attachment: nil)
instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id) instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id)
end end
end end

View file

@ -22,7 +22,7 @@ module Mutations
end end
end end
def authorized?(dossier:, instructeur:, motivation:) def authorized?(dossier:, instructeur:, motivation:, justificatif: nil)
instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id) instructeur.is_a?(Instructeur) && instructeur.dossiers.exists?(id: dossier.id)
end end
end end

View file

@ -8,7 +8,7 @@ type Association {
} }
type Avis { type Avis {
attachmentUrl: URL attachment: File
dateQuestion: ISO8601DateTime! dateQuestion: ISO8601DateTime!
dateReponse: ISO8601DateTime dateReponse: ISO8601DateTime
expert: Profile expert: Profile
@ -383,7 +383,7 @@ type Dossier {
instructeurs: [Profile!]! instructeurs: [Profile!]!
messages: [Message!]! messages: [Message!]!
motivation: String motivation: String
motivationAttachmentUrl: URL motivationAttachment: File
""" """
Le numero du dossier. Le numero du dossier.
@ -663,6 +663,14 @@ type Entreprise {
siretSiegeSocial: String! siretSiegeSocial: String!
} }
type File {
byteSize: Int!
checksum: String!
contentType: String!
filename: String!
url: URL!
}
interface GeoArea { interface GeoArea {
geometry: GeoJSON! geometry: GeoJSON!
id: ID! id: ID!
@ -742,7 +750,7 @@ type LinkedDropDownListChamp implements Champ {
} }
type Message { type Message {
attachmentUrl: URL attachment: File
body: String! body: String!
createdAt: ISO8601DateTime! createdAt: ISO8601DateTime!
email: String! email: String!
@ -875,6 +883,7 @@ type PersonnePhysique implements Demandeur {
} }
type PieceJustificativeChamp implements Champ { type PieceJustificativeChamp implements Champ {
file: File
id: ID! id: ID!
""" """
@ -886,7 +895,6 @@ type PieceJustificativeChamp implements Champ {
La valeur du champ sous forme texte. La valeur du champ sous forme texte.
""" """
stringValue: String stringValue: String
url: URL
} }
type Profile { type Profile {

View file

@ -7,7 +7,7 @@ module Types
field :date_question, GraphQL::Types::ISO8601DateTime, null: false, method: :created_at field :date_question, GraphQL::Types::ISO8601DateTime, null: false, method: :created_at
field :date_reponse, GraphQL::Types::ISO8601DateTime, null: true, method: :updated_at field :date_reponse, GraphQL::Types::ISO8601DateTime, null: true, method: :updated_at
field :attachment_url, Types::URL, null: true, extensions: [ field :attachment, Types::File, null: true, extensions: [
{ Extensions::Attachment => { attachment: :piece_justificative_file } } { Extensions::Attachment => { attachment: :piece_justificative_file } }
] ]

View file

@ -3,7 +3,7 @@ module Types::Champs
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers
implements Types::ChampType implements Types::ChampType
field :url, Types::URL, null: true, extensions: [ field :file, Types::File, null: true, extensions: [
{ Extensions::Attachment => { attachment: :piece_justificative_file } } { Extensions::Attachment => { attachment: :piece_justificative_file } }
] ]
end end

View file

@ -20,7 +20,7 @@ module Types
field :archived, Boolean, null: false field :archived, Boolean, null: false
field :motivation, String, null: true field :motivation, String, null: true
field :motivation_attachment_url, Types::URL, null: true, extensions: [ field :motivation_attachment, Types::File, null: true, extensions: [
{ Extensions::Attachment => { attachment: :justificatif_motivation } } { Extensions::Attachment => { attachment: :justificatif_motivation } }
] ]

13
app/graphql/types/file.rb Normal file
View file

@ -0,0 +1,13 @@
module Types
class File < Types::BaseObject
field :url, Types::URL, null: false
field :filename, String, null: false
field :byte_size, Int, null: false
field :checksum, String, null: false
field :content_type, String, null: false
def url
Rails.application.routes.url_helpers.url_for(object)
end
end
end

View file

@ -4,7 +4,7 @@ module Types
field :email, String, null: false field :email, String, null: false
field :body, String, null: false field :body, String, null: false
field :created_at, GraphQL::Types::ISO8601DateTime, null: false field :created_at, GraphQL::Types::ISO8601DateTime, null: false
field :attachment_url, Types::URL, null: true, extensions: [ field :attachment, Types::File, null: true, extensions: [
{ Extensions::Attachment => { attachment: :piece_jointe } } { Extensions::Attachment => { attachment: :piece_jointe } }
] ]

View file

@ -1,7 +1,7 @@
DEFAULT_QUERY = "# La documentation officielle de la spécification (Anglais) : https://graphql.org/ DEFAULT_QUERY = "# La documentation officielle de la spécification (Anglais) : https://graphql.org/
# Une introduction aux concepts et raisons d'être de GraphQL (Français) : https://blog.octo.com/graphql-et-pourquoi-faire/ # Une introduction aux concepts et raisons d'être de GraphQL (Français) : https://blog.octo.com/graphql-et-pourquoi-faire/
# Le schema GraphQL de demarches-simplifiees.fr : https://demarches-simplifiees-graphql.netlify.com # Le schema GraphQL de demarches-simplifiees.fr : https://demarches-simplifiees-graphql.netlify.com
# Le endpoint GraphQL de demarches-simplifiees.fr : https://demarches-simplifiees.fr/api/v2/graphql # Le endpoint GraphQL de demarches-simplifiees.fr : https://www.demarches-simplifiees.fr/api/v2/graphql
query getDemarche($demarcheNumber: Int!) { query getDemarche($demarcheNumber: Int!) {
demarche(number: $demarcheNumber) { demarche(number: $demarcheNumber) {
@ -54,8 +54,10 @@ query getDemarche($demarcheNumber: Int!) {
secondaryValue secondaryValue
} }
... on PieceJustificativeChamp { ... on PieceJustificativeChamp {
file {
url url
} }
}
... on CarteChamp { ... on CarteChamp {
geoAreas { geoAreas {
source source

View file

@ -10,7 +10,7 @@ describe API::V2::GraphqlController do
:with_all_champs, :with_all_champs,
:for_individual, :for_individual,
procedure: procedure) procedure: procedure)
create(:commentaire, dossier: dossier, email: 'test@test.com') create(:commentaire, :with_file, dossier: dossier, email: 'test@test.com')
dossier dossier
end end
let(:dossier1) { create(:dossier, :en_construction, :for_individual, procedure: procedure, en_construction_at: 1.day.ago) } let(:dossier1) { create(:dossier, :en_construction, :for_individual, procedure: procedure, en_construction_at: 1.day.ago) }
@ -19,6 +19,31 @@ describe API::V2::GraphqlController do
let(:dossiers) { [dossier2, dossier1, dossier] } let(:dossiers) { [dossier2, dossier1, dossier] }
let(:instructeur) { create(:instructeur, followed_dossiers: dossiers) } let(:instructeur) { create(:instructeur, followed_dossiers: dossiers) }
def compute_checksum_in_chunks(io)
Digest::MD5.new.tap do |checksum|
while (chunk = io.read(5.megabytes))
checksum << chunk
end
io.rewind
end.base64digest
end
let(:file) { Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png') }
let(:blob_info) do
{
filename: file.original_filename,
byte_size: file.size,
checksum: compute_checksum_in_chunks(file),
content_type: file.content_type
}
end
let(:blob) do
blob = ActiveStorage::Blob.create_before_direct_upload!(blob_info)
blob.upload(file)
blob
end
before do before do
instructeur.assign_to_procedure(procedure) instructeur.assign_to_procedure(procedure)
end end
@ -155,7 +180,9 @@ describe API::V2::GraphqlController do
datePassageEnInstruction datePassageEnInstruction
dateTraitement dateTraitement
motivation motivation
motivationAttachmentUrl motivationAttachment {
url
}
usager { usager {
id id
email email
@ -176,7 +203,13 @@ describe API::V2::GraphqlController do
messages { messages {
email email
body body
attachmentUrl attachment {
filename
checksum
byteSize
contentType
url
}
} }
avis { avis {
expert { expert {
@ -186,7 +219,10 @@ describe API::V2::GraphqlController do
reponse reponse
dateQuestion dateQuestion
dateReponse dateReponse
attachmentUrl attachment {
url
filename
}
} }
champs { champs {
id id
@ -209,7 +245,7 @@ describe API::V2::GraphqlController do
datePassageEnInstruction: nil, datePassageEnInstruction: nil,
dateTraitement: nil, dateTraitement: nil,
motivation: nil, motivation: nil,
motivationAttachmentUrl: nil, motivationAttachment: nil,
usager: { usager: {
id: dossier.user.to_typed_id, id: dossier.user.to_typed_id,
email: dossier.user.email email: dossier.user.email
@ -230,7 +266,13 @@ describe API::V2::GraphqlController do
messages: dossier.commentaires.map do |commentaire| messages: dossier.commentaires.map do |commentaire|
{ {
body: commentaire.body, body: commentaire.body,
attachmentUrl: nil, attachment: {
filename: commentaire.piece_jointe.filename.to_s,
contentType: commentaire.piece_jointe.content_type,
checksum: commentaire.piece_jointe.checksum,
byteSize: commentaire.piece_jointe.byte_size,
url: Rails.application.routes.url_helpers.url_for(commentaire.piece_jointe)
},
email: commentaire.email email: commentaire.email
} }
end, end,
@ -306,7 +348,8 @@ describe API::V2::GraphqlController do
dossierEnvoyerMessage(input: { dossierEnvoyerMessage(input: {
dossierId: \"#{dossier.to_typed_id}\", dossierId: \"#{dossier.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\", instructeurId: \"#{instructeur.to_typed_id}\",
body: \"Bonjour\" body: \"Bonjour\",
attachment: \"#{blob.signed_id}\"
}) { }) {
message { message {
body body
@ -429,7 +472,8 @@ describe API::V2::GraphqlController do
dossierClasserSansSuite(input: { dossierClasserSansSuite(input: {
dossierId: \"#{dossier.to_typed_id}\", dossierId: \"#{dossier.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\", instructeurId: \"#{instructeur.to_typed_id}\",
motivation: \"Parce que\" motivation: \"Parce que\",
justificatif: \"#{blob.signed_id}\"
}) { }) {
dossier { dossier {
id id
@ -478,7 +522,8 @@ describe API::V2::GraphqlController do
dossierRefuser(input: { dossierRefuser(input: {
dossierId: \"#{dossier.to_typed_id}\", dossierId: \"#{dossier.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\", instructeurId: \"#{instructeur.to_typed_id}\",
motivation: \"Parce que\" motivation: \"Parce que\",
justificatif: \"#{blob.signed_id}\"
}) { }) {
dossier { dossier {
id id
@ -527,7 +572,8 @@ describe API::V2::GraphqlController do
dossierAccepter(input: { dossierAccepter(input: {
dossierId: \"#{dossier.to_typed_id}\", dossierId: \"#{dossier.to_typed_id}\",
instructeurId: \"#{instructeur.to_typed_id}\", instructeurId: \"#{instructeur.to_typed_id}\",
motivation: \"Parce que\" motivation: \"Parce que\",
justificatif: \"#{blob.signed_id}\"
}) { }) {
dossier { dossier {
id id
@ -607,10 +653,10 @@ describe API::V2::GraphqlController do
"mutation { "mutation {
createDirectUpload(input: { createDirectUpload(input: {
dossierId: \"#{dossier.to_typed_id}\", dossierId: \"#{dossier.to_typed_id}\",
filename: \"hello.png\", filename: \"#{blob_info[:filename]}\",
byteSize: 1234, byteSize: #{blob_info[:byte_size]},
checksum: \"qwerty1234\", checksum: \"#{blob_info[:checksum]}\",
contentType: \"image/png\" contentType: \"#{blob_info[:content_type]}\"
}) { }) {
directUpload { directUpload {
url url