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
|
||||
|
||||
def execute
|
||||
variables = ensure_hash(params[:variables])
|
||||
|
||||
result = API::V2::Schema.execute(params[:query],
|
||||
result = API::V2::Schema.execute(query,
|
||||
variables: variables,
|
||||
context: context,
|
||||
operation_name: params[:operationName])
|
||||
|
@ -26,7 +24,7 @@ class API::V2::GraphqlController < API::V2::BaseController
|
|||
super
|
||||
|
||||
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
|
||||
|
||||
|
@ -41,6 +39,18 @@ class API::V2::GraphqlController < API::V2::BaseController
|
|||
}, status: 400
|
||||
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
|
||||
def ensure_hash(ambiguous_param)
|
||||
case ambiguous_param
|
||||
|
@ -99,11 +109,7 @@ class API::V2::GraphqlController < API::V2::BaseController
|
|||
|
||||
def handle_error_in_production(exception)
|
||||
id = SecureRandom.uuid
|
||||
Sentry.capture_exception(exception, extra: {
|
||||
exception_id: id,
|
||||
query: params[:query],
|
||||
variables: params[:variables].to_json
|
||||
})
|
||||
Sentry.capture_exception(exception, extra: { exception_id: id })
|
||||
|
||||
render json: {
|
||||
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)
|
||||
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)
|
||||
else
|
||||
raise ActiveRecord::RecordNotFound, "Unexpected object: #{class_name}"
|
||||
|
|
|
@ -95,11 +95,13 @@ describe API::V2::GraphqlController do
|
|||
}"
|
||||
end
|
||||
let(:variables) { {} }
|
||||
let(:operation_name) { nil }
|
||||
let(:query_id) { nil }
|
||||
let(:body) { JSON.parse(subject.body, symbolize_names: true) }
|
||||
let(:gql_data) { body[:data] }
|
||||
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
|
||||
let(:authorization_header) { ActionController::HttpAuthentication::Token.encode_credentials(legacy_token) }
|
||||
|
@ -822,6 +824,164 @@ describe API::V2::GraphqlController do
|
|||
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 'dossierEnvoyerMessage' do
|
||||
let(:query) do
|
||||
|
|
Loading…
Reference in a new issue