Merge pull request #8786 from tchak/graphql-pending_deleted_dossiers

feat(graphql): expose pendingDeletedDossiers
This commit is contained in:
Paul Chavard 2023-03-22 18:49:51 +00:00 committed by GitHub
commit f2ef239567
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 140 additions and 6 deletions

View file

@ -14,6 +14,8 @@ class API::V2::Schema < GraphQL::Schema
def self.id_from_object(object, type_definition, ctx)
if type_definition == Types::DemarcheDescriptorType
(object.is_a?(Procedure) ? object : object.procedure).to_typed_id
elsif type_definition == Types::DeletedDossierType
object.is_a?(DeletedDossier) ? object.to_typed_id : GraphQL::Schema::UniqueWithinType.encode('DeletedDossier', object.id)
elsif object.is_a?(Hash)
object[:id]
else

View file

@ -31,9 +31,14 @@ class API::V2::StoredQuery
$deletedFirst: Int
$deletedAfter: String
$deletedSince: ISO8601DateTime
$pendingDeletedOrder: Order
$pendingDeletedFirst: Int
$pendingDeletedAfter: String
$pendingDeletedSince: ISO8601DateTime
$includeGroupeInstructeurs: Boolean = false
$includeDossiers: Boolean = false
$includeDeletedDossiers: Boolean = false
$includePendingDeletedDossiers: Boolean = false
$includeRevision: Boolean = false
$includeService: Boolean = false
$includeChamps: Boolean = true
@ -78,6 +83,19 @@ class API::V2::StoredQuery
...DossierFragment
}
}
pendingDeletedDossiers(
order: $pendingDeletedOrder
first: $pendingDeletedFirst
after: $pendingDeletedAfter
deletedSince: $pendingDeletedSince
) @include(if: $includePendingDeletedDossiers) {
pageInfo {
...PageInfoFragment
}
nodes {
...DeletedDossierFragment
}
}
deletedDossiers(
order: $deletedOrder
first: $deletedFirst

View file

@ -857,6 +857,41 @@ type Demarche {
Numero de la démarche.
"""
number: Int!
"""
Liste de tous les dossiers en attente de suppression définitive dune démarche.
"""
pendingDeletedDossiers(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Dossiers en attente de suppression depuis la date.
"""
deletedSince: ISO8601DateTime
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
"""
Lordre des dossiers en attente de suppression.
"""
order: Order = ASC
): DeletedDossierConnection!
publishedRevision: Revision
revisions: [Revision!]!
service: Service

View file

@ -3,14 +3,38 @@ module Types
description "Un dossier supprimé"
global_id_field :id
field :number, Int, "Le numéro du dossier qui a été supprimé.", null: false, method: :dossier_id
field :number, Int, "Le numéro du dossier qui a été supprimé.", null: false
field :state, Types::DossierType::DossierState, "Létat du dossier supprimé.", null: false
field :reason, String, "La raison de la suppression du dossier.", null: false
field :date_supression, GraphQL::Types::ISO8601DateTime, "Date de suppression.", null: false, method: :deleted_at
field :date_supression, GraphQL::Types::ISO8601DateTime, "Date de suppression.", null: false
def self.authorized?(object, context)
context.authorized_demarche?(object.procedure)
end
def date_supression
if object.is_a?(Dossier)
object.hidden_by_administration_at || object.hidden_by_user_at
else
object.deleted_at
end
end
def number
if object.is_a?(Dossier)
object.id
else
object.dossier_id
end
end
def reason
if object.is_a?(Dossier)
object.hidden_by_reason
else
object.reason
end
end
end
end

View file

@ -49,6 +49,10 @@ module Types
argument :order, Types::Order, default_value: :asc, required: false, description: "Lordre des dossiers supprimés."
argument :deleted_since, GraphQL::Types::ISO8601DateTime, required: false, description: "Dossiers supprimés depuis la date."
end
field :pending_deleted_dossiers, Types::DeletedDossierType.connection_type, "Liste de tous les dossiers en attente de suppression définitive dune démarche.", null: false do
argument :order, Types::Order, default_value: :asc, required: false, description: "Lordre des dossiers en attente de suppression."
argument :deleted_since, GraphQL::Types::ISO8601DateTime, required: false, description: "Dossiers en attente de suppression depuis la date."
end
field :champ_descriptors, [Types::ChampDescriptorType], null: false, deprecation_reason: 'Utilisez le champ `activeRevision.champDescriptors` à la place.'
field :annotation_descriptors, [Types::ChampDescriptorType], null: false, deprecation_reason: 'Utilisez le champ `activeRevision.annotationDescriptors` à la place.'
@ -133,6 +137,16 @@ module Types
dossiers.order(deleted_at: order)
end
def pending_deleted_dossiers(deleted_since: nil, order:)
dossiers = object.dossiers.hidden_for_administration
if deleted_since.present?
dossiers = dossiers.hidden_since(deleted_since)
end
dossiers.order(hidden_by_user_at: order, hidden_by_administration_at: order)
end
def champ_descriptors
object.active_revision.revision_types_de_champ_public
end

View file

@ -241,12 +241,18 @@ class Dossier < ApplicationRecord
.merge(visible_by_user.or(state_not_en_construction))
}
scope :visible_by_user_or_administration, -> { visible_by_user.or(visible_by_administration) }
scope :hidden_for_administration, -> {
state_not_brouillon.hidden_by_administration.or(state_en_construction.hidden_by_user)
}
scope :for_procedure_preview, -> { where(for_procedure_preview: true) }
scope :order_by_updated_at, -> (order = :desc) { order(updated_at: order) }
scope :order_by_created_at, -> (order = :asc) { order(depose_at: order, created_at: order, id: order) }
scope :updated_since, -> (since) { where('dossiers.updated_at >= ?', since) }
scope :created_since, -> (since) { where('dossiers.depose_at >= ?', since) }
scope :hidden_by_user_since, -> (since) { where('dossiers.hidden_by_user_at NOT NULL AND dossiers.hidden_by_user_at >= ?', since) }
scope :hidden_by_administration_since, -> (since) { where('dossiers.hidden_by_administration_at NOT NULL AND dossiers.hidden_by_administration_at >= ?', since) }
scope :hidden_since, -> (since) { hidden_by_user_since(since).or(hidden_by_administration_since(since)) }
scope :with_type_de_champ, -> (stable_id) {
joins('INNER JOIN champs ON champs.dossier_id = dossiers.id INNER JOIN types_de_champ ON types_de_champ.id = champs.type_de_champ_id')

View file

@ -9,6 +9,7 @@ describe API::V2::GraphqlController do
let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
let(:dossier1) { create(:dossier, :en_construction, :with_individual, procedure: procedure, en_construction_at: 1.day.ago) }
let(:dossier2) { create(:dossier, :en_construction, :with_individual, :archived, procedure: procedure, en_construction_at: 3.days.ago) }
let(:dossier_accepte) { create(:dossier, :accepte, :with_individual, procedure: procedure) }
let(:dossiers) { [dossier] }
let(:instructeur) { create(:instructeur, followed_dossiers: dossiers) }
let(:authorization_header) { ActionController::HttpAuthentication::Token.encode_credentials(token) }
@ -104,6 +105,40 @@ describe API::V2::GraphqlController do
expect(gql_data[:demarche][:activeRevision]).not_to be_nil
}
end
context 'include deleted Dossiers' do
let(:variables) { { demarcheNumber: procedure.id, includeDeletedDossiers: true } }
let(:deleted_dossier) { create(:deleted_dossier, dossier: dossier_accepte) }
before { deleted_dossier }
it {
expect(gql_errors).to be_nil
expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id)
expect(gql_data[:demarche][:deletedDossiers][:nodes].size).to eq(1)
expect(gql_data[:demarche][:deletedDossiers][:nodes].first[:id]).to eq(deleted_dossier.to_typed_id)
expect(gql_data[:demarche][:deletedDossiers][:nodes].first[:dateSupression]).to eq(deleted_dossier.deleted_at.iso8601)
}
end
context 'include pending deleted Dossiers' do
let(:variables) { { demarcheNumber: procedure.id, includePendingDeletedDossiers: true } }
before {
dossier.hide_and_keep_track!(dossier.user, DeletedDossier.reasons.fetch(:user_request))
dossier_accepte.hide_and_keep_track!(instructeur, DeletedDossier.reasons.fetch(:instructeur_request))
}
it {
expect(gql_errors).to be_nil
expect(gql_data[:demarche][:id]).to eq(procedure.to_typed_id)
expect(gql_data[:demarche][:pendingDeletedDossiers][:nodes].size).to eq(2)
expect(gql_data[:demarche][:pendingDeletedDossiers][:nodes].first[:id]).to eq(GraphQL::Schema::UniqueWithinType.encode('DeletedDossier', dossier.id))
expect(gql_data[:demarche][:pendingDeletedDossiers][:nodes].second[:id]).to eq(GraphQL::Schema::UniqueWithinType.encode('DeletedDossier', dossier_accepte.id))
expect(gql_data[:demarche][:pendingDeletedDossiers][:nodes].first[:dateSupression]).to eq(dossier.hidden_by_user_at.iso8601)
expect(gql_data[:demarche][:pendingDeletedDossiers][:nodes].second[:dateSupression]).to eq(dossier_accepte.hidden_by_administration_at.iso8601)
}
end
end
context 'getGroupeInstructeur' do