Merge pull request #7984 from tchak/graphql-stored-operations
feat(graphql): implement stored queries
This commit is contained in:
commit
7e97199b7e
4 changed files with 872 additions and 11 deletions
|
@ -2,9 +2,7 @@ class API::V2::GraphqlController < API::V2::BaseController
|
||||||
include GraphqlOperationLogConcern
|
include GraphqlOperationLogConcern
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
variables = ensure_hash(params[:variables])
|
result = API::V2::Schema.execute(query,
|
||||||
|
|
||||||
result = API::V2::Schema.execute(params[:query],
|
|
||||||
variables: variables,
|
variables: variables,
|
||||||
context: context,
|
context: context,
|
||||||
operation_name: params[:operationName])
|
operation_name: params[:operationName])
|
||||||
|
@ -26,7 +24,7 @@ class API::V2::GraphqlController < API::V2::BaseController
|
||||||
super
|
super
|
||||||
|
|
||||||
payload.merge!({
|
payload.merge!({
|
||||||
graphql_operation: operation_log(params[:query], params[:operationName], to_unsafe_hash(params[:variables]))
|
graphql_operation: operation_log(query(fallback: ''), params[:operationName], to_unsafe_hash(params[:variables]))
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,6 +39,18 @@ class API::V2::GraphqlController < API::V2::BaseController
|
||||||
}, status: 400
|
}, status: 400
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def query(fallback: nil)
|
||||||
|
if params[:queryId].present?
|
||||||
|
API::V2::StoredQuery.get(params[:queryId], fallback: fallback)
|
||||||
|
else
|
||||||
|
params[:query]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def variables
|
||||||
|
ensure_hash(params[:variables])
|
||||||
|
end
|
||||||
|
|
||||||
# Handle form data, JSON body, or a blank value
|
# Handle form data, JSON body, or a blank value
|
||||||
def ensure_hash(ambiguous_param)
|
def ensure_hash(ambiguous_param)
|
||||||
case ambiguous_param
|
case ambiguous_param
|
||||||
|
@ -99,11 +109,7 @@ class API::V2::GraphqlController < API::V2::BaseController
|
||||||
|
|
||||||
def handle_error_in_production(exception)
|
def handle_error_in_production(exception)
|
||||||
id = SecureRandom.uuid
|
id = SecureRandom.uuid
|
||||||
Sentry.capture_exception(exception, extra: {
|
Sentry.capture_exception(exception, extra: { exception_id: id })
|
||||||
exception_id: id,
|
|
||||||
query: params[:query],
|
|
||||||
variables: params[:variables].to_json
|
|
||||||
})
|
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
errors: [
|
errors: [
|
||||||
|
|
693
app/graphql/api/v2/stored_query.rb
Normal file
693
app/graphql/api/v2/stored_query.rb
Normal file
|
@ -0,0 +1,693 @@
|
||||||
|
class API::V2::StoredQuery
|
||||||
|
def self.get(query_id, fallback: nil)
|
||||||
|
case query_id
|
||||||
|
when 'ds-query-v2'
|
||||||
|
QUERY_V2
|
||||||
|
when 'ds-mutation-v2'
|
||||||
|
MUTATION_V2
|
||||||
|
else
|
||||||
|
if fallback.nil?
|
||||||
|
raise GraphQL::ExecutionError.new("No query with id \"#{query_id}\"")
|
||||||
|
else
|
||||||
|
fallback
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
QUERY_V2 = <<-'GRAPHQL'
|
||||||
|
query getDemarche(
|
||||||
|
$demarcheNumber: Int!
|
||||||
|
$state: DossierState
|
||||||
|
$order: Order
|
||||||
|
$first: Int
|
||||||
|
$after: String
|
||||||
|
$archived: Boolean
|
||||||
|
$revision: ID
|
||||||
|
$createdSince: ISO8601DateTime
|
||||||
|
$updatedSince: ISO8601DateTime
|
||||||
|
$deletedOrder: Order
|
||||||
|
$deletedFirst: Int
|
||||||
|
$deletedAfter: String
|
||||||
|
$deletedSince: ISO8601DateTime
|
||||||
|
$includeGroupeInstructeurs: Boolean = false
|
||||||
|
$includeDossiers: Boolean = false
|
||||||
|
$includeDeletedDossiers: Boolean = false
|
||||||
|
$includeRevision: Boolean = false
|
||||||
|
$includeService: Boolean = false
|
||||||
|
$includeChamps: Boolean = true
|
||||||
|
$includeAnotations: Boolean = true
|
||||||
|
$includeTraitements: Boolean = true
|
||||||
|
$includeInstructeurs: Boolean = true
|
||||||
|
$includeAvis: Boolean = false
|
||||||
|
$includeMessages: Boolean = false
|
||||||
|
$includeGeometry: Boolean = false
|
||||||
|
) {
|
||||||
|
demarche(number: $demarcheNumber) {
|
||||||
|
id
|
||||||
|
number
|
||||||
|
title
|
||||||
|
state
|
||||||
|
declarative
|
||||||
|
dateCreation
|
||||||
|
dateFermeture
|
||||||
|
publishedRevision @include(if: $includeRevision) {
|
||||||
|
...RevisionFragment
|
||||||
|
}
|
||||||
|
groupeInstructeurs @include(if: $includeGroupeInstructeurs) {
|
||||||
|
...GroupeInstructeurFragment
|
||||||
|
}
|
||||||
|
service @include(if: $includeService) {
|
||||||
|
...ServiceFragment
|
||||||
|
}
|
||||||
|
dossiers(
|
||||||
|
state: $state
|
||||||
|
order: $order
|
||||||
|
first: $first
|
||||||
|
after: $after
|
||||||
|
archived: $archived
|
||||||
|
createdSince: $createdSince
|
||||||
|
updatedSince: $updatedSince
|
||||||
|
revision: $revision
|
||||||
|
) @include(if: $includeDossiers) {
|
||||||
|
pageInfo {
|
||||||
|
...PageInfoFragment
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
...DossierFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deletedDossiers(
|
||||||
|
order: $deletedOrder
|
||||||
|
first: $deletedFirst
|
||||||
|
after: $deletedAfter
|
||||||
|
deletedSince: $deletedSince
|
||||||
|
) @include(if: $includeDeletedDossiers) {
|
||||||
|
pageInfo {
|
||||||
|
...PageInfoFragment
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
...DeletedDossierFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query getGroupeInstructeur(
|
||||||
|
$groupeInstructeurNumber: Int!
|
||||||
|
$state: DossierState
|
||||||
|
$order: Order
|
||||||
|
$first: Int
|
||||||
|
$after: String
|
||||||
|
$createdSince: ISO8601DateTime
|
||||||
|
$updatedSince: ISO8601DateTime
|
||||||
|
$includeDossiers: Boolean = false
|
||||||
|
$includeChamps: Boolean = true
|
||||||
|
$includeAnotations: Boolean = true
|
||||||
|
$includeTraitements: Boolean = true
|
||||||
|
$includeInstructeurs: Boolean = true
|
||||||
|
$includeAvis: Boolean = false
|
||||||
|
$includeMessages: Boolean = false
|
||||||
|
$includeGeometry: Boolean = false
|
||||||
|
) {
|
||||||
|
groupeInstructeur(number: $groupeInstructeurNumber) {
|
||||||
|
id
|
||||||
|
number
|
||||||
|
label
|
||||||
|
instructeurs @include(if: $includeInstructeurs) {
|
||||||
|
id
|
||||||
|
email
|
||||||
|
}
|
||||||
|
dossiers(
|
||||||
|
state: $state
|
||||||
|
order: $order
|
||||||
|
first: $first
|
||||||
|
after: $after
|
||||||
|
createdSince: $createdSince
|
||||||
|
updatedSince: $updatedSince
|
||||||
|
) @include(if: $includeDossiers) {
|
||||||
|
pageInfo {
|
||||||
|
...PageInfoFragment
|
||||||
|
}
|
||||||
|
nodes {
|
||||||
|
...DossierFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query getDossier(
|
||||||
|
$dossierNumber: Int!
|
||||||
|
$includeRevision: Boolean = false
|
||||||
|
$includeService: Boolean = false
|
||||||
|
$includeChamps: Boolean = true
|
||||||
|
$includeAnotations: Boolean = true
|
||||||
|
$includeTraitements: Boolean = true
|
||||||
|
$includeInstructeurs: Boolean = true
|
||||||
|
$includeAvis: Boolean = false
|
||||||
|
$includeMessages: Boolean = false
|
||||||
|
$includeGeometry: Boolean = false
|
||||||
|
) {
|
||||||
|
dossier(number: $dossierNumber) {
|
||||||
|
...DossierFragment
|
||||||
|
demarche {
|
||||||
|
...DemarcheDescriptorFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment ServiceFragment on Service {
|
||||||
|
nom
|
||||||
|
siret
|
||||||
|
organisme
|
||||||
|
typeOrganisme
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment GroupeInstructeurFragment on GroupeInstructeur {
|
||||||
|
id
|
||||||
|
number
|
||||||
|
label
|
||||||
|
instructeurs @include(if: $includeInstructeurs) {
|
||||||
|
id
|
||||||
|
email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment DossierFragment on Dossier {
|
||||||
|
id
|
||||||
|
number
|
||||||
|
archived
|
||||||
|
state
|
||||||
|
dateDerniereModification
|
||||||
|
dateDepot
|
||||||
|
datePassageEnConstruction
|
||||||
|
datePassageEnInstruction
|
||||||
|
dateTraitement
|
||||||
|
dateExpiration
|
||||||
|
dateSuppressionParUsager
|
||||||
|
motivation
|
||||||
|
motivationAttachment {
|
||||||
|
...FileFragment
|
||||||
|
}
|
||||||
|
attestation {
|
||||||
|
...FileFragment
|
||||||
|
}
|
||||||
|
pdf {
|
||||||
|
url
|
||||||
|
}
|
||||||
|
usager {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
groupeInstructeur {
|
||||||
|
...GroupeInstructeurFragment
|
||||||
|
}
|
||||||
|
demandeur {
|
||||||
|
... on PersonnePhysique {
|
||||||
|
civilite
|
||||||
|
nom
|
||||||
|
prenom
|
||||||
|
dateDeNaissance
|
||||||
|
}
|
||||||
|
...PersonneMoraleFragment
|
||||||
|
}
|
||||||
|
demarche {
|
||||||
|
revision {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instructeurs @include(if: $includeInstructeurs) {
|
||||||
|
id
|
||||||
|
email
|
||||||
|
}
|
||||||
|
traitements @include(if: $includeTraitements) {
|
||||||
|
state
|
||||||
|
emailAgentTraitant
|
||||||
|
dateTraitement
|
||||||
|
motivation
|
||||||
|
}
|
||||||
|
champs @include(if: $includeChamps) {
|
||||||
|
...ChampFragment
|
||||||
|
...RootChampFragment
|
||||||
|
}
|
||||||
|
annotations @include(if: $includeAnotations) {
|
||||||
|
...ChampFragment
|
||||||
|
...RootChampFragment
|
||||||
|
}
|
||||||
|
avis @include(if: $includeAvis) {
|
||||||
|
...AvisFragment
|
||||||
|
}
|
||||||
|
messages @include(if: $includeMessages) {
|
||||||
|
...MessageFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment DemarcheDescriptorFragment on DemarcheDescriptor {
|
||||||
|
id
|
||||||
|
number
|
||||||
|
title
|
||||||
|
description
|
||||||
|
state
|
||||||
|
declarative
|
||||||
|
dateCreation
|
||||||
|
datePublication
|
||||||
|
dateDerniereModification
|
||||||
|
dateDepublication
|
||||||
|
dateFermeture
|
||||||
|
service @include(if: $includeService) {
|
||||||
|
...ServiceFragment
|
||||||
|
}
|
||||||
|
revision @include(if: $includeRevision) {
|
||||||
|
...RevisionFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment DeletedDossierFragment on DeletedDossier {
|
||||||
|
id
|
||||||
|
number
|
||||||
|
dateSupression
|
||||||
|
state
|
||||||
|
reason
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment RevisionFragment on Revision {
|
||||||
|
id
|
||||||
|
datePublication
|
||||||
|
champDescriptors {
|
||||||
|
...ChampDescriptorFragment
|
||||||
|
champDescriptors {
|
||||||
|
...ChampDescriptorFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
annotationDescriptors {
|
||||||
|
...ChampDescriptorFragment
|
||||||
|
champDescriptors {
|
||||||
|
...ChampDescriptorFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment ChampDescriptorFragment on ChampDescriptor {
|
||||||
|
id
|
||||||
|
type
|
||||||
|
label
|
||||||
|
description
|
||||||
|
required
|
||||||
|
options
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment AvisFragment on Avis {
|
||||||
|
id
|
||||||
|
question
|
||||||
|
reponse
|
||||||
|
dateQuestion
|
||||||
|
dateReponse
|
||||||
|
claimant {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
expert {
|
||||||
|
email
|
||||||
|
}
|
||||||
|
attachment {
|
||||||
|
...FileFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment MessageFragment on Message {
|
||||||
|
id
|
||||||
|
email
|
||||||
|
body
|
||||||
|
createdAt
|
||||||
|
attachment {
|
||||||
|
...FileFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment GeoAreaFragment on GeoArea {
|
||||||
|
id
|
||||||
|
source
|
||||||
|
description
|
||||||
|
geometry @include(if: $includeGeometry) {
|
||||||
|
type
|
||||||
|
coordinates
|
||||||
|
}
|
||||||
|
... on ParcelleCadastrale {
|
||||||
|
commune
|
||||||
|
numero
|
||||||
|
section
|
||||||
|
prefixe
|
||||||
|
surface
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment RootChampFragment on Champ {
|
||||||
|
... on RepetitionChamp {
|
||||||
|
rows {
|
||||||
|
champs {
|
||||||
|
...ChampFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on CarteChamp {
|
||||||
|
geoAreas {
|
||||||
|
...GeoAreaFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on DossierLinkChamp {
|
||||||
|
dossier {
|
||||||
|
id
|
||||||
|
number
|
||||||
|
state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment ChampFragment on Champ {
|
||||||
|
id
|
||||||
|
__typename
|
||||||
|
label
|
||||||
|
stringValue
|
||||||
|
... on DateChamp {
|
||||||
|
date
|
||||||
|
}
|
||||||
|
... on DatetimeChamp {
|
||||||
|
datetime
|
||||||
|
}
|
||||||
|
... on CheckboxChamp {
|
||||||
|
checked: value
|
||||||
|
}
|
||||||
|
... on DecimalNumberChamp {
|
||||||
|
decimalNumber: value
|
||||||
|
}
|
||||||
|
... on IntegerNumberChamp {
|
||||||
|
integerNumber: value
|
||||||
|
}
|
||||||
|
... on CiviliteChamp {
|
||||||
|
civilite: value
|
||||||
|
}
|
||||||
|
... on LinkedDropDownListChamp {
|
||||||
|
primaryValue
|
||||||
|
secondaryValue
|
||||||
|
}
|
||||||
|
... on MultipleDropDownListChamp {
|
||||||
|
values
|
||||||
|
}
|
||||||
|
... on PieceJustificativeChamp {
|
||||||
|
file {
|
||||||
|
...FileFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on AddressChamp {
|
||||||
|
address {
|
||||||
|
...AddressFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on CommuneChamp {
|
||||||
|
commune {
|
||||||
|
name
|
||||||
|
code
|
||||||
|
}
|
||||||
|
departement {
|
||||||
|
name
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on SiretChamp {
|
||||||
|
etablissement {
|
||||||
|
...PersonneMoraleFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment PersonneMoraleFragment on PersonneMorale {
|
||||||
|
siret
|
||||||
|
siegeSocial
|
||||||
|
naf
|
||||||
|
libelleNaf
|
||||||
|
address {
|
||||||
|
...AddressFragment
|
||||||
|
}
|
||||||
|
entreprise {
|
||||||
|
siren
|
||||||
|
capitalSocial
|
||||||
|
numeroTvaIntracommunautaire
|
||||||
|
formeJuridique
|
||||||
|
formeJuridiqueCode
|
||||||
|
nomCommercial
|
||||||
|
raisonSociale
|
||||||
|
siretSiegeSocial
|
||||||
|
codeEffectifEntreprise
|
||||||
|
dateCreation
|
||||||
|
nom
|
||||||
|
prenom
|
||||||
|
attestationFiscaleAttachment {
|
||||||
|
...FileFragment
|
||||||
|
}
|
||||||
|
attestationSocialeAttachment {
|
||||||
|
...FileFragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
association {
|
||||||
|
rna
|
||||||
|
titre
|
||||||
|
objet
|
||||||
|
dateCreation
|
||||||
|
dateDeclaration
|
||||||
|
datePublication
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment FileFragment on File {
|
||||||
|
filename
|
||||||
|
contentType
|
||||||
|
checksum
|
||||||
|
byteSize: byteSizeBigInt
|
||||||
|
url
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment AddressFragment on Address {
|
||||||
|
label
|
||||||
|
type
|
||||||
|
streetAddress
|
||||||
|
streetNumber
|
||||||
|
streetName
|
||||||
|
postalCode
|
||||||
|
cityName
|
||||||
|
cityCode
|
||||||
|
departmentName
|
||||||
|
departmentCode
|
||||||
|
regionName
|
||||||
|
regionCode
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment PageInfoFragment on PageInfo {
|
||||||
|
hasPreviousPage
|
||||||
|
hasNextPage
|
||||||
|
endCursor
|
||||||
|
}
|
||||||
|
GRAPHQL
|
||||||
|
|
||||||
|
MUTATION_V2 = <<-'GRAPHQL'
|
||||||
|
mutation dossierArchiver($input: DossierArchiverInput!) {
|
||||||
|
dossierArchiver(input: $input) {
|
||||||
|
dossier {
|
||||||
|
id
|
||||||
|
archived
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierPasserEnInstruction($input: DossierPasserEnInstructionInput!) {
|
||||||
|
dossierPasserEnInstruction(input: $input) {
|
||||||
|
dossier {
|
||||||
|
id
|
||||||
|
state
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierRepasserEnConstruction(
|
||||||
|
$input: DossierRepasserEnConstructionInput!
|
||||||
|
) {
|
||||||
|
dossierRepasserEnConstruction(input: $input) {
|
||||||
|
dossier {
|
||||||
|
id
|
||||||
|
state
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierAccepter($input: DossierAccepterInput!) {
|
||||||
|
dossierAccepter(input: $input) {
|
||||||
|
dossier {
|
||||||
|
id
|
||||||
|
state
|
||||||
|
attestation {
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierRefuser($input: DossierRefuserInput!) {
|
||||||
|
dossierRefuser(input: $input) {
|
||||||
|
dossier {
|
||||||
|
id
|
||||||
|
state
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierClasserSansSuite($input: DossierClasserSansSuiteInput!) {
|
||||||
|
dossierClasserSansSuite(input: $input) {
|
||||||
|
dossier {
|
||||||
|
id
|
||||||
|
state
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierRepasserEnInstruction(
|
||||||
|
$input: DossierRepasserEnInstructionInput!
|
||||||
|
) {
|
||||||
|
dossierRepasserEnInstruction(input: $input) {
|
||||||
|
dossier {
|
||||||
|
id
|
||||||
|
state
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierEnvoyerMessage($input: DossierEnvoyerMessageInput!) {
|
||||||
|
dossierEnvoyerMessage(input: $input) {
|
||||||
|
message {
|
||||||
|
id
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierModifierAnnotationText(
|
||||||
|
$input: DossierModifierAnnotationTextInput!
|
||||||
|
) {
|
||||||
|
dossierModifierAnnotationText(input: $input) {
|
||||||
|
annotation {
|
||||||
|
id
|
||||||
|
value: stringValue
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierModifierAnnotationCheckbox(
|
||||||
|
$input: DossierModifierAnnotationCheckboxInput!
|
||||||
|
) {
|
||||||
|
dossierModifierAnnotationCheckbox(input: $input) {
|
||||||
|
annotation {
|
||||||
|
id
|
||||||
|
... on CheckboxChamp {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierModifierAnnotationDate(
|
||||||
|
$input: DossierModifierAnnotationDateInput!
|
||||||
|
) {
|
||||||
|
dossierModifierAnnotationDate(input: $input) {
|
||||||
|
annotation {
|
||||||
|
id
|
||||||
|
... on DateChamp {
|
||||||
|
value: date
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierModifierAnnotationDateTime(
|
||||||
|
$input: DossierModifierAnnotationDatetimeInput!
|
||||||
|
) {
|
||||||
|
dossierModifierAnnotationDatetime(input: $input) {
|
||||||
|
annotation {
|
||||||
|
id
|
||||||
|
... on DatetimeChamp {
|
||||||
|
value: datetime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierModifierAnnotationIntegerNumber(
|
||||||
|
$input: DossierModifierAnnotationIntegerNumberInput!
|
||||||
|
) {
|
||||||
|
dossierModifierAnnotationIntegerNumber(input: $input) {
|
||||||
|
annotation {
|
||||||
|
id
|
||||||
|
... on IntegerNumberChamp {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation dossierModifierAnnotationAjouterLigne(
|
||||||
|
$input: DossierModifierAnnotationAjouterLigneInput!
|
||||||
|
) {
|
||||||
|
dossierModifierAnnotationAjouterLigne(input: $input) {
|
||||||
|
annotation {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutation createDirectUpload($input: CreateDirectUploadInput!) {
|
||||||
|
createDirectUpload(input: $input) {
|
||||||
|
directUpload {
|
||||||
|
signedBlobId
|
||||||
|
headers
|
||||||
|
url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GRAPHQL
|
||||||
|
end
|
|
@ -4,7 +4,9 @@ class ApplicationRecord < ActiveRecord::Base
|
||||||
def self.record_from_typed_id(id)
|
def self.record_from_typed_id(id)
|
||||||
class_name, record_id = GraphQL::Schema::UniqueWithinType.decode(id)
|
class_name, record_id = GraphQL::Schema::UniqueWithinType.decode(id)
|
||||||
|
|
||||||
if defined?(class_name)
|
if class_name == 'Dossier'
|
||||||
|
Dossier.visible_by_administration.find(record_id)
|
||||||
|
elsif defined?(class_name)
|
||||||
Object.const_get(class_name).find(record_id)
|
Object.const_get(class_name).find(record_id)
|
||||||
else
|
else
|
||||||
raise ActiveRecord::RecordNotFound, "Unexpected object: #{class_name}"
|
raise ActiveRecord::RecordNotFound, "Unexpected object: #{class_name}"
|
||||||
|
|
|
@ -95,11 +95,13 @@ describe API::V2::GraphqlController do
|
||||||
}"
|
}"
|
||||||
end
|
end
|
||||||
let(:variables) { {} }
|
let(:variables) { {} }
|
||||||
|
let(:operation_name) { nil }
|
||||||
|
let(:query_id) { nil }
|
||||||
let(:body) { JSON.parse(subject.body, symbolize_names: true) }
|
let(:body) { JSON.parse(subject.body, symbolize_names: true) }
|
||||||
let(:gql_data) { body[:data] }
|
let(:gql_data) { body[:data] }
|
||||||
let(:gql_errors) { body[:errors] }
|
let(:gql_errors) { body[:errors] }
|
||||||
|
|
||||||
subject { post :execute, params: { query: query, variables: variables } }
|
subject { post :execute, params: { query: query, variables: variables, operationName: operation_name, queryId: query_id }.compact, as: :json }
|
||||||
|
|
||||||
context "when authenticated with legacy token" do
|
context "when authenticated with legacy token" do
|
||||||
let(:authorization_header) { ActionController::HttpAuthentication::Token.encode_credentials(legacy_token) }
|
let(:authorization_header) { ActionController::HttpAuthentication::Token.encode_credentials(legacy_token) }
|
||||||
|
@ -822,6 +824,164 @@ describe API::V2::GraphqlController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'stored queries' do
|
||||||
|
let(:procedure) { create(:procedure, :published, :for_individual, administrateurs: [admin]) }
|
||||||
|
let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
|
||||||
|
let(:query_id) { 'ds-query-v2' }
|
||||||
|
|
||||||
|
context 'not found operation id' do
|
||||||
|
let(:query_id) { 'ds-query-v0' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors.first[:message]).to eq('No query with id "ds-query-v0"')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'not found operation name' do
|
||||||
|
let(:operation_name) { 'getStuff' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors.first[:message]).to eq('No operation named "getStuff"')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'getDossier' do
|
||||||
|
let(:variables) { { dossierNumber: dossier.id } }
|
||||||
|
let(:operation_name) { 'getDossier' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors).to be_nil
|
||||||
|
expect(gql_data[:dossier][:id]).to eq(dossier.to_typed_id)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'getDemarche' do
|
||||||
|
let(:variables) { { demarcheNumber: procedure.id } }
|
||||||
|
let(:operation_name) { 'getDemarche' }
|
||||||
|
|
||||||
|
before { dossier }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors).to be_nil
|
||||||
|
expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id)
|
||||||
|
expect(gql_data[:demarche][:dossiers]).to be_nil
|
||||||
|
}
|
||||||
|
|
||||||
|
context 'include Dossiers' do
|
||||||
|
let(:variables) { { demarcheNumber: procedure.id, includeDossiers: true } }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors).to be_nil
|
||||||
|
expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id)
|
||||||
|
expect(gql_data[:demarche][:dossiers][:nodes].size).to eq(1)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'mutation' do
|
||||||
|
let(:query_id) { 'ds-mutation-v2' }
|
||||||
|
|
||||||
|
context 'not found operation name' do
|
||||||
|
let(:operation_name) { 'dossierStuff' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors.first[:message]).to eq('No operation named "dossierStuff"')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'dossierArchiver' do
|
||||||
|
let(:dossier) { create(:dossier, :refuse, :with_individual, procedure: procedure) }
|
||||||
|
let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } }
|
||||||
|
let(:operation_name) { 'dossierArchiver' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors).to be_nil
|
||||||
|
expect(gql_data[:dossierArchiver][:errors]).to be_nil
|
||||||
|
expect(gql_data[:dossierArchiver][:dossier][:id]).to eq(dossier.to_typed_id)
|
||||||
|
expect(gql_data[:dossierArchiver][:dossier][:archived]).to be_truthy
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'dossierPasserEnInstruction' do
|
||||||
|
let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
|
||||||
|
let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } }
|
||||||
|
let(:operation_name) { 'dossierPasserEnInstruction' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors).to be_nil
|
||||||
|
expect(gql_data[:dossierPasserEnInstruction][:errors]).to be_nil
|
||||||
|
expect(gql_data[:dossierPasserEnInstruction][:dossier][:id]).to eq(dossier.to_typed_id)
|
||||||
|
expect(gql_data[:dossierPasserEnInstruction][:dossier][:state]).to eq('en_instruction')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'dossierRepasserEnConstruction' do
|
||||||
|
let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) }
|
||||||
|
let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } }
|
||||||
|
let(:operation_name) { 'dossierRepasserEnConstruction' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors).to be_nil
|
||||||
|
expect(gql_data[:dossierRepasserEnConstruction][:errors]).to be_nil
|
||||||
|
expect(gql_data[:dossierRepasserEnConstruction][:dossier][:id]).to eq(dossier.to_typed_id)
|
||||||
|
expect(gql_data[:dossierRepasserEnConstruction][:dossier][:state]).to eq('en_construction')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'dossierRepasserEnInstruction' do
|
||||||
|
let(:dossier) { create(:dossier, :refuse, :with_individual, procedure: procedure) }
|
||||||
|
let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } }
|
||||||
|
let(:operation_name) { 'dossierRepasserEnInstruction' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors).to be_nil
|
||||||
|
expect(gql_data[:dossierRepasserEnInstruction][:errors]).to be_nil
|
||||||
|
expect(gql_data[:dossierRepasserEnInstruction][:dossier][:id]).to eq(dossier.to_typed_id)
|
||||||
|
expect(gql_data[:dossierRepasserEnInstruction][:dossier][:state]).to eq('en_instruction')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'dossierAccepter' do
|
||||||
|
let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) }
|
||||||
|
let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id } } }
|
||||||
|
let(:operation_name) { 'dossierAccepter' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors).to be_nil
|
||||||
|
expect(gql_data[:dossierAccepter][:errors]).to be_nil
|
||||||
|
expect(gql_data[:dossierAccepter][:dossier][:id]).to eq(dossier.to_typed_id)
|
||||||
|
expect(gql_data[:dossierAccepter][:dossier][:state]).to eq('accepte')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'dossierRefuser' do
|
||||||
|
let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) }
|
||||||
|
let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id, motivation: 'yolo' } } }
|
||||||
|
let(:operation_name) { 'dossierRefuser' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors).to be_nil
|
||||||
|
expect(gql_data[:dossierRefuser][:errors]).to be_nil
|
||||||
|
expect(gql_data[:dossierRefuser][:dossier][:id]).to eq(dossier.to_typed_id)
|
||||||
|
expect(gql_data[:dossierRefuser][:dossier][:state]).to eq('refuse')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'dossierClasserSansSuite' do
|
||||||
|
let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) }
|
||||||
|
let(:variables) { { input: { dossierId: dossier.to_typed_id, instructeurId: instructeur.to_typed_id, motivation: 'yolo' } } }
|
||||||
|
let(:operation_name) { 'dossierClasserSansSuite' }
|
||||||
|
|
||||||
|
it {
|
||||||
|
expect(gql_errors).to be_nil
|
||||||
|
expect(gql_data[:dossierClasserSansSuite][:errors]).to be_nil
|
||||||
|
expect(gql_data[:dossierClasserSansSuite][:dossier][:id]).to eq(dossier.to_typed_id)
|
||||||
|
expect(gql_data[:dossierClasserSansSuite][:dossier][:state]).to eq('sans_suite')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "mutations" do
|
describe "mutations" do
|
||||||
describe 'dossierEnvoyerMessage' do
|
describe 'dossierEnvoyerMessage' do
|
||||||
let(:query) do
|
let(:query) do
|
||||||
|
|
Loading…
Add table
Reference in a new issue