commit
526e54ca17
27 changed files with 210 additions and 115 deletions
|
@ -138,7 +138,7 @@ GEM
|
|||
selenium-webdriver
|
||||
case_transform (0.2)
|
||||
activesupport
|
||||
chartkick (3.3.0)
|
||||
chartkick (3.3.1)
|
||||
childprocess (0.9.0)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
chunky_png (1.3.11)
|
||||
|
@ -381,7 +381,7 @@ GEM
|
|||
nenv (0.3.0)
|
||||
netrc (0.11.0)
|
||||
nio4r (2.5.2)
|
||||
nokogiri (1.10.7)
|
||||
nokogiri (1.10.8)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
notiffany (0.1.1)
|
||||
nenv (~> 0.1)
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
.procedure-form__options-summary {
|
||||
cursor: pointer;
|
||||
|
||||
.header-section {
|
||||
.header-subsection {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,9 +42,19 @@ class Users::ConfirmationsController < Devise::ConfirmationsController
|
|||
if sign_in_after_confirmation?(resource)
|
||||
resource.remember_me = true
|
||||
sign_in(resource)
|
||||
end
|
||||
|
||||
if procedure_from_params
|
||||
commencer_path(path: procedure_from_params.path)
|
||||
elsif signed_in?
|
||||
# Will try to use `stored_location_for` to find a path
|
||||
after_sign_in_path_for(resource_name)
|
||||
else
|
||||
super(resource_name, resource)
|
||||
end
|
||||
end
|
||||
|
||||
def procedure_from_params
|
||||
params[:procedure_id] && Procedure.find_by(id: params[:procedure_id])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,6 +21,12 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
|||
|
||||
# POST /resource
|
||||
def create
|
||||
# We may need the confirmation mailer to access the current procedure.
|
||||
# But there's no easy way to pass an argument to the mailer through
|
||||
# all Devise code.
|
||||
# So instead we use a per-request global variable.
|
||||
CurrentConfirmation.procedure_after_confirmation = @procedure
|
||||
|
||||
# Handle existing user trying to sign up again
|
||||
existing_user = User.find_by(email: params[:user][:email])
|
||||
if existing_user.present?
|
||||
|
|
|
@ -21,8 +21,8 @@ module ProcedureHelper
|
|||
def types_de_champ_data(procedure)
|
||||
{
|
||||
isAnnotation: false,
|
||||
typeDeChampsTypes: types_de_champ_types,
|
||||
typeDeChamps: types_de_champ_as_json(procedure.types_de_champ),
|
||||
typeDeChampsTypes: TypeDeChamp.type_de_champ_types_for(procedure, current_user),
|
||||
typeDeChamps: procedure.types_de_champ.as_json_for_editor,
|
||||
baseUrl: procedure_types_de_champ_path(procedure),
|
||||
directUploadUrl: rails_direct_uploads_url
|
||||
}
|
||||
|
@ -31,58 +31,12 @@ module ProcedureHelper
|
|||
def types_de_champ_private_data(procedure)
|
||||
{
|
||||
isAnnotation: true,
|
||||
typeDeChampsTypes: types_de_champ_types,
|
||||
typeDeChamps: types_de_champ_as_json(procedure.types_de_champ_private),
|
||||
typeDeChampsTypes: TypeDeChamp.type_de_champ_types_for(procedure, current_user),
|
||||
typeDeChamps: procedure.types_de_champ_private.as_json_for_editor,
|
||||
baseUrl: procedure_types_de_champ_path(procedure),
|
||||
directUploadUrl: rails_direct_uploads_url
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
TOGGLES = {
|
||||
TypeDeChamp.type_champs.fetch(:integer_number) => :administrateur_champ_integer_number
|
||||
}
|
||||
|
||||
def types_de_champ_types
|
||||
types_de_champ_types = TypeDeChamp.type_de_champs_list_fr
|
||||
|
||||
types_de_champ_types.select! do |tdc|
|
||||
toggle = TOGGLES[tdc.last]
|
||||
toggle.blank? || feature_enabled?(toggle)
|
||||
end
|
||||
|
||||
types_de_champ_types
|
||||
end
|
||||
|
||||
TYPES_DE_CHAMP_BASE = {
|
||||
except: [
|
||||
:created_at,
|
||||
:options,
|
||||
:order_place,
|
||||
:parent_id,
|
||||
:private,
|
||||
:procedure_id,
|
||||
:stable_id,
|
||||
:type,
|
||||
:updated_at
|
||||
],
|
||||
methods: [
|
||||
:cadastres,
|
||||
:drop_down_list_value,
|
||||
:parcelles_agricoles,
|
||||
:piece_justificative_template_filename,
|
||||
:piece_justificative_template_url,
|
||||
:quartiers_prioritaires
|
||||
]
|
||||
}
|
||||
TYPES_DE_CHAMP = TYPES_DE_CHAMP_BASE
|
||||
.merge(include: { types_de_champ: TYPES_DE_CHAMP_BASE })
|
||||
|
||||
def 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
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
import Chartkick from 'chartkick';
|
||||
import { toggle } from '@utils';
|
||||
import Highcharts from 'highcharts';
|
||||
import { toggle, delegate } from '@utils';
|
||||
|
||||
export function toggleChart(event, chartClass) {
|
||||
export default function() {
|
||||
return null;
|
||||
}
|
||||
|
||||
function toggleChart(event) {
|
||||
const nextSelectorItem = event.target,
|
||||
chartClass = event.target.dataset.toggleChart,
|
||||
nextChart = document.querySelector(chartClass),
|
||||
nextChartId = nextChart.children[0].id,
|
||||
currentSelectorItem = nextSelectorItem.parentElement.querySelector(
|
||||
|
@ -23,3 +29,8 @@ export function toggleChart(event, chartClass) {
|
|||
// Reflow needed, see https://github.com/highcharts/highcharts/issues/1979
|
||||
Chartkick.charts[nextChartId].getChartObject().reflow();
|
||||
}
|
||||
|
||||
delegate('click', '[data-toggle-chart]', toggleChart);
|
||||
|
||||
Chartkick.use(Highcharts);
|
||||
window.Chartkick = Chartkick;
|
3
app/javascript/loaders/Chartkick.js
Normal file
3
app/javascript/loaders/Chartkick.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import Loadable from '../components/Loadable';
|
||||
|
||||
export default Loadable(() => import('../components/Chartkick'));
|
|
@ -4,8 +4,6 @@ import Rails from '@rails/ujs';
|
|||
import * as ActiveStorage from '@rails/activestorage';
|
||||
import '@rails/actiontext';
|
||||
import 'whatwg-fetch'; // window.fetch polyfill
|
||||
import Chartkick from 'chartkick';
|
||||
import Highcharts from 'highcharts';
|
||||
import ReactRailsUJS from 'react_ujs';
|
||||
|
||||
import '../shared/page-update-event';
|
||||
|
@ -37,7 +35,6 @@ import {
|
|||
motivationCancel,
|
||||
showImportJustificatif
|
||||
} from '../new_design/state-button';
|
||||
import { toggleChart } from '../new_design/toggle-chart';
|
||||
import { replaceSemicolonByComma } from '../new_design/avis';
|
||||
import {
|
||||
acceptEmailSuggestion,
|
||||
|
@ -52,21 +49,18 @@ const DS = {
|
|||
showMotivation,
|
||||
motivationCancel,
|
||||
showImportJustificatif,
|
||||
toggleChart,
|
||||
replaceSemicolonByComma,
|
||||
acceptEmailSuggestion,
|
||||
discardEmailSuggestionBox
|
||||
};
|
||||
|
||||
// Start Rails helpers
|
||||
Chartkick.addAdapter(Highcharts);
|
||||
Rails.start();
|
||||
Turbolinks.start();
|
||||
ActiveStorage.start();
|
||||
|
||||
// Expose globals
|
||||
window.DS = window.DS || DS;
|
||||
window.Chartkick = Chartkick;
|
||||
// (Both Rails redirects and ReactRailsUJS expect Turbolinks to be globally available)
|
||||
window.Turbolinks = Turbolinks;
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// Include runtime-polyfills for older browsers.
|
||||
// Due to babel.config.js's 'useBuiltIns', only polyfills actually
|
||||
// required by the browsers we support will be included.
|
||||
import '@babel/polyfill';
|
||||
import 'core-js/stable';
|
||||
import 'regenerator-runtime/runtime';
|
||||
import 'dom4';
|
||||
import 'intersection-observer';
|
||||
|
||||
import './polyfills/insertAdjacentElement';
|
||||
import './polyfills/dataset';
|
||||
|
||||
import('intersection-observer');
|
||||
|
|
|
@ -15,6 +15,7 @@ class DeviseUserMailer < Devise::Mailer
|
|||
|
||||
def confirmation_instructions(record, token, opts = {})
|
||||
opts[:from] = NO_REPLY_EMAIL
|
||||
@procedure = CurrentConfirmation.procedure_after_confirmation || nil
|
||||
super
|
||||
end
|
||||
end
|
||||
|
|
3
app/models/current_confirmation.rb
Normal file
3
app/models/current_confirmation.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class CurrentConfirmation < ActiveSupport::CurrentAttributes
|
||||
attribute :procedure_after_confirmation
|
||||
end
|
|
@ -25,7 +25,9 @@ class Export < ApplicationRecord
|
|||
file.attach(
|
||||
io: io,
|
||||
filename: filename,
|
||||
content_type: content_type
|
||||
content_type: content_type,
|
||||
# We generate the exports ourselves, so they are safe
|
||||
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -115,10 +115,6 @@ class TypeDeChamp < ApplicationRecord
|
|||
dynamic_type.build_champ
|
||||
end
|
||||
|
||||
def self.type_de_champs_list_fr
|
||||
type_champs.map { |champ| [I18n.t("activerecord.attributes.type_de_champ.type_champs.#{champ.last}"), champ.first] }
|
||||
end
|
||||
|
||||
def check_mandatory
|
||||
if non_fillable?
|
||||
self.mandatory = false
|
||||
|
@ -162,6 +158,10 @@ class TypeDeChamp < ApplicationRecord
|
|||
type_champ == TypeDeChamp.type_champs.fetch(:dossier_link)
|
||||
end
|
||||
|
||||
def legacy_number?
|
||||
type_champ == TypeDeChamp.type_champs.fetch(:number)
|
||||
end
|
||||
|
||||
def public?
|
||||
!private?
|
||||
end
|
||||
|
@ -194,6 +194,54 @@ class TypeDeChamp < ApplicationRecord
|
|||
GraphQL::Schema::UniqueWithinType.encode('Champ', stable_id)
|
||||
end
|
||||
|
||||
FEATURE_FLAGS = {}
|
||||
|
||||
def self.type_de_champ_types_for(procedure, user)
|
||||
has_legacy_number = (procedure.types_de_champ + procedure.types_de_champ_private).any?(&:legacy_number?)
|
||||
|
||||
type_champs.map do |type_champ|
|
||||
[I18n.t("activerecord.attributes.type_de_champ.type_champs.#{type_champ.last}"), type_champ.first]
|
||||
end.filter do |tdc|
|
||||
if tdc.last == TypeDeChamp.type_champs.fetch(:number)
|
||||
has_legacy_number
|
||||
else
|
||||
feature_name = FEATURE_FLAGS[tdc.last]
|
||||
feature_name.blank? || Flipper.enabled?(feature_name, user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
TYPES_DE_CHAMP_BASE = {
|
||||
except: [
|
||||
:created_at,
|
||||
:options,
|
||||
:order_place,
|
||||
:parent_id,
|
||||
:private,
|
||||
:procedure_id,
|
||||
:stable_id,
|
||||
:type,
|
||||
:updated_at
|
||||
],
|
||||
methods: [
|
||||
:cadastres,
|
||||
:drop_down_list_value,
|
||||
:parcelles_agricoles,
|
||||
:piece_justificative_template_filename,
|
||||
:piece_justificative_template_url,
|
||||
:quartiers_prioritaires
|
||||
]
|
||||
}
|
||||
TYPES_DE_CHAMP = TYPES_DE_CHAMP_BASE
|
||||
.merge(include: { types_de_champ: TYPES_DE_CHAMP_BASE })
|
||||
|
||||
def self.as_json_for_editor
|
||||
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
|
||||
|
||||
private
|
||||
|
||||
def set_default_drop_down_list
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
%p
|
||||
Pour activer votre compte sur demarches-simplifiees.fr, veuillez cliquer sur le lien suivant :
|
||||
= link_to(confirmation_url(@user, confirmation_token: @token), confirmation_url(@user, confirmation_token: @token))
|
||||
- link = confirmation_url(@user, confirmation_token: @token, procedure_id: @procedure&.id)
|
||||
= link_to(link, link)
|
||||
|
||||
- else
|
||||
- content_for(:title, "Changement d'adresse email")
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
Télécharger tous les dossiers
|
||||
.dropdown-content.fade-in-down{ style: 'width: 330px' }
|
||||
%ul.dropdown-items
|
||||
- [[xlsx_export, :xlsx], [csv_export, :csv], [ods_export, :ods]].each do |(export, format)|
|
||||
- [[xlsx_export, :xlsx], [ods_export, :ods], [csv_export, :csv]].each do |(export, format)|
|
||||
%li
|
||||
- if export.nil?
|
||||
= link_to "Demander un export au format .#{format}", download_export_instructeur_procedure_path(procedure, export_format: format), remote: true
|
||||
- export_text = "Demander un export au format .#{format}"
|
||||
- if format == :csv
|
||||
- export_text = "Demander un export au format .#{format}<br/>(uniquement les dossiers, sans les champs répétables)".html_safe
|
||||
= link_to export_text, download_export_instructeur_procedure_path(procedure, export_format: format), remote: true
|
||||
- elsif export.ready?
|
||||
= link_to "Télécharger l'export au format .#{format}", export.file.service_url, target: "_blank", rel: "noopener"
|
||||
- else
|
||||
%span{ 'data-export-poll-url': download_export_instructeur_procedure_path(procedure, export_format: format, no_progress_notification: true) }
|
||||
L'export au format .#{format} est en cours de préparation
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
'Statistiques'] }
|
||||
|
||||
.statistiques
|
||||
-# Load Chartkick lazily, by using our React lazy-loader.
|
||||
-# (Chartkick itself doesn't use React though)
|
||||
= react_component('Chartkick')
|
||||
|
||||
%h1.new-h1= title
|
||||
.stat-cards
|
||||
- if @usual_traitement_time.present?
|
||||
|
@ -29,4 +33,3 @@
|
|||
.chart
|
||||
- colors = %w(#C3D9FF #0069CC #1C7EC9) # from _colors.scss
|
||||
= pie_chart @termines_states, colors: colors
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
%span.mandatory *
|
||||
= f.text_area :description, rows: '6', placeholder: 'Description de la démarche, destinataires, etc. ', class: 'form-control'
|
||||
|
||||
%h2.header-section Logo de la démarche
|
||||
%h3.header-subsection Logo de la démarche
|
||||
= render 'shared/attachment/edit',
|
||||
{ form: f,
|
||||
attached_file: @procedure.logo,
|
||||
|
@ -21,7 +21,7 @@
|
|||
user_can_destroy: true }
|
||||
|
||||
- if !@procedure.locked?
|
||||
%h2.header-section Conservation des données
|
||||
%h3.header-subsection Conservation des données
|
||||
= f.label :duree_conservation_dossiers_dans_ds do
|
||||
Sur demarches-simplifiees.fr
|
||||
%span.mandatory *
|
||||
|
@ -39,7 +39,7 @@
|
|||
Où les usagers trouveront-ils le lien vers la démarche ?
|
||||
= f.text_field :lien_site_web, class: 'form-control', placeholder: 'https://exemple.gouv.fr/ma_demarche'
|
||||
|
||||
%h2.header-section
|
||||
%h3.header-subsection
|
||||
Cadre juridique
|
||||
%span.mandatory *
|
||||
|
||||
|
@ -64,7 +64,7 @@
|
|||
attached_file: @procedure.deliberation,
|
||||
user_can_destroy: true }
|
||||
|
||||
%h2.header-section Notice explicative de la démarche
|
||||
%h3.header-subsection Notice explicative de la démarche
|
||||
|
||||
%p.notice
|
||||
Une notice explicative est un document destiné à guider l’usager dans sa démarche. C’est un document que vous avez élaboré et qui peut prendre la forme d’un fichier doc, d’un pdf ou encore de diapositives. Le bouton pour télécharger cette notice apparaît en haut du formulaire pour l’usager.
|
||||
|
@ -77,7 +77,7 @@
|
|||
user_can_destroy: true }
|
||||
|
||||
- if !@procedure.locked?
|
||||
%h2.header-section À qui s’adresse ma démarche ?
|
||||
%h3.header-subsection À qui s’adresse ma démarche ?
|
||||
.radios.vertical
|
||||
= f.label :for_individual, value: true do
|
||||
= f.radio_button :for_individual, true
|
||||
|
@ -95,7 +95,7 @@
|
|||
|
||||
%details.procedure-form__options-details
|
||||
%summary.procedure-form__options-summary
|
||||
%h2.header-section Options avancées
|
||||
%h3.header-subsection Options avancées
|
||||
|
||||
- if feature_enabled?(:administrateur_web_hook)
|
||||
= f.label :web_hook_url do
|
||||
|
@ -115,10 +115,10 @@
|
|||
|
||||
= f.label :declarative_with_state do
|
||||
Démarche déclarative
|
||||
= f.select :declarative_with_state, Procedure.declarative_attributes_for_select, { include_blank: true }, class: 'form-control'
|
||||
= f.select :declarative_with_state, Procedure.declarative_attributes_for_select, { prompt: 'Non' }, class: 'form-control'
|
||||
|
||||
%p.explication
|
||||
Par défaut, une démarche n'est pas déclarative; à son dépot, un dossier est «en construction». Vous pouvez choisir de la rendre déclarative, afin que tous les dossiers déposés soient immédiatement au statut "en instruction" en "accepté".
|
||||
Par défaut, une démarche n’est pas déclarative ; à son dépôt, un dossier est « en construction ». Vous pouvez choisir de la rendre déclarative, afin que tous les dossiers déposés passent immédiatement au statut « en instruction » ou « accepté ».
|
||||
%br
|
||||
%br
|
||||
Dans le cadre d'une démarche déclarative, au dépot, seul l'email associé à l'état choisi est envoyé. (ex: démarche déclarative «accepté»: envoi uniquement de l'email d'acceptation)
|
||||
Dans le cadre d’une démarche déclarative, au dépôt, seul l’email associé à l’état choisi est envoyé. (ex: démarche déclarative « accepté » : envoi uniquement de l’email d'acceptation)
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
- content_for(:title, 'Statistiques')
|
||||
|
||||
.statistiques
|
||||
-# Load Chartkick lazily, by using our React lazy-loader.
|
||||
-# (Chartkick itself doesn't use React though)
|
||||
= react_component('Chartkick')
|
||||
|
||||
%h1.new-h1 Statistiques
|
||||
|
||||
|
@ -55,9 +58,9 @@
|
|||
|
||||
.stat-card.stat-card-half.pull-left
|
||||
%ul.segmented-control.pull-right
|
||||
%li.segmented-control-item.segmented-control-item-active{ :onclick => "DS.toggleChart(event, '.monthly-procedures-chart');" }
|
||||
%li.segmented-control-item.segmented-control-item-active{ data: { 'toggle-chart': '.monthly-procedures-chart' } }
|
||||
Par mois
|
||||
%li.segmented-control-item{ :onclick => "DS.toggleChart(event, '.cumulative-procedures-chart');" }
|
||||
%li.segmented-control-item{ data: { 'toggle-chart': '.cumulative-procedures-chart' } }
|
||||
Cumul
|
||||
%span.stat-card-title.pull-left Démarches dématérialisées
|
||||
.clearfix
|
||||
|
@ -70,9 +73,9 @@
|
|||
|
||||
.stat-card.stat-card-half.pull-left
|
||||
%ul.segmented-control.pull-right
|
||||
%li.segmented-control-item.segmented-control-item-active{ :onclick => "DS.toggleChart(event, '.monthly-dossiers-chart');" }
|
||||
%li.segmented-control-item.segmented-control-item-active{ data: { 'toggle-chart': '.monthly-dossiers-chart' } }
|
||||
Par mois
|
||||
%li.segmented-control-item{ :onclick => "DS.toggleChart(event, '.cumulative-dossiers-chart');" }
|
||||
%li.segmented-control-item{ data: { 'toggle-chart': '.cumulative-dossiers-chart' } }
|
||||
Cumul
|
||||
%span.stat-card-title.pull-left Dossiers déposés
|
||||
.clearfix
|
||||
|
|
|
@ -29,8 +29,8 @@ module.exports = function(api) {
|
|||
require('@babel/preset-env').default,
|
||||
{
|
||||
forceAllTransforms: true,
|
||||
useBuiltIns: 'entry',
|
||||
corejs: 2,
|
||||
useBuiltIns: 'usage',
|
||||
corejs: 3,
|
||||
modules: false,
|
||||
exclude: ['transform-typeof-symbol']
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ Rails.application.configure do
|
|||
# yet still be able to expire them through the digest params.
|
||||
config.assets.digest = true
|
||||
|
||||
# Suppress logger output for asset requests.
|
||||
config.assets.quiet = true
|
||||
|
||||
# Adds additional error checking when serving assets at runtime.
|
||||
# Checks for improperly declared sprockets dependencies.
|
||||
# Raises helpful error messages.
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
"babel-plugin-macros": "^2.8.0",
|
||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
||||
"chartkick": "^3.2.0",
|
||||
"core-js": "^2.0.0",
|
||||
"core-js": "^3.6.4",
|
||||
"debounce": "^1.2.0",
|
||||
"dom4": "^2.1.5",
|
||||
"email-butler": "^1.0.13",
|
||||
"highcharts": "^6.1.2",
|
||||
"highcharts": "^8.0.0",
|
||||
"intersection-observer": "^0.7.0",
|
||||
"jquery": "^3.4.1",
|
||||
"leaflet": "^1.6.0",
|
||||
|
|
|
@ -162,6 +162,14 @@ FactoryBot.define do
|
|||
end
|
||||
end
|
||||
|
||||
trait :with_number do
|
||||
after(:build) do |procedure, _evaluator|
|
||||
type_de_champ = create(:type_de_champ_number)
|
||||
|
||||
procedure.types_de_champ << type_de_champ
|
||||
end
|
||||
end
|
||||
|
||||
trait :published do
|
||||
after(:build) do |procedure, _evaluator|
|
||||
procedure.path = generate(:published_path)
|
||||
|
|
|
@ -5,16 +5,15 @@ feature 'Signing up:' do
|
|||
let(:user_password) { 'démarches-simplifiées-pwd' }
|
||||
let(:procedure) { create :simple_procedure, :with_service }
|
||||
|
||||
scenario 'a new user can sign-up' do
|
||||
visit commencer_path(path: procedure.path)
|
||||
click_on 'Créer un compte demarches-simplifiees.fr'
|
||||
scenario 'a new user can sign-up from scratch' do
|
||||
visit new_user_registration_path
|
||||
|
||||
sign_up_with user_email, user_password
|
||||
expect(page).to have_content "nous avons besoin de vérifier votre adresse #{user_email}"
|
||||
|
||||
click_confirmation_link_for user_email
|
||||
expect(page).to have_content 'Votre compte a été activé'
|
||||
expect(page).to have_current_path commencer_path(path: procedure.path)
|
||||
expect(page).to have_current_path dossiers_path
|
||||
end
|
||||
|
||||
context 'when the user makes a typo in their email address' do
|
||||
|
@ -68,11 +67,9 @@ feature 'Signing up:' do
|
|||
context 'when visiting a procedure' do
|
||||
let(:procedure) { create :simple_procedure, :with_service }
|
||||
|
||||
before do
|
||||
visit commencer_path(path: procedure.path)
|
||||
end
|
||||
|
||||
scenario 'a new user can sign-up and fill the procedure' do
|
||||
visit commencer_path(path: procedure.path)
|
||||
|
||||
click_on 'Créer un compte'
|
||||
expect(page).to have_current_path new_user_registration_path
|
||||
expect(page).to have_procedure_description(procedure)
|
||||
|
@ -80,8 +77,10 @@ feature 'Signing up:' do
|
|||
sign_up_with user_email, user_password
|
||||
expect(page).to have_content "nous avons besoin de vérifier votre adresse #{user_email}"
|
||||
|
||||
click_confirmation_link_for user_email
|
||||
click_confirmation_link_for(user_email, in_another_browser: true)
|
||||
|
||||
# After confirmation, the user is redirected to the procedure they were initially starting
|
||||
# (even when confirming the account in another browser).
|
||||
expect(page).to have_current_path(commencer_path(path: procedure.path))
|
||||
expect(page).to have_content 'Votre compte a été activé'
|
||||
click_on 'Commencer la démarche'
|
||||
|
@ -103,12 +102,20 @@ feature 'Signing up:' do
|
|||
sign_up_with user_email, user_password
|
||||
|
||||
# The same page than for initial sign-ups is displayed, to avoid leaking informations
|
||||
# about the accound existence.
|
||||
# about the account existence.
|
||||
expect(page).to have_content "nous avons besoin de vérifier votre adresse #{user_email}"
|
||||
|
||||
# The confirmation email is sent again
|
||||
confirmation_email = open_email(user_email)
|
||||
expect(confirmation_email.body).to have_text('Pour activer votre compte')
|
||||
|
||||
click_confirmation_link_for(user_email, in_another_browser: true)
|
||||
|
||||
# After confirmation, the user is redirected to the procedure they were initially starting
|
||||
# (even when confirming the account in another browser).
|
||||
expect(page).to have_current_path(commencer_path(path: procedure.path))
|
||||
expect(page).to have_content 'Votre compte a été activé'
|
||||
expect(page).to have_content 'Commencer la démarche'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -131,8 +138,8 @@ feature 'Signing up:' do
|
|||
warning_email = open_email(user_email)
|
||||
expect(warning_email.body).to have_text('Votre compte existe déjà')
|
||||
|
||||
# When clicking the main button, the user has a link to directly sign-in
|
||||
# for the procedure they were initially starting
|
||||
# When clicking the main button, the user is redirected directly to
|
||||
# the sign-in page for the procedure they were initially starting.
|
||||
click_procedure_sign_in_link_for user_email
|
||||
|
||||
expect(page).to have_current_path new_user_session_path
|
||||
|
|
|
@ -3,6 +3,11 @@ class DeviseUserMailerPreview < ActionMailer::Preview
|
|||
DeviseUserMailer.confirmation_instructions(user, "faketoken", {})
|
||||
end
|
||||
|
||||
def confirmation_instructions___with_procedure
|
||||
CurrentConfirmation.procedure_after_confirmation = procedure
|
||||
DeviseUserMailer.confirmation_instructions(user, "faketoken", {})
|
||||
end
|
||||
|
||||
def reset_password_instructions
|
||||
DeviseUserMailer.reset_password_instructions(user, "faketoken", {})
|
||||
end
|
||||
|
@ -12,4 +17,8 @@ class DeviseUserMailerPreview < ActionMailer::Preview
|
|||
def user
|
||||
User.new(id: 10, email: "usager@example.com")
|
||||
end
|
||||
|
||||
def procedure
|
||||
Procedure.new(id: 20, libelle: 'Dotation d’Équipement des Territoires Ruraux - Exercice 2019', path: 'dotation-etr')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -166,4 +166,25 @@ shared_examples 'type_de_champ_spec' do
|
|||
expect(messages.last.starts_with?("La liste doit commencer par")).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe '#type_de_champ_types_for' do
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
context 'when procedure without legacy "number"' do
|
||||
it 'should have "nombre decimal" instead of "nombre"' do
|
||||
expect(TypeDeChamp.type_de_champ_types_for(procedure, user).find { |tdc| tdc.last == TypeDeChamp.type_champs.fetch(:number) }).to be_nil
|
||||
expect(TypeDeChamp.type_de_champ_types_for(procedure, user).find { |tdc| tdc.last == TypeDeChamp.type_champs.fetch(:decimal_number) }).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when procedure with legacy "number"' do
|
||||
let(:procedure) { create(:procedure, :with_number) }
|
||||
|
||||
it 'should have "nombre decimal" and "nombre"' do
|
||||
expect(TypeDeChamp.type_de_champ_types_for(procedure, user).find { |tdc| tdc.last == TypeDeChamp.type_champs.fetch(:number) }).not_to be_nil
|
||||
expect(TypeDeChamp.type_de_champ_types_for(procedure, user).find { |tdc| tdc.last == TypeDeChamp.type_champs.fetch(:decimal_number) }).not_to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,11 +48,16 @@ module FeatureHelpers
|
|||
end
|
||||
end
|
||||
|
||||
def click_confirmation_link_for(email)
|
||||
def click_confirmation_link_for(email, in_another_browser: false)
|
||||
confirmation_email = open_email(email)
|
||||
token_params = confirmation_email.body.match(/confirmation_token=[^"]+/)
|
||||
confirmation_link = confirmation_email.body.match(/href="[^"]*(\/users\/confirmation[^"]*)"/)[1]
|
||||
|
||||
visit "/users/confirmation?#{token_params}"
|
||||
if in_another_browser
|
||||
# Simulate the user opening the link in another browser, thus loosing the session cookie
|
||||
Capybara.reset_session!
|
||||
end
|
||||
|
||||
visit confirmation_link
|
||||
end
|
||||
|
||||
def click_procedure_sign_in_link_for(email)
|
||||
|
|
18
yarn.lock
18
yarn.lock
|
@ -2572,16 +2572,16 @@ core-js-compat@^3.6.0:
|
|||
browserslist "^4.8.3"
|
||||
semver "7.0.0"
|
||||
|
||||
core-js@^2.0.0:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
|
||||
integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
|
||||
|
||||
core-js@^3.4.0:
|
||||
version "3.6.2"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.2.tgz#2799ea1a59050f0acf50dfe89b916d6503b16caa"
|
||||
integrity sha512-hIE5dXkRzRvnZ5vhkRfQxUvDxQZmD9oueA08jDYRBKJHx+VIl/Pne/e0A4x9LObEEthC/TqiZybUoNM4tRgnKg==
|
||||
|
||||
core-js@^3.6.4:
|
||||
version "3.6.4"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647"
|
||||
integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==
|
||||
|
||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
|
@ -4426,10 +4426,10 @@ hex-color-regex@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
|
||||
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
|
||||
|
||||
highcharts@^6.1.2:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/highcharts/-/highcharts-6.2.0.tgz#2a6d04652eb43c66f462ca7e2d2808f1f2782b61"
|
||||
integrity sha512-A4E89MA+kto8giic7zyLU6ZxfXnVeCUlKOyzFsah3+n4BROx4bgonl92KIBtwLud/mIWir8ahqhuhe2by9LakQ==
|
||||
highcharts@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/highcharts/-/highcharts-8.0.0.tgz#fcf77a511d6ea477b9d8447afd9dedbfc85e2727"
|
||||
integrity sha512-jRKLiP0i29zKSEgMDASyrfpivrM3e8V8yTv8YUZtRzB2mXR+hsBNHWZw2hNRZVxqq1QCVmW/9Z/BLFvYlJELqA==
|
||||
|
||||
highlight.js@~9.12.0:
|
||||
version "9.12.0"
|
||||
|
|
Loading…
Reference in a new issue