commit
252a2c3a4f
30 changed files with 654 additions and 354 deletions
|
@ -535,6 +535,13 @@
|
||||||
padding: $default-spacer;
|
padding: $default-spacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-reach-combobox-no-results] {
|
||||||
|
font-size: 16px;
|
||||||
|
color: $dark-grey;
|
||||||
|
background: $light-grey;
|
||||||
|
padding: $default-spacer;
|
||||||
|
}
|
||||||
|
|
||||||
[data-reach-combobox-token] button {
|
[data-reach-combobox-token] button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
|
@ -32,7 +32,8 @@ module Administrateurs
|
||||||
|
|
||||||
# Prevent self-removal (Also enforced in the UI)
|
# Prevent self-removal (Also enforced in the UI)
|
||||||
if administrateur == current_administrateur
|
if administrateur == current_administrateur
|
||||||
flash.error = "Vous ne pouvez pas vous retirer vous-même d’une démarche."
|
flash.alert = "Vous ne pouvez pas vous retirer vous-même d’une démarche."
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
# Actually remove the admin
|
# Actually remove the admin
|
||||||
|
|
|
@ -14,9 +14,9 @@ module Instructeurs
|
||||||
|
|
||||||
dossiers = current_instructeur.dossiers.joins(:groupe_instructeur)
|
dossiers = current_instructeur.dossiers.joins(:groupe_instructeur)
|
||||||
@dossiers_count_per_procedure = dossiers.all_state.group('groupe_instructeurs.procedure_id').reorder(nil).count
|
@dossiers_count_per_procedure = dossiers.all_state.group('groupe_instructeurs.procedure_id').reorder(nil).count
|
||||||
@dossiers_a_suivre_count_per_procedure = dossiers.without_followers.en_cours.group('groupe_instructeurs.procedure_id').reorder(nil).count
|
@dossiers_a_suivre_count_per_procedure = dossiers.without_followers.en_cours.visible_by_administration.group('groupe_instructeurs.procedure_id').reorder(nil).count
|
||||||
@dossiers_archived_count_per_procedure = dossiers.archived.group('groupe_instructeurs.procedure_id').count
|
@dossiers_archived_count_per_procedure = dossiers.archived.group('groupe_instructeurs.procedure_id').count
|
||||||
@dossiers_termines_count_per_procedure = dossiers.termine.not_hidden_by_administration.group('groupe_instructeurs.procedure_id').reorder(nil).count
|
@dossiers_termines_count_per_procedure = dossiers.termine.visible_by_administration.group('groupe_instructeurs.procedure_id').reorder(nil).count
|
||||||
@dossiers_expirant_count_per_procedure = dossiers.termine_or_en_construction_close_to_expiration.group('groupe_instructeurs.procedure_id').count
|
@dossiers_expirant_count_per_procedure = dossiers.termine_or_en_construction_close_to_expiration.group('groupe_instructeurs.procedure_id').count
|
||||||
groupe_ids = current_instructeur.groupe_instructeurs.pluck(:id)
|
groupe_ids = current_instructeur.groupe_instructeurs.pluck(:id)
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ module Instructeurs
|
||||||
@a_suivre_dossiers = dossiers_visibles
|
@a_suivre_dossiers = dossiers_visibles
|
||||||
.without_followers
|
.without_followers
|
||||||
.en_cours
|
.en_cours
|
||||||
|
.visible_by_administration
|
||||||
|
|
||||||
@followed_dossiers = current_instructeur
|
@followed_dossiers = current_instructeur
|
||||||
.followed_dossiers
|
.followed_dossiers
|
||||||
|
@ -69,7 +70,7 @@ module Instructeurs
|
||||||
|
|
||||||
@followed_dossiers_id = @followed_dossiers.pluck(:id)
|
@followed_dossiers_id = @followed_dossiers.pluck(:id)
|
||||||
|
|
||||||
@termines_dossiers = dossiers_visibles.termine.not_hidden_by_administration
|
@termines_dossiers = dossiers_visibles.termine.visible_by_administration
|
||||||
@all_state_dossiers = dossiers_visibles.all_state
|
@all_state_dossiers = dossiers_visibles.all_state
|
||||||
@archived_dossiers = dossiers_visibles.archived
|
@archived_dossiers = dossiers_visibles.archived
|
||||||
@expirant_dossiers = dossiers_visibles.termine_or_en_construction_close_to_expiration
|
@expirant_dossiers = dossiers_visibles.termine_or_en_construction_close_to_expiration
|
||||||
|
|
|
@ -5,7 +5,7 @@ module Users
|
||||||
layout 'procedure_context', only: [:identite, :update_identite, :siret, :update_siret]
|
layout 'procedure_context', only: [:identite, :update_identite, :siret, :update_siret]
|
||||||
|
|
||||||
ACTIONS_ALLOWED_TO_ANY_USER = [:index, :recherche, :new, :transferer_all]
|
ACTIONS_ALLOWED_TO_ANY_USER = [:index, :recherche, :new, :transferer_all]
|
||||||
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [:show, :demande, :messagerie, :brouillon, :update_brouillon, :modifier, :update, :create_commentaire]
|
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [:show, :demande, :messagerie, :brouillon, :update_brouillon, :modifier, :update, :create_commentaire, :restore]
|
||||||
|
|
||||||
before_action :ensure_ownership!, except: ACTIONS_ALLOWED_TO_ANY_USER + ACTIONS_ALLOWED_TO_OWNER_OR_INVITE
|
before_action :ensure_ownership!, except: ACTIONS_ALLOWED_TO_ANY_USER + ACTIONS_ALLOWED_TO_OWNER_OR_INVITE
|
||||||
before_action :ensure_ownership_or_invitation!, only: ACTIONS_ALLOWED_TO_OWNER_OR_INVITE
|
before_action :ensure_ownership_or_invitation!, only: ACTIONS_ALLOWED_TO_OWNER_OR_INVITE
|
||||||
|
@ -16,17 +16,18 @@ module Users
|
||||||
before_action :store_user_location!, only: :new
|
before_action :store_user_location!, only: :new
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@user_dossiers = current_user.dossiers.includes(:procedure).state_not_termine.order_by_updated_at.page(page)
|
@user_dossiers = current_user.dossiers.includes(:procedure).state_not_termine.visible_by_user.order_by_updated_at.page(page)
|
||||||
@dossiers_traites = current_user.dossiers.includes(:procedure).state_termine.not_hidden_by_user.order_by_updated_at.page(page)
|
@dossiers_traites = current_user.dossiers.includes(:procedure).state_termine.visible_by_user.order_by_updated_at.page(page)
|
||||||
@dossiers_invites = current_user.dossiers_invites.includes(:procedure).order_by_updated_at.page(page)
|
@dossiers_invites = current_user.dossiers_invites.includes(:procedure).order_by_updated_at.page(page)
|
||||||
@dossiers_supprimes = current_user.deleted_dossiers.order_by_updated_at.page(page)
|
@dossiers_supprimes_recemment = current_user.dossiers.hidden_by_user.order_by_updated_at.page(page)
|
||||||
|
@dossiers_supprimes_definitivement = current_user.deleted_dossiers.order_by_updated_at.page(page)
|
||||||
@dossier_transfers = DossierTransfer
|
@dossier_transfers = DossierTransfer
|
||||||
.includes(dossiers: :user)
|
.includes(dossiers: :user)
|
||||||
.with_dossiers
|
.with_dossiers
|
||||||
.where(email: current_user.email)
|
.where(email: current_user.email)
|
||||||
.page(page)
|
.page(page)
|
||||||
@dossiers_close_to_expiration = current_user.dossiers.close_to_expiration.page(page)
|
@dossiers_close_to_expiration = current_user.dossiers.close_to_expiration.page(page)
|
||||||
@statut = statut(@user_dossiers, @dossiers_traites, @dossiers_invites, @dossiers_supprimes, @dossier_transfers, @dossiers_close_to_expiration, params[:statut])
|
@statut = statut(@user_dossiers, @dossiers_traites, @dossiers_invites, @dossiers_supprimes_recemment, @dossiers_supprimes_definitivement, @dossier_transfers, @dossiers_close_to_expiration, params[:statut])
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@ -287,17 +288,24 @@ module Users
|
||||||
@transfer = DossierTransfer.new(dossiers: current_user.dossiers)
|
@transfer = DossierTransfer.new(dossiers: current_user.dossiers)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def restore
|
||||||
|
dossier.restore(current_user)
|
||||||
|
flash.notice = t('users.dossiers.restore')
|
||||||
|
redirect_to dossiers_path
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# if the status tab is filled, then this tab
|
# if the status tab is filled, then this tab
|
||||||
# else first filled tab
|
# else first filled tab
|
||||||
# else en-cours
|
# else en-cours
|
||||||
def statut(mes_dossiers, dossiers_traites, dossiers_invites, dossiers_supprimes, dossier_transfers, dossiers_close_to_expiration, params_statut)
|
def statut(mes_dossiers, dossiers_traites, dossiers_invites, dossiers_supprimes_recemment, dossiers_supprimes_definitivement, dossier_transfers, dossiers_close_to_expiration, params_statut)
|
||||||
tabs = {
|
tabs = {
|
||||||
'en-cours' => mes_dossiers.present?,
|
'en-cours' => mes_dossiers.present?,
|
||||||
'traites' => dossiers_traites.present?,
|
'traites' => dossiers_traites.present?,
|
||||||
'dossiers-invites' => dossiers_invites.present?,
|
'dossiers-invites' => dossiers_invites.present?,
|
||||||
'dossiers-supprimes' => dossiers_supprimes.present?,
|
'dossiers-supprimes-recemment' => dossiers_supprimes_recemment.present?,
|
||||||
|
'dossiers-supprimes-definitivement' => dossiers_supprimes_definitivement.present?,
|
||||||
'dossiers-transferes' => dossier_transfers.present?,
|
'dossiers-transferes' => dossier_transfers.present?,
|
||||||
'dossiers-expirant' => dossiers_close_to_expiration.present?
|
'dossiers-expirant' => dossiers_close_to_expiration.present?
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,15 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def flash_class(level, sticky: false, fixed: false)
|
def flash_class(level, sticky: false, fixed: false)
|
||||||
class_names = case level
|
class_names = []
|
||||||
|
|
||||||
|
case level
|
||||||
when 'notice'
|
when 'notice'
|
||||||
['alert-success']
|
class_names << 'alert-success'
|
||||||
when 'alert'
|
when 'alert', 'error'
|
||||||
['alert-danger']
|
class_names << 'alert-danger'
|
||||||
end
|
end
|
||||||
|
|
||||||
if sticky
|
if sticky
|
||||||
class_names << 'sticky'
|
class_names << 'sticky'
|
||||||
end
|
end
|
||||||
|
|
|
@ -116,6 +116,7 @@ function ComboMultiple({
|
||||||
}
|
}
|
||||||
setTerm('');
|
setTerm('');
|
||||||
awaitFormSubmit.done();
|
awaitFormSubmit.done();
|
||||||
|
hidePopover();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onRemove = (label) => {
|
const onRemove = (label) => {
|
||||||
|
@ -148,6 +149,18 @@ function ComboMultiple({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const hidePopover = () => {
|
||||||
|
document
|
||||||
|
.querySelector(`[data-reach-combobox-popover-id="${inputId}"]`)
|
||||||
|
?.setAttribute('hidden', 'true');
|
||||||
|
};
|
||||||
|
|
||||||
|
const showPopover = () => {
|
||||||
|
document
|
||||||
|
.querySelector(`[data-reach-combobox-popover-id="${inputId}"]`)
|
||||||
|
?.removeAttribute('hidden');
|
||||||
|
};
|
||||||
|
|
||||||
const onBlur = () => {
|
const onBlur = () => {
|
||||||
if (
|
if (
|
||||||
term &&
|
term &&
|
||||||
|
@ -156,6 +169,10 @@ function ComboMultiple({
|
||||||
awaitFormSubmit(() => {
|
awaitFormSubmit(() => {
|
||||||
onSelect(term);
|
onSelect(term);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
hidePopover();
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -185,6 +202,7 @@ function ComboMultiple({
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
|
onClick={showPopover}
|
||||||
autocomplete={false}
|
autocomplete={false}
|
||||||
id={inputId}
|
id={inputId}
|
||||||
aria-label={label}
|
aria-label={label}
|
||||||
|
@ -195,14 +213,25 @@ function ComboMultiple({
|
||||||
/>
|
/>
|
||||||
</ComboboxTokenLabel>
|
</ComboboxTokenLabel>
|
||||||
{results && (results.length > 0 || !acceptNewValues) && (
|
{results && (results.length > 0 || !acceptNewValues) && (
|
||||||
<ComboboxPopover className="shadow-popup">
|
<ComboboxPopover
|
||||||
{results.length === 0 && (
|
className="shadow-popup"
|
||||||
<p>
|
data-reach-combobox-popover-id={inputId}
|
||||||
Aucun résultat{' '}
|
>
|
||||||
<button onClick={() => setTerm('')}>Effacer</button>
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
<ComboboxList>
|
<ComboboxList>
|
||||||
|
{results.length === 0 && (
|
||||||
|
<li data-reach-combobox-no-results>
|
||||||
|
Aucun résultat{' '}
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
setTerm('');
|
||||||
|
inputRef.current?.focus();
|
||||||
|
}}
|
||||||
|
className="button"
|
||||||
|
>
|
||||||
|
Effacer
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
{results.map(([label, value], index) => {
|
{results.map(([label, value], index) => {
|
||||||
if (label.startsWith('--')) {
|
if (label.startsWith('--')) {
|
||||||
return <ComboboxSeparator key={index} value={label} />;
|
return <ComboboxSeparator key={index} value={label} />;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
module DownloadManager
|
module DownloadManager
|
||||||
class ParallelDownloadQueue
|
class ParallelDownloadQueue
|
||||||
include Utils::Retryable
|
|
||||||
DOWNLOAD_MAX_PARALLEL = ENV.fetch('DOWNLOAD_MAX_PARALLEL') { 10 }
|
DOWNLOAD_MAX_PARALLEL = ENV.fetch('DOWNLOAD_MAX_PARALLEL') { 10 }
|
||||||
|
|
||||||
attr_accessor :attachments,
|
attr_accessor :attachments,
|
||||||
|
@ -17,11 +16,9 @@ module DownloadManager
|
||||||
|
|
||||||
attachments.map do |attachment, path|
|
attachments.map do |attachment, path|
|
||||||
begin
|
begin
|
||||||
with_retry(max_attempt: 1) do
|
download_one(attachment: attachment,
|
||||||
download_one(attachment: attachment,
|
path_in_download_dir: path,
|
||||||
path_in_download_dir: path,
|
http_client: hydra)
|
||||||
http_client: hydra)
|
|
||||||
end
|
|
||||||
rescue => e
|
rescue => e
|
||||||
on_error.call(attachment, path, e)
|
on_error.call(attachment, path, e)
|
||||||
end
|
end
|
||||||
|
@ -47,14 +44,12 @@ module DownloadManager
|
||||||
request.on_complete do |response|
|
request.on_complete do |response|
|
||||||
fd.close
|
fd.close
|
||||||
unless response.success?
|
unless response.success?
|
||||||
raise 'ko'
|
File.delete(attachment_path) if File.exist?(attachment_path) # -> case of retries failed, must cleanup partialy downloaded file
|
||||||
|
on_error.call(attachment, path_in_download_dir, response.code)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
http_client.queue(request)
|
http_client.queue(request)
|
||||||
end
|
end
|
||||||
rescue
|
|
||||||
File.delete(attachment_path) if File.exist?(attachment_path) # -> case of retries failed, must cleanup partialy downloaded file
|
|
||||||
raise
|
|
||||||
end
|
end
|
||||||
# rubocop:enable Style/AutoResourceCleanup
|
# rubocop:enable Style/AutoResourceCleanup
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,18 +9,20 @@ module DownloadManager
|
||||||
@procedure = procedure
|
@procedure = procedure
|
||||||
@errors = {}
|
@errors = {}
|
||||||
@queue = ParallelDownloadQueue.new(attachments, destination)
|
@queue = ParallelDownloadQueue.new(attachments, destination)
|
||||||
@queue.on_error = proc do |_attachment, path, error|
|
@queue.on_error = proc do |attachment, path, error|
|
||||||
errors[path] = true
|
errors[path] = [attachment, path]
|
||||||
Rails.logger.error("Fail to download filename #{path} in procedure##{@procedure.id}, reason: #{error}")
|
Rails.logger.error("Fail to download filename #{path} in procedure##{@procedure.id}, reason: #{error}")
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def download_all
|
|
||||||
@queue.download_all
|
|
||||||
write_report if !errors.empty?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
def download_all(attempt_left: 1)
|
||||||
|
@queue.download_all
|
||||||
|
if !errors.empty? && attempt_left.positive?
|
||||||
|
retryable_queue = self.class.new(@procedure, errors.values, destination)
|
||||||
|
retryable_queue.download_all(attempt_left: 0)
|
||||||
|
retryable_queue.write_report if !retryable_queue.errors.empty?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def write_report
|
def write_report
|
||||||
manifest_path = File.join(destination, 'LISEZMOI.txt')
|
manifest_path = File.join(destination, 'LISEZMOI.txt')
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
module Utils
|
|
||||||
module Retryable
|
|
||||||
# usage:
|
|
||||||
# max_attempt : retry count
|
|
||||||
# errors : only retry those errors
|
|
||||||
# with_retry(max_attempt: 10, errors: [StandardError]) do
|
|
||||||
# do_something_which_can_fail
|
|
||||||
# end
|
|
||||||
def with_retry(max_attempt: 1, errors: [StandardError], &block)
|
|
||||||
limiter = 0
|
|
||||||
begin
|
|
||||||
yield
|
|
||||||
rescue *errors
|
|
||||||
limiter += 1
|
|
||||||
retry if limiter <= max_attempt
|
|
||||||
raise
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -206,9 +206,10 @@ class Dossier < ApplicationRecord
|
||||||
|
|
||||||
scope :archived, -> { where(archived: true) }
|
scope :archived, -> { where(archived: true) }
|
||||||
scope :not_archived, -> { where(archived: false) }
|
scope :not_archived, -> { where(archived: false) }
|
||||||
|
scope :hidden_by_user, -> { where.not(hidden_by_user_at: nil) }
|
||||||
scope :hidden_by_administration, -> { where.not(hidden_by_administration_at: nil) }
|
scope :hidden_by_administration, -> { where.not(hidden_by_administration_at: nil) }
|
||||||
scope :not_hidden_by_user, -> { where(hidden_by_user_at: nil) }
|
scope :visible_by_user, -> { where(hidden_by_user_at: nil) }
|
||||||
scope :not_hidden_by_administration, -> { where(hidden_by_administration_at: nil) }
|
scope :visible_by_administration, -> { where("hidden_by_administration_at IS NULL AND NOT (hidden_by_user_at IS NOT NULL AND state = 'en_construction')") }
|
||||||
|
|
||||||
scope :order_by_updated_at, -> (order = :desc) { order(updated_at: order) }
|
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 :order_by_created_at, -> (order = :asc) { order(depose_at: order, created_at: order, id: order) }
|
||||||
|
@ -237,7 +238,7 @@ class Dossier < ApplicationRecord
|
||||||
end
|
end
|
||||||
scope :downloadable_sorted, -> {
|
scope :downloadable_sorted, -> {
|
||||||
state_not_brouillon
|
state_not_brouillon
|
||||||
.not_hidden_by_administration
|
.visible_by_administration
|
||||||
.includes(
|
.includes(
|
||||||
:user,
|
:user,
|
||||||
:individual,
|
:individual,
|
||||||
|
@ -346,23 +347,26 @@ class Dossier < ApplicationRecord
|
||||||
scope :without_en_construction_expiration_notice_sent, -> { where(en_construction_close_to_expiration_notice_sent_at: nil) }
|
scope :without_en_construction_expiration_notice_sent, -> { where(en_construction_close_to_expiration_notice_sent_at: nil) }
|
||||||
scope :without_termine_expiration_notice_sent, -> { where(termine_close_to_expiration_notice_sent_at: nil) }
|
scope :without_termine_expiration_notice_sent, -> { where(termine_close_to_expiration_notice_sent_at: nil) }
|
||||||
|
|
||||||
|
scope :discarded_expired, -> { discarded.where('dossiers.hidden_at < ?', 1.week.ago) }
|
||||||
|
scope :discarded_by_user_expired, -> { discarded.where('dossiers.hidden_by_user_at < ?', 1.week.ago) }
|
||||||
|
scope :discarded_by_administration_expired, -> { discarded.where('dossiers.hidden_by_administration_at < ?', 1.week.ago) }
|
||||||
scope :discarded_brouillon_expired, -> do
|
scope :discarded_brouillon_expired, -> do
|
||||||
with_discarded
|
with_discarded
|
||||||
.discarded
|
|
||||||
.state_brouillon
|
.state_brouillon
|
||||||
.where('hidden_at < ?', 1.week.ago)
|
.discarded_expired
|
||||||
|
.or(state_brouillon.discarded_by_user_expired)
|
||||||
end
|
end
|
||||||
scope :discarded_en_construction_expired, -> do
|
scope :discarded_en_construction_expired, -> do
|
||||||
with_discarded
|
with_discarded
|
||||||
.discarded
|
|
||||||
.state_en_construction
|
.state_en_construction
|
||||||
.where('dossiers.hidden_at < ?', 1.week.ago)
|
.discarded_expired
|
||||||
|
.or(state_en_construction.discarded_by_user_expired)
|
||||||
end
|
end
|
||||||
scope :discarded_termine_expired, -> do
|
scope :discarded_termine_expired, -> do
|
||||||
with_discarded
|
with_discarded
|
||||||
.discarded
|
|
||||||
.state_termine
|
.state_termine
|
||||||
.where('dossiers.hidden_at < ?', 1.week.ago)
|
.discarded_expired
|
||||||
|
.or(state_termine.discarded_by_user_expired.discarded_by_administration_expired)
|
||||||
end
|
end
|
||||||
|
|
||||||
scope :brouillon_near_procedure_closing_date, -> do
|
scope :brouillon_near_procedure_closing_date, -> do
|
||||||
|
@ -531,6 +535,10 @@ class Dossier < ApplicationRecord
|
||||||
brouillon? || en_construction? || termine?
|
brouillon? || en_construction? || termine?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_be_hidden_by_user?
|
||||||
|
en_construction? || termine?
|
||||||
|
end
|
||||||
|
|
||||||
def can_be_deleted_by_manager?
|
def can_be_deleted_by_manager?
|
||||||
kept? && can_be_deleted_by_user?
|
kept? && can_be_deleted_by_user?
|
||||||
end
|
end
|
||||||
|
@ -750,16 +758,26 @@ class Dossier < ApplicationRecord
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def discard_and_keep_track!(author, reason)
|
def author_is_user(author)
|
||||||
author_is_user = author.is_a?(User)
|
author.is_a?(User)
|
||||||
author_is_administration = author.is_a?(Instructeur) || author.is_a?(Administrateur) || author.is_a?(SuperAdmin)
|
end
|
||||||
|
|
||||||
if termine? && author_is_administration
|
def author_is_administration(author)
|
||||||
|
author.is_a?(Instructeur) || author.is_a?(Administrateur) || author.is_a?(SuperAdmin)
|
||||||
|
end
|
||||||
|
|
||||||
|
def restore_dossier_and_destroy_deleted_dossier(author)
|
||||||
|
deleted_dossier&.destroy!
|
||||||
|
log_dossier_operation(author, :restaurer, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def discard_and_keep_track!(author, reason)
|
||||||
|
if termine? && author_is_administration(author)
|
||||||
update(hidden_by_administration_at: Time.zone.now)
|
update(hidden_by_administration_at: Time.zone.now)
|
||||||
end
|
end
|
||||||
|
|
||||||
if termine? && author_is_user
|
if can_be_hidden_by_user? && author_is_user(author)
|
||||||
update(hidden_by_user_at: Time.zone.now)
|
update(hidden_by_user_at: Time.zone.now, dossier_transfer_id: nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
user_email = user_deleted? ? nil : user_email_for(:notification)
|
user_email = user_deleted? ? nil : user_email_for(:notification)
|
||||||
|
@ -772,8 +790,9 @@ class Dossier < ApplicationRecord
|
||||||
deleted_dossier = DeletedDossier.create_from_dossier(self, reason)
|
deleted_dossier = DeletedDossier.create_from_dossier(self, reason)
|
||||||
end
|
end
|
||||||
|
|
||||||
update!(dossier_transfer_id: nil)
|
if !(en_construction? && author_is_user(author))
|
||||||
discard!
|
discard!
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -798,11 +817,19 @@ class Dossier < ApplicationRecord
|
||||||
def restore(author)
|
def restore(author)
|
||||||
if discarded?
|
if discarded?
|
||||||
transaction do
|
transaction do
|
||||||
if hidden_by_administration?
|
if author_is_administration(author) && hidden_by_administration?
|
||||||
update(hidden_by_administration_at: nil)
|
update(hidden_by_administration_at: nil)
|
||||||
elsif undiscard && keep_track_on_deletion?
|
end
|
||||||
deleted_dossier&.destroy!
|
|
||||||
log_dossier_operation(author, :restaurer, self)
|
if undiscard && keep_track_on_deletion?
|
||||||
|
restore_dossier_and_destroy_deleted_dossier(author)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif author_is_user(author) && hidden_by_user?
|
||||||
|
transaction do
|
||||||
|
update(hidden_by_user_at: nil)
|
||||||
|
if en_construction?
|
||||||
|
restore_dossier_and_destroy_deleted_dossier(author)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -232,7 +232,7 @@ class Instructeur < ApplicationRecord
|
||||||
def dossiers_count_summary(groupe_instructeur_ids)
|
def dossiers_count_summary(groupe_instructeur_ids)
|
||||||
query = <<~EOF
|
query = <<~EOF
|
||||||
SELECT
|
SELECT
|
||||||
COUNT(DISTINCT dossiers.id) FILTER (where not archived AND dossiers.state in ('en_construction', 'en_instruction') AND follows.id IS NULL) AS a_suivre,
|
COUNT(DISTINCT dossiers.id) FILTER (where not archived AND NOT (dossiers.hidden_by_user_at IS NOT NULL AND state = 'en_construction') AND dossiers.state in ('en_construction', 'en_instruction') AND follows.id IS NULL) AS a_suivre,
|
||||||
COUNT(DISTINCT dossiers.id) FILTER (where not archived AND dossiers.state in ('en_construction', 'en_instruction') AND follows.instructeur_id = :instructeur_id) AS suivis,
|
COUNT(DISTINCT dossiers.id) FILTER (where not archived AND dossiers.state in ('en_construction', 'en_instruction') AND follows.instructeur_id = :instructeur_id) AS suivis,
|
||||||
COUNT(DISTINCT dossiers.id) FILTER (where not archived AND dossiers.state in ('accepte', 'refuse', 'sans_suite')) AS traites,
|
COUNT(DISTINCT dossiers.id) FILTER (where not archived AND dossiers.state in ('accepte', 'refuse', 'sans_suite')) AS traites,
|
||||||
COUNT(DISTINCT dossiers.id) FILTER (where not archived) AS tous,
|
COUNT(DISTINCT dossiers.id) FILTER (where not archived) AS tous,
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
%tbody
|
%tbody
|
||||||
- deleted_dossiers.each do |dossier|
|
- deleted_dossiers.each do |dossier|
|
||||||
- libelle_demarche = Procedure.find(dossier.procedure_id).libelle
|
- libelle_demarche = Procedure.find(dossier.procedure_id).libelle
|
||||||
|
|
||||||
%tr{ data: { 'dossier-id': dossier.dossier_id } }
|
%tr{ data: { 'dossier-id': dossier.dossier_id } }
|
||||||
%td.number-col
|
%td.number-col
|
||||||
%span.icon.folder
|
%span.icon.folder
|
||||||
|
|
36
app/views/users/dossiers/_hidden_dossiers_list.html.haml
Normal file
36
app/views/users/dossiers/_hidden_dossiers_list.html.haml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
- if hidden_dossiers.present?
|
||||||
|
%table.table.dossiers-table.hoverable
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th.number-col Nº dossier
|
||||||
|
%th Démarche
|
||||||
|
%th Raison de suppression
|
||||||
|
%th Date de suppression
|
||||||
|
%tbody
|
||||||
|
- hidden_dossiers.each do |dossier|
|
||||||
|
- libelle_demarche = dossier.procedure.libelle
|
||||||
|
|
||||||
|
%tr{ data: { 'dossier-id': dossier.id } }
|
||||||
|
%td.number-col
|
||||||
|
%span.icon.folder
|
||||||
|
= dossier.id
|
||||||
|
%td
|
||||||
|
= libelle_demarche
|
||||||
|
|
||||||
|
%td.cell-link
|
||||||
|
= deletion_reason_badge("user_request")
|
||||||
|
%td
|
||||||
|
= dossier.updated_at.strftime('%d/%m/%Y')
|
||||||
|
%td
|
||||||
|
= link_to restore_dossier_path(dossier.id), method: :patch, class: "button primary" do
|
||||||
|
Restaurer
|
||||||
|
|
||||||
|
= paginate(hidden_dossiers)
|
||||||
|
|
||||||
|
- else
|
||||||
|
.blank-tab
|
||||||
|
%h2.empty-text Aucun dossier.
|
||||||
|
%p.empty-text-details
|
||||||
|
Pour remplir une démarche, contactez votre administration en lui demandant le lien de la démarche.
|
||||||
|
%br
|
||||||
|
Celui ci doit ressembler à #{APPLICATION_BASE_URL}/commencer/xxx.
|
|
@ -39,11 +39,17 @@
|
||||||
active: @statut == 'dossiers-expirant',
|
active: @statut == 'dossiers-expirant',
|
||||||
badge: number_with_html_delimiter(@dossiers_close_to_expiration.count))
|
badge: number_with_html_delimiter(@dossiers_close_to_expiration.count))
|
||||||
|
|
||||||
- if @dossiers_supprimes.present?
|
- if @dossiers_supprimes_recemment.present?
|
||||||
= tab_item(t('pluralize.dossiers_supprimes', count: @dossiers_supprimes.count),
|
= tab_item(t('pluralize.dossiers_supprimes_recemment', count: @dossiers_supprimes_recemment.count),
|
||||||
dossiers_path(statut: 'dossiers-supprimes'),
|
dossiers_path(statut: 'dossiers-supprimes-recemment'),
|
||||||
active: @statut == 'dossiers-supprimes',
|
active: @statut == 'dossiers-supprimes-recemment',
|
||||||
badge: number_with_html_delimiter(@dossiers_supprimes.count))
|
badge: number_with_html_delimiter(@dossiers_supprimes_recemment.count))
|
||||||
|
|
||||||
|
- if @dossiers_supprimes_definitivement.present?
|
||||||
|
= tab_item(t('pluralize.dossiers_supprimes_definitivement', count: @dossiers_supprimes_definitivement.count),
|
||||||
|
dossiers_path(statut: 'dossiers-supprimes-definitivement'),
|
||||||
|
active: @statut == 'dossiers-supprimes-definitivement',
|
||||||
|
badge: number_with_html_delimiter(@dossiers_supprimes_definitivement.count))
|
||||||
|
|
||||||
- if @dossier_transfers.present?
|
- if @dossier_transfers.present?
|
||||||
= tab_item(t('pluralize.dossiers_transferes', count: @dossier_transfers.count),
|
= tab_item(t('pluralize.dossiers_transferes', count: @dossier_transfers.count),
|
||||||
|
@ -61,8 +67,12 @@
|
||||||
- if @statut == "dossiers-invites"
|
- if @statut == "dossiers-invites"
|
||||||
= render partial: "dossiers_list", locals: { dossiers: @dossiers_invites }
|
= render partial: "dossiers_list", locals: { dossiers: @dossiers_invites }
|
||||||
|
|
||||||
- if @statut == "dossiers-supprimes"
|
- if @statut == "dossiers-supprimes-recemment"
|
||||||
= render partial: "deleted_dossiers_list", locals: { deleted_dossiers: @dossiers_supprimes }
|
= render partial: "hidden_dossiers_list", locals: { hidden_dossiers: @dossiers_supprimes_recemment }
|
||||||
|
|
||||||
|
- if @statut == "dossiers-supprimes-definitivement"
|
||||||
|
= render partial: "deleted_dossiers_list", locals: { deleted_dossiers: @dossiers_supprimes_definitivement }
|
||||||
|
|
||||||
- if @statut == "dossiers-transferes"
|
- if @statut == "dossiers-transferes"
|
||||||
= render partial: "transfered_dossiers_list", locals: { dossier_transfers: @dossier_transfers }
|
= render partial: "transfered_dossiers_list", locals: { dossier_transfers: @dossier_transfers }
|
||||||
|
|
||||||
|
|
|
@ -364,10 +364,14 @@ en:
|
||||||
zero: guest file
|
zero: guest file
|
||||||
one: guest file
|
one: guest file
|
||||||
other: guest files
|
other: guest files
|
||||||
dossiers_supprimes:
|
dossiers_supprimes_recemment:
|
||||||
zero: deleted file
|
zero: recently deleted file
|
||||||
one: deleted file
|
one: recently deleted file
|
||||||
other: deleted files
|
other: recently deleted files
|
||||||
|
dossiers_supprimes_definitivement:
|
||||||
|
zero: permanently deleted file
|
||||||
|
one: permanently deleted file
|
||||||
|
other: permanently deleted files
|
||||||
dossiers_transferes:
|
dossiers_transferes:
|
||||||
zero: transfer request
|
zero: transfer request
|
||||||
one: transfer request
|
one: transfer request
|
||||||
|
@ -402,6 +406,7 @@ en:
|
||||||
ask_deletion:
|
ask_deletion:
|
||||||
undergoingreview: "Your file is undergoing review. It is no longer possible to delete your file. To cancel the undergoingreview contact the adminitration via the mailbox."
|
undergoingreview: "Your file is undergoing review. It is no longer possible to delete your file. To cancel the undergoingreview contact the adminitration via the mailbox."
|
||||||
soft_deleted_dossier: "Your file has been successfully deleted from your interface"
|
soft_deleted_dossier: "Your file has been successfully deleted from your interface"
|
||||||
|
restore: "Your file has been successfully restored"
|
||||||
update_brouillon:
|
update_brouillon:
|
||||||
draft_saved: "Your draft has been saved."
|
draft_saved: "Your draft has been saved."
|
||||||
etablissement:
|
etablissement:
|
||||||
|
|
|
@ -371,10 +371,14 @@ fr:
|
||||||
zero: dossier invité
|
zero: dossier invité
|
||||||
one: dossier invité
|
one: dossier invité
|
||||||
other: dossiers invités
|
other: dossiers invités
|
||||||
dossiers_supprimes:
|
dossiers_supprimes_recemment:
|
||||||
zero: dossier supprimé
|
zero: dossier supprimé recemment
|
||||||
one: dossier supprimé
|
one: dossier supprimé recemment
|
||||||
other: dossiers supprimés
|
other: dossiers supprimés recemment
|
||||||
|
dossiers_supprimes_definitivement:
|
||||||
|
zero: dossier supprimé définitivement
|
||||||
|
one: dossier supprimé définitivement
|
||||||
|
other: dossiers supprimés définitivement
|
||||||
dossiers_transferes:
|
dossiers_transferes:
|
||||||
zero: demande de transfert
|
zero: demande de transfert
|
||||||
one: demande de transfert
|
one: demande de transfert
|
||||||
|
@ -410,6 +414,7 @@ fr:
|
||||||
ask_deletion:
|
ask_deletion:
|
||||||
undergoingreview: "L’instruction de votre dossier a commencé, il n’est plus possible de supprimer votre dossier. Si vous souhaitez annuler l’instruction contactez votre administration par la messagerie de votre dossier."
|
undergoingreview: "L’instruction de votre dossier a commencé, il n’est plus possible de supprimer votre dossier. Si vous souhaitez annuler l’instruction contactez votre administration par la messagerie de votre dossier."
|
||||||
soft_deleted_dossier: "Votre dossier a bien été supprimé de votre interface"
|
soft_deleted_dossier: "Votre dossier a bien été supprimé de votre interface"
|
||||||
|
restore: "Votre dossier a bien été restauré"
|
||||||
update_brouillon:
|
update_brouillon:
|
||||||
draft_saved: "Votre brouillon a bien été sauvegardé."
|
draft_saved: "Votre brouillon a bien été sauvegardé."
|
||||||
etablissement:
|
etablissement:
|
||||||
|
|
|
@ -269,6 +269,7 @@ Rails.application.routes.draw do
|
||||||
get 'messagerie'
|
get 'messagerie'
|
||||||
post 'commentaire' => 'dossiers#create_commentaire'
|
post 'commentaire' => 'dossiers#create_commentaire'
|
||||||
patch 'delete_dossier'
|
patch 'delete_dossier'
|
||||||
|
patch 'restore', to: 'dossiers#restore'
|
||||||
get 'attestation'
|
get 'attestation'
|
||||||
get 'transferer', to: 'dossiers#transferer'
|
get 'transferer', to: 'dossiers#transferer'
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
describe Administrateurs::ProcedureAdministrateursController, type: :controller do
|
||||||
|
let(:signed_in_admin) { create(:administrateur) }
|
||||||
|
let(:other_admin) { create(:administrateur) }
|
||||||
|
let(:procedure) { create(:procedure, administrateurs: [signed_in_admin, other_admin]) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(signed_in_admin.user)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#destroy' do
|
||||||
|
subject do
|
||||||
|
delete :destroy, params: { procedure_id: procedure.id, id: admin_to_remove.id }, format: :js, xhr: true
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when removing another admin' do
|
||||||
|
let(:admin_to_remove) { other_admin }
|
||||||
|
|
||||||
|
it 'removes the admin from the procedure' do
|
||||||
|
subject
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(flash[:notice]).to be_present
|
||||||
|
expect(admin_to_remove.procedures.reload).not_to include(procedure)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when removing oneself from a procedure' do
|
||||||
|
let(:admin_to_remove) { signed_in_admin }
|
||||||
|
|
||||||
|
it 'denies the right for an admin to remove itself' do
|
||||||
|
subject
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(flash[:alert]).to be_present
|
||||||
|
expect(admin_to_remove.procedures.reload).to include(procedure)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1028,13 +1028,13 @@ describe Users::DossiersController, type: :controller do
|
||||||
subject
|
subject
|
||||||
end
|
end
|
||||||
|
|
||||||
it "deletes the dossier" do
|
it "hide the dossier and create a deleted dossier" do
|
||||||
procedure = dossier.procedure
|
procedure = dossier.procedure
|
||||||
dossier_id = dossier.id
|
dossier_id = dossier.id
|
||||||
subject
|
subject
|
||||||
expect(Dossier.find_by(id: dossier_id)).to eq(nil)
|
expect(Dossier.find_by(id: dossier_id)).to be_present
|
||||||
|
expect(Dossier.find_by(id: dossier_id).hidden_by_user_at).to be_present
|
||||||
expect(procedure.deleted_dossiers.count).to eq(1)
|
expect(procedure.deleted_dossiers.count).to eq(1)
|
||||||
expect(procedure.deleted_dossiers.first.dossier_id).to eq(dossier_id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it { is_expected.to redirect_to(dossiers_path) }
|
it { is_expected.to redirect_to(dossiers_path) }
|
||||||
|
@ -1065,6 +1065,21 @@ describe Users::DossiersController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#restore' do
|
||||||
|
before { sign_in(user) }
|
||||||
|
subject { patch :restore, params: { id: dossier.id } }
|
||||||
|
|
||||||
|
context 'when the user want to restore his dossier' do
|
||||||
|
let!(:dossier) { create(:dossier, :with_individual, state: :accepte, en_construction_at: Time.zone.yesterday.beginning_of_day.utc, hidden_by_user_at: Time.zone.yesterday.beginning_of_day.utc, user: user, autorisation_donnees: true) }
|
||||||
|
|
||||||
|
before { subject }
|
||||||
|
|
||||||
|
it 'must have hidden_by_user_at nil' do
|
||||||
|
expect(dossier.reload.hidden_by_user_at).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#new' do
|
describe '#new' do
|
||||||
let(:procedure) { create(:procedure, :published) }
|
let(:procedure) { create(:procedure, :published) }
|
||||||
let(:procedure_id) { procedure.id }
|
let(:procedure_id) { procedure.id }
|
||||||
|
|
51
spec/fixtures/cassettes/archive/file_to_get.yml
vendored
51
spec/fixtures/cassettes/archive/file_to_get.yml
vendored
|
@ -1,51 +0,0 @@
|
||||||
---
|
|
||||||
http_interactions:
|
|
||||||
- request:
|
|
||||||
method: get
|
|
||||||
uri: http://file.to/get.ext
|
|
||||||
body:
|
|
||||||
encoding: US-ASCII
|
|
||||||
string: ''
|
|
||||||
headers:
|
|
||||||
User-Agent:
|
|
||||||
- demarches-simplifiees.fr
|
|
||||||
Expect:
|
|
||||||
- ''
|
|
||||||
response:
|
|
||||||
status:
|
|
||||||
code: 200
|
|
||||||
message: ''
|
|
||||||
headers:
|
|
||||||
Last-Modified:
|
|
||||||
- Thu, 16 Dec 2021 13:04:07 GMT
|
|
||||||
X-Trans-Id:
|
|
||||||
- tx62bf43b03d7e4b60b3f25-0061d45dbd
|
|
||||||
Accept-Ranges:
|
|
||||||
- bytes
|
|
||||||
Expires:
|
|
||||||
- Tue, 04 Jan 2022 15:20:54 GMT
|
|
||||||
X-Openstack-Request-Id:
|
|
||||||
- tx62bf43b03d7e4b60b3f25-0061d45dbd
|
|
||||||
Content-Type:
|
|
||||||
- image/png
|
|
||||||
Date:
|
|
||||||
- Tue, 04 Jan 2022 14:46:21 GMT
|
|
||||||
X-Iplb-Request-Id:
|
|
||||||
- 877D6D0C:B8E4_5762BBC9:01BB_61D45DBD_104936A5:293F4
|
|
||||||
X-Timestamp:
|
|
||||||
- '1639659846.52947'
|
|
||||||
Etag:
|
|
||||||
- 49961feab1c277af65fcb876c379cebf
|
|
||||||
X-Iplb-Instance:
|
|
||||||
- '42085'
|
|
||||||
Content-Length:
|
|
||||||
- '494761'
|
|
||||||
Content-Disposition:
|
|
||||||
- inline; filename="Screen Shot 2021-12-09 at 9.42.44 AM.png"; filename*=UTF-8''Screen%20Shot%202021-12-09%20at%209.42.44%20AM.png
|
|
||||||
Strict-Transport-Security:
|
|
||||||
- max-age=63072000
|
|
||||||
body:
|
|
||||||
encoding: ASCII-8BIT
|
|
||||||
string: ''
|
|
||||||
recorded_at: Wed, 04 Mar 2020 23:00:00 GMT
|
|
||||||
recorded_with: VCR 6.0.0
|
|
|
@ -1,145 +0,0 @@
|
||||||
---
|
|
||||||
http_interactions:
|
|
||||||
- request:
|
|
||||||
method: get
|
|
||||||
uri: https://i.etsystatic.com/6212702/r/il/744d2c/470726480/il_1588xN.470726480_bpk5.jpg
|
|
||||||
body:
|
|
||||||
encoding: US-ASCII
|
|
||||||
string: ''
|
|
||||||
headers:
|
|
||||||
User-Agent:
|
|
||||||
- demarches-simplifiees.fr
|
|
||||||
Expect:
|
|
||||||
- ''
|
|
||||||
response:
|
|
||||||
status:
|
|
||||||
code: 200
|
|
||||||
message: ''
|
|
||||||
headers:
|
|
||||||
Cache-Control:
|
|
||||||
- public, max-age=365000000, immutable
|
|
||||||
Content-Type:
|
|
||||||
- image/jpeg
|
|
||||||
Etag:
|
|
||||||
- '"J9Qt3QnUKZIbmKehfH+pmv/rYxafyM81ENfBKsCN6Qw"'
|
|
||||||
Expires:
|
|
||||||
- Mon, 02 Jan 2023 05:24:30 GMT
|
|
||||||
Fastly-Io-Info:
|
|
||||||
- ifsz=14677 idim=600x600 ifmt=jpeg ofsz=43339 odim=1588x1588 ofmt=jpeg
|
|
||||||
Fastly-Stats:
|
|
||||||
- io=1
|
|
||||||
Server:
|
|
||||||
- UploadServer
|
|
||||||
X-Goog-Generation:
|
|
||||||
- '1514228438620441'
|
|
||||||
X-Goog-Hash:
|
|
||||||
- crc32c=ZohETA==
|
|
||||||
- md5=iKPGsaOoUN0hhNZYYzYDLQ==
|
|
||||||
X-Goog-Metageneration:
|
|
||||||
- '1'
|
|
||||||
X-Goog-Storage-Class:
|
|
||||||
- MULTI_REGIONAL
|
|
||||||
X-Goog-Stored-Content-Encoding:
|
|
||||||
- identity
|
|
||||||
X-Goog-Stored-Content-Length:
|
|
||||||
- '14677'
|
|
||||||
X-Guploader-Uploadid:
|
|
||||||
- ADPycdvXmKF1KUStMVeN1v5TUKBQA_YezSueBDRwp4qiVKTn5IDoW7f3_t6_tyvJwjkOoUE4lO1cC_NxSl-LkM5ukthJcv6JkA
|
|
||||||
Via:
|
|
||||||
- 1.1 varnish, 1.1 varnish
|
|
||||||
Accept-Ranges:
|
|
||||||
- bytes
|
|
||||||
Date:
|
|
||||||
- Tue, 04 Jan 2022 14:59:40 GMT
|
|
||||||
Age:
|
|
||||||
- '207310'
|
|
||||||
X-Served-By:
|
|
||||||
- cache-mdw17340-MDW, cache-cdg20755-CDG
|
|
||||||
X-Cache:
|
|
||||||
- HIT, HIT
|
|
||||||
X-Cache-Hits:
|
|
||||||
- 1, 1
|
|
||||||
X-Timer:
|
|
||||||
- S1641308380.238785,VS0,VE1
|
|
||||||
Vary:
|
|
||||||
- Accept
|
|
||||||
Strict-Transport-Security:
|
|
||||||
- max-age=300
|
|
||||||
Content-Length:
|
|
||||||
- '43339'
|
|
||||||
body:
|
|
||||||
encoding: ASCII-8BIT
|
|
||||||
string: ''
|
|
||||||
recorded_at: Wed, 04 Mar 2020 23:00:00 GMT
|
|
||||||
- request:
|
|
||||||
method: get
|
|
||||||
uri: https://i.etsystatic.com/6212702/r/il/744d2c/470726480/il_1588xN.470726480_bpk5.jpg
|
|
||||||
body:
|
|
||||||
encoding: US-ASCII
|
|
||||||
string: ''
|
|
||||||
headers:
|
|
||||||
User-Agent:
|
|
||||||
- demarches-simplifiees.fr
|
|
||||||
Expect:
|
|
||||||
- ''
|
|
||||||
response:
|
|
||||||
status:
|
|
||||||
code: 200
|
|
||||||
message: ''
|
|
||||||
headers:
|
|
||||||
Cache-Control:
|
|
||||||
- public, max-age=365000000, immutable
|
|
||||||
Content-Type:
|
|
||||||
- image/jpeg
|
|
||||||
Etag:
|
|
||||||
- '"J9Qt3QnUKZIbmKehfH+pmv/rYxafyM81ENfBKsCN6Qw"'
|
|
||||||
Expires:
|
|
||||||
- Mon, 02 Jan 2023 05:24:30 GMT
|
|
||||||
Fastly-Io-Info:
|
|
||||||
- ifsz=14677 idim=600x600 ifmt=jpeg ofsz=43339 odim=1588x1588 ofmt=jpeg
|
|
||||||
Fastly-Stats:
|
|
||||||
- io=1
|
|
||||||
Server:
|
|
||||||
- UploadServer
|
|
||||||
X-Goog-Generation:
|
|
||||||
- '1514228438620441'
|
|
||||||
X-Goog-Hash:
|
|
||||||
- crc32c=ZohETA==
|
|
||||||
- md5=iKPGsaOoUN0hhNZYYzYDLQ==
|
|
||||||
X-Goog-Metageneration:
|
|
||||||
- '1'
|
|
||||||
X-Goog-Storage-Class:
|
|
||||||
- MULTI_REGIONAL
|
|
||||||
X-Goog-Stored-Content-Encoding:
|
|
||||||
- identity
|
|
||||||
X-Goog-Stored-Content-Length:
|
|
||||||
- '14677'
|
|
||||||
X-Guploader-Uploadid:
|
|
||||||
- ADPycdvXmKF1KUStMVeN1v5TUKBQA_YezSueBDRwp4qiVKTn5IDoW7f3_t6_tyvJwjkOoUE4lO1cC_NxSl-LkM5ukthJcv6JkA
|
|
||||||
Via:
|
|
||||||
- 1.1 varnish, 1.1 varnish
|
|
||||||
Accept-Ranges:
|
|
||||||
- bytes
|
|
||||||
Date:
|
|
||||||
- Tue, 04 Jan 2022 14:59:40 GMT
|
|
||||||
Age:
|
|
||||||
- '207310'
|
|
||||||
X-Served-By:
|
|
||||||
- cache-mdw17340-MDW, cache-cdg20737-CDG
|
|
||||||
X-Cache:
|
|
||||||
- HIT, HIT
|
|
||||||
X-Cache-Hits:
|
|
||||||
- 1, 1
|
|
||||||
X-Timer:
|
|
||||||
- S1641308380.241689,VS0,VE1
|
|
||||||
Vary:
|
|
||||||
- Accept
|
|
||||||
Strict-Transport-Security:
|
|
||||||
- max-age=300
|
|
||||||
Content-Length:
|
|
||||||
- '43339'
|
|
||||||
body:
|
|
||||||
encoding: ASCII-8BIT
|
|
||||||
string: ''
|
|
||||||
recorded_at: Wed, 04 Mar 2020 23:00:00 GMT
|
|
||||||
recorded_with: VCR 6.0.0
|
|
80
spec/fixtures/cassettes/archive/new_file_to_get_200.yml
vendored
Normal file
80
spec/fixtures/cassettes/archive/new_file_to_get_200.yml
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
---
|
||||||
|
http_interactions:
|
||||||
|
- request:
|
||||||
|
method: get
|
||||||
|
uri: https://opengraph.githubassets.com/d0e7862b24d8026a3c03516d865b28151eb3859029c6c6c2e86605891fbdcd7a/socketry/async-io
|
||||||
|
body:
|
||||||
|
encoding: US-ASCII
|
||||||
|
string: ''
|
||||||
|
headers:
|
||||||
|
User-Agent:
|
||||||
|
- demarches-simplifiees.fr
|
||||||
|
Expect:
|
||||||
|
- ''
|
||||||
|
response:
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: ''
|
||||||
|
headers:
|
||||||
|
X-Ratelimit-Limit:
|
||||||
|
- '100'
|
||||||
|
X-Ratelimit-Remaining:
|
||||||
|
- '31'
|
||||||
|
X-Ratelimit-Reset:
|
||||||
|
- '1641406997'
|
||||||
|
Access-Control-Allow-Origin:
|
||||||
|
- "*"
|
||||||
|
Content-Security-Policy:
|
||||||
|
- default-src 'none';style-src 'unsafe-inline';font-src https://github.github.com;img-src
|
||||||
|
https://avatars.githubusercontent.com https://github.githubassets.com https://camo.githubusercontent.com
|
||||||
|
X-Dns-Prefetch-Control:
|
||||||
|
- 'off'
|
||||||
|
Expect-Ct:
|
||||||
|
- max-age=0
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
Referrer-Policy:
|
||||||
|
- no-referrer
|
||||||
|
X-Xss-Protection:
|
||||||
|
- '0'
|
||||||
|
Cache-Control:
|
||||||
|
- public, max-age=21600, immutable
|
||||||
|
Content-Type:
|
||||||
|
- image/png
|
||||||
|
Etag:
|
||||||
|
- W/"106ec-qZkXmv4Ygfd8LZzQoW8mwToCU7k"
|
||||||
|
X-Github-Backend:
|
||||||
|
- Kubernetes
|
||||||
|
X-Github-Request-Id:
|
||||||
|
- 2BDC:1C4E:5B580:368C45:61D5E1B1
|
||||||
|
Via:
|
||||||
|
- 1.1 varnish, 1.1 varnish
|
||||||
|
Accept-Ranges:
|
||||||
|
- bytes
|
||||||
|
Date:
|
||||||
|
- Thu, 06 Jan 2022 14:38:48 GMT
|
||||||
|
Age:
|
||||||
|
- '3435'
|
||||||
|
X-Served-By:
|
||||||
|
- cache-iad-kiad7000127-IAD, cache-cdg20776-CDG
|
||||||
|
X-Cache:
|
||||||
|
- HIT, HIT
|
||||||
|
X-Cache-Hits:
|
||||||
|
- 1, 1
|
||||||
|
Strict-Transport-Security:
|
||||||
|
- max-age=31536000
|
||||||
|
X-Fastly-Request-Id:
|
||||||
|
- '064738cfe513e9a05fc3af47b513b4f63b3f199c'
|
||||||
|
Content-Length:
|
||||||
|
- '67308'
|
||||||
|
body:
|
||||||
|
encoding: ASCII-8BIT
|
||||||
|
string: ''
|
||||||
|
recorded_at: Wed, 04 Mar 2020 23:00:00 GMT
|
||||||
|
recorded_with: VCR 6.0.0
|
105
spec/fixtures/cassettes/archive/new_file_to_get_400_html.yml
vendored
Normal file
105
spec/fixtures/cassettes/archive/new_file_to_get_400_html.yml
vendored
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
---
|
||||||
|
http_interactions:
|
||||||
|
- request:
|
||||||
|
method: get
|
||||||
|
uri: https://www.demarches-simplifiees.fr/error_2
|
||||||
|
body:
|
||||||
|
encoding: US-ASCII
|
||||||
|
string: ''
|
||||||
|
headers:
|
||||||
|
User-Agent:
|
||||||
|
- demarches-simplifiees.fr
|
||||||
|
Expect:
|
||||||
|
- ''
|
||||||
|
response:
|
||||||
|
status:
|
||||||
|
code: 404
|
||||||
|
message: ''
|
||||||
|
headers:
|
||||||
|
Server:
|
||||||
|
- nginx
|
||||||
|
Date:
|
||||||
|
- Thu, 06 Jan 2022 14:39:31 GMT
|
||||||
|
Content-Type:
|
||||||
|
- text/html; charset=UTF-8
|
||||||
|
Content-Length:
|
||||||
|
- '1583'
|
||||||
|
X-Request-Id:
|
||||||
|
- 8881aea9-7dfc-442b-b818-a2988a8a39ee
|
||||||
|
X-Runtime:
|
||||||
|
- '0.003713'
|
||||||
|
Strict-Transport-Security:
|
||||||
|
- max-age=63072000
|
||||||
|
body:
|
||||||
|
encoding: ASCII-8BIT
|
||||||
|
string: ''
|
||||||
|
recorded_at: Wed, 04 Mar 2020 23:00:00 GMT
|
||||||
|
- request:
|
||||||
|
method: get
|
||||||
|
uri: https://www.demarches-simplifiees.fr/error_1
|
||||||
|
body:
|
||||||
|
encoding: US-ASCII
|
||||||
|
string: ''
|
||||||
|
headers:
|
||||||
|
User-Agent:
|
||||||
|
- demarches-simplifiees.fr
|
||||||
|
Expect:
|
||||||
|
- ''
|
||||||
|
response:
|
||||||
|
status:
|
||||||
|
code: 404
|
||||||
|
message: ''
|
||||||
|
headers:
|
||||||
|
Server:
|
||||||
|
- nginx
|
||||||
|
Date:
|
||||||
|
- Thu, 06 Jan 2022 14:53:09 GMT
|
||||||
|
Content-Type:
|
||||||
|
- text/html; charset=UTF-8
|
||||||
|
Content-Length:
|
||||||
|
- '1583'
|
||||||
|
X-Request-Id:
|
||||||
|
- ea764501-134e-49a4-bd65-7fb96f772908
|
||||||
|
X-Runtime:
|
||||||
|
- '0.005202'
|
||||||
|
Strict-Transport-Security:
|
||||||
|
- max-age=63072000
|
||||||
|
body:
|
||||||
|
encoding: ASCII-8BIT
|
||||||
|
string: ''
|
||||||
|
recorded_at: Wed, 04 Mar 2020 23:00:00 GMT
|
||||||
|
- request:
|
||||||
|
method: get
|
||||||
|
uri: https://www.demarches-simplifiees.fr/error_1
|
||||||
|
body:
|
||||||
|
encoding: US-ASCII
|
||||||
|
string: ''
|
||||||
|
headers:
|
||||||
|
User-Agent:
|
||||||
|
- demarches-simplifiees.fr
|
||||||
|
Expect:
|
||||||
|
- ''
|
||||||
|
response:
|
||||||
|
status:
|
||||||
|
code: 404
|
||||||
|
message: ''
|
||||||
|
headers:
|
||||||
|
Server:
|
||||||
|
- nginx
|
||||||
|
Date:
|
||||||
|
- Thu, 06 Jan 2022 14:53:09 GMT
|
||||||
|
Content-Type:
|
||||||
|
- text/html; charset=UTF-8
|
||||||
|
Content-Length:
|
||||||
|
- '1583'
|
||||||
|
X-Request-Id:
|
||||||
|
- 27892c10-cc06-4b63-80ea-b14428d4585c
|
||||||
|
X-Runtime:
|
||||||
|
- '0.003955'
|
||||||
|
Strict-Transport-Security:
|
||||||
|
- max-age=63072000
|
||||||
|
body:
|
||||||
|
encoding: ASCII-8BIT
|
||||||
|
string: ''
|
||||||
|
recorded_at: Wed, 04 Mar 2020 23:00:00 GMT
|
||||||
|
recorded_with: VCR 6.0.0
|
157
spec/fixtures/cassettes/archive/old_file_to_get_200.yml
vendored
Normal file
157
spec/fixtures/cassettes/archive/old_file_to_get_200.yml
vendored
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
---
|
||||||
|
http_interactions:
|
||||||
|
- request:
|
||||||
|
method: get
|
||||||
|
uri: https://opengraph.githubassets.com/5e61989aecb78e369c93674f877d7bf4ecde378850114a9563cdf8b6a2472536/typhoeus/typhoeus/issues/110
|
||||||
|
body:
|
||||||
|
encoding: US-ASCII
|
||||||
|
string: ''
|
||||||
|
headers:
|
||||||
|
User-Agent:
|
||||||
|
- demarches-simplifiees.fr
|
||||||
|
Expect:
|
||||||
|
- ''
|
||||||
|
response:
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: ''
|
||||||
|
headers:
|
||||||
|
X-Ratelimit-Limit:
|
||||||
|
- '100'
|
||||||
|
X-Ratelimit-Remaining:
|
||||||
|
- '83'
|
||||||
|
X-Ratelimit-Reset:
|
||||||
|
- '1641476165'
|
||||||
|
Access-Control-Allow-Origin:
|
||||||
|
- "*"
|
||||||
|
Content-Security-Policy:
|
||||||
|
- default-src 'none';style-src 'unsafe-inline';font-src https://github.github.com;img-src
|
||||||
|
https://avatars.githubusercontent.com https://github.githubassets.com https://camo.githubusercontent.com
|
||||||
|
X-Dns-Prefetch-Control:
|
||||||
|
- 'off'
|
||||||
|
Expect-Ct:
|
||||||
|
- max-age=0
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
Referrer-Policy:
|
||||||
|
- no-referrer
|
||||||
|
X-Xss-Protection:
|
||||||
|
- '0'
|
||||||
|
Cache-Control:
|
||||||
|
- public, max-age=21600, immutable
|
||||||
|
Content-Type:
|
||||||
|
- image/png
|
||||||
|
Etag:
|
||||||
|
- W/"1066a-R45DSLyb/5W3DaEyAWdsUpLVmr4"
|
||||||
|
X-Github-Backend:
|
||||||
|
- Kubernetes
|
||||||
|
X-Github-Request-Id:
|
||||||
|
- CB64:6748:E2B78:86C62A:61D6EE15
|
||||||
|
Via:
|
||||||
|
- 1.1 varnish, 1.1 varnish
|
||||||
|
Accept-Ranges:
|
||||||
|
- bytes
|
||||||
|
Date:
|
||||||
|
- Thu, 06 Jan 2022 14:38:47 GMT
|
||||||
|
Age:
|
||||||
|
- '4322'
|
||||||
|
X-Served-By:
|
||||||
|
- cache-iad-kiad7000110-IAD, cache-cdg20721-CDG
|
||||||
|
X-Cache:
|
||||||
|
- MISS, HIT
|
||||||
|
X-Cache-Hits:
|
||||||
|
- 0, 1
|
||||||
|
Strict-Transport-Security:
|
||||||
|
- max-age=31536000
|
||||||
|
X-Fastly-Request-Id:
|
||||||
|
- b6b7ae28f1e40734296daed0187e36df9f25de8d
|
||||||
|
Content-Length:
|
||||||
|
- '67178'
|
||||||
|
body:
|
||||||
|
encoding: ASCII-8BIT
|
||||||
|
string: ''
|
||||||
|
recorded_at: Wed, 04 Mar 2020 23:00:00 GMT
|
||||||
|
- request:
|
||||||
|
method: get
|
||||||
|
uri: https://opengraph.githubassets.com/5e61989aecb78e369c93674f877d7bf4ecde378850114a9563cdf8b6a2472536/typhoeus/typhoeus/issues/110
|
||||||
|
body:
|
||||||
|
encoding: US-ASCII
|
||||||
|
string: ''
|
||||||
|
headers:
|
||||||
|
User-Agent:
|
||||||
|
- demarches-simplifiees.fr
|
||||||
|
Expect:
|
||||||
|
- ''
|
||||||
|
response:
|
||||||
|
status:
|
||||||
|
code: 200
|
||||||
|
message: ''
|
||||||
|
headers:
|
||||||
|
X-Ratelimit-Limit:
|
||||||
|
- '100'
|
||||||
|
X-Ratelimit-Remaining:
|
||||||
|
- '83'
|
||||||
|
X-Ratelimit-Reset:
|
||||||
|
- '1641476165'
|
||||||
|
Access-Control-Allow-Origin:
|
||||||
|
- "*"
|
||||||
|
Content-Security-Policy:
|
||||||
|
- default-src 'none';style-src 'unsafe-inline';font-src https://github.github.com;img-src
|
||||||
|
https://avatars.githubusercontent.com https://github.githubassets.com https://camo.githubusercontent.com
|
||||||
|
X-Dns-Prefetch-Control:
|
||||||
|
- 'off'
|
||||||
|
Expect-Ct:
|
||||||
|
- max-age=0
|
||||||
|
X-Frame-Options:
|
||||||
|
- SAMEORIGIN
|
||||||
|
X-Download-Options:
|
||||||
|
- noopen
|
||||||
|
X-Content-Type-Options:
|
||||||
|
- nosniff
|
||||||
|
X-Permitted-Cross-Domain-Policies:
|
||||||
|
- none
|
||||||
|
Referrer-Policy:
|
||||||
|
- no-referrer
|
||||||
|
X-Xss-Protection:
|
||||||
|
- '0'
|
||||||
|
Cache-Control:
|
||||||
|
- public, max-age=21600, immutable
|
||||||
|
Content-Type:
|
||||||
|
- image/png
|
||||||
|
Etag:
|
||||||
|
- W/"1066a-R45DSLyb/5W3DaEyAWdsUpLVmr4"
|
||||||
|
X-Github-Backend:
|
||||||
|
- Kubernetes
|
||||||
|
X-Github-Request-Id:
|
||||||
|
- CB64:6748:E2B78:86C62A:61D6EE15
|
||||||
|
Via:
|
||||||
|
- 1.1 varnish, 1.1 varnish
|
||||||
|
Accept-Ranges:
|
||||||
|
- bytes
|
||||||
|
Date:
|
||||||
|
- Thu, 06 Jan 2022 14:38:47 GMT
|
||||||
|
Age:
|
||||||
|
- '4322'
|
||||||
|
X-Served-By:
|
||||||
|
- cache-iad-kiad7000110-IAD, cache-cdg20767-CDG
|
||||||
|
X-Cache:
|
||||||
|
- MISS, HIT
|
||||||
|
X-Cache-Hits:
|
||||||
|
- 0, 1
|
||||||
|
Strict-Transport-Security:
|
||||||
|
- max-age=31536000
|
||||||
|
X-Fastly-Request-Id:
|
||||||
|
- 58c062baca0e760a7a6c348ab9c64cceb965dd1a
|
||||||
|
Content-Length:
|
||||||
|
- '67178'
|
||||||
|
body:
|
||||||
|
encoding: ASCII-8BIT
|
||||||
|
string: ''
|
||||||
|
recorded_at: Wed, 04 Mar 2020 23:00:00 GMT
|
||||||
|
recorded_with: VCR 6.0.0
|
|
@ -18,6 +18,13 @@ describe ApplicationHelper do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#flash_class" do
|
||||||
|
it { expect(flash_class('notice')).to eq 'alert-success' }
|
||||||
|
it { expect(flash_class('alert', sticky: true, fixed: true)).to eq 'alert-danger sticky alert-fixed' }
|
||||||
|
it { expect(flash_class('error')).to eq 'alert-danger' }
|
||||||
|
it { expect(flash_class('unknown-level')).to eq '' }
|
||||||
|
end
|
||||||
|
|
||||||
describe "#try_format_date" do
|
describe "#try_format_date" do
|
||||||
subject { try_format_date(date) }
|
subject { try_format_date(date) }
|
||||||
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
describe Utils::Retryable do
|
|
||||||
Includer = Struct.new(:something) do
|
|
||||||
include Utils::Retryable
|
|
||||||
|
|
||||||
def caller(max_attempt:, errors:)
|
|
||||||
with_retry(max_attempt: max_attempt, errors: errors) do
|
|
||||||
yield
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { Includer.new("test") }
|
|
||||||
let(:spy) { double() }
|
|
||||||
|
|
||||||
describe '#with_retry' do
|
|
||||||
it 'works while retry count is less than max attempts' do
|
|
||||||
divider_that_raise_error = 0
|
|
||||||
divider_that_works = 1
|
|
||||||
expect(spy).to receive(:divider).and_return(divider_that_raise_error, divider_that_works)
|
|
||||||
result = subject.caller(max_attempt: 2, errors: [ZeroDivisionError]) { 10 / spy.divider }
|
|
||||||
expect(result).to eq(10 / divider_that_works)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 're raise error if it occures more than max_attempt' do
|
|
||||||
expect(spy).to receive(:divider).and_return(0, 0)
|
|
||||||
expect { subject.caller(max_attempt: 1, errors: [ZeroDivisionError]) { 0 / spy.divider } }
|
|
||||||
.to raise_error(ZeroDivisionError)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not retry other errors' do
|
|
||||||
expect(spy).to receive(:divider).and_raise(StandardError).once
|
|
||||||
expect { subject.caller(max_attempt: 2, errors: [ZeroDivisionError]) { 0 / spy.divider } }
|
|
||||||
.to raise_error(StandardError)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -793,6 +793,7 @@ describe Dossier do
|
||||||
|
|
||||||
describe "#discard_and_keep_track!" do
|
describe "#discard_and_keep_track!" do
|
||||||
let(:dossier) { create(:dossier, :en_construction) }
|
let(:dossier) { create(:dossier, :en_construction) }
|
||||||
|
let(:user) { dossier.user }
|
||||||
let(:deleted_dossier) { DeletedDossier.find_by(dossier_id: dossier.id) }
|
let(:deleted_dossier) { DeletedDossier.find_by(dossier_id: dossier.id) }
|
||||||
let(:last_operation) { dossier.dossier_operation_logs.last }
|
let(:last_operation) { dossier.dossier_operation_logs.last }
|
||||||
let(:reason) { :user_request }
|
let(:reason) { :user_request }
|
||||||
|
@ -802,7 +803,7 @@ describe Dossier do
|
||||||
allow(DossierMailer).to receive(:notify_deletion_to_administration).and_return(double(deliver_later: nil))
|
allow(DossierMailer).to receive(:notify_deletion_to_administration).and_return(double(deliver_later: nil))
|
||||||
end
|
end
|
||||||
|
|
||||||
subject! { dossier.discard_and_keep_track!(dossier.user, reason) }
|
subject! { dossier.discard_and_keep_track!(user, reason) }
|
||||||
|
|
||||||
context 'brouillon' do
|
context 'brouillon' do
|
||||||
let(:dossier) { create(:dossier) }
|
let(:dossier) { create(:dossier) }
|
||||||
|
@ -821,8 +822,9 @@ describe Dossier do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'en_construction' do
|
context 'en_construction' do
|
||||||
it 'hides the dossier' do
|
it 'hide the dossier but does not discard' do
|
||||||
expect(dossier.hidden_at).to be_present
|
expect(dossier.hidden_at).to be_nil
|
||||||
|
expect(dossier.hidden_by_user_at).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a DeletedDossier record' do
|
it 'creates a DeletedDossier record' do
|
||||||
|
@ -872,6 +874,7 @@ describe Dossier do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with reason: manager_request' do
|
context 'with reason: manager_request' do
|
||||||
|
let(:user) { dossier.procedure.administrateurs.first }
|
||||||
let(:reason) { :manager_request }
|
let(:reason) { :manager_request }
|
||||||
|
|
||||||
it 'hides the dossier' do
|
it 'hides the dossier' do
|
||||||
|
@ -887,13 +890,12 @@ describe Dossier do
|
||||||
context 'with reason: user_removed' do
|
context 'with reason: user_removed' do
|
||||||
let(:reason) { :user_removed }
|
let(:reason) { :user_removed }
|
||||||
|
|
||||||
it 'hides the dossier' do
|
it 'does not discard the dossier' do
|
||||||
expect(dossier.discarded?).to be_truthy
|
expect(dossier.discarded?).to be_falsy
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'records the operation in the log' do
|
it 'hide the dossier' do
|
||||||
expect(last_operation.operation).to eq("supprimer")
|
expect(dossier.hidden_by_user_at).to be_present
|
||||||
expect(last_operation.automatic_operation?).to be_falsey
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -128,12 +128,11 @@ describe ProcedureArchiveService do
|
||||||
let(:archive) { create(:archive, time_span_type: 'monthly', status: 'pending', month: date_month) }
|
let(:archive) { create(:archive, time_span_type: 'monthly', status: 'pending', month: date_month) }
|
||||||
let(:year) { 2021 }
|
let(:year) { 2021 }
|
||||||
let(:mailer) { double('mailer', deliver_later: true) }
|
let(:mailer) { double('mailer', deliver_later: true) }
|
||||||
before do
|
|
||||||
allow_any_instance_of(ActiveStorage::Attached::One).to receive(:url).and_return("http://file.to/get.ext")
|
it 'collects files with success' do
|
||||||
end
|
allow_any_instance_of(ActiveStorage::Attached::One).to receive(:url).and_return("https://opengraph.githubassets.com/d0e7862b24d8026a3c03516d865b28151eb3859029c6c6c2e86605891fbdcd7a/socketry/async-io")
|
||||||
it 'collect files' do
|
|
||||||
expect(InstructeurMailer).to receive(:send_archive).and_return(mailer)
|
expect(InstructeurMailer).to receive(:send_archive).and_return(mailer)
|
||||||
VCR.use_cassette('archive/file_to_get') do
|
VCR.use_cassette('archive/new_file_to_get_200') do
|
||||||
service.collect_files_archive(archive, instructeur)
|
service.collect_files_archive(archive, instructeur)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -152,6 +151,26 @@ describe ProcedureArchiveService do
|
||||||
expect(archive.file.attached?).to be_truthy
|
expect(archive.file.attached?).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'retry errors files with errors' do
|
||||||
|
allow_any_instance_of(ActiveStorage::Attached::One).to receive(:url).and_return("https://www.demarches-simplifiees.fr/error_1")
|
||||||
|
expect(InstructeurMailer).to receive(:send_archive).and_return(mailer)
|
||||||
|
VCR.use_cassette('archive/new_file_to_get_400.html') do
|
||||||
|
service.collect_files_archive(archive, instructeur)
|
||||||
|
end
|
||||||
|
archive.file.open do |f|
|
||||||
|
files = ZipTricks::FileReader.read_zip_structure(io: f)
|
||||||
|
structure = [
|
||||||
|
"procedure-#{procedure.id}/",
|
||||||
|
"procedure-#{procedure.id}/dossier-#{dossier.id}/",
|
||||||
|
"procedure-#{procedure.id}/dossier-#{dossier.id}/pieces_justificatives/",
|
||||||
|
"procedure-#{procedure.id}/dossier-#{dossier.id}/export-#{dossier.id}-05-03-2021-00-00-#{dossier.id}.pdf",
|
||||||
|
"procedure-#{procedure.id}/LISEZMOI.txt"
|
||||||
|
]
|
||||||
|
expect(files.map(&:filename)).to match_array(structure)
|
||||||
|
end
|
||||||
|
expect(archive.file.attached?).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
context 'with a missing file' do
|
context 'with a missing file' do
|
||||||
let(:pj) do
|
let(:pj) do
|
||||||
PiecesJustificativesService::FakeAttachment.new(
|
PiecesJustificativesService::FakeAttachment.new(
|
||||||
|
@ -211,14 +230,12 @@ describe ProcedureArchiveService do
|
||||||
context 'for all months' do
|
context 'for all months' do
|
||||||
let(:archive) { create(:archive, time_span_type: 'everything', status: 'pending') }
|
let(:archive) { create(:archive, time_span_type: 'everything', status: 'pending') }
|
||||||
let(:mailer) { double('mailer', deliver_later: true) }
|
let(:mailer) { double('mailer', deliver_later: true) }
|
||||||
before do
|
|
||||||
allow_any_instance_of(ActiveStorage::Attached::One).to receive(:url).and_return("https://i.etsystatic.com/6212702/r/il/744d2c/470726480/il_1588xN.470726480_bpk5.jpg")
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'collect files' do
|
it 'collect files' do
|
||||||
|
allow_any_instance_of(ActiveStorage::Attached::One).to receive(:url).and_return("https://opengraph.githubassets.com/5e61989aecb78e369c93674f877d7bf4ecde378850114a9563cdf8b6a2472536/typhoeus/typhoeus/issues/110")
|
||||||
expect(InstructeurMailer).to receive(:send_archive).and_return(mailer)
|
expect(InstructeurMailer).to receive(:send_archive).and_return(mailer)
|
||||||
|
|
||||||
VCR.use_cassette('archive/file_to_get_typhoeus') do
|
VCR.use_cassette('archive/old_file_to_get_200') do
|
||||||
service.collect_files_archive(archive, instructeur)
|
service.collect_files_archive(archive, instructeur)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,8 @@ describe 'users/dossiers/index.html.haml', type: :view do
|
||||||
allow(controller).to receive(:current_user) { user }
|
allow(controller).to receive(:current_user) { user }
|
||||||
assign(:user_dossiers, Kaminari.paginate_array(user_dossiers).page(1))
|
assign(:user_dossiers, Kaminari.paginate_array(user_dossiers).page(1))
|
||||||
assign(:dossiers_invites, Kaminari.paginate_array(dossiers_invites).page(1))
|
assign(:dossiers_invites, Kaminari.paginate_array(dossiers_invites).page(1))
|
||||||
assign(:dossiers_supprimes, Kaminari.paginate_array(user_dossiers).page(1))
|
assign(:dossiers_supprimes_recemment, Kaminari.paginate_array(user_dossiers).page(1))
|
||||||
|
assign(:dossiers_supprimes_definitivement, Kaminari.paginate_array(user_dossiers).page(1))
|
||||||
assign(:dossiers_traites, Kaminari.paginate_array(user_dossiers).page(1))
|
assign(:dossiers_traites, Kaminari.paginate_array(user_dossiers).page(1))
|
||||||
assign(:dossier_transfers, Kaminari.paginate_array([]).page(1))
|
assign(:dossier_transfers, Kaminari.paginate_array([]).page(1))
|
||||||
assign(:dossiers_close_to_expiration, Kaminari.paginate_array([]).page(1))
|
assign(:dossiers_close_to_expiration, Kaminari.paginate_array([]).page(1))
|
||||||
|
@ -69,7 +70,7 @@ describe 'users/dossiers/index.html.haml', type: :view do
|
||||||
|
|
||||||
it 'affiche la barre d’onglets' do
|
it 'affiche la barre d’onglets' do
|
||||||
expect(rendered).to have_selector('nav.tabs')
|
expect(rendered).to have_selector('nav.tabs')
|
||||||
expect(rendered).to have_selector('nav.tabs li', count: 4)
|
expect(rendered).to have_selector('nav.tabs li', count: 5)
|
||||||
expect(rendered).to have_selector('nav.tabs li.active', count: 1)
|
expect(rendered).to have_selector('nav.tabs li.active', count: 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6038,9 +6038,9 @@ folder-walker@^3.2.0:
|
||||||
from2 "^2.1.0"
|
from2 "^2.1.0"
|
||||||
|
|
||||||
follow-redirects@^1.0.0:
|
follow-redirects@^1.0.0:
|
||||||
version "1.14.6"
|
version "1.14.7"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
|
||||||
integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==
|
integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
|
||||||
|
|
||||||
for-in@^1.0.2:
|
for-in@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
|
Loading…
Reference in a new issue