commit
c231270e34
14 changed files with 101 additions and 32 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 } }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
13
app/graphql/types/file.rb
Normal 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
|
|
@ -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 } }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue