Merge pull request #8015 from mfo/US/clone-demarche
amélioration(dossier.clone): permettre a un usager de cloner un de ses dossiers
This commit is contained in:
commit
876d6173e7
19 changed files with 295 additions and 9 deletions
|
@ -329,6 +329,15 @@ module Users
|
|||
redirect_to dossiers_path
|
||||
end
|
||||
|
||||
def clone
|
||||
cloned_dossier = @dossier.clone
|
||||
flash.notice = t('users.dossiers.cloned_success')
|
||||
redirect_to brouillon_dossier_path(cloned_dossier)
|
||||
rescue ActiveRecord::ActiveRecordError => e
|
||||
flash.alert = e.errors.full_messages
|
||||
redirect_to dossier_path(@dossier)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# if the status tab is filled, then this tab
|
||||
|
|
|
@ -215,6 +215,35 @@ class Champ < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def clone(dossier:, parent: nil)
|
||||
kopy = deep_clone(only: (private? ? [] : [:value, :value_json]) + [:data, :private, :row, :type, :external_id, :type_de_champ_id],
|
||||
include: private? ? [] : [:etablissement, :geo_areas])
|
||||
|
||||
kopy.dossier = dossier
|
||||
kopy.parent = parent if parent
|
||||
case self
|
||||
when Champs::RepetitionChamp
|
||||
kopy.champs = (private? ? champs.where(row: 0) : champs).map do |champ_de_repetition|
|
||||
champ_de_repetition.clone(dossier: dossier, parent: kopy)
|
||||
end
|
||||
when Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp
|
||||
PiecesJustificativesService.clone_attachments(self, kopy) if !private? && piece_justificative_file.attached?
|
||||
end
|
||||
kopy
|
||||
end
|
||||
|
||||
def clone_piece_justificative(kopy)
|
||||
piece_justificative_file.open do |tempfile|
|
||||
kopy.piece_justificative_file.attach({
|
||||
io: File.open(tempfile.path),
|
||||
filename: piece_justificative_file.filename,
|
||||
content_type: piece_justificative_file.content_type,
|
||||
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
|
||||
})
|
||||
end
|
||||
rescue ActiveStorage::FileNotFoundError, ActiveStorage::IntegrityError
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def champs_for_condition
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
# updated_at :datetime
|
||||
# dossier_transfer_id :bigint
|
||||
# groupe_instructeur_id :bigint
|
||||
# parent_dossier_id :bigint
|
||||
# revision_id :bigint
|
||||
# user_id :integer
|
||||
#
|
||||
|
@ -130,6 +131,8 @@ class Dossier < ApplicationRecord
|
|||
belongs_to :groupe_instructeur, optional: true
|
||||
belongs_to :revision, class_name: 'ProcedureRevision', optional: false
|
||||
belongs_to :user, optional: true
|
||||
belongs_to :parent_dossier, class_name: 'Dossier', optional: true
|
||||
|
||||
has_one :france_connect_information, through: :user
|
||||
|
||||
has_one :attestation_template, through: :revision
|
||||
|
@ -139,6 +142,7 @@ class Dossier < ApplicationRecord
|
|||
|
||||
belongs_to :transfer, class_name: 'DossierTransfer', foreign_key: 'dossier_transfer_id', optional: true, inverse_of: :dossiers
|
||||
has_many :transfer_logs, class_name: 'DossierTransferLog', dependent: :destroy
|
||||
has_many :parent_dossiers, class_name: 'Dossier', foreign_key: 'parent_dossier_id', dependent: :nullify, inverse_of: :parent_dossier
|
||||
|
||||
accepts_nested_attributes_for :champs_public
|
||||
accepts_nested_attributes_for :champs_private
|
||||
|
@ -413,7 +417,7 @@ class Dossier < ApplicationRecord
|
|||
delegate :siret, :siren, to: :etablissement, allow_nil: true
|
||||
delegate :france_connect_information, to: :user, allow_nil: true
|
||||
|
||||
before_save :build_default_champs, if: Proc.new { revision_id_was.nil? }
|
||||
before_save :build_default_champs_for_new_dossier, if: Proc.new { revision_id_was.nil? && parent_dossier_id.nil? }
|
||||
before_save :update_search_terms
|
||||
|
||||
after_save :send_web_hook
|
||||
|
@ -473,7 +477,7 @@ class Dossier < ApplicationRecord
|
|||
self.private_search_terms = champs_private.flat_map(&:search_terms).compact.join(' ')
|
||||
end
|
||||
|
||||
def build_default_champs
|
||||
def build_default_champs_for_new_dossier
|
||||
revision.build_champs_public.each do |champ|
|
||||
champs_public << champ
|
||||
end
|
||||
|
@ -1178,6 +1182,29 @@ class Dossier < ApplicationRecord
|
|||
@sections[champ.parent || (champ.public? ? :public : :private)]
|
||||
end
|
||||
|
||||
# while cloning we do not have champ.id. it comes after transaction
|
||||
# so we collect a list of jobs to process. then enqueue this list
|
||||
def clone
|
||||
cloned_dossier = deep_clone(only: [:autorisation_donnees, :user_id, :revision_id, :groupe_instructeur_id],
|
||||
include: [:individual, :etablissement]) do |original, kopy|
|
||||
if original.is_a?(Dossier)
|
||||
kopy.parent_dossier_id = original.id
|
||||
kopy.state = Dossier.states.fetch(:brouillon)
|
||||
kopy.champs_public = original.champs_public.map do |champ|
|
||||
champ.clone(dossier: kopy)
|
||||
end
|
||||
kopy.champs_private = original.champs_private.map do |champ|
|
||||
champ.clone(dossier: kopy)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
transaction do
|
||||
cloned_dossier.save!
|
||||
end
|
||||
cloned_dossier
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_missing_traitemets
|
||||
|
|
|
@ -57,6 +57,8 @@ class PiecesJustificativesService
|
|||
|
||||
def self.clone_attachments(original, kopy)
|
||||
case original
|
||||
when Champs::PieceJustificativeChamp, Champs::TitreIdentiteChamp
|
||||
clone_attachment(original.piece_justificative_file, kopy.piece_justificative_file)
|
||||
when TypeDeChamp
|
||||
clone_attachment(original.piece_justificative_template, kopy.piece_justificative_template)
|
||||
when Procedure
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
%span.icon.archive
|
||||
.dropdown-description
|
||||
Archiver le dossier
|
||||
|
||||
%li.danger
|
||||
= link_to instructeur_dossier_path(procedure_id, dossier_id), method: :delete do
|
||||
%span.icon.delete
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
%span.icon.new-folder
|
||||
.dropdown-description
|
||||
= t('views.users.dossiers.dossier_action.start_other_dossier')
|
||||
%li
|
||||
= link_to clone_dossier_path(dossier), method: :post do
|
||||
%span.icon.new-folder
|
||||
.dropdown-description
|
||||
= t('views.users.dossiers.dossier_action.clone')
|
||||
|
||||
- if has_delete_action
|
||||
%li.danger
|
||||
|
|
|
@ -249,7 +249,8 @@ en:
|
|||
actions: "Actions"
|
||||
dossier_action:
|
||||
edit_dossier: "Edit the file"
|
||||
start_other_dossier: "Start an other file"
|
||||
start_other_dossier: "Start another empty file"
|
||||
clone: "Duplicate the file"
|
||||
delete_dossier: "Delete the file"
|
||||
transfer_dossier: "Transfer the file"
|
||||
edit_draft: "Edit the draft"
|
||||
|
@ -442,6 +443,7 @@ en:
|
|||
no_longer_editable: "Your file can no longer be edited"
|
||||
create_commentaire:
|
||||
message_send: "Your message has been sent to the instructor in charge of your file."
|
||||
cloned_success: "Your file has been duplicated. Please review it then you can submit it"
|
||||
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."
|
||||
soft_deleted_dossier: "Your file has been successfully deleted from your interface"
|
||||
|
|
|
@ -245,7 +245,8 @@ fr:
|
|||
actions: "Actions"
|
||||
dossier_action:
|
||||
edit_dossier: "Modifier le dossier"
|
||||
start_other_dossier: "Commencer un autre dossier"
|
||||
start_other_dossier: "Commencer un autre dossier vide"
|
||||
clone: "Dupliquer ce dossier"
|
||||
delete_dossier: "Supprimer le dossier"
|
||||
transfer_dossier: "Transferer le dossier"
|
||||
edit_draft: "Modifier le brouillon"
|
||||
|
@ -450,9 +451,9 @@ fr:
|
|||
test_procedure: "Ce dossier est déposé sur une démarche en test. Toute modification de la démarche par l’administrateur (ajout d'un champ, publication de la démarche...) entraînera sa suppression."
|
||||
no_access: "Vous n’avez pas accès à ce dossier"
|
||||
no_longer_editable: "Votre dossier ne peut plus être modifié"
|
||||
|
||||
create_commentaire:
|
||||
message_send: "Votre message a bien été envoyé à l’instructeur en charge de votre dossier."
|
||||
cloned_success: "Votre dossier a bien été dupliqué. Vous pouvez maintenant le vérifier, l’adapter puis le déposer."
|
||||
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."
|
||||
soft_deleted_dossier: "Votre dossier a bien été supprimé de votre interface"
|
||||
|
|
|
@ -275,6 +275,7 @@ Rails.application.routes.draw do
|
|||
member do
|
||||
get 'identite'
|
||||
patch 'update_identite'
|
||||
post 'clone'
|
||||
get 'siret'
|
||||
post 'siret', to: 'dossiers#update_siret'
|
||||
get 'etablissement'
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddParentDossierIdToDossier < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_column :dossiers, :parent_dossier_id, :bigint
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class AddForeignKeyToParentDossierId < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_foreign_key "dossiers", "dossiers", column: "parent_dossier_id", validate: false
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class ValidateForeignKeyToParentDossierId < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
validate_foreign_key "dossiers", "dossiers"
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2022_11_04_071959) do
|
||||
ActiveRecord::Schema.define(version: 2022_11_10_100759) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pgcrypto"
|
||||
|
@ -327,7 +327,8 @@ ActiveRecord::Schema.define(version: 2022_11_04_071959) do
|
|||
t.datetime "last_champ_updated_at"
|
||||
t.datetime "last_commentaire_updated_at"
|
||||
t.text "motivation"
|
||||
t.text "private_search_terms"
|
||||
t.bigint "parent_dossier_id"
|
||||
t.string "private_search_terms"
|
||||
t.datetime "processed_at"
|
||||
t.bigint "revision_id"
|
||||
t.text "search_terms"
|
||||
|
@ -920,6 +921,7 @@ ActiveRecord::Schema.define(version: 2022_11_04_071959) do
|
|||
add_foreign_key "dossier_operation_logs", "bill_signatures"
|
||||
add_foreign_key "dossier_transfer_logs", "dossiers"
|
||||
add_foreign_key "dossiers", "dossier_transfers"
|
||||
add_foreign_key "dossiers", "dossiers", column: "parent_dossier_id"
|
||||
add_foreign_key "dossiers", "groupe_instructeurs"
|
||||
add_foreign_key "dossiers", "procedure_revisions", column: "revision_id"
|
||||
add_foreign_key "dossiers", "users"
|
||||
|
|
|
@ -1185,4 +1185,21 @@ describe Users::DossiersController, type: :controller do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#clone' do
|
||||
let(:procedure) { create(:procedure, :with_all_champs) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
subject { post :clone, params: { id: dossier.id } }
|
||||
|
||||
context 'not signed in' do
|
||||
it { expect(subject).to redirect_to(new_user_session_path) }
|
||||
end
|
||||
|
||||
context 'signed with user dossier' do
|
||||
before { sign_in dossier.user }
|
||||
|
||||
it { expect(subject).to redirect_to(brouillon_dossier_path(Dossier.last)) }
|
||||
it { expect { subject }.to change { dossier.user.dossiers.count }.by(1) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -139,7 +139,9 @@ FactoryBot.define do
|
|||
type_de_champ { association :type_de_champ_dossier_link, procedure: dossier.procedure }
|
||||
value { create(:dossier).id }
|
||||
end
|
||||
|
||||
factory :champ_without_piece_justificative, class: 'Champs::PieceJustificativeChamp' do
|
||||
type_de_champ { association :type_de_champ_piece_justificative, procedure: dossier.procedure }
|
||||
end
|
||||
factory :champ_piece_justificative, class: 'Champs::PieceJustificativeChamp' do
|
||||
type_de_champ { association :type_de_champ_piece_justificative, procedure: dossier.procedure }
|
||||
|
||||
|
|
|
@ -103,6 +103,18 @@ FactoryBot.define do
|
|||
commentaires { [build(:commentaire), build(:commentaire)] }
|
||||
end
|
||||
|
||||
trait :with_invites do
|
||||
invites { [build(:invite)] }
|
||||
end
|
||||
|
||||
trait :with_avis do
|
||||
avis { [build(:avis)] }
|
||||
end
|
||||
|
||||
trait :with_dossier_operation_logs do
|
||||
dossier_operation_logs { [build(:dossier_operation_log)] }
|
||||
end
|
||||
|
||||
trait :followed do
|
||||
after(:create) do |dossier, _evaluator|
|
||||
g = create(:instructeur)
|
||||
|
|
|
@ -279,6 +279,11 @@ FactoryBot.define do
|
|||
build(:type_de_champ_explication, procedure: procedure)
|
||||
end
|
||||
end
|
||||
trait :with_carte do
|
||||
after(:build) do |procedure, _evaluator|
|
||||
build(:type_de_champ_carte, procedure: procedure)
|
||||
end
|
||||
end
|
||||
|
||||
trait :published do
|
||||
aasm_state { :publiee }
|
||||
|
|
|
@ -1685,6 +1685,145 @@ describe Dossier do
|
|||
it { expect(dossier.spreadsheet_columns(types_de_champ: [])).to include(["État du dossier", "Brouillon"]) }
|
||||
end
|
||||
|
||||
describe '#clone' do
|
||||
let(:procedure) { create(:procedure, :with_type_de_champ, :with_type_de_champ_private) }
|
||||
let(:dossier) { create(:dossier, procedure: procedure) }
|
||||
let(:new_dossier) { dossier.clone }
|
||||
|
||||
context 'reset most attributes' do
|
||||
it { expect(new_dossier.id).not_to eq(dossier.id) }
|
||||
it { expect(new_dossier.api_entreprise_job_exceptions).to be_nil }
|
||||
it { expect(new_dossier.archived).to be_falsey }
|
||||
it { expect(new_dossier.brouillon_close_to_expiration_notice_sent_at).to be_nil }
|
||||
it { expect(new_dossier.conservation_extension).to eq(0.seconds) }
|
||||
it { expect(new_dossier.declarative_triggered_at).to be_nil }
|
||||
it { expect(new_dossier.deleted_user_email_never_send).to be_nil }
|
||||
it { expect(new_dossier.depose_at).to be_nil }
|
||||
it { expect(new_dossier.en_construction_at).to be_nil }
|
||||
it { expect(new_dossier.en_construction_close_to_expiration_notice_sent_at).to be_nil }
|
||||
it { expect(new_dossier.en_instruction_at).to be_nil }
|
||||
it { expect(new_dossier.for_procedure_preview).to be_falsey }
|
||||
it { expect(new_dossier.groupe_instructeur_updated_at).to be_nil }
|
||||
it { expect(new_dossier.hidden_at).to be_nil }
|
||||
it { expect(new_dossier.hidden_by_administration_at).to be_nil }
|
||||
it { expect(new_dossier.hidden_by_reason).to be_nil }
|
||||
it { expect(new_dossier.hidden_by_user_at).to be_nil }
|
||||
it { expect(new_dossier.identity_updated_at).to be_nil }
|
||||
it { expect(new_dossier.last_avis_updated_at).to be_nil }
|
||||
it { expect(new_dossier.last_champ_private_updated_at).to be_nil }
|
||||
it { expect(new_dossier.last_champ_updated_at).to be_nil }
|
||||
it { expect(new_dossier.last_commentaire_updated_at).to be_nil }
|
||||
it { expect(new_dossier.motivation).to be_nil }
|
||||
it { expect(new_dossier.private_search_terms).to eq("") }
|
||||
it { expect(new_dossier.processed_at).to be_nil }
|
||||
it { expect(new_dossier.search_terms).to match(dossier.user.email) }
|
||||
it { expect(new_dossier.termine_close_to_expiration_notice_sent_at).to be_nil }
|
||||
it { expect(new_dossier.dossier_transfer_id).to be_nil }
|
||||
end
|
||||
|
||||
context 'copies some attributes' do
|
||||
it { expect(new_dossier.groupe_instructeur).to eq(dossier.groupe_instructeur) }
|
||||
it { expect(new_dossier.autorisation_donnees).to eq(dossier.autorisation_donnees) }
|
||||
it { expect(new_dossier.revision_id).to eq(dossier.revision_id) }
|
||||
it { expect(new_dossier.user_id).to eq(dossier.user_id) }
|
||||
end
|
||||
|
||||
context 'forces some attributes' do
|
||||
let(:dossier) { create(:dossier, :accepte) }
|
||||
|
||||
it { expect(new_dossier.brouillon?).to eq(true) }
|
||||
it { expect(new_dossier.parent_dossier).to eq(dossier) }
|
||||
|
||||
context 'destroy parent' do
|
||||
before { new_dossier }
|
||||
|
||||
it 'clean fk' do
|
||||
expect { dossier.destroy }.to change { new_dossier.reload.parent_dossier_id }.from(dossier.id).to(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'procedure with_individual' do
|
||||
let(:procedure) { create(:procedure, :for_individual) }
|
||||
it { expect(new_dossier.individual.slice(:nom, :prenom, :gender)).to eq(dossier.individual.slice(:nom, :prenom, :gender)) }
|
||||
it { expect(new_dossier.individual.id).not_to eq(dossier.individual.id) }
|
||||
end
|
||||
|
||||
context 'procedure with etablissement' do
|
||||
let(:dossier) { create(:dossier, :with_entreprise) }
|
||||
it { expect(new_dossier.etablissement.slice(:siret)).to eq(dossier.etablissement.slice(:siret)) }
|
||||
it { expect(new_dossier.etablissement.id).not_to eq(dossier.etablissement.id) }
|
||||
end
|
||||
|
||||
describe 'champs' do
|
||||
it { expect(new_dossier.id).not_to eq(dossier.id) }
|
||||
|
||||
context 'public are duplicated' do
|
||||
it { expect(new_dossier.champs_public.count).to eq(dossier.champs_public.count) }
|
||||
it { expect(new_dossier.champs_public.ids).not_to eq(dossier.champs_public.ids) }
|
||||
|
||||
it 'keeps champs.values' do
|
||||
original_first_champ = dossier.champs_public.first
|
||||
original_first_champ.update!(value: 'kthxbye')
|
||||
|
||||
expect(new_dossier.champs_public.first.value).to eq(original_first_champ.value)
|
||||
end
|
||||
|
||||
context 'for Champs::Repetition with rows, original_champ.repetition and rows are duped' do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:type_de_champ_repetition) { create(:type_de_champ_repetition, procedure: dossier.procedure) }
|
||||
let(:champ_repetition) { create(:champ_repetition, type_de_champ: type_de_champ_repetition, dossier: dossier) }
|
||||
before { dossier.champs_public << champ_repetition }
|
||||
|
||||
it { expect(Champs::RepetitionChamp.where(dossier: new_dossier).first.champs.count).to eq(4) }
|
||||
it { expect(Champs::RepetitionChamp.where(dossier: new_dossier).first.champs.ids).not_to eq(champ_repetition.champs.ids) }
|
||||
end
|
||||
|
||||
context 'for Champs::CarteChamp with geo areas, original_champ.geo_areas are duped' do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:type_de_champ_carte) { create(:type_de_champ_carte, procedure: dossier.procedure) }
|
||||
let(:geo_area) { create(:geo_area, :selection_utilisateur, :polygon) }
|
||||
let(:champ_carte) { create(:champ_carte, type_de_champ: type_de_champ_carte, geo_areas: [geo_area]) }
|
||||
before { dossier.champs_public << champ_carte }
|
||||
|
||||
it { expect(Champs::CarteChamp.where(dossier: new_dossier).first.geo_areas.count).to eq(1) }
|
||||
it { expect(Champs::CarteChamp.where(dossier: new_dossier).first.geo_areas.ids).not_to eq(champ_carte.geo_areas.ids) }
|
||||
end
|
||||
|
||||
context 'for Champs::SiretChamp, original_champ.etablissement is duped' do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:type_de_champs_siret) { create(:type_de_champ_siret, procedure: dossier.procedure) }
|
||||
let(:etablissement) { create(:etablissement) }
|
||||
let(:champ_siret) { create(:champ_siret, type_de_champ: type_de_champs_siret, etablissement: create(:etablissement)) }
|
||||
before { dossier.champs_public << champ_siret }
|
||||
|
||||
it { expect(Champs::SiretChamp.where(dossier: dossier).first.etablissement).not_to be_nil }
|
||||
it { expect(Champs::SiretChamp.where(dossier: new_dossier).first.etablissement.id).not_to eq(champ_siret.etablissement.id) }
|
||||
end
|
||||
|
||||
context 'for Champs::PieceJustificative, original_champ.piece_justificative_file is duped' do
|
||||
let(:dossier) { create(:dossier) }
|
||||
let(:champ_piece_justificative) { create(:champ_piece_justificative, dossier_id: dossier.id) }
|
||||
before { dossier.champs_public << champ_piece_justificative }
|
||||
it { expect(Champs::PieceJustificativeChamp.where(dossier: new_dossier).first.piece_justificative_file.blob).to eq(champ_piece_justificative.piece_justificative_file.blob) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'private are renewd' do
|
||||
it { expect(new_dossier.champs_private.count).to eq(dossier.champs_private.count) }
|
||||
it { expect(new_dossier.champs_private.ids).not_to eq(dossier.champs_private.ids) }
|
||||
|
||||
it 'reset champs private values' do
|
||||
original_first_champs_private = dossier.champs_private.first
|
||||
original_first_champs_private.update!(value: 'kthxbye')
|
||||
|
||||
expect(new_dossier.champs_private.first.value).not_to eq(original_first_champs_private.value)
|
||||
expect(new_dossier.champs_private.first.value).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#processed_in_month' do
|
||||
include ActiveSupport::Testing::TimeHelpers
|
||||
|
||||
|
|
|
@ -80,6 +80,25 @@ describe 'user access to the list of their dossiers', js: true do
|
|||
expect(page).not_to have_content(dossier_brouillon.procedure.libelle)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'clone' do
|
||||
it 'should have links to clone dossiers' do
|
||||
expect(page).to have_link(nil, href: clone_dossier_path(dossier_brouillon))
|
||||
expect(page).to have_link(nil, href: clone_dossier_path(dossier_en_construction))
|
||||
expect(page).to have_link(nil, href: clone_dossier_path(dossier_en_instruction))
|
||||
end
|
||||
|
||||
context 'when user clicks on clone button', js: true do
|
||||
scenario 'the dossier is deleted' do
|
||||
within(:css, "tr[data-dossier-id=\"#{dossier_brouillon.id}\"]") do
|
||||
click_on 'Actions'
|
||||
click_on 'Dupliquer ce dossier'
|
||||
end
|
||||
|
||||
expect(page).to have_content("Votre dossier a bien été dupliqué. Vous pouvez maintenant le vérifier, l’adapter puis le déposer.")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "recherche" do
|
||||
|
|
Loading…
Reference in a new issue