2019-09-18 18:45:24 +02:00
describe API :: V2 :: GraphqlController do
2024-06-01 22:50:48 +02:00
let ( :admin ) { administrateurs ( :default_admin ) }
2023-02-13 14:57:51 +01:00
let ( :generated_token ) { APIToken . generate ( admin ) }
let ( :api_token ) { generated_token . first }
let ( :token ) { generated_token . second }
2021-11-03 17:00:40 +01:00
let ( :procedure ) { create ( :procedure , :published , :for_individual , :with_service , administrateurs : [ admin ] ) }
2021-11-03 17:04:38 +01:00
let ( :dossier ) { create ( :dossier , :en_construction , :with_individual , procedure : procedure ) }
2020-01-07 17:47:22 +01:00
let ( :dossier1 ) { create ( :dossier , :en_construction , :with_individual , procedure : procedure , en_construction_at : 1 . day . ago ) }
2020-07-29 16:43:41 +02:00
let ( :dossier2 ) { create ( :dossier , :en_construction , :with_individual , :archived , procedure : procedure , en_construction_at : 3 . days . ago ) }
2021-11-03 17:12:14 +01:00
let ( :dossiers ) { [ dossier ] }
2019-09-26 14:57:58 +02:00
let ( :instructeur ) { create ( :instructeur , followed_dossiers : dossiers ) }
2019-12-11 13:14:18 +01:00
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
2020-06-30 17:53:54 +02:00
let ( :file ) { fixture_file_upload ( 'spec/fixtures/files/logo_test_procedure.png' , 'image/png' ) }
2019-12-11 13:14:18 +01:00
let ( :blob_info ) do
{
filename : file . original_filename ,
byte_size : file . size ,
checksum : compute_checksum_in_chunks ( file ) ,
2021-09-02 12:26:57 +02:00
content_type : file . content_type ,
# we don't want to run virus scanner on this file
metadata : { virus_scan_result : ActiveStorage :: VirusScanner :: SAFE }
2019-12-11 13:14:18 +01:00
}
end
let ( :blob ) do
2020-11-25 10:46:34 +01:00
blob = ActiveStorage :: Blob . create_before_direct_upload! ( ** blob_info )
2019-12-11 13:14:18 +01:00
blob . upload ( file )
blob
end
2023-04-13 13:10:23 +02:00
before { instructeur . assign_to_procedure ( procedure ) }
2019-09-18 18:45:24 +02:00
let ( :query ) do
" {
demarche ( number : #{procedure.id}) {
id
number
title
description
state
2019-09-26 15:17:58 +02:00
dateCreation
dateDerniereModification
dateFermeture
2019-09-24 19:41:48 +02:00
groupeInstructeurs {
label
instructeurs {
email
}
}
2020-07-16 12:48:35 +02:00
revisions {
id
}
draftRevision {
id
}
publishedRevision {
id
champDescriptors {
2022-11-24 13:16:37 +01:00
__typename
2020-07-16 12:48:35 +02:00
}
}
2019-11-29 12:45:58 +01:00
service {
nom
typeOrganisme
organisme
}
2019-09-18 18:45:24 +02:00
champDescriptors {
2022-11-24 13:16:37 +01:00
__typename
2019-09-18 18:45:24 +02:00
id
label
description
required
2022-11-24 13:16:37 +01:00
... on RepetitionChampDescriptor {
champDescriptors {
__typename
id
}
}
... on DropDownListChampDescriptor {
options
}
... on MultipleDropDownListChampDescriptor {
options
}
... on LinkedDropDownListChampDescriptor {
options
2020-07-16 12:50:00 +02:00
}
2019-09-18 18:45:24 +02:00
}
dossiers {
nodes {
id
}
}
}
} "
end
2022-10-29 12:35:52 +02:00
let ( :variables ) { { } }
2022-10-31 18:21:24 +01:00
let ( :operation_name ) { nil }
let ( :query_id ) { nil }
2019-09-18 18:45:24 +02:00
let ( :body ) { JSON . parse ( subject . body , symbolize_names : true ) }
let ( :gql_data ) { body [ :data ] }
let ( :gql_errors ) { body [ :errors ] }
2022-10-31 18:21:24 +01:00
subject { post :execute , params : { query : query , variables : variables , operationName : operation_name , queryId : query_id } . compact , as : :json }
2019-09-18 18:45:24 +02:00
context " when authenticated " do
let ( :authorization_header ) { ActionController :: HttpAuthentication :: Token . encode_credentials ( token ) }
before do
request . env [ 'HTTP_AUTHORIZATION' ] = authorization_header
end
2022-11-25 16:27:11 +01:00
describe " token authentication " do
it {
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . not_to be_nil
}
context " when the token is invalid " do
before do
request . env [ 'HTTP_AUTHORIZATION' ] = ActionController :: HttpAuthentication :: Token . encode_credentials ( 'invalid' )
end
it {
expect ( gql_errors . first [ :message ] ) . to eq ( " An object of type Demarche was hidden due to permissions " )
}
end
2023-01-19 17:40:19 +01:00
context " when the token does not belong to an admin of the procedure " do
2023-01-19 17:33:19 +01:00
let ( :another_administrateur ) { create ( :administrateur ) }
2023-01-19 17:40:19 +01:00
let ( :token_v3 ) { APIToken . generate ( another_administrateur ) [ 1 ] }
let ( :plain_token ) { APIToken . send ( :unpack , token_v3 ) [ :plain_token ] }
2023-01-19 17:33:19 +01:00
before do
2023-01-19 17:40:19 +01:00
request . env [ 'HTTP_AUTHORIZATION' ] = ActionController :: HttpAuthentication :: Token . encode_credentials ( token )
2023-01-19 17:33:19 +01:00
end
2023-01-19 17:40:19 +01:00
context 'v3' do
let ( :token ) { token_v3 }
it {
expect ( gql_errors . first [ :message ] ) . to eq ( " An object of type Demarche was hidden due to permissions " )
}
end
2023-01-19 17:33:19 +01:00
end
2022-11-25 16:27:11 +01:00
context " when the token is revoked " do
before do
2022-11-30 10:14:23 +01:00
admin . api_tokens . destroy_all
2022-11-25 16:27:11 +01:00
end
it {
expect ( token ) . not_to be_nil
expect ( gql_errors . first [ :message ] ) . to eq ( " An object of type Demarche was hidden due to permissions " )
}
end
2023-02-13 14:57:51 +01:00
context 'when procedure is not selected' do
let ( :other_procedure ) { create ( :procedure , administrateurs : [ admin ] ) }
before { api_token . update ( allowed_procedure_ids : [ other_procedure . id ] ) }
it {
expect ( gql_errors . first [ :message ] ) . to eq ( " An object of type Demarche was hidden due to permissions " )
}
end
2022-11-25 16:27:11 +01:00
end
2021-11-03 16:04:50 +01:00
describe " demarche " do
2021-11-03 17:00:40 +01:00
describe " query a demarche " do
let ( :procedure ) { create ( :procedure , :published , :for_individual , :with_service , :with_all_champs , :with_all_annotations , administrateurs : [ admin ] ) }
2022-11-24 13:16:37 +01:00
def format_type_champ ( type_champ )
" #{ type_champ . gsub ( 'regions' , 'region' ) . gsub ( 'departements' , 'departement' ) . gsub ( 'communes' , 'commune' ) . camelcase } ChampDescriptor "
end
2021-11-03 17:00:40 +01:00
it " returns the demarche " do
expect ( gql_errors ) . to eq ( nil )
2022-11-24 13:16:37 +01:00
expect ( gql_data ) . to include ( demarche : {
2021-11-03 17:00:40 +01:00
id : procedure . to_typed_id ,
number : procedure . id ,
title : procedure . libelle ,
description : procedure . description ,
state : 'publiee' ,
dateFermeture : nil ,
dateCreation : procedure . created_at . iso8601 ,
dateDerniereModification : procedure . updated_at . iso8601 ,
groupeInstructeurs : [
2020-07-16 12:48:35 +02:00
{
2021-11-03 17:00:40 +01:00
instructeurs : [ { email : instructeur . email } ] ,
label : " défaut "
2020-07-16 12:48:35 +02:00
}
2021-11-03 17:00:40 +01:00
] ,
2022-11-24 13:16:37 +01:00
revisions : procedure . revisions . map { { id : _1 . to_typed_id } } ,
2021-11-03 17:00:40 +01:00
draftRevision : { id : procedure . draft_revision . to_typed_id } ,
publishedRevision : {
id : procedure . published_revision . to_typed_id ,
2022-11-24 13:16:37 +01:00
champDescriptors : procedure . published_revision . types_de_champ_public . map { { __typename : format_type_champ ( _1 . type_champ ) } }
2021-11-03 17:00:40 +01:00
} ,
service : {
nom : procedure . service . nom ,
typeOrganisme : procedure . service . type_organisme ,
organisme : procedure . service . organisme
} ,
2022-11-16 12:46:33 +01:00
champDescriptors : procedure . active_revision . types_de_champ_public . map do | tdc |
2021-11-03 17:00:40 +01:00
{
id : tdc . to_typed_id ,
label : tdc . libelle ,
2022-11-24 13:16:37 +01:00
__typename : format_type_champ ( tdc . type_champ ) ,
2021-11-03 17:00:40 +01:00
description : tdc . description ,
required : tdc . mandatory? ,
2022-11-24 13:16:37 +01:00
champDescriptors : tdc . repetition? ? procedure . active_revision . children_of ( tdc . reload ) . map { { id : _1 . to_typed_id , __typename : format_type_champ ( _1 . type_champ ) } } : nil ,
2021-11-03 17:00:40 +01:00
options : tdc . drop_down_list? ? tdc . drop_down_list_options . reject ( & :empty? ) : nil
2022-11-24 13:16:37 +01:00
} . compact
2021-11-03 17:00:40 +01:00
end ,
dossiers : {
2022-11-24 13:16:37 +01:00
nodes : dossiers . map { { id : _1 . to_typed_id } }
2019-09-26 14:57:58 +02:00
}
2021-11-03 17:00:40 +01:00
} )
end
2019-09-26 14:57:58 +02:00
end
2021-11-03 16:04:50 +01:00
describe " filter dossiers " do
2021-11-03 17:12:14 +01:00
let ( :dossiers ) { [ dossier , dossier1 , dossier2 ] }
2019-09-26 14:57:58 +02:00
let ( :query ) do
" {
demarche ( number : #{procedure.id}) {
id
number
dossiers ( createdSince : \ " #{ 2 . days . ago . iso8601 } \" ) {
nodes {
id
}
}
}
} "
end
it " should be returned " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( demarche : {
id : procedure . to_typed_id ,
2019-11-07 13:24:34 +01:00
number : procedure . id ,
2019-09-26 14:57:58 +02:00
dossiers : {
nodes : [ { id : dossier1 . to_typed_id } , { id : dossier . to_typed_id } ]
}
} )
end
end
2020-07-29 16:43:41 +02:00
2021-11-03 16:04:50 +01:00
describe " filter archived dossiers " do
2021-11-03 17:12:14 +01:00
let ( :dossiers ) { [ dossier , dossier1 , dossier2 ] }
2020-07-29 16:43:41 +02:00
let ( :query ) do
" {
demarche ( number : #{procedure.id}) {
id
number
dossiers ( archived : #{archived_filter}) {
nodes {
id
}
}
}
} "
end
context 'with archived=true' do
let ( :archived_filter ) { 'true' }
2021-11-03 16:04:50 +01:00
it 'returns only archived dossiers' do
2020-07-29 16:43:41 +02:00
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( demarche : {
id : procedure . to_typed_id ,
number : procedure . id ,
dossiers : {
nodes : [ { id : dossier2 . to_typed_id } ]
}
} )
end
end
context 'with archived=false' do
let ( :archived_filter ) { 'false' }
2021-11-03 16:04:50 +01:00
it 'returns only non-archived dossiers' do
2020-07-29 16:43:41 +02:00
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( demarche : {
id : procedure . to_typed_id ,
number : procedure . id ,
dossiers : {
nodes : [ { id : dossier1 . to_typed_id } , { id : dossier . to_typed_id } ]
}
} )
end
end
end
2021-01-21 19:04:35 +01:00
2021-11-03 16:04:50 +01:00
describe " filter by minRevision " do
2021-01-21 19:04:35 +01:00
let ( :query ) do
" {
demarche ( number : #{procedure.id}) {
id
number
dossiers ( minRevision : \ " #{ procedure . revisions . first . to_typed_id } \" ) {
nodes {
id
}
}
}
} "
end
it " should be returned " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( demarche : {
id : procedure . to_typed_id ,
number : procedure . id ,
dossiers : {
nodes : procedure . dossiers . order ( :created_at ) . map do | dossier |
{ id : dossier . to_typed_id }
end
}
} )
end
end
2021-11-03 16:04:50 +01:00
describe " filter by maxRevision " do
2021-01-21 19:04:35 +01:00
let ( :query ) do
" {
demarche ( number : #{procedure.id}) {
id
number
dossiers ( maxRevision : \ " #{ procedure . revisions . last . to_typed_id } \" ) {
nodes {
id
}
}
}
} "
end
it " should be returned " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( demarche : {
id : procedure . to_typed_id ,
number : procedure . id ,
dossiers : {
nodes : procedure . dossiers . order ( :created_at ) . map do | dossier |
{ id : dossier . to_typed_id }
end
}
} )
end
end
2019-09-18 18:45:24 +02:00
end
2021-11-03 16:04:50 +01:00
describe " dossier " do
2021-11-03 17:04:38 +01:00
let ( :dossier ) do
dossier = create ( :dossier ,
:en_construction ,
:with_populated_champs ,
:with_populated_annotations ,
:with_individual ,
procedure : procedure )
create ( :commentaire , :with_file , dossier : dossier , email : 'test@test.com' )
dossier
end
2023-04-13 13:10:23 +02:00
context " for individual " do
2021-11-03 17:00:40 +01:00
let ( :procedure ) { create ( :procedure , :published , :for_individual , :with_service , :with_all_champs , :with_all_annotations , administrateurs : [ admin ] ) }
2020-01-07 17:27:00 +01:00
let ( :query ) do
" {
dossier ( number : #{dossier.id}) {
2019-09-18 18:45:24 +02:00
id
2020-01-07 17:27:00 +01:00
number
state
dateDerniereModification
datePassageEnConstruction
datePassageEnInstruction
dateTraitement
2021-12-06 15:49:17 +01:00
dateDepot
2020-01-07 17:27:00 +01:00
motivation
motivationAttachment {
2019-12-11 12:24:50 +01:00
url
}
2021-08-19 11:23:27 +02:00
demarche {
number
title
state
}
2020-01-07 17:27:00 +01:00
usager {
id
2019-09-26 15:17:58 +02:00
email
}
2020-01-07 17:27:00 +01:00
demandeur {
id
... on PersonnePhysique {
nom
prenom
civilite
dateDeNaissance
}
}
instructeurs {
id
email
}
2020-02-27 18:37:19 +01:00
groupeInstructeur {
id
2020-04-08 19:30:16 +02:00
number
2020-02-27 18:37:19 +01:00
label
}
2020-07-16 12:48:35 +02:00
revision {
id
champDescriptors {
type
}
}
2020-01-07 17:27:00 +01:00
messages {
email
body
attachment {
filename
checksum
byteSize
contentType
}
2024-02-21 03:01:24 +01:00
attachments {
filename
checksum
byteSize
contentType
}
2020-01-07 17:27:00 +01:00
}
avis {
expert {
email
}
question
reponse
dateQuestion
dateReponse
attachment {
url
filename
}
}
champs {
id
label
stringValue
2019-12-11 12:24:50 +01:00
}
2019-09-18 18:45:24 +02:00
}
2020-01-07 17:27:00 +01:00
} "
end
2019-09-18 18:45:24 +02:00
2019-11-21 18:52:07 +01:00
it " should be returned " do
expect ( gql_errors ) . to eq ( nil )
2024-04-15 13:56:03 +02:00
expect ( gql_data [ :dossier ] ) . to include (
2019-11-21 18:52:07 +01:00
id : dossier . to_typed_id ,
number : dossier . id ,
state : 'en_construction' ,
dateDerniereModification : dossier . updated_at . iso8601 ,
datePassageEnConstruction : dossier . en_construction_at . iso8601 ,
2021-12-06 15:49:17 +01:00
dateDepot : dossier . depose_at . iso8601 ,
2019-11-21 18:52:07 +01:00
datePassageEnInstruction : nil ,
dateTraitement : nil ,
motivation : nil ,
2019-12-11 12:24:50 +01:00
motivationAttachment : nil ,
2021-08-19 11:23:27 +02:00
demarche : {
number : dossier . procedure . id ,
title : dossier . procedure . libelle ,
state : 'publiee'
} ,
2019-11-21 18:52:07 +01:00
usager : {
id : dossier . user . to_typed_id ,
email : dossier . user . email
} ,
instructeurs : [
{
id : instructeur . to_typed_id ,
email : instructeur . email
}
] ,
2020-02-27 18:37:19 +01:00
groupeInstructeur : {
id : dossier . groupe_instructeur . to_typed_id ,
2020-04-08 19:30:16 +02:00
number : dossier . groupe_instructeur . id ,
2020-02-27 18:37:19 +01:00
label : dossier . groupe_instructeur . label
} ,
2020-07-16 12:48:35 +02:00
revision : {
id : dossier . revision . to_typed_id ,
champDescriptors : dossier . types_de_champ . map do | tdc |
{
type : tdc . type_champ
}
end
} ,
2019-11-21 18:52:07 +01:00
demandeur : {
id : dossier . individual . to_typed_id ,
nom : dossier . individual . nom ,
prenom : dossier . individual . prenom ,
civilite : 'M' ,
dateDeNaissance : '1991-11-01'
} ,
2024-04-15 13:56:03 +02:00
avis : [ ]
)
expected_champs = dossier . champs_public . map do | champ |
{
id : champ . to_typed_id ,
label : champ . libelle ,
stringValue : champ . for_api_v2
}
end
expect ( gql_data [ :dossier ] [ :champs ] ) . to match_array ( expected_champs )
expected_messages = dossier . commentaires . map do | commentaire |
{
body : commentaire . body ,
attachment : {
2024-02-21 03:01:24 +01:00
filename : commentaire . piece_jointe . first . filename . to_s ,
contentType : commentaire . piece_jointe . first . content_type ,
checksum : commentaire . piece_jointe . first . checksum ,
byteSize : commentaire . piece_jointe . first . byte_size
2024-04-15 13:56:03 +02:00
} ,
2024-02-21 03:01:24 +01:00
attachments : commentaire . piece_jointe . map do | pj |
{
filename : pj . filename . to_s ,
contentType : pj . content_type ,
checksum : pj . checksum ,
byteSize : pj . byte_size
}
end ,
2024-04-15 13:56:03 +02:00
email : commentaire . email
}
end
expect ( gql_data [ :dossier ] [ :messages ] ) . to match_array ( expected_messages )
2022-11-10 22:21:14 +01:00
expect ( gql_data [ :dossier ] [ :champs ] [ 0 ] [ :id ] ) . to eq ( dossier . champs_public [ 0 ] . type_de_champ . to_typed_id )
2019-11-21 18:52:07 +01:00
end
end
2021-11-03 17:00:40 +01:00
context " for entreprise " do
2020-01-07 17:50:49 +01:00
let ( :procedure_for_entreprise ) { create ( :procedure , :published , administrateurs : [ admin ] ) }
let ( :dossier ) { create ( :dossier , :en_construction , :with_entreprise , procedure : procedure_for_entreprise ) }
2019-11-21 18:52:07 +01:00
let ( :query ) do
" {
dossier ( number : #{dossier.id}) {
id
number
usager {
id
email
}
demandeur {
id
... on PersonneMorale {
siret
siegeSocial
2020-09-22 09:26:46 +02:00
numeroVoie
typeVoie
2019-11-21 18:52:07 +01:00
entreprise {
siren
dateCreation
2020-01-28 16:26:02 +01:00
capitalSocial
2020-09-21 20:38:05 +02:00
codeEffectifEntreprise
2021-03-16 12:56:56 +01:00
numeroTvaIntracommunautaire
2019-11-21 18:52:07 +01:00
}
}
}
2019-09-18 18:45:24 +02:00
}
2019-11-21 18:52:07 +01:00
} "
end
2020-12-18 11:21:03 +01:00
2020-09-21 20:39:54 +02:00
context " in the nominal case " do
it " should be returned " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( dossier : {
id : dossier . to_typed_id ,
number : dossier . id ,
usager : {
id : dossier . user . to_typed_id ,
email : dossier . user . email
} ,
demandeur : {
id : dossier . etablissement . to_typed_id ,
siret : dossier . etablissement . siret ,
siegeSocial : dossier . etablissement . siege_social ,
2020-09-22 09:26:46 +02:00
numeroVoie : dossier . etablissement . numero_voie . to_s ,
typeVoie : dossier . etablissement . type_voie . to_s ,
2020-09-21 20:39:54 +02:00
entreprise : {
siren : dossier . etablissement . entreprise_siren ,
dateCreation : dossier . etablissement . entreprise_date_creation . iso8601 ,
capitalSocial : dossier . etablissement . entreprise_capital_social . to_s ,
2021-03-16 12:56:56 +01:00
codeEffectifEntreprise : dossier . etablissement . entreprise_code_effectif_entreprise . to_s ,
numeroTvaIntracommunautaire : dossier . etablissement . entreprise_numero_tva_intracommunautaire
2020-09-21 20:39:54 +02:00
}
}
} )
end
end
2019-11-21 18:52:07 +01:00
2020-10-01 12:41:57 +02:00
context " with links " do
let ( :dossier ) { create ( :dossier , :accepte , :with_attestation , procedure : procedure ) }
let ( :query ) do
" {
dossier ( number : #{dossier.id}) {
id
number
pdf {
url
}
geojson {
url
}
attestation {
url
}
}
} "
end
it " urls should be returned " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data [ :dossier ] [ :pdf ] [ :url ] ) . not_to be_nil
expect ( gql_data [ :dossier ] [ :geojson ] [ :url ] ) . not_to be_nil
expect ( gql_data [ :dossier ] [ :attestation ] [ :url ] ) . not_to be_nil
end
end
2020-09-21 20:39:54 +02:00
context " when there are missing data " do
before do
2020-09-22 09:26:46 +02:00
dossier . etablissement . update! ( entreprise_code_effectif_entreprise : nil , entreprise_capital_social : nil ,
2021-03-16 12:56:56 +01:00
numero_voie : nil , type_voie : nil , entreprise_numero_tva_intracommunautaire : nil )
2020-09-21 20:39:54 +02:00
end
it " should be returned " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( dossier : {
id : dossier . to_typed_id ,
number : dossier . id ,
usager : {
id : dossier . user . to_typed_id ,
email : dossier . user . email
} ,
demandeur : {
id : dossier . etablissement . to_typed_id ,
siret : dossier . etablissement . siret ,
siegeSocial : dossier . etablissement . siege_social ,
2020-09-22 09:26:46 +02:00
numeroVoie : nil ,
typeVoie : nil ,
2020-09-21 20:39:54 +02:00
entreprise : {
siren : dossier . etablissement . entreprise_siren ,
dateCreation : dossier . etablissement . entreprise_date_creation . iso8601 ,
2020-09-21 21:16:58 +02:00
capitalSocial : '-1' ,
2021-03-16 12:56:56 +01:00
codeEffectifEntreprise : nil ,
numeroTvaIntracommunautaire : nil
2020-09-21 20:39:54 +02:00
}
2019-11-21 18:52:07 +01:00
}
2020-09-21 20:39:54 +02:00
} )
end
2019-11-21 18:52:07 +01:00
end
2023-04-04 14:45:22 +02:00
context " error in degraded mode " do
before do
dossier . etablissement . update! ( adresse : nil , siege_social : nil )
end
it " should return an error " do
2023-04-18 09:48:38 +02:00
expect ( gql_errors ) . to eq ( [ { message : " Cannot return null for non-nullable field PersonneMorale.siegeSocial " , extensions : { code : " invalid_null " } } ] )
2023-04-04 14:45:22 +02:00
end
end
2019-09-18 18:45:24 +02:00
end
2020-12-18 11:21:03 +01:00
context " champs " do
2022-08-04 11:39:07 +02:00
let ( :procedure ) { create ( :procedure , :published , :for_individual , administrateurs : [ admin ] , types_de_champ_public : [ { type : :date } , { type : :datetime } ] ) }
2020-12-18 11:21:03 +01:00
let ( :dossier ) { create ( :dossier , :en_construction , procedure : procedure ) }
2022-11-10 22:21:14 +01:00
let ( :champ_date ) { dossier . champs_public . first }
let ( :champ_datetime ) { dossier . champs_public . second }
2020-12-18 11:21:03 +01:00
before do
champ_date . update ( value : '2019-07-10' )
champ_datetime . update ( value : '15/09/1962 15:35' )
end
context " with Date " do
let ( :query ) do
" {
dossier ( number : #{dossier.id}) {
champs {
id
label
... on DateChamp {
value
}
}
}
} "
end
it " should be returned " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( dossier : {
champs : [
{
id : champ_date . to_typed_id ,
label : champ_date . libelle ,
value : '2019-07-10T00:00:00+02:00'
} ,
{
id : champ_datetime . to_typed_id ,
label : champ_datetime . libelle ,
value : '1962-09-15T15:35:00+01:00'
}
]
} )
end
end
context " with Datetime " do
let ( :query ) do
" {
dossier ( number : #{dossier.id}) {
champs {
id
label
... on DateChamp {
value
date
}
... on DatetimeChamp {
datetime
}
}
}
} "
end
it " should be returned " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( dossier : {
champs : [
{
id : champ_date . to_typed_id ,
label : champ_date . libelle ,
value : '2019-07-10T00:00:00+02:00' ,
date : '2019-07-10'
} ,
{
id : champ_datetime . to_typed_id ,
label : champ_datetime . libelle ,
datetime : '1962-09-15T15:35:00+01:00'
}
]
} )
end
end
end
2019-09-18 18:45:24 +02:00
end
2019-09-17 18:11:34 +02:00
2021-11-03 16:04:50 +01:00
describe " deletedDossiers " do
2021-05-26 13:50:02 +02:00
let ( :query ) do
" {
demarche ( number : #{procedure.id}) {
deletedDossiers {
nodes {
id
number
state
reason
dateSupression
}
}
}
} "
end
let ( :deleted_dossier ) { create ( :deleted_dossier , procedure : procedure ) }
before { deleted_dossier }
it " should be returned " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( demarche : {
deletedDossiers : {
nodes : [
{
id : deleted_dossier . to_typed_id ,
number : deleted_dossier . dossier_id ,
state : deleted_dossier . state ,
reason : deleted_dossier . reason ,
dateSupression : deleted_dossier . deleted_at . iso8601
}
]
}
} )
end
end
2022-11-07 14:24:28 +01:00
describe " champ piece_justificative " do
2021-06-02 15:16:35 +02:00
let ( :champ ) { create ( :champ_piece_justificative , dossier : dossier ) }
let ( :byte_size ) { 2712286911 }
2022-11-07 14:24:28 +01:00
context " with deprecated file field " do
2021-06-02 15:16:35 +02:00
let ( :query ) do
" {
dossier ( number : #{dossier.id}) {
champs ( id : \ " #{ champ . to_typed_id } \" ) {
... on PieceJustificativeChamp {
file { byteSize }
}
}
}
} "
end
it {
expect ( gql_errors ) . to be_nil
expect ( gql_data ) . to eq ( dossier : { champs : [ { file : { byteSize : 4 } } ] } )
}
end
2022-11-07 14:24:28 +01:00
context " byteSize " do
let ( :query ) do
" {
dossier ( number : #{dossier.id}) {
champs ( id : \ " #{ champ . to_typed_id } \" ) {
... on PieceJustificativeChamp {
files { byteSize }
}
}
}
} "
end
it {
expect ( gql_errors ) . to be_nil
expect ( gql_data ) . to eq ( dossier : { champs : [ { files : [ { byteSize : 4 } ] } ] } )
}
end
2021-11-03 17:00:40 +01:00
context " when the file is really big " do
2021-06-02 15:16:35 +02:00
before do
2022-11-07 14:24:28 +01:00
champ . piece_justificative_file . first . blob . update ( byte_size : byte_size )
2021-06-02 15:16:35 +02:00
end
context " byteSize " do
let ( :query ) do
" {
dossier ( number : #{dossier.id}) {
champs ( id : \ " #{ champ . to_typed_id } \" ) {
... on PieceJustificativeChamp {
2022-11-07 14:24:28 +01:00
files { byteSize }
2021-06-02 15:16:35 +02:00
}
}
}
} "
end
it {
expect ( gql_errors ) . not_to be_nil
}
end
context " byteSizeBigInt " do
let ( :query ) do
" {
dossier ( number : #{dossier.id}) {
champs ( id : \ " #{ champ . to_typed_id } \" ) {
... on PieceJustificativeChamp {
2022-11-07 14:24:28 +01:00
files { byteSizeBigInt }
2021-06-02 15:16:35 +02:00
}
}
}
} "
end
it {
expect ( gql_errors ) . to be_nil
2022-11-07 14:24:28 +01:00
expect ( gql_data ) . to eq ( dossier : { champs : [ { files : [ { byteSizeBigInt : '2712286911' } ] } ] } )
2021-06-02 15:16:35 +02:00
}
end
end
end
2021-11-03 16:04:50 +01:00
describe " groupeInstructeur " do
2020-04-08 19:30:16 +02:00
let ( :groupe_instructeur ) { procedure . groupe_instructeurs . first }
let ( :query ) do
" {
groupeInstructeur ( number : #{groupe_instructeur.id}) {
id
number
label
dossiers {
nodes {
id
}
}
}
} "
end
it " should be returned " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( groupeInstructeur : {
id : groupe_instructeur . to_typed_id ,
number : groupe_instructeur . id ,
label : groupe_instructeur . label ,
dossiers : {
nodes : dossiers . map { | dossier | { id : dossier . to_typed_id } }
}
} )
end
end
2021-11-03 16:04:50 +01:00
describe " mutations " do
2019-11-12 15:51:51 +01:00
describe 'dossierEnvoyerMessage' do
2022-10-29 12:35:52 +02:00
let ( :query ) do
" mutation($input: DossierEnvoyerMessageInput!) {
dossierEnvoyerMessage ( input : $input ) {
message {
body
2019-11-12 15:51:51 +01:00
}
2022-10-29 12:35:52 +02:00
errors {
message
}
}
} "
end
let ( :variables ) { { input : input } }
let ( :input ) do
{
dossierId : dossier_id ,
instructeurId : instructeur_id ,
body : input_body ,
attachment : attachment
}
end
let ( :dossier_id ) { dossier . to_typed_id }
let ( :instructeur_id ) { instructeur . to_typed_id }
let ( :input_body ) { " Bonjour " }
let ( :attachment ) { nil }
context 'success' do
let ( :attachment ) { blob . signed_id }
2019-11-12 15:51:51 +01:00
it " should post a message " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( dossierEnvoyerMessage : {
message : {
body : " Bonjour "
2022-10-29 12:35:52 +02:00
} ,
errors : nil
2019-11-12 15:51:51 +01:00
} )
end
end
2023-07-12 12:56:16 +02:00
context 'with correction' do
let ( :input ) { super ( ) . merge ( correction : :incorrect ) }
it 'should create a correction' do
expect ( gql_data ) . to eq ( dossierEnvoyerMessage : {
message : {
body : " Bonjour "
} ,
errors : nil
} )
expect ( dossier ) . to be_pending_correction
expect ( dossier . pending_correction ) . to be_dossier_incorrect
expect ( dossier . pending_correction . commentaire . body ) . to eq ( " Bonjour " )
end
end
2019-11-12 15:51:51 +01:00
context 'schema error' do
2022-10-29 12:35:52 +02:00
let ( :input ) do
{
dossierId : dossier_id ,
instructeurId : instructeur_id
}
2019-11-12 15:51:51 +01:00
end
it " should fail " do
expect ( gql_data ) . to eq ( nil )
expect ( gql_errors ) . not_to eq ( nil )
2022-10-29 12:35:52 +02:00
expect ( body [ :errors ] . first [ :message ] ) . to eq ( " Variable $input of type DossierEnvoyerMessageInput! was provided invalid value for body (Expected value to not be null) " )
expect ( body [ :errors ] . first . key? ( :backtrace ) ) . to be_falsey
2019-11-12 15:51:51 +01:00
end
end
2022-10-29 12:35:52 +02:00
context 'variables error' do
let ( :variables ) { " { " }
it " should fail " do
expect ( gql_data ) . to eq ( nil )
expect ( gql_errors ) . not_to eq ( nil )
2024-02-22 14:56:10 +01:00
expect ( body [ :errors ] . first [ :message ] ) . to eq ( " unexpected token at '{' " )
2022-10-29 12:35:52 +02:00
expect ( body [ :errors ] . first . key? ( :backtrace ) ) . to be_falsey
2019-11-12 15:51:51 +01:00
end
2022-10-29 12:35:52 +02:00
end
context 'validation error' do
let ( :input_body ) { " " }
2019-11-12 15:51:51 +01:00
it " should fail " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( dossierEnvoyerMessage : {
2022-12-20 17:51:36 +01:00
errors : [ { message : " Le champ « Votre message » ne peut être vide " } ] ,
2019-11-12 15:51:51 +01:00
message : nil
} )
end
end
2020-11-12 20:07:42 +01:00
context 'upload error' do
2022-10-29 12:35:52 +02:00
let ( :attachment ) { 'fake' }
2020-11-12 20:07:42 +01:00
it " should fail " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( dossierEnvoyerMessage : {
2020-12-10 21:55:45 +01:00
errors : [ { message : " L’ identifiant du fichier téléversé est invalide " } ] ,
2020-11-12 20:07:42 +01:00
message : nil
} )
end
end
2019-11-12 15:51:51 +01:00
end
2019-11-13 20:01:58 +01:00
describe 'dossierAccepter' do
2020-01-07 17:47:22 +01:00
let ( :dossier ) { create ( :dossier , :en_instruction , :with_individual , procedure : procedure ) }
2019-11-13 20:01:58 +01:00
let ( :query ) do
" mutation {
dossierAccepter ( input : {
dossierId : \ " #{ dossier . to_typed_id } \" ,
instructeurId : \ " #{ instructeur . to_typed_id } \" ,
2019-12-11 13:14:18 +01:00
motivation : \ " Parce que \" ,
justificatif : \ " #{ blob . signed_id } \"
2019-11-13 20:01:58 +01:00
} ) {
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
2020-01-07 17:47:22 +01:00
let ( :dossier ) { create ( :dossier , :refuse , :with_individual , procedure : procedure ) }
2019-11-13 20:01:58 +01:00
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
2019-09-17 18:11:34 +02:00
let ( :query ) do
" mutation {
createDirectUpload ( input : {
dossierId : \ " #{ dossier . to_typed_id } \" ,
2019-12-11 13:14:18 +01:00
filename : \ " #{ blob_info [ :filename ] } \" ,
byteSize : #{blob_info[:byte_size]},
checksum : \ " #{ blob_info [ :checksum ] } \" ,
contentType : \ " #{ blob_info [ :content_type ] } \"
2019-09-17 18:11:34 +02:00
} ) {
directUpload {
url
headers
blobId
signedBlobId
}
}
} "
end
2020-12-10 21:55:45 +01:00
let ( :attach_query ) do
" mutation {
dossierEnvoyerMessage ( input : {
dossierId : \ " #{ dossier . to_typed_id } \" ,
instructeurId : \ " #{ instructeur . to_typed_id } \" ,
body : \ " Hello world \" ,
attachment : \ " #{ direct_upload_blob_id } \"
} ) {
message {
body
}
errors {
message
}
}
} "
end
let ( :attach_query_exec ) { post :execute , params : { query : attach_query } }
let ( :attach_query_body ) { JSON . parse ( attach_query_exec . body , symbolize_names : true ) }
let ( :attach_query_data ) { attach_query_body [ :data ] }
let ( :direct_upload_data ) { gql_data [ :createDirectUpload ] [ :directUpload ] }
let ( :direct_upload_blob_id ) { direct_upload_data [ :signedBlobId ] }
2019-09-17 18:11:34 +02:00
it " should initiate a direct upload " do
expect ( gql_errors ) . to eq ( nil )
data = gql_data [ :createDirectUpload ] [ :directUpload ]
expect ( data [ :url ] ) . not_to be_nil
expect ( data [ :headers ] ) . not_to be_nil
expect ( data [ :blobId ] ) . not_to be_nil
expect ( data [ :signedBlobId ] ) . not_to be_nil
end
2020-12-10 21:55:45 +01:00
it " wrong hash error " do
blob = ActiveStorage :: Blob . find direct_upload_data [ :blobId ]
blob . service . upload blob . key , StringIO . new ( 'toto' )
expect ( attach_query_data ) . to eq ( dossierEnvoyerMessage : {
errors : [ { message : " Le hash du fichier téléversé est invalide " } ] ,
message : nil
} )
end
2019-09-17 18:11:34 +02:00
end
2020-02-21 11:57:36 +01:00
describe 'dossierChangerGroupeInstructeur' do
let ( :query ) do
" mutation {
dossierChangerGroupeInstructeur ( input : {
dossierId : \ " #{ dossier . to_typed_id } \" ,
groupeInstructeurId : \ " #{ dossier . groupe_instructeur . to_typed_id } \"
} ) {
errors {
message
}
}
} "
end
it " validation error " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( dossierChangerGroupeInstructeur : {
errors : [ { message : " Le dossier est déjà avec le grope instructeur: 'défaut' " } ]
} )
end
context " should changer groupe instructeur " do
2023-06-29 11:45:20 +02:00
let! ( :new_groupe_instructeur ) { create ( :groupe_instructeur , label : 'new groupe instructeur' , procedure : procedure ) }
2020-02-21 11:57:36 +01:00
let ( :query ) do
" mutation {
dossierChangerGroupeInstructeur ( input : {
dossierId : \ " #{ dossier . to_typed_id } \" ,
groupeInstructeurId : \ " #{ new_groupe_instructeur . to_typed_id } \"
} ) {
errors {
message
}
}
} "
end
it " change made " do
expect ( gql_errors ) . to eq ( nil )
expect ( gql_data ) . to eq ( dossierChangerGroupeInstructeur : {
errors : nil
} )
end
end
end
2020-08-19 10:42:42 +02:00
2020-07-28 18:16:03 +02:00
describe 'dossierModifierAnnotation' do
2021-11-03 17:00:40 +01:00
let ( :procedure ) { create ( :procedure , :published , :for_individual , :with_service , :with_all_annotations , administrateurs : [ admin ] ) }
2020-07-28 18:16:03 +02:00
describe 'text' do
let ( :query ) do
" mutation {
dossierModifierAnnotationText ( input : {
dossierId : \ " #{ dossier . to_typed_id } \" ,
2022-11-28 17:41:46 +01:00
annotationId : \ " #{ dossier . champs_private . find { | c | c . type == 'Champs::TextChamp' } . to_typed_id } \" ,
2020-07-28 18:16:03 +02:00
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
2019-09-17 18:11:34 +02:00
end
2019-09-18 18:45:24 +02:00
end
context " when not authenticated " do
it " should return error " do
expect ( gql_data ) . to eq ( nil )
expect ( gql_errors ) . not_to eq ( nil )
end
2021-11-03 16:04:50 +01:00
describe " dossier " do
2019-09-18 18:45:24 +02:00
let ( :query ) { " { dossier(number: #{ dossier . id } ) { id number usager { email } } } " }
it " should return error " do
expect ( gql_data ) . to eq ( nil )
expect ( gql_errors ) . not_to eq ( nil )
end
end
2019-11-07 16:30:37 +01:00
2021-11-03 16:04:50 +01:00
describe " mutation " do
2019-11-07 16:30:37 +01:00
let ( :query ) do
" mutation {
dossierEnvoyerMessage ( input : {
dossierId : \ " #{ dossier . to_typed_id } \" ,
instructeurId : \ " #{ instructeur . to_typed_id } \" ,
body : \ " Bonjour \"
} ) {
message {
body
}
2023-08-03 10:23:05 +02:00
errors {
message
}
2019-11-07 16:30:37 +01:00
}
} "
end
it " should return error " do
2023-08-03 10:23:05 +02:00
expect ( gql_data [ :dossierEnvoyerMessage ] [ :errors ] . first [ :message ] ) . to eq ( " Le jeton utilisé est configuré seulement en lecture " )
2019-11-07 16:30:37 +01:00
end
end
2019-09-18 18:45:24 +02:00
end
end