commit
5e3edb1233
25 changed files with 141 additions and 91 deletions
|
@ -163,8 +163,8 @@ class StatsController < ApplicationController
|
||||||
def contact_percentage
|
def contact_percentage
|
||||||
number_of_months = 13
|
number_of_months = 13
|
||||||
|
|
||||||
from = Date.today.prev_month(number_of_months)
|
from = Time.zone.today.prev_month(number_of_months)
|
||||||
to = Date.today.prev_month
|
to = Time.zone.today.prev_month
|
||||||
|
|
||||||
adapter = Helpscout::UserConversationsAdapter.new(from, to)
|
adapter = Helpscout::UserConversationsAdapter.new(from, to)
|
||||||
if !adapter.can_fetch_reports?
|
if !adapter.can_fetch_reports?
|
||||||
|
|
|
@ -155,7 +155,7 @@ module Users
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { render :brouillon }
|
format.html { render :brouillon }
|
||||||
format.json { head :ok }
|
format.json { render json: {}, status: :ok }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ module CommentaireHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def commentaire_date(commentaire)
|
def commentaire_date(commentaire)
|
||||||
is_current_year = (commentaire.created_at.year == Date.current.year)
|
is_current_year = (commentaire.created_at.year == Time.zone.today.year)
|
||||||
template = is_current_year ? :message_date : :message_date_with_year
|
template = is_current_year ? :message_date : :message_date_with_year
|
||||||
I18n.l(commentaire.created_at, format: template)
|
I18n.l(commentaire.created_at, format: template)
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,12 +12,7 @@ function TypeDeChamps({ state: rootState, typeDeChamps }) {
|
||||||
typeDeChamps
|
typeDeChamps
|
||||||
});
|
});
|
||||||
|
|
||||||
if (state.typeDeChamps.length === 0) {
|
const hasUnsavedChamps = state.typeDeChamps.some(tdc => tdc.id == undefined);
|
||||||
dispatch({
|
|
||||||
type: 'addFirstTypeDeChamp',
|
|
||||||
done: () => dispatch({ type: 'refresh' })
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="champs-editor">
|
<div className="champs-editor">
|
||||||
|
@ -39,10 +34,18 @@ function TypeDeChamps({ state: rootState, typeDeChamps }) {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</SortableContainer>
|
</SortableContainer>
|
||||||
|
{state.typeDeChamps.length === 0 && (
|
||||||
|
<h2>
|
||||||
|
<FontAwesomeIcon icon="arrow-circle-down" />
|
||||||
|
Cliquez sur le bouton « Ajouter un champ » pour
|
||||||
|
créer votre premier champ.
|
||||||
|
</h2>
|
||||||
|
)}
|
||||||
<div className="footer"> </div>
|
<div className="footer"> </div>
|
||||||
<div className="buttons">
|
<div className="buttons">
|
||||||
<button
|
<button
|
||||||
className="button"
|
className="button"
|
||||||
|
disabled={hasUnsavedChamps}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'addNewTypeDeChamp',
|
type: 'addNewTypeDeChamp',
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
faArrowDown,
|
faArrowDown,
|
||||||
faArrowsAltV,
|
faArrowsAltV,
|
||||||
faArrowUp,
|
faArrowUp,
|
||||||
|
faArrowCircleDown,
|
||||||
faPlus,
|
faPlus,
|
||||||
faTrash
|
faTrash
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
|
@ -13,7 +14,14 @@ import Flash from './Flash';
|
||||||
import OperationsQueue from './OperationsQueue';
|
import OperationsQueue from './OperationsQueue';
|
||||||
import TypeDeChamps from './components/TypeDeChamps';
|
import TypeDeChamps from './components/TypeDeChamps';
|
||||||
|
|
||||||
library.add(faArrowDown, faArrowsAltV, faArrowUp, faPlus, faTrash);
|
library.add(
|
||||||
|
faArrowDown,
|
||||||
|
faArrowsAltV,
|
||||||
|
faArrowUp,
|
||||||
|
faArrowCircleDown,
|
||||||
|
faPlus,
|
||||||
|
faTrash
|
||||||
|
);
|
||||||
|
|
||||||
class TypesDeChampEditor extends Component {
|
class TypesDeChampEditor extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
|
|
@ -11,8 +11,6 @@ export default function typeDeChampsReducer(state, { type, params, done }) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'addNewTypeDeChamp':
|
case 'addNewTypeDeChamp':
|
||||||
return addNewTypeDeChamp(state, state.typeDeChamps, done);
|
return addNewTypeDeChamp(state, state.typeDeChamps, done);
|
||||||
case 'addFirstTypeDeChamp':
|
|
||||||
return addFirstTypeDeChamp(state, state.typeDeChamps, done);
|
|
||||||
case 'addNewRepetitionTypeDeChamp':
|
case 'addNewRepetitionTypeDeChamp':
|
||||||
return addNewRepetitionTypeDeChamp(
|
return addNewRepetitionTypeDeChamp(
|
||||||
state,
|
state,
|
||||||
|
@ -98,19 +96,6 @@ function addNewRepetitionTypeDeChamp(state, typeDeChamps, typeDeChamp, done) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addFirstTypeDeChamp(state, typeDeChamps, done) {
|
|
||||||
const typeDeChamp = { ...state.defaultTypeDeChampAttributes, order_place: 0 };
|
|
||||||
|
|
||||||
createTypeDeChampOperation(typeDeChamp, state.queue)
|
|
||||||
.then(() => done())
|
|
||||||
.catch(message => state.flash.error(message));
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
typeDeChamps: [...typeDeChamps, typeDeChamp]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateTypeDeChamp(
|
function updateTypeDeChamp(
|
||||||
state,
|
state,
|
||||||
typeDeChamps,
|
typeDeChamps,
|
||||||
|
@ -223,10 +208,14 @@ function getUpdateHandler(typeDeChamp, { queue, flash }) {
|
||||||
function findItemToInsertAfter() {
|
function findItemToInsertAfter() {
|
||||||
const target = getLastVisibleTypeDeChamp();
|
const target = getLastVisibleTypeDeChamp();
|
||||||
|
|
||||||
return {
|
if (target) {
|
||||||
target,
|
return {
|
||||||
index: parseInt(target.dataset.index) + 1
|
target,
|
||||||
};
|
index: parseInt(target.dataset.index) + 1
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLastVisibleTypeDeChamp() {
|
function getLastVisibleTypeDeChamp() {
|
||||||
|
|
|
@ -37,6 +37,7 @@ export default class AutosaveController {
|
||||||
const fetchOptions = {
|
const fetchOptions = {
|
||||||
method: form.method,
|
method: form.method,
|
||||||
body: formData,
|
body: formData,
|
||||||
|
credentials: 'same-origin',
|
||||||
headers: { Accept: 'application/json' }
|
headers: { Accept: 'application/json' }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ export default class AutosaveController {
|
||||||
// exclude them from the draft (by disabling them).
|
// exclude them from the draft (by disabling them).
|
||||||
// (Also Safari has issue with FormData containing empty file inputs)
|
// (Also Safari has issue with FormData containing empty file inputs)
|
||||||
const fileInputs = form.querySelectorAll(
|
const fileInputs = form.querySelectorAll(
|
||||||
'input[type="file"]:not([disabled])'
|
'input[type="file"]:not([disabled]), .editable-champ-piece_justificative input:not([disabled])'
|
||||||
);
|
);
|
||||||
fileInputs.forEach(fileInput => (fileInput.disabled = true));
|
fileInputs.forEach(fileInput => (fileInput.disabled = true));
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ const autosaveController = new AutosaveController();
|
||||||
// Whenever a 'change' event is triggered on one of the form inputs, try to autosave.
|
// Whenever a 'change' event is triggered on one of the form inputs, try to autosave.
|
||||||
|
|
||||||
const formSelector = 'form#dossier-edit-form.autosave-enabled';
|
const formSelector = 'form#dossier-edit-form.autosave-enabled';
|
||||||
const formInputsSelector = `${formSelector} input, ${formSelector} select, ${formSelector} textarea`;
|
const formInputsSelector = `${formSelector} input:not([type=input]), ${formSelector} select, ${formSelector} textarea`;
|
||||||
|
|
||||||
delegate(
|
delegate(
|
||||||
'change',
|
'change',
|
||||||
|
|
|
@ -3,6 +3,7 @@ import Turbolinks from 'turbolinks';
|
||||||
import Rails from '@rails/ujs';
|
import Rails from '@rails/ujs';
|
||||||
import * as ActiveStorage from '@rails/activestorage';
|
import * as ActiveStorage from '@rails/activestorage';
|
||||||
import '@rails/actiontext';
|
import '@rails/actiontext';
|
||||||
|
import 'whatwg-fetch'; // window.fetch polyfill
|
||||||
import Chartkick from 'chartkick';
|
import Chartkick from 'chartkick';
|
||||||
import Highcharts from 'highcharts';
|
import Highcharts from 'highcharts';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ class AutoArchiveProcedureJob < ApplicationJob
|
||||||
queue_as :cron
|
queue_as :cron
|
||||||
|
|
||||||
def perform(*args)
|
def perform(*args)
|
||||||
Procedure.publiees.where("auto_archive_on <= ?", Date.today).each do |procedure|
|
Procedure.publiees.where("auto_archive_on <= ?", Time.zone.today).each do |procedure|
|
||||||
procedure
|
procedure
|
||||||
.dossiers
|
.dossiers
|
||||||
.state_en_construction
|
.state_en_construction
|
||||||
|
|
|
@ -35,7 +35,7 @@ class Helpscout::UserConversationsAdapter
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_productivity_report(year, month)
|
def fetch_productivity_report(year, month)
|
||||||
if year == Date.today.year && month == Date.today.month
|
if year == Time.zone.today.year && month == Time.zone.today.month
|
||||||
raise ArgumentError, 'The report for the current month will change in the future, and cannot be cached.'
|
raise ArgumentError, 'The report for the current month will change in the future, and cannot be cached.'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@ class Champs::DateChamp < Champ
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
value.present? ? I18n.l(Date.parse(value)) : ""
|
value.present? ? I18n.l(Time.zone.parse(value), format: '%d %B %Y') : ""
|
||||||
end
|
end
|
||||||
|
|
||||||
def for_tag
|
def for_tag
|
||||||
value.present? ? I18n.l(Date.parse(value)) : ""
|
value.present? ? I18n.l(Time.zone.parse(value), format: '%d %B %Y') : ""
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -18,7 +18,7 @@ class Champs::DateChamp < Champ
|
||||||
def format_before_save
|
def format_before_save
|
||||||
self.value =
|
self.value =
|
||||||
begin
|
begin
|
||||||
Date.parse(value).iso8601
|
Time.zone.parse(value).to_date.iso8601
|
||||||
rescue
|
rescue
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,7 +32,8 @@
|
||||||
"react_ujs": "^2.6.0",
|
"react_ujs": "^2.6.0",
|
||||||
"select2": "^4.0.11",
|
"select2": "^4.0.11",
|
||||||
"trix": "^1.2.1",
|
"trix": "^1.2.1",
|
||||||
"turbolinks": "^5.2.0"
|
"turbolinks": "^5.2.0",
|
||||||
|
"whatwg-fetch": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "^10.0.3",
|
"babel-eslint": "^10.0.3",
|
||||||
|
|
|
@ -107,7 +107,7 @@ describe FranceConnect::ParticulierController, type: :controller do
|
||||||
|
|
||||||
before { subject }
|
before { subject }
|
||||||
|
|
||||||
it { expect(stored_fci).to have_attributes(user_info.merge(birthdate: Date.parse(birthdate))) }
|
it { expect(stored_fci).to have_attributes(user_info.merge(birthdate: Time.zone.parse(birthdate).to_datetime)) }
|
||||||
end
|
end
|
||||||
|
|
||||||
it { is_expected.to redirect_to(root_path) }
|
it { is_expected.to redirect_to(root_path) }
|
||||||
|
|
|
@ -69,14 +69,12 @@ 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))
|
||||||
|
|
||||||
expect(page).to have_selector('#champ-0-libelle')
|
add_champ(remove_flash_message: true)
|
||||||
fill_in 'champ-0-libelle', with: 'libelle de champ'
|
fill_in 'champ-0-libelle', with: 'libelle de champ'
|
||||||
blur
|
blur
|
||||||
expect(page).to have_content('Formulaire enregistré')
|
expect(page).to have_content('Formulaire enregistré')
|
||||||
|
|
||||||
within '.buttons' do
|
add_champ
|
||||||
click_on 'Ajouter un champ'
|
|
||||||
end
|
|
||||||
expect(page).to have_selector('#champ-1-libelle')
|
expect(page).to have_selector('#champ-1-libelle')
|
||||||
|
|
||||||
click_on Procedure.last.libelle
|
click_on Procedure.last.libelle
|
||||||
|
@ -91,6 +89,7 @@ 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
|
||||||
|
|
||||||
|
add_champ(remove_flash_message: true)
|
||||||
fill_in 'champ-0-libelle', with: 'libelle de champ'
|
fill_in 'champ-0-libelle', with: 'libelle de champ'
|
||||||
blur
|
blur
|
||||||
expect(page).to have_content('Formulaire enregistré')
|
expect(page).to have_content('Formulaire enregistré')
|
||||||
|
|
|
@ -10,14 +10,8 @@ feature 'As an administrateur I can edit types de champ', js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Add a new champ" do
|
it "Add a new champ" do
|
||||||
page.accept_alert do
|
add_champ
|
||||||
click_on 'Supprimer'
|
|
||||||
end
|
|
||||||
|
|
||||||
within '.buttons' do
|
|
||||||
click_on 'Ajouter un champ'
|
|
||||||
end
|
|
||||||
expect(page).to have_selector('#champ-0-libelle')
|
|
||||||
fill_in 'champ-0-libelle', with: 'libellé de champ'
|
fill_in 'champ-0-libelle', with: 'libellé de champ'
|
||||||
blur
|
blur
|
||||||
expect(page).to have_content('Formulaire enregistré')
|
expect(page).to have_content('Formulaire enregistré')
|
||||||
|
@ -26,65 +20,64 @@ feature 'As an administrateur I can edit types de champ', js: true do
|
||||||
within '.buttons' do
|
within '.buttons' do
|
||||||
click_on 'Enregistrer'
|
click_on 'Enregistrer'
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(page).to have_content('Formulaire enregistré')
|
expect(page).to have_content('Formulaire enregistré')
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Add multiple champs" do
|
it "Add multiple champs" do
|
||||||
within '.buttons' do
|
# Champs are created when clicking the 'Add field' button
|
||||||
click_on 'Ajouter un champ'
|
add_champs(count: 3)
|
||||||
click_on 'Ajouter un champ'
|
|
||||||
click_on 'Ajouter un champ'
|
|
||||||
end
|
|
||||||
page.refresh
|
|
||||||
|
|
||||||
|
# Champs are automatically saved
|
||||||
|
expect(page).to have_button('Ajouter un champ', disabled: false)
|
||||||
|
page.refresh
|
||||||
|
expect(page).to have_selector('.type-de-champ', count: 3)
|
||||||
|
|
||||||
|
# Multiple champs can be edited
|
||||||
fill_in 'champ-0-libelle', with: 'libellé de champ 0'
|
fill_in 'champ-0-libelle', with: 'libellé de champ 0'
|
||||||
fill_in 'champ-1-libelle', with: 'libellé de champ 1'
|
fill_in 'champ-1-libelle', with: 'libellé de champ 1'
|
||||||
blur
|
blur
|
||||||
expect(page).to have_content('Formulaire enregistré')
|
expect(page).to have_content('Formulaire enregistré')
|
||||||
|
|
||||||
expect(page).to have_selector('#champ-0-libelle')
|
# Champs can be deleted
|
||||||
expect(page).to have_selector('#champ-1-libelle')
|
|
||||||
expect(page).to have_selector('#champ-2-libelle')
|
|
||||||
expect(page).to have_selector('#champ-3-libelle')
|
|
||||||
|
|
||||||
within '.type-de-champ[data-index="2"]' do
|
within '.type-de-champ[data-index="2"]' do
|
||||||
page.accept_alert do
|
page.accept_alert do
|
||||||
click_on 'Supprimer'
|
click_on 'Supprimer'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
expect(page).not_to have_selector('#champ-2-libelle')
|
||||||
|
|
||||||
expect(page).not_to have_selector('#champ-3-libelle')
|
fill_in 'champ-1-libelle', with: 'edited libellé de champ 1'
|
||||||
fill_in 'champ-2-libelle', with: 'libellé de champ 2'
|
|
||||||
blur
|
blur
|
||||||
expect(page).to have_content('Formulaire enregistré')
|
expect(page).to have_content('Formulaire enregistré')
|
||||||
|
expect(page).to have_content('Supprimer', count: 2)
|
||||||
expect(page).to have_content('Supprimer', count: 3)
|
|
||||||
|
|
||||||
page.refresh
|
page.refresh
|
||||||
|
expect(page).to have_content('Supprimer', count: 2)
|
||||||
expect(page).to have_content('Supprimer', count: 3)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Remove champs" do
|
it "Remove champs" do
|
||||||
|
add_champ(remove_flash_message: true)
|
||||||
|
|
||||||
fill_in 'champ-0-libelle', with: 'libellé de champ'
|
fill_in 'champ-0-libelle', with: 'libellé de champ'
|
||||||
blur
|
blur
|
||||||
expect(page).to have_content('Formulaire enregistré')
|
expect(page).to have_content('Formulaire enregistré')
|
||||||
page.refresh
|
page.refresh
|
||||||
|
|
||||||
page.accept_alert do
|
page.accept_alert do
|
||||||
click_on 'Supprimer'
|
click_on 'Supprimer'
|
||||||
end
|
end
|
||||||
expect(page).to have_content('Formulaire enregistré')
|
expect(page).to have_content('Formulaire enregistré')
|
||||||
expect(page).to have_content('Supprimer', count: 1)
|
expect(page).to have_content('Supprimer', count: 0)
|
||||||
page.refresh
|
page.refresh
|
||||||
|
|
||||||
expect(page).to have_content('Supprimer', count: 1)
|
expect(page).to have_content('Supprimer', count: 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Only add valid champs" do
|
it "Only add valid champs" do
|
||||||
expect(page).to have_selector('#champ-0-description')
|
add_champ(remove_flash_message: true)
|
||||||
|
|
||||||
fill_in 'champ-0-libelle', with: ''
|
fill_in 'champ-0-libelle', with: ''
|
||||||
fill_in 'champ-0-description', with: 'déscription du champ'
|
fill_in 'champ-0-description', with: 'description du champ'
|
||||||
blur
|
blur
|
||||||
expect(page).not_to have_content('Formulaire enregistré')
|
expect(page).not_to have_content('Formulaire enregistré')
|
||||||
|
|
||||||
|
@ -94,7 +87,8 @@ feature 'As an administrateur I can edit types de champ', js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Add repetition champ" do
|
it "Add repetition champ" do
|
||||||
expect(page).to have_selector('#champ-0-libelle')
|
add_champ(remove_flash_message: true)
|
||||||
|
|
||||||
select('Bloc répétable', from: 'champ-0-type_champ')
|
select('Bloc répétable', from: 'champ-0-type_champ')
|
||||||
fill_in 'champ-0-libelle', with: 'libellé de champ'
|
fill_in 'champ-0-libelle', with: 'libellé de champ'
|
||||||
blur
|
blur
|
||||||
|
@ -124,6 +118,8 @@ feature 'As an administrateur I can edit types de champ', js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Add carte champ" do
|
it "Add carte champ" do
|
||||||
|
add_champ
|
||||||
|
|
||||||
select('Carte', from: 'champ-0-type_champ')
|
select('Carte', from: 'champ-0-type_champ')
|
||||||
fill_in 'champ-0-libelle', with: 'Libellé de champ carte', fill_options: { clear: :backspace }
|
fill_in 'champ-0-libelle', with: 'Libellé de champ carte', fill_options: { clear: :backspace }
|
||||||
check 'Quartiers prioritaires'
|
check 'Quartiers prioritaires'
|
||||||
|
@ -140,6 +136,8 @@ feature 'As an administrateur I can edit types de champ', js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "Add dropdown champ" do
|
it "Add dropdown champ" do
|
||||||
|
add_champ
|
||||||
|
|
||||||
select('Menu déroulant', from: 'champ-0-type_champ')
|
select('Menu déroulant', from: 'champ-0-type_champ')
|
||||||
fill_in 'champ-0-libelle', with: 'Libellé de champ menu déroulant', fill_options: { clear: :backspace }
|
fill_in 'champ-0-libelle', with: 'Libellé de champ menu déroulant', fill_options: { clear: :backspace }
|
||||||
fill_in 'champ-0-drop_down_list_value', with: 'Un menu', fill_options: { clear: :backspace }
|
fill_in 'champ-0-drop_down_list_value', with: 'Un menu', fill_options: { clear: :backspace }
|
||||||
|
|
|
@ -34,7 +34,7 @@ feature 'Signin in:' do
|
||||||
scenario 'an existing user can sign-in and fill the procedure' do
|
scenario 'an existing user can sign-in and fill the procedure' do
|
||||||
click_on 'J’ai déjà un compte'
|
click_on 'J’ai déjà un compte'
|
||||||
expect(page).to have_current_path new_user_session_path
|
expect(page).to have_current_path new_user_session_path
|
||||||
expect_page_to_have_procedure_description(procedure)
|
expect(page).to have_procedure_description(procedure)
|
||||||
|
|
||||||
sign_in_with user.email, password
|
sign_in_with user.email, password
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ feature 'Signin in:' do
|
||||||
click_on 'Commencer la démarche'
|
click_on 'Commencer la démarche'
|
||||||
|
|
||||||
expect(page).to have_current_path identite_dossier_path(user.reload.dossiers.last)
|
expect(page).to have_current_path identite_dossier_path(user.reload.dossiers.last)
|
||||||
expect_page_to_have_procedure_description(procedure)
|
expect(page).to have_procedure_description(procedure)
|
||||||
expect(page).to have_content "Données d'identité"
|
expect(page).to have_content "Données d'identité"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,7 +20,7 @@ feature 'Creating a new dossier:' do
|
||||||
click_on 'Commencer la démarche'
|
click_on 'Commencer la démarche'
|
||||||
|
|
||||||
expect(page).to have_current_path identite_dossier_path(user.reload.dossiers.last)
|
expect(page).to have_current_path identite_dossier_path(user.reload.dossiers.last)
|
||||||
expect_page_to_have_procedure_description(procedure)
|
expect(page).to have_procedure_description(procedure)
|
||||||
|
|
||||||
fill_in 'individual_nom', with: 'Nom'
|
fill_in 'individual_nom', with: 'Nom'
|
||||||
fill_in 'individual_prenom', with: 'Prenom'
|
fill_in 'individual_prenom', with: 'Prenom'
|
||||||
|
@ -82,7 +82,7 @@ feature 'Creating a new dossier:' do
|
||||||
click_on 'Commencer la démarche'
|
click_on 'Commencer la démarche'
|
||||||
|
|
||||||
expect(page).to have_current_path siret_dossier_path(dossier)
|
expect(page).to have_current_path siret_dossier_path(dossier)
|
||||||
expect_page_to_have_procedure_description(procedure)
|
expect(page).to have_procedure_description(procedure)
|
||||||
|
|
||||||
fill_in 'Numéro SIRET', with: siret
|
fill_in 'Numéro SIRET', with: siret
|
||||||
click_on 'Valider'
|
click_on 'Valider'
|
||||||
|
@ -99,7 +99,7 @@ feature 'Creating a new dossier:' do
|
||||||
click_on 'Commencer la démarche'
|
click_on 'Commencer la démarche'
|
||||||
|
|
||||||
expect(page).to have_current_path(siret_dossier_path(dossier))
|
expect(page).to have_current_path(siret_dossier_path(dossier))
|
||||||
expect_page_to_have_procedure_description(procedure)
|
expect(page).to have_procedure_description(procedure)
|
||||||
|
|
||||||
fill_in 'Numéro SIRET', with: '0000'
|
fill_in 'Numéro SIRET', with: '0000'
|
||||||
click_on 'Valider'
|
click_on 'Valider'
|
||||||
|
|
|
@ -42,7 +42,7 @@ feature 'Signing up:' do
|
||||||
scenario 'a new user can sign-up and fill the procedure' do
|
scenario 'a new user can sign-up and fill the procedure' do
|
||||||
click_on 'Créer un compte'
|
click_on 'Créer un compte'
|
||||||
expect(page).to have_current_path new_user_registration_path
|
expect(page).to have_current_path new_user_registration_path
|
||||||
expect_page_to_have_procedure_description(procedure)
|
expect(page).to have_procedure_description(procedure)
|
||||||
|
|
||||||
sign_up_with user_email, user_password
|
sign_up_with user_email, user_password
|
||||||
expect(page).to have_content "nous avons besoin de vérifier votre adresse #{user_email}"
|
expect(page).to have_content "nous avons besoin de vérifier votre adresse #{user_email}"
|
||||||
|
@ -54,7 +54,7 @@ feature 'Signing up:' do
|
||||||
click_on 'Commencer la démarche'
|
click_on 'Commencer la démarche'
|
||||||
|
|
||||||
expect(page).to have_current_path identite_dossier_path(procedure.reload.dossiers.last)
|
expect(page).to have_current_path identite_dossier_path(procedure.reload.dossiers.last)
|
||||||
expect_page_to_have_procedure_description(procedure)
|
expect(page).to have_procedure_description(procedure)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ require 'rails_helper'
|
||||||
RSpec.describe AutoArchiveProcedureJob, type: :job do
|
RSpec.describe AutoArchiveProcedureJob, type: :job do
|
||||||
let!(:procedure) { create(:procedure, :published, :with_instructeur, auto_archive_on: nil) }
|
let!(:procedure) { create(:procedure, :published, :with_instructeur, auto_archive_on: nil) }
|
||||||
let!(:procedure_hier) { create(:procedure, :published, :with_instructeur, auto_archive_on: 1.day.ago) }
|
let!(:procedure_hier) { create(:procedure, :published, :with_instructeur, auto_archive_on: 1.day.ago) }
|
||||||
let!(:procedure_aujourdhui) { create(:procedure, :published, :with_instructeur, auto_archive_on: Date.today) }
|
let!(:procedure_aujourdhui) { create(:procedure, :published, :with_instructeur, auto_archive_on: Time.zone.today) }
|
||||||
let!(:procedure_demain) { create(:procedure, :published, :with_instructeur, auto_archive_on: 1.day.from_now) }
|
let!(:procedure_demain) { create(:procedure, :published, :with_instructeur, auto_archive_on: 1.day.from_now) }
|
||||||
|
|
||||||
subject { AutoArchiveProcedureJob.new.perform }
|
subject { AutoArchiveProcedureJob.new.perform }
|
||||||
|
|
|
@ -4,7 +4,7 @@ describe BillSignatureService do
|
||||||
describe ".grouped_unsigned_operation_until" do
|
describe ".grouped_unsigned_operation_until" do
|
||||||
subject { BillSignatureService.grouped_unsigned_operation_until(date).length }
|
subject { BillSignatureService.grouped_unsigned_operation_until(date).length }
|
||||||
|
|
||||||
let(:date) { Date.today }
|
let(:date) { Time.zone.today }
|
||||||
|
|
||||||
context "when operations of several days need to be signed" do
|
context "when operations of several days need to be signed" do
|
||||||
before do
|
before do
|
||||||
|
|
|
@ -33,7 +33,7 @@ describe FranceConnectService do
|
||||||
expect(subject).to have_attributes({
|
expect(subject).to have_attributes({
|
||||||
given_name: given_name,
|
given_name: given_name,
|
||||||
family_name: family_name,
|
family_name: family_name,
|
||||||
birthdate: Date.parse(birthdate),
|
birthdate: Time.zone.parse(birthdate).to_date,
|
||||||
birthplace: birthplace,
|
birthplace: birthplace,
|
||||||
gender: gender,
|
gender: gender,
|
||||||
email_france_connect: email,
|
email_france_connect: email,
|
||||||
|
|
|
@ -55,14 +55,6 @@ module FeatureHelpers
|
||||||
visit "/users/confirmation?#{token_params}"
|
visit "/users/confirmation?#{token_params}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def expect_page_to_have_procedure_description(procedure)
|
|
||||||
# Procedure context on the page
|
|
||||||
expect(page).to have_content(procedure.libelle)
|
|
||||||
expect(page).to have_content(procedure.description)
|
|
||||||
# Procedure contact infos in the footer
|
|
||||||
expect(page).to have_content(procedure.service.email)
|
|
||||||
end
|
|
||||||
|
|
||||||
def click_reset_password_link_for(email)
|
def click_reset_password_link_for(email)
|
||||||
reset_password_email = open_email(email)
|
reset_password_email = open_email(email)
|
||||||
token_params = reset_password_email.body.match(/reset_password_token=[^"]+/)
|
token_params = reset_password_email.body.match(/reset_password_token=[^"]+/)
|
||||||
|
@ -70,6 +62,24 @@ module FeatureHelpers
|
||||||
visit "/users/password/edit?#{token_params}"
|
visit "/users/password/edit?#{token_params}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Add a new type de champ in the procedure editor
|
||||||
|
def add_champ(options = {})
|
||||||
|
add_champs(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add several new type de champ in the procedure editor
|
||||||
|
def add_champs(count: 1, remove_flash_message: false)
|
||||||
|
within '.buttons' do
|
||||||
|
count.times { click_on 'Ajouter un champ' }
|
||||||
|
end
|
||||||
|
|
||||||
|
if remove_flash_message
|
||||||
|
expect(page).to have_button('Ajouter un champ', disabled: false)
|
||||||
|
expect(page).to have_content('Formulaire enregistré')
|
||||||
|
execute_script("document.querySelector('#flash_message').remove();")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def blur
|
def blur
|
||||||
page.find('body').click
|
page.find('body').click
|
||||||
end
|
end
|
||||||
|
@ -85,6 +95,32 @@ module FeatureHelpers
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Keep the brower window open after a test success of failure, to
|
||||||
|
# allow inspecting the page or the console.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# 1. Disable the 'headless' mode in `spec_helper.rb`
|
||||||
|
# 2. Call `leave_browser_open` at the beginning of your scenario
|
||||||
|
def leave_browser_open
|
||||||
|
Selenium::WebDriver::Chrome::Service.class_eval do
|
||||||
|
def stop
|
||||||
|
STDOUT.puts "#{self.class}#stop is a no-op, because leave_browser_open is enabled"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Selenium::WebDriver::Driver.class_eval do
|
||||||
|
def quit
|
||||||
|
STDOUT.puts "#{self.class}#quit is a no-op, because leave_browser_open is enabled"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Capybara::Selenium::Driver.class_eval do
|
||||||
|
def reset!
|
||||||
|
STDOUT.puts "#{self.class}#reset! is a no-op, because leave_browser_open is enabled"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
|
|
9
spec/support/feature_matchers.rb
Normal file
9
spec/support/feature_matchers.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
module Capybara
|
||||||
|
class Session
|
||||||
|
# Find the description of a procedure on the page
|
||||||
|
# Usage: expect(page).to have_procedure_description(procedure)
|
||||||
|
def has_procedure_description?(procedure)
|
||||||
|
has_content?(procedure.libelle) && has_content?(procedure.description) && has_content?(procedure.service.email)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -8931,6 +8931,11 @@ websocket-extensions@>=0.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
|
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
|
||||||
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
|
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
|
||||||
|
|
||||||
|
whatwg-fetch@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
|
||||||
|
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
|
||||||
|
|
||||||
which-module@^1.0.0:
|
which-module@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
|
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
|
||||||
|
|
Loading…
Reference in a new issue