2015-09-21 17:59:03 +02:00
|
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
|
|
describe Procedure do
|
2017-05-29 14:44:38 +02:00
|
|
|
|
describe 'mail templates' do
|
2017-05-27 01:08:01 +02:00
|
|
|
|
subject { create(:procedure) }
|
|
|
|
|
|
|
|
|
|
it { expect(subject.initiated_mail_template).to be_a(Mails::InitiatedMail) }
|
|
|
|
|
it { expect(subject.received_mail_template).to be_a(Mails::ReceivedMail) }
|
|
|
|
|
it { expect(subject.closed_mail_template).to be_a(Mails::ClosedMail) }
|
|
|
|
|
it { expect(subject.refused_mail_template).to be_a(Mails::RefusedMail) }
|
|
|
|
|
it { expect(subject.without_continuation_mail_template).to be_a(Mails::WithoutContinuationMail) }
|
2017-03-06 15:00:05 +01:00
|
|
|
|
end
|
|
|
|
|
|
2017-03-04 09:56:09 +01:00
|
|
|
|
describe 'initiated_mail' do
|
2017-12-22 21:37:08 +01:00
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
|
|
|
|
|
subject { procedure }
|
2017-03-04 09:56:09 +01:00
|
|
|
|
|
|
|
|
|
context 'when initiated_mail is not customize' do
|
2017-12-22 21:37:08 +01:00
|
|
|
|
it { expect(subject.initiated_mail_template.body).to eq(Mails::InitiatedMail.default_for_procedure(procedure).body) }
|
2017-03-04 09:56:09 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when initiated_mail is customize' do
|
|
|
|
|
before :each do
|
2017-03-06 22:37:37 +01:00
|
|
|
|
subject.initiated_mail = Mails::InitiatedMail.new(body: 'sisi')
|
2017-03-04 09:56:09 +01:00
|
|
|
|
subject.save
|
|
|
|
|
subject.reload
|
|
|
|
|
end
|
2017-05-27 01:08:01 +02:00
|
|
|
|
it { expect(subject.initiated_mail_template.body).to eq('sisi') }
|
2017-03-04 09:56:09 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when initiated_mail is customize ... again' do
|
|
|
|
|
before :each do
|
2017-03-06 22:37:37 +01:00
|
|
|
|
subject.initiated_mail = Mails::InitiatedMail.new(body: 'toto')
|
2017-03-04 09:56:09 +01:00
|
|
|
|
subject.save
|
|
|
|
|
subject.reload
|
|
|
|
|
end
|
2017-05-27 01:08:01 +02:00
|
|
|
|
it { expect(subject.initiated_mail_template.body).to eq('toto') }
|
2017-03-04 09:56:09 +01:00
|
|
|
|
|
2017-03-06 22:37:37 +01:00
|
|
|
|
it { expect(Mails::InitiatedMail.count).to eq(1) }
|
2017-03-04 09:56:09 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-03-16 19:39:48 +01:00
|
|
|
|
describe 'closed mail template body' do
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
|
|
|
|
|
subject { procedure.closed_mail_template.body }
|
|
|
|
|
|
|
|
|
|
context 'for procedures without an attestation' do
|
|
|
|
|
it { is_expected.not_to include('lien attestation') }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'for procedures with an attestation' do
|
|
|
|
|
before { create(:attestation_template, procedure: procedure, activated: activated) }
|
|
|
|
|
|
|
|
|
|
context 'when the attestation is inactive' do
|
|
|
|
|
let(:activated) { false }
|
|
|
|
|
|
|
|
|
|
it { is_expected.not_to include('lien attestation') }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the attestation is inactive' do
|
|
|
|
|
let(:activated) { true }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to include('lien attestation') }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-04-03 11:33:11 +02:00
|
|
|
|
describe '#closed_mail_template_attestation_inconsistency_state' do
|
|
|
|
|
let(:procedure_without_attestation) { create(:procedure, closed_mail: closed_mail) }
|
|
|
|
|
let(:procedure_with_active_attestation) do
|
|
|
|
|
procedure = create(:procedure, closed_mail: closed_mail)
|
|
|
|
|
create(:attestation_template, procedure: procedure, activated: true)
|
|
|
|
|
procedure
|
|
|
|
|
end
|
|
|
|
|
let(:procedure_with_inactive_attestation) do
|
|
|
|
|
procedure = create(:procedure, closed_mail: closed_mail)
|
|
|
|
|
create(:attestation_template, procedure: procedure, activated: false)
|
|
|
|
|
procedure
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
subject { procedure.closed_mail_template_attestation_inconsistency_state }
|
|
|
|
|
|
|
|
|
|
context 'with a custom mail template' do
|
|
|
|
|
context 'that contains a lien attestation tag' do
|
|
|
|
|
let(:closed_mail) { create(:closed_mail, body: '--lien attestation--') }
|
|
|
|
|
|
|
|
|
|
context 'when the procedure doesn’t have an attestation' do
|
|
|
|
|
let(:procedure) { procedure_without_attestation }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to eq(:extraneous_tag) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the procedure has an active attestation' do
|
|
|
|
|
let(:procedure) { procedure_with_active_attestation }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to be(nil) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the procedure has an inactive attestation' do
|
|
|
|
|
let(:procedure) { procedure_with_inactive_attestation }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to eq(:extraneous_tag) }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'that doesn’t contain a lien attestation tag' do
|
|
|
|
|
let(:closed_mail) { create(:closed_mail) }
|
|
|
|
|
|
|
|
|
|
context 'when the procedure doesn’t have an attestation' do
|
|
|
|
|
let(:procedure) { procedure_without_attestation }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to be(nil) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the procedure has an active attestation' do
|
|
|
|
|
let(:procedure) { procedure_with_active_attestation }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to eq(:missing_tag) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the procedure has an inactive attestation' do
|
|
|
|
|
let(:procedure) { procedure_with_inactive_attestation }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to be(nil) }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with the default mail template' do
|
|
|
|
|
let(:closed_mail) { nil }
|
|
|
|
|
|
|
|
|
|
context 'when the procedure doesn’t have an attestation' do
|
|
|
|
|
let(:procedure) { procedure_without_attestation }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to be(nil) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the procedure has an active attestation' do
|
|
|
|
|
let(:procedure) { procedure_with_active_attestation }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to be(nil) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the procedure has an inactive attestation' do
|
|
|
|
|
let(:procedure) { procedure_with_inactive_attestation }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to be(nil) }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2015-09-22 11:21:52 +02:00
|
|
|
|
describe 'validation' do
|
|
|
|
|
context 'libelle' do
|
|
|
|
|
it { is_expected.not_to allow_value(nil).for(:libelle) }
|
|
|
|
|
it { is_expected.not_to allow_value('').for(:libelle) }
|
|
|
|
|
it { is_expected.to allow_value('Demande de subvention').for(:libelle) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'description' do
|
|
|
|
|
it { is_expected.not_to allow_value(nil).for(:description) }
|
|
|
|
|
it { is_expected.not_to allow_value('').for(:description) }
|
|
|
|
|
it { is_expected.to allow_value('Description Demande de subvention').for(:description) }
|
|
|
|
|
end
|
|
|
|
|
|
2017-11-23 11:37:41 +01:00
|
|
|
|
context 'organisation' do
|
|
|
|
|
it { is_expected.to allow_value('URRSAF').for(:organisation) }
|
|
|
|
|
end
|
2018-05-31 10:59:38 +02:00
|
|
|
|
|
2019-04-29 18:27:44 +02:00
|
|
|
|
context 'administrateurs' do
|
|
|
|
|
it { is_expected.not_to allow_value([]).for(:administrateurs) }
|
|
|
|
|
end
|
|
|
|
|
|
2018-05-31 10:59:38 +02:00
|
|
|
|
context 'juridique' do
|
|
|
|
|
it { is_expected.not_to allow_value(nil).for(:cadre_juridique) }
|
|
|
|
|
it { is_expected.to allow_value('text').for(:cadre_juridique) }
|
|
|
|
|
|
|
|
|
|
context 'with deliberation' do
|
|
|
|
|
let(:procedure) { build(:procedure, cadre_juridique: nil) }
|
|
|
|
|
|
|
|
|
|
it { expect(procedure.valid?).to eq(false) }
|
|
|
|
|
|
|
|
|
|
context 'when the deliberation is uploaded ' do
|
|
|
|
|
before do
|
|
|
|
|
allow(procedure).to receive(:deliberation)
|
|
|
|
|
.and_return(double('attached?': true))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it { expect(procedure.valid?).to eq(true) }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-06-01 10:51:04 +02:00
|
|
|
|
|
|
|
|
|
context 'when juridique_required is false' do
|
|
|
|
|
let(:procedure) { build(:procedure, juridique_required: false, cadre_juridique: nil) }
|
|
|
|
|
|
|
|
|
|
it { expect(procedure.valid?).to eq(true) }
|
|
|
|
|
end
|
2018-05-24 23:29:33 +02:00
|
|
|
|
|
2019-07-17 15:12:07 +02:00
|
|
|
|
context 'monavis' do
|
|
|
|
|
context 'nil is allowed' do
|
2019-07-17 15:34:10 +02:00
|
|
|
|
it { is_expected.to allow_value(nil).for(:monavis_embed) }
|
|
|
|
|
it { is_expected.to allow_value('').for(:monavis_embed) }
|
2019-07-17 15:12:07 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'random string is not allowed' do
|
2019-07-17 15:34:10 +02:00
|
|
|
|
let(:procedure) { build(:procedure, monavis_embed: "plop") }
|
2019-07-17 15:12:07 +02:00
|
|
|
|
it { expect(procedure.valid?).to eq(false) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'random html is not allowed' do
|
2019-07-17 15:34:10 +02:00
|
|
|
|
let(:procedure) { build(:procedure, monavis_embed: '<img src="http://some.analytics/hello.gif">') }
|
2019-07-17 15:12:07 +02:00
|
|
|
|
it { expect(procedure.valid?).to eq(false) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'Monavis embed code with white button is allowed' do
|
|
|
|
|
monavis_blanc = <<-MSG
|
2019-07-17 15:34:10 +02:00
|
|
|
|
<a href="https://monavis.numerique.gouv.fr/Demarches/123?&view-mode=formulaire-avis&nd_mode=en-ligne-enti%C3%A8rement&nd_source=button&key=cd4a872d475e4045666057f">
|
|
|
|
|
<img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-blanc.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" />
|
|
|
|
|
</a>
|
|
|
|
|
MSG
|
|
|
|
|
let(:procedure) { build(:procedure, monavis_embed: monavis_blanc) }
|
2019-07-17 15:12:07 +02:00
|
|
|
|
it { expect(procedure.valid?).to eq(true) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'Monavis embed code with blue button is allowed' do
|
2019-07-17 15:34:10 +02:00
|
|
|
|
monavis_bleu = <<-MSG
|
|
|
|
|
<a href="https://monavis.numerique.gouv.fr/Demarches/123?&view-mode=formulaire-avis&nd_mode=en-ligne-enti%C3%A8rement&nd_source=button&key=cd4a872d475e4045666057f">
|
|
|
|
|
<img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-bleu.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" />
|
|
|
|
|
</a>
|
|
|
|
|
MSG
|
|
|
|
|
let(:procedure) { build(:procedure, monavis_embed: monavis_bleu) }
|
2019-07-17 15:12:07 +02:00
|
|
|
|
it { expect(procedure.valid?).to eq(true) }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-05-24 23:29:33 +02:00
|
|
|
|
shared_examples 'duree de conservation' do
|
|
|
|
|
context 'duree_conservation_required it true, the field gets validated' do
|
|
|
|
|
before { subject.durees_conservation_required = true }
|
|
|
|
|
|
|
|
|
|
it { is_expected.not_to allow_value(nil).for(field_name) }
|
|
|
|
|
it { is_expected.not_to allow_value('').for(field_name) }
|
|
|
|
|
it { is_expected.not_to allow_value('trois').for(field_name) }
|
|
|
|
|
it { is_expected.to allow_value(3).for(field_name) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'duree_conservation_required is false, the field doesn’t get validated' do
|
|
|
|
|
before { subject.durees_conservation_required = false }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to allow_value(nil).for(field_name) }
|
|
|
|
|
it { is_expected.to allow_value('').for(field_name) }
|
|
|
|
|
it { is_expected.not_to allow_value('trois').for(field_name) }
|
|
|
|
|
it { is_expected.to allow_value(3).for(field_name) }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe 'duree de conservation dans ds' do
|
|
|
|
|
let(:field_name) { :duree_conservation_dossiers_dans_ds }
|
|
|
|
|
|
|
|
|
|
it_behaves_like 'duree de conservation'
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe 'duree de conservation hors ds' do
|
|
|
|
|
let(:field_name) { :duree_conservation_dossiers_hors_ds }
|
|
|
|
|
|
|
|
|
|
it_behaves_like 'duree de conservation'
|
|
|
|
|
end
|
2015-09-22 11:21:52 +02:00
|
|
|
|
end
|
2015-11-17 15:30:03 +01:00
|
|
|
|
|
2018-05-25 00:16:13 +02:00
|
|
|
|
describe '#duree_de_conservation_required' do
|
|
|
|
|
it 'automatically jumps to true once both durees de conservation have been set' do
|
|
|
|
|
p = build(
|
|
|
|
|
:procedure,
|
|
|
|
|
durees_conservation_required: false,
|
|
|
|
|
duree_conservation_dossiers_dans_ds: nil,
|
|
|
|
|
duree_conservation_dossiers_hors_ds: nil
|
|
|
|
|
)
|
|
|
|
|
p.save
|
|
|
|
|
expect(p.durees_conservation_required).to be_falsey
|
|
|
|
|
|
|
|
|
|
p.duree_conservation_dossiers_hors_ds = 3
|
|
|
|
|
p.save
|
|
|
|
|
expect(p.durees_conservation_required).to be_falsey
|
|
|
|
|
|
|
|
|
|
p.duree_conservation_dossiers_dans_ds = 6
|
|
|
|
|
p.save
|
|
|
|
|
expect(p.durees_conservation_required).to be_truthy
|
|
|
|
|
|
|
|
|
|
p.duree_conservation_dossiers_dans_ds = nil
|
|
|
|
|
p.save
|
|
|
|
|
expect(p.durees_conservation_required).to be_truthy
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-12-20 12:00:27 +01:00
|
|
|
|
describe '#types_de_champ (ordered)' do
|
2015-11-17 15:30:03 +01:00
|
|
|
|
let(:procedure) { create(:procedure) }
|
2018-02-13 17:00:19 +01:00
|
|
|
|
let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 1) }
|
|
|
|
|
let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 0) }
|
2018-12-20 12:00:27 +01:00
|
|
|
|
subject { procedure.types_de_champ }
|
2015-11-17 15:30:03 +01:00
|
|
|
|
it { expect(subject.first).to eq(type_de_champ_1) }
|
|
|
|
|
it { expect(subject.last).to eq(type_de_champ_0) }
|
|
|
|
|
end
|
2015-11-19 11:37:01 +01:00
|
|
|
|
|
|
|
|
|
describe '#switch_types_de_champ' do
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
let(:index) { 0 }
|
2019-01-03 15:12:55 +01:00
|
|
|
|
subject { procedure.switch_types_de_champ(index) }
|
2015-11-19 11:37:01 +01:00
|
|
|
|
|
2019-01-03 15:12:55 +01:00
|
|
|
|
context 'when procedure has no types_de_champ' do
|
2015-11-19 11:37:01 +01:00
|
|
|
|
it { expect(subject).to eq(false) }
|
|
|
|
|
end
|
2019-01-03 15:12:55 +01:00
|
|
|
|
context 'when procedure has 3 types de champ' do
|
2018-02-13 17:00:19 +01:00
|
|
|
|
let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) }
|
|
|
|
|
let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) }
|
2019-01-03 15:12:55 +01:00
|
|
|
|
let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure, order_place: 2) }
|
2015-11-19 11:37:01 +01:00
|
|
|
|
context 'when index is not the last element' do
|
|
|
|
|
it { expect(subject).to eq(true) }
|
2019-01-03 15:12:55 +01:00
|
|
|
|
it 'switches the position of the champ N and N+1' do
|
|
|
|
|
subject
|
|
|
|
|
expect(procedure.types_de_champ[0]).to eq(type_de_champ_1)
|
|
|
|
|
expect(procedure.types_de_champ[0].order_place).to eq(0)
|
|
|
|
|
expect(procedure.types_de_champ[1]).to eq(type_de_champ_0)
|
|
|
|
|
expect(procedure.types_de_champ[1].order_place).to eq(1)
|
|
|
|
|
end
|
|
|
|
|
it 'doesn’t move other types de champ' do
|
|
|
|
|
subject
|
|
|
|
|
expect(procedure.types_de_champ[2]).to eq(type_de_champ_2)
|
|
|
|
|
expect(procedure.types_de_champ[2].order_place).to eq(2)
|
2015-11-19 11:37:01 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
context 'when index is the last element' do
|
2019-01-03 15:12:55 +01:00
|
|
|
|
let(:index) { 2 }
|
2015-11-19 11:37:01 +01:00
|
|
|
|
it { expect(subject).to eq(false) }
|
|
|
|
|
end
|
|
|
|
|
end
|
2015-12-21 14:40:28 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe 'locked?' do
|
2018-05-17 15:43:33 +02:00
|
|
|
|
let(:procedure) { create(:procedure, aasm_state: aasm_state) }
|
2015-12-21 14:40:28 +01:00
|
|
|
|
|
|
|
|
|
subject { procedure.locked? }
|
|
|
|
|
|
2018-05-17 15:43:33 +02:00
|
|
|
|
context 'when procedure is in brouillon status' do
|
|
|
|
|
let(:aasm_state) { :brouillon }
|
2015-12-21 14:40:28 +01:00
|
|
|
|
it { is_expected.to be_falsey }
|
|
|
|
|
end
|
|
|
|
|
|
2018-05-17 15:43:33 +02:00
|
|
|
|
context 'when procedure is in publiee status' do
|
|
|
|
|
let(:aasm_state) { :publiee }
|
2016-06-09 17:49:38 +02:00
|
|
|
|
it { is_expected.to be_truthy }
|
2015-12-21 14:40:28 +01:00
|
|
|
|
end
|
2016-06-09 17:49:38 +02:00
|
|
|
|
end
|
2015-12-21 14:40:28 +01:00
|
|
|
|
|
2016-06-09 17:49:38 +02:00
|
|
|
|
describe 'active' do
|
2018-05-16 17:21:12 +02:00
|
|
|
|
let(:procedure) { create(:procedure) }
|
2016-06-09 17:49:38 +02:00
|
|
|
|
subject { Procedure.active(procedure.id) }
|
2015-12-21 14:40:28 +01:00
|
|
|
|
|
2016-06-09 17:49:38 +02:00
|
|
|
|
context 'when procedure is in draft status and not archived' do
|
|
|
|
|
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when procedure is published and not archived' do
|
2018-05-16 17:21:12 +02:00
|
|
|
|
let(:procedure) { create(:procedure, :published) }
|
2015-12-21 14:40:28 +01:00
|
|
|
|
it { is_expected.to be_truthy }
|
|
|
|
|
end
|
2016-06-09 17:49:38 +02:00
|
|
|
|
|
|
|
|
|
context 'when procedure is published and archived' do
|
2018-05-16 17:21:12 +02:00
|
|
|
|
let(:procedure) { create(:procedure, :archived) }
|
2016-06-09 17:49:38 +02:00
|
|
|
|
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
|
|
|
|
|
end
|
2015-12-21 14:40:28 +01:00
|
|
|
|
end
|
2016-06-15 11:34:05 +02:00
|
|
|
|
|
|
|
|
|
describe 'clone' do
|
2018-04-23 16:29:32 +02:00
|
|
|
|
let!(:service) { create(:service) }
|
2018-05-28 14:58:40 +02:00
|
|
|
|
let(:procedure) { create(:procedure, received_mail: received_mail, service: service) }
|
2018-02-13 17:00:19 +01:00
|
|
|
|
let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) }
|
|
|
|
|
let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) }
|
2018-02-14 15:12:57 +01:00
|
|
|
|
let!(:type_de_champ_2) { create(:type_de_champ_drop_down_list, procedure: procedure, order_place: 2) }
|
2019-01-10 13:37:40 +01:00
|
|
|
|
let!(:type_de_champ_pj) { create(:type_de_champ_piece_justificative, procedure: procedure, order_place: 3, old_pj: { stable_id: 2713 }) }
|
2018-02-13 17:00:19 +01:00
|
|
|
|
let!(:type_de_champ_private_0) { create(:type_de_champ, :private, procedure: procedure, order_place: 0) }
|
|
|
|
|
let!(:type_de_champ_private_1) { create(:type_de_champ, :private, procedure: procedure, order_place: 1) }
|
2018-02-14 15:12:57 +01:00
|
|
|
|
let!(:type_de_champ_private_2) { create(:type_de_champ_drop_down_list, :private, procedure: procedure, order_place: 2) }
|
2018-12-19 15:35:07 +01:00
|
|
|
|
let(:received_mail) { create(:received_mail) }
|
2018-04-12 18:35:13 +02:00
|
|
|
|
let(:from_library) { false }
|
2019-02-26 16:57:04 +01:00
|
|
|
|
let(:administrateur) { procedure.administrateurs.first }
|
2016-09-01 10:43:49 +02:00
|
|
|
|
|
2017-06-08 14:16:48 +02:00
|
|
|
|
before do
|
2018-10-16 00:01:53 +02:00
|
|
|
|
@logo = File.open('spec/fixtures/files/white.png')
|
|
|
|
|
@signature = File.open('spec/fixtures/files/black.png')
|
2017-06-08 14:16:48 +02:00
|
|
|
|
@attestation_template = create(:attestation_template, procedure: procedure, logo: @logo, signature: @signature)
|
2018-12-19 15:35:07 +01:00
|
|
|
|
@procedure = procedure.clone(administrateur, from_library)
|
2018-01-08 15:42:38 +01:00
|
|
|
|
@procedure.save
|
2017-06-08 14:16:48 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
after do
|
|
|
|
|
@logo.close
|
|
|
|
|
@signature.close
|
|
|
|
|
end
|
|
|
|
|
|
2018-01-08 15:42:38 +01:00
|
|
|
|
subject { @procedure }
|
2016-06-15 11:34:05 +02:00
|
|
|
|
|
2018-04-24 15:23:07 +02:00
|
|
|
|
it { expect(subject.parent_procedure).to eq(procedure) }
|
2019-10-15 18:32:18 +02:00
|
|
|
|
it { expect(subject.defaut_groupe_instructeur.instructeurs.map(&:email)).to eq([administrateur.email]) }
|
2018-04-24 15:23:07 +02:00
|
|
|
|
|
2016-06-15 11:34:05 +02:00
|
|
|
|
it 'should duplicate specific objects with different id' do
|
|
|
|
|
expect(subject.id).not_to eq(procedure.id)
|
|
|
|
|
|
2019-07-25 16:49:06 +02:00
|
|
|
|
expect(subject.types_de_champ.size).to eq(procedure.types_de_champ.size)
|
2016-09-09 17:39:56 +02:00
|
|
|
|
expect(subject.types_de_champ_private.size).to eq procedure.types_de_champ_private.size
|
2017-06-26 17:18:47 +02:00
|
|
|
|
expect(subject.types_de_champ.map(&:drop_down_list).compact.size).to eq procedure.types_de_champ.map(&:drop_down_list).compact.size
|
|
|
|
|
expect(subject.types_de_champ_private.map(&:drop_down_list).compact.size).to eq procedure.types_de_champ_private.map(&:drop_down_list).compact.size
|
2016-09-01 10:43:49 +02:00
|
|
|
|
|
2019-01-10 13:34:47 +01:00
|
|
|
|
procedure.types_de_champ.zip(subject.types_de_champ).each do |ptc, stc|
|
2016-06-15 11:34:05 +02:00
|
|
|
|
expect(stc).to have_same_attributes_as(ptc)
|
|
|
|
|
end
|
|
|
|
|
|
2016-09-09 17:39:56 +02:00
|
|
|
|
subject.types_de_champ_private.zip(procedure.types_de_champ_private).each do |stc, ptc|
|
|
|
|
|
expect(stc).to have_same_attributes_as(ptc)
|
|
|
|
|
end
|
|
|
|
|
|
2017-06-08 14:16:48 +02:00
|
|
|
|
expect(subject.attestation_template.title).to eq(procedure.attestation_template.title)
|
2018-04-12 18:35:13 +02:00
|
|
|
|
|
|
|
|
|
expect(subject.cloned_from_library).to be(false)
|
2018-04-24 15:23:07 +02:00
|
|
|
|
|
|
|
|
|
cloned_procedure = subject
|
|
|
|
|
cloned_procedure.parent_procedure_id = nil
|
2019-03-06 14:42:27 +01:00
|
|
|
|
expect(cloned_procedure).to have_same_attributes_as(procedure, except: ["path"])
|
2018-04-12 18:35:13 +02:00
|
|
|
|
end
|
|
|
|
|
|
2019-01-10 13:34:47 +01:00
|
|
|
|
context 'when the procedure is cloned from the library' do
|
2018-04-12 18:35:13 +02:00
|
|
|
|
let(:from_library) { true }
|
|
|
|
|
|
2019-01-29 11:49:28 +01:00
|
|
|
|
it 'should set cloned_from_library to true' do
|
|
|
|
|
expect(subject.cloned_from_library).to be(true)
|
|
|
|
|
end
|
2018-12-19 15:35:07 +01:00
|
|
|
|
|
|
|
|
|
it 'should set service_id to nil' do
|
|
|
|
|
expect(subject.service).to eq(nil)
|
|
|
|
|
end
|
2019-01-10 13:43:22 +01:00
|
|
|
|
|
|
|
|
|
it 'should discard old pj information' do
|
|
|
|
|
subject.types_de_champ.each do |stc|
|
|
|
|
|
expect(stc.old_pj).to be_nil
|
|
|
|
|
end
|
|
|
|
|
end
|
2019-01-29 11:49:28 +01:00
|
|
|
|
|
|
|
|
|
it 'should have one administrateur' do
|
|
|
|
|
expect(subject.administrateurs).to eq([administrateur])
|
|
|
|
|
end
|
2019-08-27 15:05:56 +02:00
|
|
|
|
|
|
|
|
|
it 'should set ask_birthday to false' do
|
|
|
|
|
expect(subject.ask_birthday?).to eq(false)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the procedure is cloned from the library' do
|
|
|
|
|
let(:procedure) { create(:procedure, received_mail: received_mail, service: service, ask_birthday: true) }
|
|
|
|
|
|
|
|
|
|
it 'should set ask_birthday to false' do
|
|
|
|
|
expect(subject.ask_birthday?).to eq(false)
|
|
|
|
|
end
|
2017-03-07 18:19:48 +01:00
|
|
|
|
end
|
|
|
|
|
|
2018-04-23 16:29:32 +02:00
|
|
|
|
it 'should keep service_id' do
|
|
|
|
|
expect(subject.service).to eq(service)
|
|
|
|
|
end
|
|
|
|
|
|
2018-12-19 15:35:07 +01:00
|
|
|
|
context 'when the procedure is cloned to another administrateur' do
|
|
|
|
|
let(:administrateur) { create(:administrateur) }
|
|
|
|
|
|
|
|
|
|
it 'should clone service' do
|
|
|
|
|
expect(subject.service.id).not_to eq(service.id)
|
|
|
|
|
expect(subject.service.administrateur_id).not_to eq(service.administrateur_id)
|
|
|
|
|
expect(subject.service.attributes.except("id", "administrateur_id", "created_at", "updated_at")).to eq(service.attributes.except("id", "administrateur_id", "created_at", "updated_at"))
|
|
|
|
|
end
|
2019-01-10 13:43:22 +01:00
|
|
|
|
|
|
|
|
|
it 'should discard old pj information' do
|
|
|
|
|
subject.types_de_champ.each do |stc|
|
|
|
|
|
expect(stc.old_pj).to be_nil
|
|
|
|
|
end
|
|
|
|
|
end
|
2019-01-29 11:49:28 +01:00
|
|
|
|
|
|
|
|
|
it 'should have one administrateur' do
|
|
|
|
|
expect(subject.administrateurs).to eq([administrateur])
|
|
|
|
|
end
|
2018-12-19 15:35:07 +01:00
|
|
|
|
end
|
|
|
|
|
|
2017-03-07 18:19:48 +01:00
|
|
|
|
it 'should duplicate existing mail_templates' do
|
|
|
|
|
expect(subject.received_mail.attributes.except("id", "procedure_id", "created_at", "updated_at")).to eq procedure.received_mail.attributes.except("id", "procedure_id", "created_at", "updated_at")
|
|
|
|
|
expect(subject.received_mail.id).not_to eq procedure.received_mail.id
|
|
|
|
|
expect(subject.received_mail.id).not_to be nil
|
|
|
|
|
expect(subject.received_mail.procedure_id).not_to eq procedure.received_mail.procedure_id
|
|
|
|
|
expect(subject.received_mail.procedure_id).not_to be nil
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should not duplicate default mail_template' do
|
2017-12-22 21:37:08 +01:00
|
|
|
|
expect(subject.initiated_mail_template.attributes).to eq Mails::InitiatedMail.default_for_procedure(subject).attributes
|
2016-06-15 11:34:05 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'should not duplicate specific related objects' do
|
|
|
|
|
expect(subject.dossiers).to eq([])
|
|
|
|
|
end
|
|
|
|
|
|
2018-12-06 13:51:41 +01:00
|
|
|
|
describe 'should not duplicate lien_notice' do
|
|
|
|
|
let(:procedure) { create(:procedure, lien_notice: "http://toto.com") }
|
|
|
|
|
|
|
|
|
|
it { expect(subject.lien_notice).to be_nil }
|
|
|
|
|
end
|
|
|
|
|
|
2016-06-15 11:34:05 +02:00
|
|
|
|
describe 'procedure status is reset' do
|
2018-05-28 14:58:40 +02:00
|
|
|
|
let(:procedure) { create(:procedure, :archived, received_mail: received_mail, service: service) }
|
|
|
|
|
|
2016-06-24 16:41:44 +02:00
|
|
|
|
it 'Not published nor archived' do
|
2017-07-10 23:42:33 +02:00
|
|
|
|
expect(subject.archived_at).to be_nil
|
2017-07-11 14:21:10 +02:00
|
|
|
|
expect(subject.published_at).to be_nil
|
2018-05-28 14:58:40 +02:00
|
|
|
|
expect(subject.test_started_at).to be_nil
|
|
|
|
|
expect(subject.aasm_state).to eq "brouillon"
|
2019-03-06 14:42:27 +01:00
|
|
|
|
expect(subject.path).not_to be_nil
|
2016-06-15 11:34:05 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
2018-11-27 14:52:20 +01:00
|
|
|
|
|
|
|
|
|
it 'should keep types_de_champ ids stable' do
|
2018-12-20 12:00:27 +01:00
|
|
|
|
expect(subject.types_de_champ.first.id).not_to eq(procedure.types_de_champ.first.id)
|
|
|
|
|
expect(subject.types_de_champ.first.stable_id).to eq(procedure.types_de_champ.first.id)
|
2018-11-27 14:52:20 +01:00
|
|
|
|
end
|
2019-03-26 11:00:24 +01:00
|
|
|
|
|
|
|
|
|
it 'should duplicate piece_justificative_template on a type_de_champ' do
|
|
|
|
|
expect(subject.types_de_champ.where(type_champ: "piece_justificative").first.piece_justificative_template.attached?).to be true
|
|
|
|
|
end
|
2019-03-28 17:17:29 +01:00
|
|
|
|
|
|
|
|
|
context 'with a notice attached' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_notice, received_mail: received_mail, service: service) }
|
|
|
|
|
|
|
|
|
|
it 'should duplicate notice' do
|
|
|
|
|
expect(subject.notice.attached?).to be true
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with a deliberation attached' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_deliberation, received_mail: received_mail, service: service) }
|
|
|
|
|
|
|
|
|
|
it 'should duplicate deliberation' do
|
|
|
|
|
expect(subject.deliberation.attached?).to be true
|
|
|
|
|
end
|
|
|
|
|
end
|
2016-06-15 11:34:05 +02:00
|
|
|
|
end
|
2016-06-24 16:41:44 +02:00
|
|
|
|
|
2017-06-27 13:48:27 +02:00
|
|
|
|
describe '#publish!' do
|
2019-07-30 16:54:43 +02:00
|
|
|
|
let(:procedure) { create(:procedure, path: 'example-path') }
|
2018-10-25 15:11:12 +02:00
|
|
|
|
let(:now) { Time.zone.now.beginning_of_minute }
|
2017-06-27 13:48:27 +02:00
|
|
|
|
|
|
|
|
|
before do
|
2017-07-04 15:36:35 +02:00
|
|
|
|
Timecop.freeze(now)
|
2019-07-30 16:54:43 +02:00
|
|
|
|
procedure.publish!
|
2017-06-27 13:48:27 +02:00
|
|
|
|
end
|
2017-11-29 16:07:39 +01:00
|
|
|
|
after { Timecop.return }
|
2017-06-27 13:48:27 +02:00
|
|
|
|
|
2017-07-10 23:42:33 +02:00
|
|
|
|
it { expect(procedure.archived_at).to eq(nil) }
|
2017-07-04 15:36:35 +02:00
|
|
|
|
it { expect(procedure.published_at).to eq(now) }
|
2018-10-25 17:40:23 +02:00
|
|
|
|
it { expect(Procedure.find_by(path: "example-path")).to eq(procedure) }
|
2019-02-26 16:57:04 +01:00
|
|
|
|
it { expect(Procedure.find_by(path: "example-path").administrateurs).to eq(procedure.administrateurs) }
|
2017-06-27 13:48:27 +02:00
|
|
|
|
end
|
|
|
|
|
|
2017-07-13 15:21:52 +02:00
|
|
|
|
describe "#brouillon?" do
|
|
|
|
|
let(:procedure_brouillon) { Procedure.new() }
|
2018-10-25 15:11:12 +02:00
|
|
|
|
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
|
|
|
|
let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.zone.now, archived_at: Time.zone.now) }
|
2017-07-13 15:21:52 +02:00
|
|
|
|
|
|
|
|
|
it { expect(procedure_brouillon.brouillon?).to be_truthy }
|
|
|
|
|
it { expect(procedure_publiee.brouillon?).to be_falsey }
|
|
|
|
|
it { expect(procedure_archivee.brouillon?).to be_falsey }
|
|
|
|
|
end
|
|
|
|
|
|
2017-07-13 15:14:28 +02:00
|
|
|
|
describe "#publiee?" do
|
|
|
|
|
let(:procedure_brouillon) { Procedure.new() }
|
2018-10-25 15:11:12 +02:00
|
|
|
|
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
|
|
|
|
let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.zone.now, archived_at: Time.zone.now) }
|
2017-07-13 15:14:28 +02:00
|
|
|
|
|
|
|
|
|
it { expect(procedure_brouillon.publiee?).to be_falsey }
|
|
|
|
|
it { expect(procedure_publiee.publiee?).to be_truthy }
|
|
|
|
|
it { expect(procedure_archivee.publiee?).to be_falsey }
|
|
|
|
|
end
|
|
|
|
|
|
2017-07-13 15:09:25 +02:00
|
|
|
|
describe "#archivee?" do
|
|
|
|
|
let(:procedure_brouillon) { Procedure.new() }
|
2018-10-25 15:11:12 +02:00
|
|
|
|
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
|
|
|
|
let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.zone.now, archived_at: Time.zone.now) }
|
2017-07-13 15:09:25 +02:00
|
|
|
|
|
|
|
|
|
it { expect(procedure_brouillon.archivee?).to be_falsey }
|
|
|
|
|
it { expect(procedure_publiee.archivee?).to be_falsey }
|
|
|
|
|
it { expect(procedure_archivee.archivee?).to be_truthy }
|
2017-07-13 15:20:24 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe "#publiee_ou_archivee?" do
|
|
|
|
|
let(:procedure_brouillon) { Procedure.new() }
|
2018-10-25 15:11:12 +02:00
|
|
|
|
let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.zone.now) }
|
|
|
|
|
let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.zone.now, archived_at: Time.zone.now) }
|
2017-07-13 15:20:24 +02:00
|
|
|
|
|
|
|
|
|
it { expect(procedure_brouillon.publiee_ou_archivee?).to be_falsey }
|
|
|
|
|
it { expect(procedure_publiee.publiee_ou_archivee?).to be_truthy }
|
|
|
|
|
it { expect(procedure_archivee.publiee_ou_archivee?).to be_truthy }
|
2017-07-13 15:09:25 +02:00
|
|
|
|
end
|
|
|
|
|
|
2016-06-24 16:41:44 +02:00
|
|
|
|
describe 'archive' do
|
|
|
|
|
let(:procedure) { create(:procedure, :published) }
|
2018-10-25 15:11:12 +02:00
|
|
|
|
let(:now) { Time.zone.now.beginning_of_minute }
|
2016-06-24 16:41:44 +02:00
|
|
|
|
before do
|
2017-07-04 15:36:35 +02:00
|
|
|
|
Timecop.freeze(now)
|
2018-05-17 15:43:33 +02:00
|
|
|
|
procedure.archive!
|
2016-06-24 16:41:44 +02:00
|
|
|
|
procedure.reload
|
|
|
|
|
end
|
2017-11-29 16:07:39 +01:00
|
|
|
|
after { Timecop.return }
|
2016-06-24 16:41:44 +02:00
|
|
|
|
|
2017-07-13 15:09:25 +02:00
|
|
|
|
it { expect(procedure.archivee?).to be_truthy }
|
2017-07-04 15:36:35 +02:00
|
|
|
|
it { expect(procedure.archived_at).to eq(now) }
|
2016-06-24 16:41:44 +02:00
|
|
|
|
end
|
2016-07-22 15:06:30 +02:00
|
|
|
|
|
2019-07-05 14:38:20 +02:00
|
|
|
|
describe 'path_customized?' do
|
|
|
|
|
let(:procedure) { create :procedure }
|
|
|
|
|
|
|
|
|
|
subject { procedure.path_customized? }
|
|
|
|
|
|
|
|
|
|
context 'when the path is still the default' do
|
|
|
|
|
it { is_expected.to be_falsey }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the path has been changed' do
|
|
|
|
|
before { procedure.path = 'custom_path' }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to be_truthy }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2016-07-22 15:06:30 +02:00
|
|
|
|
describe 'total_dossier' do
|
|
|
|
|
let(:procedure) { create :procedure }
|
|
|
|
|
|
|
|
|
|
before do
|
2018-08-28 14:10:55 +02:00
|
|
|
|
create :dossier, procedure: procedure, state: Dossier.states.fetch(:en_construction)
|
|
|
|
|
create :dossier, procedure: procedure, state: Dossier.states.fetch(:brouillon)
|
|
|
|
|
create :dossier, procedure: procedure, state: Dossier.states.fetch(:en_construction)
|
2016-07-22 15:06:30 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
subject { procedure.total_dossier }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to eq 2 }
|
|
|
|
|
end
|
2017-04-05 11:34:16 +02:00
|
|
|
|
|
2019-07-05 14:38:20 +02:00
|
|
|
|
describe 'suggested_path' do
|
|
|
|
|
let(:procedure) { create :procedure, aasm_state: :publiee, libelle: 'Inscription au Collège' }
|
2017-04-14 11:34:53 +02:00
|
|
|
|
|
2019-07-05 14:38:20 +02:00
|
|
|
|
subject { procedure.suggested_path(procedure.administrateurs.first) }
|
|
|
|
|
|
|
|
|
|
context 'when the path has been customized' do
|
|
|
|
|
before { procedure.path = 'custom_path' }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to eq 'custom_path' }
|
|
|
|
|
end
|
2017-04-14 11:34:53 +02:00
|
|
|
|
|
2019-07-05 14:38:20 +02:00
|
|
|
|
context 'when the suggestion does not conflict' do
|
|
|
|
|
it { is_expected.to eq 'inscription-au-college' }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the suggestion conflicts with one procedure' do
|
|
|
|
|
before do
|
|
|
|
|
create :procedure, aasm_state: :publiee, path: 'inscription-au-college'
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it { is_expected.to eq 'inscription-au-college-2' }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the suggestion conflicts with several procedures' do
|
|
|
|
|
before do
|
|
|
|
|
create :procedure, aasm_state: :publiee, path: 'inscription-au-college'
|
|
|
|
|
create :procedure, aasm_state: :publiee, path: 'inscription-au-college-2'
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it { is_expected.to eq 'inscription-au-college-3' }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the suggestion conflicts with another procedure of the same admin' do
|
|
|
|
|
before do
|
|
|
|
|
create :procedure, aasm_state: :publiee, path: 'inscription-au-college', administrateurs: procedure.administrateurs
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it { is_expected.to eq 'inscription-au-college' }
|
|
|
|
|
end
|
2017-04-14 11:34:53 +02:00
|
|
|
|
end
|
2017-06-27 14:22:43 +02:00
|
|
|
|
|
|
|
|
|
describe ".default_scope" do
|
|
|
|
|
let!(:procedure) { create(:procedure, hidden_at: hidden_at) }
|
|
|
|
|
|
|
|
|
|
context "when hidden_at is nil" do
|
|
|
|
|
let(:hidden_at) { nil }
|
|
|
|
|
|
|
|
|
|
it { expect(Procedure.count).to eq(1) }
|
|
|
|
|
it { expect(Procedure.all).to include(procedure) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when hidden_at is not nil" do
|
|
|
|
|
let(:hidden_at) { 2.days.ago }
|
|
|
|
|
|
|
|
|
|
it { expect(Procedure.count).to eq(0) }
|
|
|
|
|
it { expect { Procedure.find(procedure.id) }.to raise_error(ActiveRecord::RecordNotFound) }
|
|
|
|
|
end
|
|
|
|
|
end
|
2017-06-27 15:26:40 +02:00
|
|
|
|
|
|
|
|
|
describe "#hide!" do
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
let!(:dossier) { create(:dossier, procedure: procedure) }
|
|
|
|
|
let!(:dossier2) { create(:dossier, procedure: procedure) }
|
2019-08-06 11:02:54 +02:00
|
|
|
|
let(:instructeur) { create(:instructeur) }
|
2017-06-27 15:26:40 +02:00
|
|
|
|
|
|
|
|
|
it { expect(Dossier.count).to eq(2) }
|
|
|
|
|
it { expect(Dossier.all).to include(dossier, dossier2) }
|
|
|
|
|
|
|
|
|
|
context "when hidding procedure" do
|
|
|
|
|
before do
|
2019-08-06 11:02:54 +02:00
|
|
|
|
instructeur.followed_dossiers << dossier
|
2017-06-27 15:26:40 +02:00
|
|
|
|
procedure.hide!
|
2019-08-06 11:02:54 +02:00
|
|
|
|
instructeur.reload
|
2017-06-27 15:26:40 +02:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it { expect(procedure.dossiers.count).to eq(0) }
|
|
|
|
|
it { expect(Dossier.count).to eq(0) }
|
2019-08-06 11:02:54 +02:00
|
|
|
|
it { expect(instructeur.followed_dossiers).not_to include(dossier) }
|
2017-06-27 15:26:40 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
2017-10-02 17:03:38 +02:00
|
|
|
|
|
2017-09-27 15:16:07 +02:00
|
|
|
|
describe ".default_sort" do
|
2018-09-20 17:02:28 +02:00
|
|
|
|
it { expect(Procedure.default_sort).to eq({ "table" => "self", "column" => "id", "order" => "desc" }) }
|
2017-09-27 15:16:07 +02:00
|
|
|
|
end
|
2018-03-16 12:00:01 +01:00
|
|
|
|
|
2018-03-20 16:00:30 +01:00
|
|
|
|
describe "#export_filename" do
|
2018-10-25 15:21:06 +02:00
|
|
|
|
before { Timecop.freeze(Time.zone.local(2018, 1, 2, 23, 11, 14)) }
|
2018-11-14 14:34:12 +01:00
|
|
|
|
after { Timecop.return }
|
2018-03-16 12:00:01 +01:00
|
|
|
|
|
2018-11-22 00:14:16 +01:00
|
|
|
|
subject { procedure.export_filename(:csv) }
|
2018-03-16 12:00:01 +01:00
|
|
|
|
|
2019-07-04 16:15:40 +02:00
|
|
|
|
let(:procedure) { create(:procedure, :published) }
|
2018-03-16 12:00:01 +01:00
|
|
|
|
|
2019-07-04 16:15:40 +02:00
|
|
|
|
it { is_expected.to eq("dossiers_#{procedure.path}_2018-01-02_23-11.csv") }
|
2018-03-16 12:00:01 +01:00
|
|
|
|
end
|
2018-04-13 16:11:37 +02:00
|
|
|
|
|
|
|
|
|
describe '#new_dossier' do
|
|
|
|
|
let(:procedure) do
|
|
|
|
|
procedure = create(:procedure)
|
|
|
|
|
|
|
|
|
|
create(:type_de_champ_text, procedure: procedure, order_place: 1)
|
|
|
|
|
create(:type_de_champ_number, procedure: procedure, order_place: 2)
|
|
|
|
|
create(:type_de_champ_textarea, :private, procedure: procedure)
|
|
|
|
|
|
|
|
|
|
procedure
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
let(:dossier) { procedure.new_dossier }
|
|
|
|
|
|
|
|
|
|
it { expect(dossier.procedure).to eq(procedure) }
|
|
|
|
|
|
|
|
|
|
it { expect(dossier.champs.size).to eq(2) }
|
|
|
|
|
it { expect(dossier.champs[0].type).to eq("Champs::TextChamp") }
|
|
|
|
|
|
|
|
|
|
it { expect(dossier.champs_private.size).to eq(1) }
|
|
|
|
|
it { expect(dossier.champs_private[0].type).to eq("Champs::TextareaChamp") }
|
|
|
|
|
|
|
|
|
|
it { expect(Champ.count).to eq(0) }
|
|
|
|
|
end
|
2018-06-01 11:06:12 +02:00
|
|
|
|
|
2018-07-03 20:18:49 +02:00
|
|
|
|
describe "#organisation_name" do
|
|
|
|
|
subject { procedure.organisation_name }
|
|
|
|
|
context 'when the procedure has a service (and no organization)' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_service, organisation: nil) }
|
|
|
|
|
it { is_expected.to eq procedure.service.nom }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when the procedure has an organization (and no service)' do
|
|
|
|
|
let(:procedure) { create(:procedure, organisation: 'DDT des Vosges', service: nil) }
|
|
|
|
|
it { is_expected.to eq procedure.organisation }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-06-01 11:06:12 +02:00
|
|
|
|
describe '#juridique_required' do
|
|
|
|
|
it 'automatically jumps to true once cadre_juridique or deliberation have been set' do
|
|
|
|
|
p = create(
|
|
|
|
|
:procedure,
|
|
|
|
|
juridique_required: false,
|
2018-10-01 14:08:12 +02:00
|
|
|
|
cadre_juridique: nil
|
2018-06-01 11:06:12 +02:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
expect(p.juridique_required).to be_falsey
|
|
|
|
|
|
|
|
|
|
p.update(cadre_juridique: 'cadre')
|
|
|
|
|
expect(p.juridique_required).to be_truthy
|
|
|
|
|
|
|
|
|
|
p.update(cadre_juridique: nil)
|
|
|
|
|
expect(p.juridique_required).to be_truthy
|
|
|
|
|
|
|
|
|
|
p.update_columns(cadre_juridique: nil, juridique_required: false)
|
|
|
|
|
p.reload
|
|
|
|
|
expect(p.juridique_required).to be_falsey
|
|
|
|
|
|
|
|
|
|
allow(p).to receive(:deliberation).and_return(double('attached?': true))
|
|
|
|
|
p.save
|
|
|
|
|
expect(p.juridique_required).to be_truthy
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-09-27 14:24:42 +02:00
|
|
|
|
|
2019-04-10 16:29:03 +02:00
|
|
|
|
describe '#usual_traitement_time' do
|
2019-03-18 13:19:37 +01:00
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
|
2019-04-10 16:29:03 +02:00
|
|
|
|
def create_dossier(construction_date:, instruction_date:, processed_date:)
|
2018-11-13 16:20:08 +01:00
|
|
|
|
dossier = create(:dossier, :accepte, procedure: procedure)
|
2019-04-10 16:29:03 +02:00
|
|
|
|
dossier.update!(en_construction_at: construction_date, en_instruction_at: instruction_date, processed_at: processed_date)
|
2018-11-13 16:20:08 +01:00
|
|
|
|
end
|
|
|
|
|
|
2018-11-08 18:09:27 +01:00
|
|
|
|
before do
|
2019-11-04 10:56:15 +01:00
|
|
|
|
Timecop.freeze(Time.utc(2019, 6, 1, 12, 0))
|
|
|
|
|
|
2019-03-18 13:19:37 +01:00
|
|
|
|
delays.each do |delay|
|
2019-04-10 16:29:03 +02:00
|
|
|
|
create_dossier(construction_date: 1.week.ago - delay, instruction_date: 1.week.ago - delay + 12.hours, processed_date: 1.week.ago)
|
2018-11-08 18:09:27 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
2018-09-27 14:24:42 +02:00
|
|
|
|
|
2019-11-04 10:56:15 +01:00
|
|
|
|
after { Timecop.return }
|
|
|
|
|
|
2018-11-08 18:09:27 +01:00
|
|
|
|
context 'when there are several processed dossiers' do
|
2019-03-18 13:19:37 +01:00
|
|
|
|
let(:delays) { [1.day, 2.days, 2.days, 2.days, 2.days, 3.days, 3.days, 3.days, 3.days, 12.days] }
|
2018-09-27 14:24:42 +02:00
|
|
|
|
|
2018-11-08 18:09:27 +01:00
|
|
|
|
it 'returns a time representative of the dossier instruction delay' do
|
2019-04-10 16:29:03 +02:00
|
|
|
|
expect(procedure.usual_traitement_time).to be_between(3.days, 4.days)
|
2018-09-27 14:24:42 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
2018-11-08 18:09:27 +01:00
|
|
|
|
|
2018-11-13 16:21:15 +01:00
|
|
|
|
context 'when there are very old dossiers' do
|
2019-03-18 13:19:37 +01:00
|
|
|
|
let(:delays) { [2.days, 2.days] }
|
2019-04-10 16:29:03 +02:00
|
|
|
|
let!(:old_dossier) { create_dossier(construction_date: 3.months.ago, instruction_date: 2.months.ago, processed_date: 2.months.ago) }
|
2018-11-13 16:21:15 +01:00
|
|
|
|
|
|
|
|
|
it 'ignores dossiers older than 1 month' do
|
2019-04-10 16:29:03 +02:00
|
|
|
|
expect(procedure.usual_traitement_time).to be_within(1.hour).of(2.days)
|
2018-11-13 16:21:15 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-03-20 17:45:41 +01:00
|
|
|
|
context 'when there is a dossier with bad data' do
|
|
|
|
|
let(:delays) { [2.days, 2.days] }
|
2019-04-10 16:29:03 +02:00
|
|
|
|
let!(:bad_dossier) { create_dossier(construction_date: nil, instruction_date: nil, processed_date: 10.days.ago) }
|
2019-03-20 17:45:41 +01:00
|
|
|
|
|
|
|
|
|
it 'ignores bad dossiers' do
|
2019-04-10 16:29:03 +02:00
|
|
|
|
expect(procedure.usual_traitement_time).to be_within(1.hour).of(2.days)
|
2019-03-20 17:45:41 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2018-11-08 18:09:27 +01:00
|
|
|
|
context 'when there is only one processed dossier' do
|
2019-03-18 13:19:37 +01:00
|
|
|
|
let(:delays) { [1.day] }
|
2019-04-10 16:29:03 +02:00
|
|
|
|
it { expect(procedure.usual_traitement_time).to be_within(1.hour).of(1.day) }
|
2018-11-08 18:09:27 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'where there is no processed dossier' do
|
2019-03-18 13:19:37 +01:00
|
|
|
|
let(:delays) { [] }
|
2019-04-10 16:29:03 +02:00
|
|
|
|
it { expect(procedure.usual_traitement_time).to be_nil }
|
2018-11-08 18:09:27 +01:00
|
|
|
|
end
|
2018-09-27 14:24:42 +02:00
|
|
|
|
end
|
2019-03-20 14:27:30 +01:00
|
|
|
|
|
|
|
|
|
describe '#move_type_de_champ' do
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
|
|
|
|
|
context 'type_de_champ' do
|
|
|
|
|
let(:type_de_champ) { create(:type_de_champ_text, order_place: 0, procedure: procedure) }
|
|
|
|
|
let!(:type_de_champ1) { create(:type_de_champ_text, order_place: 1, procedure: procedure) }
|
|
|
|
|
let!(:type_de_champ2) { create(:type_de_champ_text, order_place: 2, procedure: procedure) }
|
|
|
|
|
|
|
|
|
|
it 'move down' do
|
|
|
|
|
procedure.move_type_de_champ(type_de_champ, 2)
|
|
|
|
|
|
|
|
|
|
type_de_champ.reload
|
|
|
|
|
procedure.reload
|
|
|
|
|
|
|
|
|
|
expect(procedure.types_de_champ.index(type_de_champ)).to eq(2)
|
|
|
|
|
expect(type_de_champ.order_place).to eq(2)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'repetition' do
|
|
|
|
|
let!(:type_de_champ_repetition) do
|
|
|
|
|
create(:type_de_champ_repetition, types_de_champ: [
|
|
|
|
|
type_de_champ,
|
|
|
|
|
type_de_champ1,
|
|
|
|
|
type_de_champ2
|
|
|
|
|
], procedure: procedure)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'move down' do
|
|
|
|
|
procedure.move_type_de_champ(type_de_champ, 2)
|
|
|
|
|
|
|
|
|
|
type_de_champ.reload
|
|
|
|
|
procedure.reload
|
|
|
|
|
|
|
|
|
|
expect(type_de_champ.parent.types_de_champ.index(type_de_champ)).to eq(2)
|
|
|
|
|
expect(type_de_champ.order_place).to eq(2)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'private' do
|
|
|
|
|
let!(:type_de_champ_repetition) do
|
|
|
|
|
create(:type_de_champ_repetition, types_de_champ: [
|
|
|
|
|
type_de_champ,
|
|
|
|
|
type_de_champ1,
|
|
|
|
|
type_de_champ2
|
|
|
|
|
], private: true, procedure: procedure)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'move down' do
|
|
|
|
|
procedure.move_type_de_champ(type_de_champ, 2)
|
|
|
|
|
|
|
|
|
|
type_de_champ.reload
|
|
|
|
|
procedure.reload
|
|
|
|
|
|
|
|
|
|
expect(type_de_champ.parent.types_de_champ.index(type_de_champ)).to eq(2)
|
|
|
|
|
expect(type_de_champ.order_place).to eq(2)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'private' do
|
|
|
|
|
let(:type_de_champ) { create(:type_de_champ_text, order_place: 0, private: true, procedure: procedure) }
|
|
|
|
|
let!(:type_de_champ1) { create(:type_de_champ_text, order_place: 1, private: true, procedure: procedure) }
|
|
|
|
|
let!(:type_de_champ2) { create(:type_de_champ_text, order_place: 2, private: true, procedure: procedure) }
|
|
|
|
|
|
|
|
|
|
it 'move down' do
|
|
|
|
|
procedure.move_type_de_champ(type_de_champ, 2)
|
|
|
|
|
|
|
|
|
|
type_de_champ.reload
|
|
|
|
|
procedure.reload
|
|
|
|
|
|
|
|
|
|
expect(procedure.types_de_champ_private.index(type_de_champ)).to eq(2)
|
|
|
|
|
expect(type_de_champ.order_place).to eq(2)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2019-08-27 15:28:02 +02:00
|
|
|
|
|
|
|
|
|
describe '.ensure_a_groupe_instructeur_exists' do
|
|
|
|
|
let!(:procedure) { create(:procedure) }
|
|
|
|
|
|
|
|
|
|
it { expect(procedure.groupe_instructeurs.count).to eq(1) }
|
|
|
|
|
it { expect(procedure.groupe_instructeurs.first.label).to eq(GroupeInstructeur::DEFAULT_LABEL) }
|
|
|
|
|
end
|
2019-08-21 13:53:53 +02:00
|
|
|
|
|
|
|
|
|
describe '.missing_instructeurs?' do
|
|
|
|
|
let!(:procedure) { create(:procedure) }
|
|
|
|
|
|
|
|
|
|
subject { procedure.missing_instructeurs? }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
|
|
|
|
|
context 'when an instructeur is assign to this procedure' do
|
|
|
|
|
let!(:instructeur) { create(:instructeur) }
|
|
|
|
|
|
|
|
|
|
before { instructeur.assign_to_procedure(procedure) }
|
|
|
|
|
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
end
|
2019-10-03 15:35:31 +02:00
|
|
|
|
|
|
|
|
|
describe '.ods_export_stale?' do
|
|
|
|
|
subject { procedure.ods_export_stale? }
|
|
|
|
|
|
|
|
|
|
context 'with no ods export' do
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with a recent ods export' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_ods_export_file) }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with an old ods export' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_stale_ods_export_file) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '.csv_export_stale?' do
|
|
|
|
|
subject { procedure.csv_export_stale? }
|
|
|
|
|
|
|
|
|
|
context 'with no csv export' do
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with a recent csv export' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_csv_export_file) }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with an old csv export' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_stale_csv_export_file) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '.xlsx_export_stale?' do
|
|
|
|
|
subject { procedure.xlsx_export_stale? }
|
|
|
|
|
|
|
|
|
|
context 'with no xlsx export' do
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with a recent xlsx export' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_xlsx_export_file) }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with an old xlsx export' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_stale_xlsx_export_file) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '.should_generate_export?' do
|
|
|
|
|
context 'xlsx' do
|
|
|
|
|
subject { procedure.should_generate_export?('xlsx') }
|
|
|
|
|
context 'with no export' do
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with a recent export' do
|
|
|
|
|
context 'when its not queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_xlsx_export_file, xlsx_export_queued: false) }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when its already queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_xlsx_export_file, xlsx_export_queued: true) }
|
|
|
|
|
it { expect(procedure.xlsx_export_queued).to be true }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with an old export' do
|
|
|
|
|
context 'when its not queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_stale_xlsx_export_file, xlsx_export_queued: false) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when its already queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_stale_xlsx_export_file, xlsx_export_queued: true) }
|
|
|
|
|
it { expect(procedure.xlsx_export_queued).to be true }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'csv' do
|
|
|
|
|
subject { procedure.should_generate_export?('csv') }
|
|
|
|
|
context 'with no export' do
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with a recent export' do
|
|
|
|
|
context 'when its not queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_csv_export_file, csv_export_queued: false) }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when its already queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_csv_export_file, csv_export_queued: true) }
|
|
|
|
|
it { expect(procedure.csv_export_queued).to be true }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with an old export' do
|
|
|
|
|
context 'when its not queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_stale_csv_export_file, csv_export_queued: false) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when its already queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_stale_csv_export_file, csv_export_queued: true) }
|
|
|
|
|
it { expect(procedure.csv_export_queued).to be true }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'ods' do
|
|
|
|
|
subject { procedure.should_generate_export?('ods') }
|
|
|
|
|
context 'with no export' do
|
|
|
|
|
let(:procedure) { create(:procedure) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with a recent export' do
|
|
|
|
|
context 'when its not queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_ods_export_file, ods_export_queued: false) }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when its already queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_ods_export_file, ods_export_queued: true) }
|
|
|
|
|
it { expect(procedure.ods_export_queued).to be true }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'with an old export' do
|
|
|
|
|
context 'when its not queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_stale_ods_export_file, ods_export_queued: false) }
|
|
|
|
|
it { is_expected.to be true }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when its already queued' do
|
|
|
|
|
let(:procedure) { create(:procedure, :with_stale_ods_export_file, ods_export_queued: true) }
|
|
|
|
|
it { expect(procedure.ods_export_queued).to be true }
|
|
|
|
|
it { is_expected.to be false }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2015-09-21 17:59:03 +02:00
|
|
|
|
end
|