commit
d19bccb935
19 changed files with 180 additions and 107 deletions
|
@ -89,6 +89,9 @@ module ProcedureHelper
|
||||||
.merge(include: TYPES_DE_CHAMP_INCLUDE.merge(types_de_champ: TYPES_DE_CHAMP_BASE))
|
.merge(include: TYPES_DE_CHAMP_INCLUDE.merge(types_de_champ: TYPES_DE_CHAMP_BASE))
|
||||||
|
|
||||||
def types_de_champ_as_json(types_de_champ)
|
def types_de_champ_as_json(types_de_champ)
|
||||||
types_de_champ.as_json(TYPES_DE_CHAMP)
|
types_de_champ.includes(:drop_down_list,
|
||||||
|
piece_justificative_template_attachment: :blob,
|
||||||
|
types_de_champ: [:drop_down_list, piece_justificative_template_attachment: :blob])
|
||||||
|
.as_json(TYPES_DE_CHAMP)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -130,9 +130,7 @@ export default {
|
||||||
addChamp() {
|
addChamp() {
|
||||||
this.typesDeChamp.push({
|
this.typesDeChamp.push({
|
||||||
type_champ: 'text',
|
type_champ: 'text',
|
||||||
drop_down_list: {},
|
types_de_champ: []
|
||||||
types_de_champ: [],
|
|
||||||
options: {}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,14 @@ function initEditor(el) {
|
||||||
|
|
||||||
this.update = update;
|
this.update = update;
|
||||||
this.updateAll = updateAll;
|
this.updateAll = updateAll;
|
||||||
|
|
||||||
|
// We add an initial type de champ here if form is empty
|
||||||
|
if (this.state.typesDeChamp.length === 0) {
|
||||||
|
this.state.typesDeChamp.push({
|
||||||
|
type_champ: 'text',
|
||||||
|
types_de_champ: []
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,28 @@
|
||||||
addEventListener('turbolinks:load', () => {
|
import { delegate } from '@utils';
|
||||||
const primaries = document.querySelectorAll('select[data-secondary-options]');
|
|
||||||
|
|
||||||
for (let primary of primaries) {
|
const PRIMARY_SELECTOR = 'select[data-secondary-options]';
|
||||||
let secondary = document.querySelector(
|
const SECONDARY_SELECTOR = 'select[data-secondary]';
|
||||||
`select[data-secondary-id="${primary.dataset.primaryId}"]`
|
const CHAMP_SELECTOR = '.editable-champ';
|
||||||
);
|
|
||||||
let secondaryOptions = JSON.parse(primary.dataset.secondaryOptions);
|
|
||||||
|
|
||||||
primary.addEventListener('change', e => {
|
delegate('change', PRIMARY_SELECTOR, evt => {
|
||||||
let option, options, element;
|
const primary = evt.target;
|
||||||
|
const secondary = primary
|
||||||
|
.closest(CHAMP_SELECTOR)
|
||||||
|
.querySelector(SECONDARY_SELECTOR);
|
||||||
|
const options = JSON.parse(primary.dataset.secondaryOptions);
|
||||||
|
|
||||||
while ((option = secondary.firstChild)) {
|
selectOptions(secondary, options[primary.value]);
|
||||||
secondary.removeChild(option);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
options = secondaryOptions[e.target.value];
|
function selectOptions(selectElement, options) {
|
||||||
|
selectElement.innerHTML = '';
|
||||||
|
|
||||||
for (let option of options) {
|
for (let option of options) {
|
||||||
element = document.createElement('option');
|
let element = document.createElement('option');
|
||||||
element.textContent = option;
|
element.textContent = option;
|
||||||
element.value = option;
|
element.value = option;
|
||||||
secondary.appendChild(element);
|
selectElement.appendChild(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
secondary.selectedIndex = 0;
|
selectElement.selectedIndex = 0;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ const BUTTON_SELECTOR = '.button.remove-row';
|
||||||
const DESTROY_INPUT_SELECTOR = 'input[type=hidden][name*=_destroy]';
|
const DESTROY_INPUT_SELECTOR = 'input[type=hidden][name*=_destroy]';
|
||||||
const CHAMP_SELECTOR = '.editable-champ';
|
const CHAMP_SELECTOR = '.editable-champ';
|
||||||
|
|
||||||
addEventListener('turbolinks:load', () => {
|
|
||||||
delegate('click', BUTTON_SELECTOR, evt => {
|
delegate('click', BUTTON_SELECTOR, evt => {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
|
|
||||||
|
@ -21,4 +20,3 @@ addEventListener('turbolinks:load', () => {
|
||||||
evt.target.remove();
|
evt.target.remove();
|
||||||
row.classList.remove('row');
|
row.classList.remove('row');
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ class Champs::LinkedDropDownListChamp < Champ
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
value.present? ? [primary_value, secondary_value].compact.join(' / ') : ""
|
value.present? ? [primary_value, secondary_value].select(&:present?).join(' / ') : ""
|
||||||
end
|
end
|
||||||
|
|
||||||
def for_export
|
def for_export
|
||||||
|
|
|
@ -167,13 +167,11 @@ module TagsSubstitutionConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def types_de_champ_tags(types_de_champ, available_for_states)
|
def types_de_champ_tags(types_de_champ, available_for_states)
|
||||||
types_de_champ.map do |tdc|
|
tags = types_de_champ.flat_map(&:tags_for_template)
|
||||||
{
|
tags.each do |tag|
|
||||||
libelle: tdc.libelle,
|
tag[:available_for_states] = available_for_states
|
||||||
description: tdc.description,
|
|
||||||
available_for_states: available_for_states
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
tags
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace_tags(text, dossier)
|
def replace_tags(text, dossier)
|
||||||
|
@ -181,10 +179,9 @@ module TagsSubstitutionConcern
|
||||||
return ''
|
return ''
|
||||||
end
|
end
|
||||||
|
|
||||||
text = replace_type_de_champ_tags(text, filter_tags(champ_public_tags), dossier.champs)
|
|
||||||
text = replace_type_de_champ_tags(text, filter_tags(champ_private_tags), dossier.champs_private)
|
|
||||||
|
|
||||||
tags_and_datas = [
|
tags_and_datas = [
|
||||||
|
[champ_public_tags, dossier.champs],
|
||||||
|
[champ_private_tags, dossier.champs_private],
|
||||||
[dossier_tags, dossier],
|
[dossier_tags, dossier],
|
||||||
[INDIVIDUAL_TAGS, dossier.individual],
|
[INDIVIDUAL_TAGS, dossier.individual],
|
||||||
[ENTREPRISE_TAGS, dossier.etablissement&.entreprise]
|
[ENTREPRISE_TAGS, dossier.etablissement&.entreprise]
|
||||||
|
@ -195,38 +192,29 @@ module TagsSubstitutionConcern
|
||||||
.inject(text) { |acc, (tags, data)| replace_tags_with_values_from_data(acc, tags, data) }
|
.inject(text) { |acc, (tags, data)| replace_tags_with_values_from_data(acc, tags, data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace_type_de_champ_tags(text, types_de_champ, dossier_champs)
|
|
||||||
types_de_champ.inject(text) do |acc, tag|
|
|
||||||
champ = dossier_champs
|
|
||||||
.select { |dossier_champ| dossier_champ.libelle == tag[:libelle] }
|
|
||||||
.first
|
|
||||||
|
|
||||||
replace_tag(acc, tag, champ)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def replace_tags_with_values_from_data(text, tags, data)
|
def replace_tags_with_values_from_data(text, tags, data)
|
||||||
if data.present?
|
if data.present?
|
||||||
tags.inject(text) do |acc, tag|
|
tags.inject(text) do |acc, tag|
|
||||||
if tag.key?(:target)
|
replace_tag(acc, tag, data)
|
||||||
value = data.send(tag[:target])
|
|
||||||
else
|
|
||||||
value = instance_exec(data, &tag[:lambda])
|
|
||||||
end
|
|
||||||
replace_tag(acc, tag, value)
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
text
|
text
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace_tag(text, tag, value)
|
def replace_tag(text, tag, data)
|
||||||
libelle = Regexp.quote(tag[:libelle])
|
libelle = Regexp.quote(tag[:libelle])
|
||||||
|
|
||||||
# allow any kind of space (non-breaking or other) in the tag’s libellé to match any kind of space in the template
|
# allow any kind of space (non-breaking or other) in the tag’s libellé to match any kind of space in the template
|
||||||
# (the '\\ |' is there because plain ASCII spaces were escaped by preceding Regexp.quote)
|
# (the '\\ |' is there because plain ASCII spaces were escaped by preceding Regexp.quote)
|
||||||
libelle.gsub!(/\\ |[[:blank:]]/, "[[:blank:]]")
|
libelle.gsub!(/\\ |[[:blank:]]/, "[[:blank:]]")
|
||||||
|
|
||||||
|
if tag.key?(:target)
|
||||||
|
value = data.send(tag[:target])
|
||||||
|
else
|
||||||
|
value = instance_exec(data, &tag[:lambda])
|
||||||
|
end
|
||||||
|
|
||||||
text.gsub(/--#{libelle}--/, value.to_s)
|
text.gsub(/--#{libelle}--/, value.to_s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -186,7 +186,7 @@ class Dossier < ApplicationRecord
|
||||||
"Dossier en brouillon répondant à la démarche ",
|
"Dossier en brouillon répondant à la démarche ",
|
||||||
procedure.libelle,
|
procedure.libelle,
|
||||||
" gérée par l'organisme ",
|
" gérée par l'organisme ",
|
||||||
procedure.organisation
|
procedure.organisation_name
|
||||||
]
|
]
|
||||||
else
|
else
|
||||||
parts = [
|
parts = [
|
||||||
|
@ -195,7 +195,7 @@ class Dossier < ApplicationRecord
|
||||||
" sur la démarche ",
|
" sur la démarche ",
|
||||||
procedure.libelle,
|
procedure.libelle,
|
||||||
" gérée par l'organisme ",
|
" gérée par l'organisme ",
|
||||||
procedure.organisation
|
procedure.organisation_name
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ class TypeDeChamp < ApplicationRecord
|
||||||
has_many :types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'TypeDeChamp', dependent: :destroy
|
has_many :types_de_champ, -> { ordered }, foreign_key: :parent_id, class_name: 'TypeDeChamp', dependent: :destroy
|
||||||
|
|
||||||
store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :old_pj
|
store_accessor :options, :cadastres, :quartiers_prioritaires, :parcelles_agricoles, :old_pj
|
||||||
|
delegate :tags_for_template, to: :dynamic_type
|
||||||
|
|
||||||
# TODO simplify after migrating `options` column to (non YAML encoded) JSON
|
# TODO simplify after migrating `options` column to (non YAML encoded) JSON
|
||||||
class MaybeYaml
|
class MaybeYaml
|
||||||
|
|
|
@ -21,6 +21,34 @@ class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBas
|
||||||
secondary_options
|
secondary_options
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def tags_for_template
|
||||||
|
tags = super
|
||||||
|
l = libelle
|
||||||
|
tags.push(
|
||||||
|
{
|
||||||
|
libelle: "#{l}/primaire",
|
||||||
|
description: "#{description} (menu primaire)",
|
||||||
|
lambda: -> (champs) {
|
||||||
|
champs
|
||||||
|
.detect { |champ| champ.libelle == l }
|
||||||
|
&.primary_value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
tags.push(
|
||||||
|
{
|
||||||
|
libelle: "#{l}/secondaire",
|
||||||
|
description: "#{description} (menu secondaire)",
|
||||||
|
lambda: -> (champs) {
|
||||||
|
champs
|
||||||
|
.detect { |champ| champ.libelle == l }
|
||||||
|
&.secondary_value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
tags
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def check_presence_of_primary_options
|
def check_presence_of_primary_options
|
||||||
|
|
|
@ -1,9 +1,22 @@
|
||||||
class TypesDeChamp::TypeDeChampBase
|
class TypesDeChamp::TypeDeChampBase
|
||||||
include ActiveModel::Validations
|
include ActiveModel::Validations
|
||||||
|
|
||||||
delegate :libelle, to: :@type_de_champ
|
delegate :description, :libelle, to: :@type_de_champ
|
||||||
|
|
||||||
def initialize(type_de_champ)
|
def initialize(type_de_champ)
|
||||||
@type_de_champ = type_de_champ
|
@type_de_champ = type_de_champ
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def tags_for_template
|
||||||
|
l = libelle
|
||||||
|
[
|
||||||
|
{
|
||||||
|
libelle: l,
|
||||||
|
description: description,
|
||||||
|
lambda: -> (champs) {
|
||||||
|
champs.detect { |champ| champ.libelle == l }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
class ClamavService
|
class ClamavService
|
||||||
def self.safe_file?(file_path)
|
def self.safe_file?(file_path)
|
||||||
if Rails.env.development?
|
if Rails.env.development?
|
||||||
Rails.logger.info("Rails.env = development => fake scan") # FIXME : remove me
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
FileUtils.chmod(0666, file_path)
|
FileUtils.chmod(0666, file_path)
|
||||||
|
|
||||||
client = ClamAV::Client.new
|
client = ClamAV::Client.new
|
||||||
response = client.execute(ClamAV::Commands::ScanCommand.new(file_path))
|
response = client.execute(ClamAV::Commands::ScanCommand.new(file_path)).first
|
||||||
Rails.logger.info("ClamAV response for #{file_path} : #{response.first.class.name}") # FIXME : remove me
|
if response.class == ClamAV::SuccessResponse
|
||||||
response.first.class != ClamAV::VirusResponse
|
true
|
||||||
|
elsif response.class == ClamAV::VirusResponse
|
||||||
|
false
|
||||||
|
elsif response.class == ClamAV::ErrorResponse
|
||||||
|
raise "ClamAV ErrorResponse : #{response.error_str}"
|
||||||
|
else
|
||||||
|
raise "ClamAV unkown response #{response.class.name}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
- if champ.drop_down_list && champ.drop_down_list.options.any?
|
- if champ.drop_down_list && champ.drop_down_list.options.any?
|
||||||
- champ_id = champ.object_id
|
|
||||||
= form.select :primary_value,
|
= form.select :primary_value,
|
||||||
champ.primary_options,
|
champ.primary_options,
|
||||||
{ required: champ.mandatory? },
|
{ required: champ.mandatory? },
|
||||||
{ data: { "secondary-options" => champ.secondary_options, "primary-id" => champ_id } }
|
{ data: { secondary_options: champ.secondary_options } }
|
||||||
= form.select :secondary_value,
|
= form.select :secondary_value,
|
||||||
champ.secondary_options[champ.primary_value],
|
champ.secondary_options[champ.primary_value],
|
||||||
{ required: champ.mandatory? },
|
{ required: champ.mandatory? },
|
||||||
{ data: { "secondary-id" => champ_id } }
|
{ data: { secondary: true } }
|
||||||
|
|
|
@ -100,9 +100,6 @@ feature 'As an administrateur I wanna create a new procedure', js: true do
|
||||||
page.refresh
|
page.refresh
|
||||||
expect(page).to have_current_path(champs_procedure_path(Procedure.last))
|
expect(page).to have_current_path(champs_procedure_path(Procedure.last))
|
||||||
|
|
||||||
within '.footer' do
|
|
||||||
click_on 'Ajouter un champ'
|
|
||||||
end
|
|
||||||
expect(page).to have_selector('#procedure_types_de_champ_attributes_0_libelle')
|
expect(page).to have_selector('#procedure_types_de_champ_attributes_0_libelle')
|
||||||
fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libelle de champ'
|
fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libelle de champ'
|
||||||
expect(page).to have_content('Formulaire mis à jour')
|
expect(page).to have_content('Formulaire mis à jour')
|
||||||
|
@ -131,9 +128,6 @@ feature 'As an administrateur I wanna create a new procedure', js: true do
|
||||||
scenario 'After adding champ and file, make publication' do
|
scenario 'After adding champ and file, make publication' do
|
||||||
page.refresh
|
page.refresh
|
||||||
|
|
||||||
within '.footer' do
|
|
||||||
click_on 'Ajouter un champ'
|
|
||||||
end
|
|
||||||
fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libelle de champ'
|
fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libelle de champ'
|
||||||
expect(page).to have_content('Formulaire mis à jour')
|
expect(page).to have_content('Formulaire mis à jour')
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ feature 'As an administrateur I edit procedure', js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Add a new champ" do
|
it "Add a new champ" do
|
||||||
|
click_on 'Supprimer'
|
||||||
|
|
||||||
within '.footer' do
|
within '.footer' do
|
||||||
click_on 'Ajouter un champ'
|
click_on 'Ajouter un champ'
|
||||||
end
|
end
|
||||||
|
@ -31,7 +33,6 @@ feature 'As an administrateur I edit procedure', js: true do
|
||||||
click_on 'Ajouter un champ'
|
click_on 'Ajouter un champ'
|
||||||
click_on 'Ajouter un champ'
|
click_on 'Ajouter un champ'
|
||||||
click_on 'Ajouter un champ'
|
click_on 'Ajouter un champ'
|
||||||
click_on 'Ajouter un champ'
|
|
||||||
end
|
end
|
||||||
expect(page).not_to have_content('Le libellé doit être rempli.')
|
expect(page).not_to have_content('Le libellé doit être rempli.')
|
||||||
expect(page).not_to have_content('Modifications non sauvegardées.')
|
expect(page).not_to have_content('Modifications non sauvegardées.')
|
||||||
|
@ -66,9 +67,6 @@ feature 'As an administrateur I edit procedure', js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Remove champs" do
|
it "Remove champs" do
|
||||||
within '.footer' do
|
|
||||||
click_on 'Ajouter un champ'
|
|
||||||
end
|
|
||||||
fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libellé de champ'
|
fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libellé de champ'
|
||||||
expect(page).to have_content('Formulaire mis à jour')
|
expect(page).to have_content('Formulaire mis à jour')
|
||||||
page.refresh
|
page.refresh
|
||||||
|
@ -78,13 +76,10 @@ feature 'As an administrateur I edit procedure', js: true do
|
||||||
expect(page).not_to have_content('Supprimer')
|
expect(page).not_to have_content('Supprimer')
|
||||||
page.refresh
|
page.refresh
|
||||||
|
|
||||||
expect(page).not_to have_content('Supprimer')
|
expect(page).to have_content('Supprimer', count: 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Only add valid champs" do
|
it "Only add valid champs" do
|
||||||
within '.footer' do
|
|
||||||
click_on 'Ajouter un champ'
|
|
||||||
end
|
|
||||||
expect(page).to have_selector('#procedure_types_de_champ_attributes_0_description')
|
expect(page).to have_selector('#procedure_types_de_champ_attributes_0_description')
|
||||||
fill_in 'procedure_types_de_champ_attributes_0_description', with: 'déscription du champ'
|
fill_in 'procedure_types_de_champ_attributes_0_description', with: 'déscription du champ'
|
||||||
expect(page).to have_content('Le libellé doit être rempli.')
|
expect(page).to have_content('Le libellé doit être rempli.')
|
||||||
|
@ -95,9 +90,6 @@ feature 'As an administrateur I edit procedure', js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Add repetition champ" do
|
it "Add repetition champ" do
|
||||||
within '.footer' do
|
|
||||||
click_on 'Ajouter un champ'
|
|
||||||
end
|
|
||||||
expect(page).to have_selector('#procedure_types_de_champ_attributes_0_libelle')
|
expect(page).to have_selector('#procedure_types_de_champ_attributes_0_libelle')
|
||||||
select('Bloc répétable', from: 'procedure_types_de_champ_attributes_0_type_champ')
|
select('Bloc répétable', from: 'procedure_types_de_champ_attributes_0_type_champ')
|
||||||
fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libellé de champ'
|
fill_in 'procedure_types_de_champ_attributes_0_libelle', with: 'libellé de champ'
|
||||||
|
|
|
@ -74,7 +74,8 @@ feature 'linked dropdown lists' do
|
||||||
|
|
||||||
def secondary_id_for(libelle)
|
def secondary_id_for(libelle)
|
||||||
primary_id = primary_id_for(libelle)
|
primary_id = primary_id_for(libelle)
|
||||||
link = find("\##{primary_id}")['data-primary-id']
|
find("\##{primary_id}")
|
||||||
find("[data-secondary-id=\"#{link}\"]")['id']
|
.ancestor('.editable-champ')
|
||||||
|
.find("[data-secondary]")['id']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -110,6 +110,40 @@ describe TagsSubstitutionConcern, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the procedure has a linked drop down menus type de champ' do
|
||||||
|
let(:types_de_champ) do
|
||||||
|
[
|
||||||
|
create(:type_de_champ_linked_drop_down_list, libelle: 'libelle')
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:template) { 'tout : --libelle--, primaire : --libelle/primaire--, secondaire : --libelle/secondaire--' }
|
||||||
|
|
||||||
|
context 'and the champ has no value' do
|
||||||
|
it { is_expected.to eq('tout : , primaire : , secondaire : ') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the champ has a primary value' do
|
||||||
|
before do
|
||||||
|
c = dossier.champs.detect { |champ| champ.libelle == 'libelle' }
|
||||||
|
c.primary_value = 'primo'
|
||||||
|
c.save
|
||||||
|
end
|
||||||
|
it { is_expected.to eq('tout : primo, primaire : primo, secondaire : ') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the champ has a primary and secondary value' do
|
||||||
|
before do
|
||||||
|
c = dossier.champs.detect { |champ| champ.libelle == 'libelle' }
|
||||||
|
c.primary_value = 'primo'
|
||||||
|
c.secondary_value = 'secundo'
|
||||||
|
c.save
|
||||||
|
end
|
||||||
|
|
||||||
|
it { is_expected.to eq('tout : primo / secundo, primaire : primo, secondaire : secundo') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when the dossier has a motivation' do
|
context 'when the dossier has a motivation' do
|
||||||
let(:dossier) { create(:dossier, motivation: 'motivation') }
|
let(:dossier) { create(:dossier, motivation: 'motivation') }
|
||||||
|
|
||||||
|
|
|
@ -236,14 +236,15 @@ describe Dossier do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#text_summary" do
|
describe "#text_summary" do
|
||||||
let(:procedure) { create(:procedure, libelle: "Démarche", organisation: "Organisme") }
|
let(:service) { create(:service, nom: 'nom du service') }
|
||||||
|
let(:procedure) { create(:procedure, libelle: "Démarche", organisation: "Organisme", service: service) }
|
||||||
|
|
||||||
context 'when the dossier has been en_construction' do
|
context 'when the dossier has been en_construction' do
|
||||||
let(:dossier) { create :dossier, procedure: procedure, state: Dossier.states.fetch(:en_construction), en_construction_at: "31/12/2010".to_date }
|
let(:dossier) { create :dossier, procedure: procedure, state: Dossier.states.fetch(:en_construction), en_construction_at: "31/12/2010".to_date }
|
||||||
|
|
||||||
subject { dossier.text_summary }
|
subject { dossier.text_summary }
|
||||||
|
|
||||||
it { is_expected.to eq("Dossier déposé le 31/12/2010 sur la démarche Démarche gérée par l'organisme Organisme") }
|
it { is_expected.to eq("Dossier déposé le 31/12/2010 sur la démarche Démarche gérée par l'organisme nom du service") }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the dossier has not been en_construction' do
|
context 'when the dossier has not been en_construction' do
|
||||||
|
@ -251,7 +252,7 @@ describe Dossier do
|
||||||
|
|
||||||
subject { dossier.text_summary }
|
subject { dossier.text_summary }
|
||||||
|
|
||||||
it { is_expected.to eq("Dossier en brouillon répondant à la démarche Démarche gérée par l'organisme Organisme") }
|
it { is_expected.to eq("Dossier en brouillon répondant à la démarche Démarche gérée par l'organisme nom du service") }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,17 +4,27 @@ describe ClamavService do
|
||||||
describe '.safe_file?' do
|
describe '.safe_file?' do
|
||||||
let(:path_file) { '/tmp/plop.txt' }
|
let(:path_file) { '/tmp/plop.txt' }
|
||||||
|
|
||||||
subject { ClamavService.safe_file? path_file }
|
subject { ClamavService.safe_file?(path_file) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
client = instance_double("ClamAV::Client", :execute => [ClamAV::SuccessResponse])
|
client = double("ClamAV::Client", execute: [response])
|
||||||
allow(ClamAV::Client).to receive(:new).and_return(client)
|
allow(ClamAV::Client).to receive(:new).and_return(client)
|
||||||
end
|
|
||||||
|
|
||||||
it 'change permission of file path' do
|
|
||||||
allow(FileUtils).to receive(:chmod).with(0666, path_file).and_return(true)
|
allow(FileUtils).to receive(:chmod).with(0666, path_file).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
subject
|
context 'When response type is ClamAV::SuccessResponse' do
|
||||||
|
let(:response) { ClamAV::SuccessResponse.new("OK") }
|
||||||
|
it { expect(subject).to eq(true) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'When response type is ClamAV::VirusResponse' do
|
||||||
|
let(:response) { ClamAV::VirusResponse.new("KO", "VirusN4ame") }
|
||||||
|
it { expect(subject).to eq(false) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'When response type is ClamAV::ErrorResponse' do
|
||||||
|
let(:response) { ClamAV::ErrorResponse.new("File not found") }
|
||||||
|
it { expect { subject }.to raise_error("ClamAV ErrorResponse : File not found") }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue