Merge pull request #5922 from tchak/operation-serializer
Operation serializer
This commit is contained in:
commit
e2063e0fc8
21 changed files with 404 additions and 92 deletions
|
@ -10,6 +10,32 @@ class API::V2::Context < GraphQL::Query::Context
|
|||
end
|
||||
end
|
||||
|
||||
def internal_use?
|
||||
self[:internal_use]
|
||||
end
|
||||
|
||||
def authorized_demarche?(demarche)
|
||||
if internal_use?
|
||||
return true
|
||||
end
|
||||
|
||||
# We are caching authorization logic because it is called for each node
|
||||
# of the requested graph and can be expensive. Context is reset per request so it is safe.
|
||||
self[:authorized] ||= Hash.new do |hash, demarche_id|
|
||||
# Compute the hash value dynamically when first requested
|
||||
authorized_administrateur = demarche.administrateurs.find do |administrateur|
|
||||
if self[:token]
|
||||
administrateur.valid_api_token?(self[:token])
|
||||
else
|
||||
administrateur.id == self[:administrateur_id]
|
||||
end
|
||||
end
|
||||
hash[demarche_id] = authorized_administrateur.present?
|
||||
end
|
||||
|
||||
self[:authorized][demarche.id]
|
||||
end
|
||||
|
||||
class HasFragment < GraphQL::Language::Visitor
|
||||
def initialize(document, name)
|
||||
super(document)
|
||||
|
|
27
app/graphql/loaders/champ.rb
Normal file
27
app/graphql/loaders/champ.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# references:
|
||||
# https://github.com/Shopify/graphql-batch/blob/master/examples/record_loader.rb
|
||||
|
||||
module Loaders
|
||||
class Champ < GraphQL::Batch::Loader
|
||||
def initialize(dossier, private: false)
|
||||
@where = { dossier: dossier, private: private }
|
||||
end
|
||||
|
||||
def load(key)
|
||||
super(key.to_i)
|
||||
end
|
||||
|
||||
def perform(keys)
|
||||
query(keys).each { |record| fulfill(record.stable_id, [record].compact) }
|
||||
keys.each { |key| fulfill(key, nil) unless fulfilled?(key) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def query(keys)
|
||||
::Champ.where(@where)
|
||||
.includes(:type_de_champ)
|
||||
.where(types_de_champ: { stable_id: keys })
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,11 +3,13 @@
|
|||
|
||||
module Loaders
|
||||
class Record < GraphQL::Batch::Loader
|
||||
def initialize(model, column: model.primary_key, where: nil)
|
||||
def initialize(model, column: model.primary_key, where: nil, includes: nil, array: false)
|
||||
@model = model
|
||||
@column = column.to_s
|
||||
@column_type = model.type_for_attribute(@column)
|
||||
@where = where
|
||||
@includes = includes
|
||||
@array = array
|
||||
end
|
||||
|
||||
def load(key)
|
||||
|
@ -15,7 +17,10 @@ module Loaders
|
|||
end
|
||||
|
||||
def perform(keys)
|
||||
query(keys).each { |record| fulfill(record.public_send(@column), record) }
|
||||
query(keys).each do |record|
|
||||
fulfilled_value = @array ? [record].compact : record
|
||||
fulfill(record.public_send(@column), fulfilled_value)
|
||||
end
|
||||
keys.each { |key| fulfill(key, nil) unless fulfilled?(key) }
|
||||
end
|
||||
|
||||
|
@ -24,6 +29,7 @@ module Loaders
|
|||
def query(keys)
|
||||
scope = @model
|
||||
scope = scope.where(@where) if @where
|
||||
scope = scope.includes(@includes) if @includes
|
||||
scope.where(@column => keys)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -508,15 +508,15 @@ type DirectUpload {
|
|||
Un dossier
|
||||
"""
|
||||
type Dossier {
|
||||
annotations: [Champ!]!
|
||||
annotations(id: ID): [Champ!]!
|
||||
archived: Boolean!
|
||||
|
||||
"""
|
||||
L’URL de l’attestation au format PDF.
|
||||
"""
|
||||
attestation: File
|
||||
avis: [Avis!]!
|
||||
champs: [Champ!]!
|
||||
avis(id: ID): [Avis!]!
|
||||
champs(id: ID): [Champ!]!
|
||||
|
||||
"""
|
||||
Date de la dernière modification.
|
||||
|
@ -546,7 +546,7 @@ type Dossier {
|
|||
groupeInstructeur: GroupeInstructeur!
|
||||
id: ID!
|
||||
instructeurs: [Profile!]!
|
||||
messages: [Message!]!
|
||||
messages(id: ID): [Message!]!
|
||||
motivation: String
|
||||
motivationAttachment: File
|
||||
|
||||
|
|
|
@ -1,25 +1,4 @@
|
|||
module Types
|
||||
class BaseObject < GraphQL::Schema::Object
|
||||
def self.authorized_demarche?(demarche, context)
|
||||
# We are caching authorization logic because it is called for each node
|
||||
# of the requested graph and can be expensive. Context is reset per request so it is safe.
|
||||
context[:authorized] ||= {}
|
||||
if context[:authorized][demarche.id]
|
||||
return true
|
||||
end
|
||||
|
||||
administrateur = demarche.administrateurs.find do |administrateur|
|
||||
if context[:token]
|
||||
administrateur.valid_api_token?(context[:token])
|
||||
else
|
||||
administrateur.id == context[:administrateur_id]
|
||||
end
|
||||
end
|
||||
|
||||
if administrateur
|
||||
context[:authorized][demarche.id] = true
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -88,7 +88,7 @@ module Types
|
|||
end
|
||||
|
||||
def self.authorized?(object, context)
|
||||
authorized_demarche?(object, context)
|
||||
context.authorized_demarche?(object)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,11 +35,19 @@ module Types
|
|||
field :demandeur, Types::DemandeurType, null: false
|
||||
|
||||
field :instructeurs, [Types::ProfileType], null: false
|
||||
field :messages, [Types::MessageType], null: false
|
||||
field :avis, [Types::AvisType], null: false
|
||||
|
||||
field :champs, [Types::ChampType], null: false
|
||||
field :annotations, [Types::ChampType], null: false
|
||||
field :messages, [Types::MessageType], null: false do
|
||||
argument :id, ID, required: false
|
||||
end
|
||||
field :avis, [Types::AvisType], null: false do
|
||||
argument :id, ID, required: false
|
||||
end
|
||||
field :champs, [Types::ChampType], null: false do
|
||||
argument :id, ID, required: false
|
||||
end
|
||||
field :annotations, [Types::ChampType], null: false do
|
||||
argument :id, ID, required: false
|
||||
end
|
||||
|
||||
def state
|
||||
object.state
|
||||
|
@ -69,20 +77,44 @@ module Types
|
|||
Loaders::Association.for(object.class, :followers_instructeurs).load(object)
|
||||
end
|
||||
|
||||
def messages
|
||||
def messages(id: nil)
|
||||
if id.present?
|
||||
Loaders::Record
|
||||
.for(Commentaire, where: { dossier: object }, includes: [:instructeur, :user], array: true)
|
||||
.load(ApplicationRecord.id_from_typed_id(id))
|
||||
else
|
||||
Loaders::Association.for(object.class, commentaires: [:instructeur, :user]).load(object)
|
||||
end
|
||||
end
|
||||
|
||||
def avis
|
||||
def avis(id: nil)
|
||||
if id.present?
|
||||
Loaders::Record
|
||||
.for(Avis, where: { dossier: object }, includes: [:instructeur, :claimant], array: true)
|
||||
.load(ApplicationRecord.id_from_typed_id(id))
|
||||
else
|
||||
Loaders::Association.for(object.class, avis: [:instructeur, :claimant]).load(object)
|
||||
end
|
||||
|
||||
def champs
|
||||
Loaders::Association.for(object.class, champs: [:type_de_champ]).load(object)
|
||||
end
|
||||
|
||||
def annotations
|
||||
Loaders::Association.for(object.class, champs_private: [:type_de_champ]).load(object)
|
||||
def champs(id: nil)
|
||||
if id.present?
|
||||
Loaders::Champ
|
||||
.for(object, private: false)
|
||||
.load(ApplicationRecord.id_from_typed_id(id))
|
||||
else
|
||||
Loaders::Association.for(object.class, champs: :type_de_champ).load(object)
|
||||
end
|
||||
end
|
||||
|
||||
def annotations(id: nil)
|
||||
if id.present?
|
||||
Loaders::Champ
|
||||
.for(object, private: true)
|
||||
.load(ApplicationRecord.id_from_typed_id(id))
|
||||
else
|
||||
Loaders::Association.for(object.class, champs_private: :type_de_champ).load(object)
|
||||
end
|
||||
end
|
||||
|
||||
def pdf
|
||||
|
@ -110,7 +142,7 @@ module Types
|
|||
end
|
||||
|
||||
def self.authorized?(object, context)
|
||||
authorized_demarche?(object.procedure, context)
|
||||
context.authorized_demarche?(object.procedure)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ module Types
|
|||
end
|
||||
|
||||
def self.authorized?(object, context)
|
||||
authorized_demarche?(object.procedure, context)
|
||||
context.authorized_demarche?(object.procedure)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,7 +19,11 @@ module Types
|
|||
end
|
||||
|
||||
def dossier(number:)
|
||||
if context.internal_use?
|
||||
Dossier.state_not_brouillon.with_discarded.for_api_v2.find(number)
|
||||
else
|
||||
Dossier.state_not_brouillon.for_api_v2.find(number)
|
||||
end
|
||||
rescue => e
|
||||
raise GraphQL::ExecutionError.new(e.message, extensions: { code: :not_found })
|
||||
end
|
||||
|
|
|
@ -13,6 +13,10 @@ class ApplicationRecord < ActiveRecord::Base
|
|||
raise ActiveRecord::RecordNotFound, e.message
|
||||
end
|
||||
|
||||
def self.id_from_typed_id(id)
|
||||
GraphQL::Schema::UniqueWithinType.decode(id)[1]
|
||||
end
|
||||
|
||||
def to_typed_id
|
||||
GraphQL::Schema::UniqueWithinType.encode(self.class.name, id)
|
||||
end
|
||||
|
|
|
@ -80,7 +80,25 @@ class DossierOperationLog < ApplicationRecord
|
|||
if author.nil?
|
||||
nil
|
||||
else
|
||||
OperationAuthorSerializer.new(author).as_json
|
||||
{
|
||||
id: serialize_author_id(author),
|
||||
email: author.email
|
||||
}.as_json
|
||||
end
|
||||
end
|
||||
|
||||
def self.serialize_author_id(object)
|
||||
case object
|
||||
when User
|
||||
"Usager##{object.id}"
|
||||
when Instructeur
|
||||
"Instructeur##{object.id}"
|
||||
when Administrateur
|
||||
"Administrateur##{object.id}"
|
||||
when SuperAdmin
|
||||
"Manager##{object.id}"
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -96,11 +114,11 @@ class DossierOperationLog < ApplicationRecord
|
|||
else
|
||||
case subject
|
||||
when Dossier
|
||||
DossierSerializer.new(subject).as_json
|
||||
SerializerService.dossier(subject)
|
||||
when Champ
|
||||
ChampSerializer.new(subject).as_json
|
||||
SerializerService.champ(subject)
|
||||
when Avis
|
||||
AvisSerializer.new(subject).as_json
|
||||
SerializerService.avis(subject)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
class OperationAuthorSerializer < ActiveModel::Serializer
|
||||
attributes :id, :email
|
||||
|
||||
def id
|
||||
case object
|
||||
when User
|
||||
"Usager##{object.id}"
|
||||
when Instructeur
|
||||
"Instructeur##{object.id}"
|
||||
when Administrateur
|
||||
"Administrateur##{object.id}"
|
||||
when SuperAdmin
|
||||
"Manager##{object.id}"
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
233
app/services/serializer_service.rb
Normal file
233
app/services/serializer_service.rb
Normal file
|
@ -0,0 +1,233 @@
|
|||
class SerializerService
|
||||
def self.dossier(dossier)
|
||||
data = execute_query('serializeDossier', { number: dossier.id })
|
||||
data && data['dossier']
|
||||
end
|
||||
|
||||
def self.avis(avis)
|
||||
data = execute_query('serializeAvis', { number: avis.dossier_id, id: avis.to_typed_id })
|
||||
data && data['dossier']['avis'].first
|
||||
end
|
||||
|
||||
def self.champ(champ)
|
||||
if champ.private?
|
||||
data = execute_query('serializeAnnotation', { number: champ.dossier_id, id: champ.to_typed_id })
|
||||
data && data['dossier']['annotations'].first
|
||||
else
|
||||
data = execute_query('serializeChamp', { number: champ.dossier_id, id: champ.to_typed_id })
|
||||
data && data['dossier']['champs'].first
|
||||
end
|
||||
end
|
||||
|
||||
def self.execute_query(operation_name, variables)
|
||||
result = API::V2::Schema.execute(QUERY,
|
||||
variables: variables,
|
||||
context: { internal_use: true },
|
||||
operation_name: operation_name)
|
||||
if result['errors'].present?
|
||||
raise result['errors'].first['message']
|
||||
end
|
||||
result['data']
|
||||
end
|
||||
|
||||
QUERY = <<-'GRAPHQL'
|
||||
query serializeDossier($number: Int!) {
|
||||
dossier(number: $number) {
|
||||
...DossierFragment
|
||||
}
|
||||
}
|
||||
|
||||
query serializeAvis($number: Int!, $id: ID!) {
|
||||
dossier(number: $number) {
|
||||
avis(id: $id) {
|
||||
...AvisFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query serializeChamp($number: Int!, $id: ID!) {
|
||||
dossier(number: $number) {
|
||||
champs(id: $id) {
|
||||
...RootChampFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query serializeAnnotation($number: Int!, $id: ID!) {
|
||||
dossier(number: $number) {
|
||||
annotations(id: $id) {
|
||||
...RootChampFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment DossierFragment on Dossier {
|
||||
id
|
||||
number
|
||||
archived
|
||||
state
|
||||
dateDerniereModification
|
||||
datePassageEnConstruction
|
||||
datePassageEnInstruction
|
||||
dateTraitement
|
||||
instructeurs {
|
||||
email
|
||||
}
|
||||
groupeInstructeur {
|
||||
label
|
||||
}
|
||||
champs {
|
||||
...RootChampFragment
|
||||
}
|
||||
annotations {
|
||||
...RootChampFragment
|
||||
}
|
||||
avis {
|
||||
...AvisFragment
|
||||
}
|
||||
demandeur {
|
||||
... on PersonnePhysique {
|
||||
civilite
|
||||
nom
|
||||
prenom
|
||||
dateDeNaissance
|
||||
}
|
||||
...PersonneMoraleFragment
|
||||
}
|
||||
motivation
|
||||
motivationAttachment {
|
||||
byteSize
|
||||
checksum
|
||||
filename
|
||||
contentType
|
||||
}
|
||||
}
|
||||
|
||||
fragment AvisFragment on Avis {
|
||||
id
|
||||
question
|
||||
reponse
|
||||
dateQuestion
|
||||
dateReponse
|
||||
instructeur {
|
||||
email
|
||||
}
|
||||
expert {
|
||||
email
|
||||
}
|
||||
attachment {
|
||||
byteSize
|
||||
checksum
|
||||
filename
|
||||
contentType
|
||||
}
|
||||
}
|
||||
|
||||
fragment ChampFragment on Champ {
|
||||
id
|
||||
label
|
||||
stringValue
|
||||
... on SiretChamp {
|
||||
etablissement {
|
||||
...PersonneMoraleFragment
|
||||
}
|
||||
}
|
||||
... on LinkedDropDownListChamp {
|
||||
primaryValue
|
||||
secondaryValue
|
||||
}
|
||||
... on MultipleDropDownListChamp {
|
||||
values
|
||||
}
|
||||
... on PieceJustificativeChamp {
|
||||
file {
|
||||
byteSize
|
||||
checksum
|
||||
filename
|
||||
contentType
|
||||
}
|
||||
}
|
||||
... on AddressChamp {
|
||||
address {
|
||||
...AddressFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment RootChampFragment on Champ {
|
||||
...ChampFragment
|
||||
... on RepetitionChamp {
|
||||
champs {
|
||||
...ChampFragment
|
||||
}
|
||||
}
|
||||
... on CarteChamp {
|
||||
geoAreas {
|
||||
source
|
||||
geometry {
|
||||
type
|
||||
coordinates
|
||||
}
|
||||
... on ParcelleCadastrale {
|
||||
codeArr
|
||||
codeCom
|
||||
codeDep
|
||||
feuille
|
||||
nomCom
|
||||
numero
|
||||
section
|
||||
surfaceParcelle
|
||||
surfaceIntersection
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment PersonneMoraleFragment on PersonneMorale {
|
||||
siret
|
||||
siegeSocial
|
||||
naf
|
||||
libelleNaf
|
||||
address {
|
||||
...AddressFragment
|
||||
}
|
||||
entreprise {
|
||||
siren
|
||||
capitalSocial
|
||||
numeroTvaIntracommunautaire
|
||||
formeJuridique
|
||||
formeJuridiqueCode
|
||||
nomCommercial
|
||||
raisonSociale
|
||||
siretSiegeSocial
|
||||
codeEffectifEntreprise
|
||||
dateCreation
|
||||
nom
|
||||
prenom
|
||||
}
|
||||
association {
|
||||
rna
|
||||
titre
|
||||
objet
|
||||
dateCreation
|
||||
dateDeclaration
|
||||
datePublication
|
||||
}
|
||||
}
|
||||
|
||||
fragment AddressFragment on Address {
|
||||
label
|
||||
type
|
||||
streetAddress
|
||||
streetNumber
|
||||
streetName
|
||||
postalCode
|
||||
cityName
|
||||
cityCode
|
||||
departmentName
|
||||
departmentCode
|
||||
regionName
|
||||
regionCode
|
||||
}
|
||||
GRAPHQL
|
||||
end
|
|
@ -5,8 +5,8 @@ describe Instructeurs::DossiersController, type: :controller do
|
|||
let(:administrateur) { create(:administrateur) }
|
||||
let(:administration) { create(:administration) }
|
||||
let(:instructeurs) { [instructeur] }
|
||||
let(:procedure) { create(:procedure, :published, instructeurs: instructeurs) }
|
||||
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||
let(:procedure) { create(:procedure, :published, :for_individual, instructeurs: instructeurs) }
|
||||
let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
|
||||
let(:fake_justificatif) { fixture_file_upload('spec/fixtures/files/piece_justificative_0.pdf', 'application/pdf') }
|
||||
|
||||
before { sign_in(instructeur.user) }
|
||||
|
@ -328,7 +328,7 @@ describe Instructeurs::DossiersController, type: :controller do
|
|||
context 'when the attestation template uses the motivation field' do
|
||||
let(:emailable) { false }
|
||||
let(:template) { create(:attestation_template) }
|
||||
let(:procedure) { create(:procedure, :published, attestation_template: template, instructeurs: [instructeur]) }
|
||||
let(:procedure) { create(:procedure, :published, :for_individual, attestation_template: template, instructeurs: [instructeur]) }
|
||||
|
||||
subject do
|
||||
post :terminer, params: {
|
||||
|
@ -552,6 +552,7 @@ describe Instructeurs::DossiersController, type: :controller do
|
|||
describe "#show" do
|
||||
context "when the dossier is exported as PDF" do
|
||||
let(:instructeur) { create(:instructeur) }
|
||||
let(:procedure) { create(:procedure, :published, instructeurs: instructeurs) }
|
||||
let(:dossier) do
|
||||
create(:dossier,
|
||||
:accepte,
|
||||
|
|
|
@ -20,7 +20,7 @@ describe Manager::DossiersController, type: :controller do
|
|||
end
|
||||
|
||||
describe '#restore' do
|
||||
let(:dossier) { create(:dossier, :en_construction) }
|
||||
let(:dossier) { create(:dossier, :en_construction, :with_individual) }
|
||||
|
||||
before do
|
||||
dossier.discard_and_keep_track!(super_admin, :manager_request)
|
||||
|
|
|
@ -46,7 +46,7 @@ describe Manager::ProceduresController, type: :controller do
|
|||
end
|
||||
|
||||
describe '#restore' do
|
||||
let(:dossier) { create(:dossier, :en_construction) }
|
||||
let(:dossier) { create(:dossier, :en_construction, :with_individual) }
|
||||
let(:procedure) { dossier.procedure }
|
||||
let(:deleted_dossier) { DeletedDossier.find_by(dossier_id: dossier.id) }
|
||||
let(:operations) { dossier.dossier_operation_logs.map(&:operation).map(&:to_sym) }
|
||||
|
|
|
@ -2,7 +2,7 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
|||
render_views
|
||||
|
||||
let(:admin) { create(:administrateur) }
|
||||
let(:procedure) { create(:procedure, :published, administrateurs: [admin]) }
|
||||
let(:procedure) { create(:procedure, :published, :for_individual, administrateurs: [admin]) }
|
||||
let!(:gi_1_1) { procedure.defaut_groupe_instructeur }
|
||||
|
||||
let(:procedure2) { create(:procedure, :published) }
|
||||
|
@ -137,9 +137,9 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
|||
|
||||
describe '#reaffecter' do
|
||||
let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
|
||||
let!(:dossier12) { create(:dossier, :en_construction, procedure: procedure, groupe_instructeur: gi_1_1) }
|
||||
let!(:dossier12) { create(:dossier, :en_construction, :with_individual, procedure: procedure, groupe_instructeur: gi_1_1) }
|
||||
let!(:dossier_discarded) do
|
||||
dossier = create(:dossier, :en_construction, procedure: procedure, groupe_instructeur: gi_1_1)
|
||||
dossier = create(:dossier, :en_construction, :with_individual, procedure: procedure, groupe_instructeur: gi_1_1)
|
||||
dossier.discard!
|
||||
dossier
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ feature 'Instructing a dossier:' do
|
|||
let!(:instructeur) { create(:instructeur, password: password) }
|
||||
|
||||
let!(:procedure) { create(:procedure, :published, instructeurs: [instructeur]) }
|
||||
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||
let!(:dossier) { create(:dossier, :en_construction, :with_entreprise, procedure: procedure) }
|
||||
context 'the instructeur is also a user' do
|
||||
scenario 'a instructeur can fill a dossier' do
|
||||
visit commencer_path(path: procedure.path)
|
||||
|
|
|
@ -4,10 +4,10 @@ RSpec.describe Cron::DeclarativeProceduresJob, type: :job do
|
|||
let(:instruction_date) { date + 120 }
|
||||
|
||||
let(:state) { nil }
|
||||
let(:procedure) { create(:procedure, :published, :with_instructeur, declarative_with_state: state) }
|
||||
let(:nouveau_dossier1) { create(:dossier, :en_construction, procedure: procedure) }
|
||||
let(:nouveau_dossier2) { create(:dossier, :en_construction, procedure: procedure) }
|
||||
let(:dossier_recu) { create(:dossier, :en_instruction, procedure: procedure) }
|
||||
let(:procedure) { create(:procedure, :published, :for_individual, :with_instructeur, declarative_with_state: state) }
|
||||
let(:nouveau_dossier1) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
|
||||
let(:nouveau_dossier2) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
|
||||
let(:dossier_recu) { create(:dossier, :en_instruction, :with_individual, procedure: procedure) }
|
||||
let(:dossier_brouillon) { create(:dossier, procedure: procedure) }
|
||||
|
||||
before do
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
RSpec.describe Cron::DiscardedDossiersDeletionJob, type: :job do
|
||||
describe '#perform' do
|
||||
let(:instructeur) { create(:instructeur) }
|
||||
let(:dossier) { create(:dossier, state, hidden_at: hidden_at) }
|
||||
let(:dossier) { create(:dossier, :with_individual, state) }
|
||||
|
||||
before do
|
||||
# hack to add passer_en_instruction and supprimer to dossier.dossier_operation_logs
|
||||
dossier.send(:log_dossier_operation, instructeur, :passer_en_instruction, dossier)
|
||||
dossier.send(:log_dossier_operation, instructeur, :supprimer, dossier)
|
||||
dossier.update_column(:hidden_at, hidden_at)
|
||||
|
||||
Cron::DiscardedDossiersDeletionJob.perform_now
|
||||
end
|
||||
|
@ -35,7 +36,7 @@ RSpec.describe Cron::DiscardedDossiersDeletionJob, type: :job do
|
|||
end
|
||||
end
|
||||
|
||||
[:brouillon, :en_construction, :en_instruction, :accepte, :refuse, :sans_suite].each do |state|
|
||||
[:en_construction, :en_instruction, :accepte, :refuse, :sans_suite].each do |state|
|
||||
context "with a dossier #{state}" do
|
||||
let(:state) { state }
|
||||
|
||||
|
|
|
@ -354,8 +354,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
describe '#update_state_dates' do
|
||||
let(:state) { Dossier.states.fetch(:brouillon) }
|
||||
let(:dossier) { create(:dossier, state: state) }
|
||||
let(:dossier) { create(:dossier, :brouillon, :with_individual) }
|
||||
let(:beginning_of_day) { Time.zone.now.beginning_of_day }
|
||||
let(:instructeur) { create(:instructeur) }
|
||||
|
||||
|
@ -381,7 +380,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
context 'when dossier is en_instruction' do
|
||||
let(:state) { Dossier.states.fetch(:en_construction) }
|
||||
let(:dossier) { create(:dossier, :en_construction, :with_individual) }
|
||||
let(:instructeur) { create(:instructeur) }
|
||||
|
||||
before do
|
||||
|
@ -402,7 +401,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
context 'when dossier is accepte' do
|
||||
let(:state) { Dossier.states.fetch(:en_instruction) }
|
||||
let(:dossier) { create(:dossier, :en_instruction, :with_individual) }
|
||||
|
||||
before do
|
||||
dossier.accepter!(instructeur, nil, nil)
|
||||
|
@ -415,7 +414,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
context 'when dossier is refuse' do
|
||||
let(:state) { Dossier.states.fetch(:en_instruction) }
|
||||
let(:dossier) { create(:dossier, :en_instruction, :with_individual) }
|
||||
|
||||
before do
|
||||
dossier.refuser!(instructeur, nil, nil)
|
||||
|
@ -427,7 +426,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
context 'when dossier is sans_suite' do
|
||||
let(:state) { Dossier.states.fetch(:en_instruction) }
|
||||
let(:dossier) { create(:dossier, :en_instruction, :with_individual) }
|
||||
|
||||
before do
|
||||
dossier.classer_sans_suite!(instructeur, nil, nil)
|
||||
|
@ -469,11 +468,11 @@ describe Dossier do
|
|||
end
|
||||
|
||||
describe "#unfollow_stale_instructeurs" do
|
||||
let(:procedure) { create(:procedure, :published) }
|
||||
let(:procedure) { create(:procedure, :published, :for_individual) }
|
||||
let(:instructeur) { create(:instructeur) }
|
||||
let(:new_groupe_instructeur) { create(:groupe_instructeur, procedure: procedure) }
|
||||
let(:instructeur2) { create(:instructeur, groupe_instructeurs: [procedure.defaut_groupe_instructeur, new_groupe_instructeur]) }
|
||||
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||
let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
|
||||
let(:last_operation) { DossierOperationLog.last }
|
||||
|
||||
before do
|
||||
|
@ -918,7 +917,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
describe '#accepter!' do
|
||||
let(:dossier) { create(:dossier, :en_instruction) }
|
||||
let(:dossier) { create(:dossier, :en_instruction, :with_individual) }
|
||||
let(:last_operation) { dossier.dossier_operation_logs.last }
|
||||
let(:operation_serialized) { JSON.parse(last_operation.serialized.download) }
|
||||
let!(:instructeur) { create(:instructeur) }
|
||||
|
@ -953,7 +952,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
describe '#accepter_automatiquement!' do
|
||||
let(:dossier) { create(:dossier, :en_construction) }
|
||||
let(:dossier) { create(:dossier, :en_construction, :with_individual) }
|
||||
let(:last_operation) { dossier.dossier_operation_logs.last }
|
||||
let!(:now) { Time.zone.parse('01/01/2100') }
|
||||
let(:attestation) { Attestation.new }
|
||||
|
@ -1372,7 +1371,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
describe "remove_titres_identite!" do
|
||||
let(:dossier) { create(:dossier, :en_instruction, :followed) }
|
||||
let(:dossier) { create(:dossier, :en_instruction, :followed, :with_individual) }
|
||||
let(:type_de_champ_titre_identite) { create(:type_de_champ_titre_identite, procedure: dossier.procedure) }
|
||||
let(:champ_titre_identite) { create(:champ_titre_identite, type_de_champ: type_de_champ_titre_identite) }
|
||||
let(:type_de_champ_titre_identite_vide) { create(:type_de_champ_titre_identite, procedure: dossier.procedure) }
|
||||
|
@ -1412,7 +1411,7 @@ describe Dossier do
|
|||
end
|
||||
|
||||
context 'en_construction' do
|
||||
let(:dossier) { create(:dossier, :en_construction, :followed) }
|
||||
let(:dossier) { create(:dossier, :en_construction, :followed, :with_individual) }
|
||||
|
||||
it "clean up titres identite on accepter_automatiquement" do
|
||||
expect(champ_titre_identite.piece_justificative_file.attached?).to be_truthy
|
||||
|
|
Loading…
Reference in a new issue