commit
6a81006708
65 changed files with 326 additions and 347 deletions
|
@ -3,7 +3,9 @@ class Administrateurs::ActivateController < ApplicationController
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@token = params[:token]
|
@token = params[:token]
|
||||||
@administrateur = Administrateur.find_inactive_by_token(@token)
|
|
||||||
|
user = User.with_reset_password_token(@token)
|
||||||
|
@administrateur = user&.administrateur
|
||||||
|
|
||||||
if @administrateur
|
if @administrateur
|
||||||
# the administrateur activates its account from an email
|
# the administrateur activates its account from an email
|
||||||
|
@ -16,14 +18,16 @@ class Administrateurs::ActivateController < ApplicationController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
password = update_administrateur_params[:password]
|
password = update_administrateur_params[:password]
|
||||||
administrateur = Administrateur.reset_password(
|
|
||||||
update_administrateur_params[:reset_password_token],
|
|
||||||
password
|
|
||||||
)
|
|
||||||
|
|
||||||
if administrateur && administrateur.errors.empty?
|
user = User.reset_password_by_token({
|
||||||
sign_in(administrateur, scope: :administrateur)
|
password: password,
|
||||||
try_to_authenticate(User, administrateur.email, password)
|
password_confirmation: password,
|
||||||
|
reset_password_token: update_administrateur_params[:reset_password_token]
|
||||||
|
})
|
||||||
|
|
||||||
|
if user&.administrateur&.errors&.empty?
|
||||||
|
sign_in(user, scope: :user)
|
||||||
|
|
||||||
flash.notice = "Mot de passe enregistré"
|
flash.notice = "Mot de passe enregistré"
|
||||||
redirect_to admin_procedures_path
|
redirect_to admin_procedures_path
|
||||||
else
|
else
|
||||||
|
|
|
@ -18,7 +18,8 @@ class ApplicationController < ActionController::Base
|
||||||
before_action :set_active_storage_host
|
before_action :set_active_storage_host
|
||||||
before_action :setup_tracking
|
before_action :setup_tracking
|
||||||
|
|
||||||
helper_method :logged_in?, :multiple_devise_profile_connect?, :instructeur_signed_in?, :current_instructeur
|
helper_method :logged_in?, :multiple_devise_profile_connect?, :instructeur_signed_in?, :current_instructeur,
|
||||||
|
:administrateur_signed_in?, :current_administrateur
|
||||||
|
|
||||||
def staging_authenticate
|
def staging_authenticate
|
||||||
if StagingAuthService.enabled? && !authenticate_with_http_basic { |username, password| StagingAuthService.authenticate(username, password) }
|
if StagingAuthService.enabled? && !authenticate_with_http_basic { |username, password| StagingAuthService.authenticate(username, password) }
|
||||||
|
@ -66,6 +67,14 @@ class ApplicationController < ActionController::Base
|
||||||
user_signed_in? && current_user&.instructeur.present?
|
user_signed_in? && current_user&.instructeur.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def current_administrateur
|
||||||
|
current_user&.administrateur
|
||||||
|
end
|
||||||
|
|
||||||
|
def administrateur_signed_in?
|
||||||
|
current_administrateur.present?
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def authenticate_logged_user!
|
def authenticate_logged_user!
|
||||||
|
@ -85,9 +94,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def authenticate_administrateur!
|
def authenticate_administrateur!
|
||||||
if administrateur_signed_in?
|
if !administrateur_signed_in?
|
||||||
super
|
|
||||||
else
|
|
||||||
redirect_to new_user_session_path
|
redirect_to new_user_session_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -183,7 +190,7 @@ class ApplicationController < ActionController::Base
|
||||||
def redirect_if_untrusted
|
def redirect_if_untrusted
|
||||||
if instructeur_signed_in? &&
|
if instructeur_signed_in? &&
|
||||||
sensitive_path &&
|
sensitive_path &&
|
||||||
Flipflop.enable_email_login_token? &&
|
!Flipflop.bypass_email_login_token? &&
|
||||||
!IPService.ip_trusted?(request.headers['X-Forwarded-For']) &&
|
!IPService.ip_trusted?(request.headers['X-Forwarded-For']) &&
|
||||||
!trusted_device?
|
!trusted_device?
|
||||||
|
|
||||||
|
@ -201,6 +208,8 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
if path == '/' ||
|
if path == '/' ||
|
||||||
path == '/users/sign_out' ||
|
path == '/users/sign_out' ||
|
||||||
|
path == '/contact' ||
|
||||||
|
path == '/contact-admin' ||
|
||||||
path.start_with?('/connexion-par-jeton') ||
|
path.start_with?('/connexion-par-jeton') ||
|
||||||
path.start_with?('/api/') ||
|
path.start_with?('/api/') ||
|
||||||
path.start_with?('/lien-envoye')
|
path.start_with?('/lien-envoye')
|
||||||
|
|
|
@ -2,7 +2,7 @@ module Manager
|
||||||
class InstructeursController < Manager::ApplicationController
|
class InstructeursController < Manager::ApplicationController
|
||||||
def reinvite
|
def reinvite
|
||||||
instructeur = Instructeur.find(params[:id])
|
instructeur = Instructeur.find(params[:id])
|
||||||
instructeur.invite!
|
instructeur.user.invite!
|
||||||
flash[:notice] = "Instructeur réinvité."
|
flash[:notice] = "Instructeur réinvité."
|
||||||
redirect_to manager_instructeur_path(instructeur)
|
redirect_to manager_instructeur_path(instructeur)
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,7 +23,7 @@ class Users::ActivateController < ApplicationController
|
||||||
|
|
||||||
if user && user.errors.empty?
|
if user && user.errors.empty?
|
||||||
sign_in(user, scope: :user)
|
sign_in(user, scope: :user)
|
||||||
try_to_authenticate(Administrateur, user.email, password)
|
|
||||||
flash.notice = "Mot de passe enregistré"
|
flash.notice = "Mot de passe enregistré"
|
||||||
redirect_to instructeur_procedures_path
|
redirect_to instructeur_procedures_path
|
||||||
else
|
else
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Users::PasswordsController < Devise::PasswordsController
|
||||||
administrateur = Administrateur.find_by(email: current_user.email)
|
administrateur = Administrateur.find_by(email: current_user.email)
|
||||||
|
|
||||||
if administrateur
|
if administrateur
|
||||||
sign_in administrateur
|
sign_in(administrateur.user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,8 +16,7 @@ class Users::SessionsController < Sessions::SessionsController
|
||||||
def create
|
def create
|
||||||
remember_me = params[:user][:remember_me] == '1'
|
remember_me = params[:user][:remember_me] == '1'
|
||||||
|
|
||||||
if resource_locked?(try_to_authenticate(User, remember_me)) ||
|
if resource_locked?(try_to_authenticate(User, remember_me))
|
||||||
resource_locked?(try_to_authenticate(Administrateur, remember_me))
|
|
||||||
flash.alert = 'Votre compte est verrouillé.'
|
flash.alert = 'Votre compte est verrouillé.'
|
||||||
new
|
new
|
||||||
return render :new, status: 401
|
return render :new, status: 401
|
||||||
|
@ -43,14 +42,6 @@ class Users::SessionsController < Sessions::SessionsController
|
||||||
|
|
||||||
# DELETE /resource/sign_out
|
# DELETE /resource/sign_out
|
||||||
def destroy
|
def destroy
|
||||||
if instructeur_signed_in?
|
|
||||||
sign_out :instructeur
|
|
||||||
end
|
|
||||||
|
|
||||||
if administrateur_signed_in?
|
|
||||||
sign_out :administrateur
|
|
||||||
end
|
|
||||||
|
|
||||||
if user_signed_in?
|
if user_signed_in?
|
||||||
connected_with_france_connect = current_user.loged_in_with_france_connect
|
connected_with_france_connect = current_user.loged_in_with_france_connect
|
||||||
current_user.update(loged_in_with_france_connect: '')
|
current_user.update(loged_in_with_france_connect: '')
|
||||||
|
|
|
@ -64,8 +64,7 @@ module ProcedureHelper
|
||||||
private
|
private
|
||||||
|
|
||||||
TOGGLES = {
|
TOGGLES = {
|
||||||
TypeDeChamp.type_champs.fetch(:integer_number) => :champ_integer_number?,
|
TypeDeChamp.type_champs.fetch(:integer_number) => :champ_integer_number?
|
||||||
TypeDeChamp.type_champs.fetch(:repetition) => :champ_repetition?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def types_de_champ_types
|
def types_de_champ_types
|
||||||
|
|
|
@ -39,7 +39,7 @@ function diplayMap(element, data, initial = false) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener('turbolinks:load', initialize);
|
addEventListener('ds:page:update', initialize);
|
||||||
|
|
||||||
addEventListener('carte:update', ({ detail: { selector, data } }) => {
|
addEventListener('carte:update', ({ detail: { selector, data } }) => {
|
||||||
const element = document.querySelector(selector);
|
const element = document.querySelector(selector);
|
||||||
|
|
|
@ -14,4 +14,4 @@ export function scrollMessagerie() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener('turbolinks:load', scrollMessagerie);
|
addEventListener('ds:page:update', scrollMessagerie);
|
||||||
|
|
|
@ -14,7 +14,7 @@ function expandProcedureDescription() {
|
||||||
descBody.classList.remove('read-more-collapsed');
|
descBody.classList.remove('read-more-collapsed');
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener('turbolinks:load', updateReadMoreVisibility);
|
addEventListener('ds:page:update', updateReadMoreVisibility);
|
||||||
addEventListener('resize', updateReadMoreVisibility);
|
addEventListener('resize', updateReadMoreVisibility);
|
||||||
|
|
||||||
delegate('click', '.read-more-button', expandProcedureDescription);
|
delegate('click', '.read-more-button', expandProcedureDescription);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import 'select2';
|
import 'select2';
|
||||||
|
|
||||||
addEventListener('turbolinks:load', () => {
|
addEventListener('ds:page:update', () => {
|
||||||
$('select.select2').select2({
|
$('select.select2').select2({
|
||||||
language: 'fr',
|
language: 'fr',
|
||||||
width: '100%'
|
width: '100%'
|
||||||
|
|
|
@ -12,5 +12,5 @@ function updateContactElementsVisibility() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener('turbolinks:load', updateContactElementsVisibility);
|
addEventListener('ds:page:update', updateContactElementsVisibility);
|
||||||
delegate('change', '#contact-form #type', updateContactElementsVisibility);
|
delegate('change', '#contact-form #type', updateContactElementsVisibility);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Rails from '@rails/ujs';
|
||||||
import * as ActiveStorage from '@rails/activestorage';
|
import * as ActiveStorage from '@rails/activestorage';
|
||||||
import jQuery from 'jquery';
|
import jQuery from 'jquery';
|
||||||
|
|
||||||
|
import '../shared/page-update-event';
|
||||||
import '../shared/activestorage/ujs';
|
import '../shared/activestorage/ujs';
|
||||||
import '../shared/rails-ujs-fix';
|
import '../shared/rails-ujs-fix';
|
||||||
import '../shared/safari-11-file-xhr-workaround';
|
import '../shared/safari-11-file-xhr-workaround';
|
||||||
|
|
|
@ -9,6 +9,7 @@ import Highcharts from 'highcharts';
|
||||||
import ReactUJS from '../shared/react-ujs';
|
import ReactUJS from '../shared/react-ujs';
|
||||||
import reactComponents from '../shared/react-components';
|
import reactComponents from '../shared/react-components';
|
||||||
|
|
||||||
|
import '../shared/page-update-event';
|
||||||
import '../shared/activestorage/ujs';
|
import '../shared/activestorage/ujs';
|
||||||
import '../shared/activestorage/attachment-checker';
|
import '../shared/activestorage/attachment-checker';
|
||||||
import '../shared/rails-ujs-fix';
|
import '../shared/rails-ujs-fix';
|
||||||
|
|
|
@ -37,22 +37,14 @@ function source(url) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener('turbolinks:load', function() {
|
addEventListener('ds:page:update', function() {
|
||||||
autocompleteSetup();
|
|
||||||
});
|
|
||||||
|
|
||||||
addEventListener('ajax:success', function() {
|
|
||||||
autocompleteSetup();
|
|
||||||
});
|
|
||||||
|
|
||||||
function autocompleteSetup() {
|
|
||||||
for (let { type, url } of sources) {
|
for (let { type, url } of sources) {
|
||||||
for (let element of document.querySelectorAll(selector(type))) {
|
for (let element of document.querySelectorAll(selector(type))) {
|
||||||
element.removeAttribute('data-autocomplete');
|
element.removeAttribute('data-autocomplete');
|
||||||
autocompleteInitializeElement(element, url);
|
autocompleteInitializeElement(element, url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
function autocompleteInitializeElement(element, url) {
|
function autocompleteInitializeElement(element, url) {
|
||||||
const select = autocomplete(element, options, [source(url)]);
|
const select = autocomplete(element, options, [source(url)]);
|
||||||
|
|
|
@ -20,8 +20,7 @@ function init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener('DOMContentLoaded', init);
|
addEventListener('ds:page:update', init);
|
||||||
addEventListener('turbolinks:load', init);
|
|
||||||
|
|
||||||
function toggleElement(event) {
|
function toggleElement(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
9
app/javascript/shared/page-update-event.js
Normal file
9
app/javascript/shared/page-update-event.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { fire } from '@utils';
|
||||||
|
|
||||||
|
addEventListener('turbolinks:load', function() {
|
||||||
|
fire(document, 'ds:page:update');
|
||||||
|
});
|
||||||
|
|
||||||
|
addEventListener('ajax:success', function() {
|
||||||
|
fire(document, 'ds:page:update');
|
||||||
|
});
|
2
app/javascript/shared/react-ujs.js
vendored
2
app/javascript/shared/react-ujs.js
vendored
|
@ -56,6 +56,6 @@ export default class ReactUJS {
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
addEventListener('turbolinks:load', () => this.mountComponents());
|
addEventListener('ds:page:update', () => this.mountComponents());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,10 @@ class Administrateurs::ActivateBeforeExpirationJob < ApplicationJob
|
||||||
queue_as :cron
|
queue_as :cron
|
||||||
|
|
||||||
def perform(*args)
|
def perform(*args)
|
||||||
Administrateur.inactive.where(created_at: 3.days.ago.all_day).each(&:remind_invitation!)
|
Administrateur
|
||||||
|
.includes(:user)
|
||||||
|
.inactive
|
||||||
|
.where(created_at: 3.days.ago.all_day)
|
||||||
|
.each { |a| a.user.remind_invitation! }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
class AdministrateurMailer < ApplicationMailer
|
class AdministrateurMailer < ApplicationMailer
|
||||||
layout 'mailers/layout'
|
layout 'mailers/layout'
|
||||||
|
|
||||||
def activate_before_expiration(administrateur, reset_password_token)
|
def activate_before_expiration(user, reset_password_token)
|
||||||
@administrateur = administrateur
|
@user = user
|
||||||
@reset_password_token = reset_password_token
|
@reset_password_token = reset_password_token
|
||||||
@expiration_date = @administrateur.reset_password_sent_at + Devise.reset_password_within
|
@expiration_date = @user.reset_password_sent_at + Devise.reset_password_within
|
||||||
@subject = "N'oubliez pas d'activer votre compte administrateur"
|
@subject = "N'oubliez pas d'activer votre compte administrateur"
|
||||||
|
|
||||||
mail(to: administrateur.email,
|
mail(to: user.email,
|
||||||
subject: @subject,
|
subject: @subject,
|
||||||
reply_to: CONTACT_EMAIL)
|
reply_to: CONTACT_EMAIL)
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,21 +3,20 @@ class Administrateur < ApplicationRecord
|
||||||
include EmailSanitizableConcern
|
include EmailSanitizableConcern
|
||||||
include ActiveRecord::SecureToken
|
include ActiveRecord::SecureToken
|
||||||
|
|
||||||
devise :database_authenticatable, :registerable, :async,
|
|
||||||
:recoverable, :rememberable, :trackable, :validatable, :lockable
|
|
||||||
|
|
||||||
has_and_belongs_to_many :instructeurs
|
has_and_belongs_to_many :instructeurs
|
||||||
has_many :administrateurs_procedures
|
has_many :administrateurs_procedures
|
||||||
has_many :procedures, through: :administrateurs_procedures
|
has_many :procedures, through: :administrateurs_procedures
|
||||||
has_many :services
|
has_many :services
|
||||||
has_many :dossiers, -> { state_not_brouillon }, through: :procedures
|
has_many :dossiers, -> { state_not_brouillon }, through: :procedures
|
||||||
|
|
||||||
|
has_one :user
|
||||||
|
|
||||||
before_validation -> { sanitize_email(:email) }
|
before_validation -> { sanitize_email(:email) }
|
||||||
|
|
||||||
scope :inactive, -> { where(active: false) }
|
scope :inactive, -> { where(active: false) }
|
||||||
scope :with_publiees_ou_archivees, -> { joins(:procedures).where(procedures: { aasm_state: [:publiee, :archivee] }) }
|
scope :with_publiees_ou_archivees, -> { joins(:procedures).where(procedures: { aasm_state: [:publiee, :archivee] }) }
|
||||||
|
|
||||||
validate :password_complexity, if: Proc.new { |a| Devise.password_length.include?(a.password.try(:size)) }
|
# validate :password_complexity, if: Proc.new { |a| Devise.password_length.include?(a.password.try(:size)) }
|
||||||
|
|
||||||
def password_complexity
|
def password_complexity
|
||||||
if password.present? && ZxcvbnService.new(password).score < PASSWORD_COMPLEXITY_FOR_ADMIN
|
if password.present? && ZxcvbnService.new(password).score < PASSWORD_COMPLEXITY_FOR_ADMIN
|
||||||
|
@ -56,28 +55,6 @@ class Administrateur < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def invite!(administration_id)
|
|
||||||
if active?
|
|
||||||
raise "Impossible d'inviter un utilisateur déjà actif !"
|
|
||||||
end
|
|
||||||
|
|
||||||
reset_password_token = set_reset_password_token
|
|
||||||
|
|
||||||
AdministrationMailer.invite_admin(self, reset_password_token, administration_id).deliver_later
|
|
||||||
|
|
||||||
reset_password_token
|
|
||||||
end
|
|
||||||
|
|
||||||
def remind_invitation!
|
|
||||||
if active?
|
|
||||||
raise "Impossible d'envoyer un rappel d'invitation à un utilisateur déjà actif !"
|
|
||||||
end
|
|
||||||
|
|
||||||
reset_password_token = set_reset_password_token
|
|
||||||
|
|
||||||
AdministrateurMailer.activate_before_expiration(self, reset_password_token).deliver_later
|
|
||||||
end
|
|
||||||
|
|
||||||
def invitation_expired?
|
def invitation_expired?
|
||||||
!active && !reset_password_period_valid?
|
!active && !reset_password_period_valid?
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,29 +9,33 @@ class Administration < ApplicationRecord
|
||||||
|
|
||||||
def invite_admin(email)
|
def invite_admin(email)
|
||||||
password = SecureRandom.hex
|
password = SecureRandom.hex
|
||||||
administrateur = Administrateur.new({
|
|
||||||
email: email,
|
|
||||||
active: false,
|
|
||||||
password: password,
|
|
||||||
password_confirmation: password
|
|
||||||
})
|
|
||||||
|
|
||||||
if administrateur.save
|
user = User.find_by(email: email)
|
||||||
AdministrationMailer.new_admin_email(administrateur, self).deliver_later
|
|
||||||
administrateur.invite!(id)
|
|
||||||
|
|
||||||
user = User.create({
|
if user.nil?
|
||||||
|
# set confirmed_at otherwise admin confirmation doesnt work
|
||||||
|
# we somehow mess up using reset_password logic instead of
|
||||||
|
# confirmation_logic
|
||||||
|
# FIXME
|
||||||
|
user = User.create(
|
||||||
email: email,
|
email: email,
|
||||||
password: password,
|
password: password,
|
||||||
confirmed_at: Time.zone.now
|
confirmed_at: Time.zone.now
|
||||||
})
|
)
|
||||||
|
|
||||||
Instructeur.create({
|
|
||||||
email: email,
|
|
||||||
user: user
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
administrateur
|
if user.errors.empty?
|
||||||
|
if user.instructeur.nil?
|
||||||
|
Instructeur.create!(email: email, user: user)
|
||||||
|
end
|
||||||
|
|
||||||
|
if user.administrateur.nil?
|
||||||
|
administrateur = Administrateur.create!(email: email, active: false, user: user)
|
||||||
|
AdministrationMailer.new_admin_email(administrateur, self).deliver_later
|
||||||
|
user.invite_administrateur!(id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
user
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,6 +18,7 @@ class User < ApplicationRecord
|
||||||
has_many :feedbacks, dependent: :destroy
|
has_many :feedbacks, dependent: :destroy
|
||||||
has_one :france_connect_information, dependent: :destroy
|
has_one :france_connect_information, dependent: :destroy
|
||||||
belongs_to :instructeur
|
belongs_to :instructeur
|
||||||
|
belongs_to :administrateur
|
||||||
|
|
||||||
accepts_nested_attributes_for :france_connect_information
|
accepts_nested_attributes_for :france_connect_information
|
||||||
|
|
||||||
|
@ -44,6 +45,23 @@ class User < ApplicationRecord
|
||||||
UserMailer.invite_instructeur(self, set_reset_password_token).deliver_later
|
UserMailer.invite_instructeur(self, set_reset_password_token).deliver_later
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def invite_administrateur!(administration_id)
|
||||||
|
if administrateur.active?
|
||||||
|
raise "Impossible d'inviter un utilisateur déjà actif !"
|
||||||
|
end
|
||||||
|
|
||||||
|
reset_password_token = set_reset_password_token
|
||||||
|
AdministrationMailer.invite_admin(self, reset_password_token, administration_id).deliver_later
|
||||||
|
|
||||||
|
reset_password_token
|
||||||
|
end
|
||||||
|
|
||||||
|
def remind_invitation!
|
||||||
|
reset_password_token = set_reset_password_token
|
||||||
|
|
||||||
|
AdministrateurMailer.activate_before_expiration(self, reset_password_token).deliver_later
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def link_invites!
|
def link_invites!
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
%p
|
%p
|
||||||
Afin d’activer votre compte, veuillez cliquer sur le lien ci-dessous :
|
Afin d’activer votre compte, veuillez cliquer sur le lien ci-dessous :
|
||||||
= link_to(admin_activate_url(token: @reset_password_token), admin_activate_url(token: @reset_password_token))
|
= link_to(users_activate_url(token: @reset_password_token), users_activate_url(token: @reset_password_token))
|
||||||
|
|
||||||
%p
|
%p
|
||||||
Nous restons à votre disposition si vous avez besoin d’accompagnement.
|
Nous restons à votre disposition si vous avez besoin d’accompagnement.
|
||||||
|
|
|
@ -4,18 +4,16 @@
|
||||||
Télécharger tous les dossiers
|
Télécharger tous les dossiers
|
||||||
- old_format_limit_date = Date.parse("Oct 31 2019")
|
- old_format_limit_date = Date.parse("Oct 31 2019")
|
||||||
- export_v1_enabled = old_format_limit_date > Time.zone.today
|
- export_v1_enabled = old_format_limit_date > Time.zone.today
|
||||||
- export_v2_enabled = Flipflop.procedure_export_v2_enabled? || !export_v1_enabled
|
.dropdown-content.fade-in-down{ style: !export_v1_enabled ? 'width: 330px' : '' }
|
||||||
- old_format_message = export_v1_enabled && export_v2_enabled ? "(ancien format, jusqu’au #{old_format_limit_date.strftime('%d/%m/%Y')})" : ''
|
|
||||||
.dropdown-content.fade-in-down{ style: export_v1_enabled && export_v2_enabled ? 'width: 330px' : '' }
|
|
||||||
%ul.dropdown-items
|
%ul.dropdown-items
|
||||||
- if export_v2_enabled
|
%li
|
||||||
%li
|
= link_to "Au format .xlsx", procedure_dossiers_download_path(procedure, format: :xlsx, version: 'v2'), target: "_blank", rel: "noopener"
|
||||||
= link_to "Au format .xlsx", procedure_dossiers_download_path(procedure, format: :xlsx, version: 'v2'), target: "_blank", rel: "noopener"
|
%li
|
||||||
%li
|
= link_to "Au format .ods", procedure_dossiers_download_path(procedure, format: :ods, version: 'v2'), target: "_blank", rel: "noopener"
|
||||||
= link_to "Au format .ods", procedure_dossiers_download_path(procedure, format: :ods, version: 'v2'), target: "_blank", rel: "noopener"
|
%li
|
||||||
%li
|
= link_to "Au format .csv", procedure_dossiers_download_path(procedure, format: :csv, version: 'v2'), target: "_blank", rel: "noopener"
|
||||||
= link_to "Au format .csv", procedure_dossiers_download_path(procedure, format: :csv, version: 'v2'), target: "_blank", rel: "noopener"
|
|
||||||
- if export_v1_enabled
|
- if export_v1_enabled
|
||||||
|
- old_format_message = "(ancien format, jusqu’au #{old_format_limit_date.strftime('%d/%m/%Y')})"
|
||||||
%li
|
%li
|
||||||
= link_to "Au format .xlsx #{old_format_message}", procedure_dossiers_download_path(procedure, format: :xlsx, version: 'v1'), target: "_blank", rel: "noopener"
|
= link_to "Au format .xlsx #{old_format_message}", procedure_dossiers_download_path(procedure, format: :xlsx, version: 'v1'), target: "_blank", rel: "noopener"
|
||||||
%li
|
%li
|
||||||
|
|
|
@ -10,16 +10,6 @@
|
||||||
%span.mandatory *
|
%span.mandatory *
|
||||||
= f.text_field :organisme, placeholder: "mairie de Mours, préfecture de l'Oise, ministère de la Culture", required: true
|
= f.text_field :organisme, placeholder: "mairie de Mours, préfecture de l'Oise, ministère de la Culture", required: true
|
||||||
|
|
||||||
= f.label :siret do
|
|
||||||
SIRET
|
|
||||||
%span.mandatory *
|
|
||||||
%p
|
|
||||||
Pour trouver votre numéro SIRET, utilisez
|
|
||||||
%a{ href: 'https://entreprise.data.gouv.fr/', target: '_blank', rel: 'noopener' }
|
|
||||||
entreprise.data.gouv.fr
|
|
||||||
ou renseignez-vous auprès de votre service comptable
|
|
||||||
= f.number_field :siret, required: true
|
|
||||||
|
|
||||||
= f.label :type_organisme do
|
= f.label :type_organisme do
|
||||||
Type d’organisme
|
Type d’organisme
|
||||||
%span.mandatory *
|
%span.mandatory *
|
||||||
|
|
|
@ -9,17 +9,14 @@ Flipflop.configure do
|
||||||
group :champs do
|
group :champs do
|
||||||
feature :champ_integer_number,
|
feature :champ_integer_number,
|
||||||
title: "Champ nombre entier"
|
title: "Champ nombre entier"
|
||||||
feature :champ_repetition,
|
|
||||||
title: "Bloc répétable"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
feature :web_hook
|
feature :web_hook
|
||||||
feature :enable_email_login_token
|
|
||||||
|
|
||||||
feature :procedure_export_v2_enabled
|
|
||||||
feature :operation_log_serialize_subject
|
feature :operation_log_serialize_subject
|
||||||
feature :download_as_zip_enabled,
|
feature :download_as_zip_enabled
|
||||||
default: false
|
feature :bypass_email_login_token,
|
||||||
|
default: Rails.env.test?
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
feature :mini_profiler_enabled,
|
feature :mini_profiler_enabled,
|
||||||
|
|
|
@ -77,8 +77,6 @@ Rails.application.routes.draw do
|
||||||
omniauth_callbacks: 'administrations/omniauth_callbacks'
|
omniauth_callbacks: 'administrations/omniauth_callbacks'
|
||||||
}
|
}
|
||||||
|
|
||||||
devise_for :administrateurs, skip: :all
|
|
||||||
|
|
||||||
devise_for :users, controllers: {
|
devise_for :users, controllers: {
|
||||||
sessions: 'users/sessions',
|
sessions: 'users/sessions',
|
||||||
registrations: 'users/registrations',
|
registrations: 'users/registrations',
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
class LinkUserAndAdministrateur < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_reference :users, :administrateur, index: true
|
||||||
|
add_foreign_key :users, :administrateurs
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2019_08_08_144607) do
|
ActiveRecord::Schema.define(version: 2019_08_09_073736) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -597,6 +597,8 @@ ActiveRecord::Schema.define(version: 2019_08_08_144607) do
|
||||||
t.datetime "locked_at"
|
t.datetime "locked_at"
|
||||||
t.text "unconfirmed_email"
|
t.text "unconfirmed_email"
|
||||||
t.bigint "instructeur_id"
|
t.bigint "instructeur_id"
|
||||||
|
t.bigint "administrateur_id"
|
||||||
|
t.index ["administrateur_id"], name: "index_users_on_administrateur_id"
|
||||||
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
||||||
t.index ["email"], name: "index_users_on_email", unique: true
|
t.index ["email"], name: "index_users_on_email", unique: true
|
||||||
t.index ["instructeur_id"], name: "index_users_on_instructeur_id"
|
t.index ["instructeur_id"], name: "index_users_on_instructeur_id"
|
||||||
|
@ -644,6 +646,7 @@ ActiveRecord::Schema.define(version: 2019_08_08_144607) do
|
||||||
add_foreign_key "services", "administrateurs"
|
add_foreign_key "services", "administrateurs"
|
||||||
add_foreign_key "trusted_device_tokens", "instructeurs"
|
add_foreign_key "trusted_device_tokens", "instructeurs"
|
||||||
add_foreign_key "types_de_champ", "types_de_champ", column: "parent_id"
|
add_foreign_key "types_de_champ", "types_de_champ", column: "parent_id"
|
||||||
|
add_foreign_key "users", "administrateurs"
|
||||||
add_foreign_key "users", "instructeurs"
|
add_foreign_key "users", "instructeurs"
|
||||||
add_foreign_key "without_continuation_mails", "procedures"
|
add_foreign_key "without_continuation_mails", "procedures"
|
||||||
end
|
end
|
||||||
|
|
12
db/seeds.rb
12
db/seeds.rb
|
@ -10,6 +10,12 @@ default_password = "this is a very complicated password !"
|
||||||
|
|
||||||
puts "Create test user '#{default_user}'"
|
puts "Create test user '#{default_user}'"
|
||||||
Administration.create!(email: default_user, password: default_password)
|
Administration.create!(email: default_user, password: default_password)
|
||||||
Administrateur.create!(email: default_user, password: default_password)
|
administrateur = Administrateur.create!(email: default_user)
|
||||||
Instructeur.create!(email: default_user, password: default_password)
|
instructeur = Instructeur.create!(email: default_user)
|
||||||
User.create!(email: default_user, password: default_password, confirmed_at: Time.zone.now)
|
User.create!(
|
||||||
|
email: default_user,
|
||||||
|
password: default_password,
|
||||||
|
confirmed_at: Time.zone.now,
|
||||||
|
administrateur: administrateur,
|
||||||
|
instructeur: instructeur
|
||||||
|
)
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
namespace :'activate_trusted_device_for_a-f' do
|
|
||||||
task run: :environment do
|
|
||||||
letters_a_to_f = ('a'..'f').to_a
|
|
||||||
Gestionnaire
|
|
||||||
.where("substr(email, 1, 1) IN (?)", letters_a_to_f)
|
|
||||||
.update_all(features: { "enable_email_login_token" => true })
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace :after_party do
|
||||||
|
desc 'Deployment task: populate_user_administrateur_ids'
|
||||||
|
task populate_user_administrateur_ids: :environment do
|
||||||
|
Administrateur.find_each do |administrateur|
|
||||||
|
User.where(email: administrateur.email).update(administrateur_id: administrateur.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
AfterParty::TaskRecord.create version: '20190809074534'
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,7 +6,7 @@ describe Admin::AssignsController, type: :controller do
|
||||||
let(:instructeur) { create :instructeur, administrateurs: [admin] }
|
let(:instructeur) { create :instructeur, administrateurs: [admin] }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET #show' do
|
describe 'GET #show' do
|
||||||
|
|
|
@ -11,7 +11,7 @@ describe Admin::AttestationTemplatesController, type: :controller do
|
||||||
let(:uninterlaced_logo) { fixture_file_upload('spec/fixtures/files/uninterlaced-black.png', 'image/png') }
|
let(:uninterlaced_logo) { fixture_file_upload('spec/fixtures/files/uninterlaced-black.png', 'image/png') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
Timecop.freeze(Time.zone.now)
|
Timecop.freeze(Time.zone.now)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe Admin::InstructeursController, type: :controller do
|
||||||
let(:admin_2) { create :administrateur, email: email_2 }
|
let(:admin_2) { create :administrateur, email: email_2 }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET #index' do
|
describe 'GET #index' do
|
||||||
|
@ -117,8 +117,8 @@ describe Admin::InstructeursController, type: :controller do
|
||||||
before do
|
before do
|
||||||
create :instructeur, email: email, administrateurs: [admin]
|
create :instructeur, email: email, administrateurs: [admin]
|
||||||
|
|
||||||
sign_out admin
|
sign_out(admin.user)
|
||||||
sign_in admin_2
|
sign_in(admin_2.user)
|
||||||
|
|
||||||
subject
|
subject
|
||||||
end
|
end
|
||||||
|
@ -138,8 +138,8 @@ describe Admin::InstructeursController, type: :controller do
|
||||||
before do
|
before do
|
||||||
create :instructeur, email: email, administrateurs: [admin]
|
create :instructeur, email: email, administrateurs: [admin]
|
||||||
|
|
||||||
sign_out admin
|
sign_out(admin.user)
|
||||||
sign_in admin_2
|
sign_in(admin_2.user)
|
||||||
|
|
||||||
subject
|
subject
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@ describe Admin::MailTemplatesController, type: :controller do
|
||||||
let(:initiated_mail) { Mails::InitiatedMail.default_for_procedure(procedure) }
|
let(:initiated_mail) { Mails::InitiatedMail.default_for_procedure(procedure) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in procedure.administrateurs.first
|
sign_in(procedure.administrateurs.first.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET index' do
|
describe 'GET index' do
|
||||||
|
|
|
@ -33,7 +33,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
}
|
}
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET #index' do
|
describe 'GET #index' do
|
||||||
|
@ -155,7 +155,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
|
|
||||||
context 'when user is not connected' do
|
context 'when user is not connected' do
|
||||||
before do
|
before do
|
||||||
sign_out admin
|
sign_out(admin.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it { is_expected.to redirect_to new_user_session_path }
|
it { is_expected.to redirect_to new_user_session_path }
|
||||||
|
@ -252,7 +252,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
|
|
||||||
context 'when administrateur is not connected' do
|
context 'when administrateur is not connected' do
|
||||||
before do
|
before do
|
||||||
sign_out admin
|
sign_out(admin.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { put :update, params: { id: procedure.id } }
|
subject { put :update, params: { id: procedure.id } }
|
||||||
|
@ -411,8 +411,8 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
let(:admin_2) { create(:administrateur) }
|
let(:admin_2) { create(:administrateur) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_out admin
|
sign_out(admin.user)
|
||||||
sign_in admin_2
|
sign_in(admin_2.user)
|
||||||
|
|
||||||
put :publish, params: { procedure_id: procedure.id, path: 'fake_path' }
|
put :publish, params: { procedure_id: procedure.id, path: 'fake_path' }
|
||||||
procedure.reload
|
procedure.reload
|
||||||
|
@ -471,8 +471,8 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
let(:admin_2) { create(:administrateur) }
|
let(:admin_2) { create(:administrateur) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_out admin
|
sign_out(admin.user)
|
||||||
sign_in admin_2
|
sign_in(admin_2.user)
|
||||||
|
|
||||||
put :archive, params: { procedure_id: procedure.id }
|
put :archive, params: { procedure_id: procedure.id }
|
||||||
procedure.reload
|
procedure.reload
|
||||||
|
@ -517,8 +517,8 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
let(:admin_2) { create(:administrateur) }
|
let(:admin_2) { create(:administrateur) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_out admin
|
sign_out(admin.user)
|
||||||
sign_in admin_2
|
sign_in(admin_2.user)
|
||||||
subject
|
subject
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -783,7 +783,7 @@ describe Admin::ProceduresController, type: :controller do
|
||||||
|
|
||||||
context 'when administrateur is not connected' do
|
context 'when administrateur is not connected' do
|
||||||
before do
|
before do
|
||||||
sign_out admin
|
sign_out(admin.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { patch :update_monavis, params: { procedure_id: procedure.id } }
|
subject { patch :update_monavis, params: { procedure_id: procedure.id } }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
describe Administrateurs::ActivateController, type: :controller do
|
describe Administrateurs::ActivateController, type: :controller do
|
||||||
describe '#new' do
|
describe '#new' do
|
||||||
let(:admin) { create(:administrateur) }
|
let(:admin) { create(:administrateur) }
|
||||||
let(:token) { admin.send(:set_reset_password_token) }
|
let(:token) { admin.user.send(:set_reset_password_token) }
|
||||||
|
|
||||||
before { allow(controller).to receive(:trust_device) }
|
before { allow(controller).to receive(:trust_device) }
|
||||||
|
|
||||||
|
|
|
@ -166,56 +166,44 @@ describe ApplicationController, type: :controller do
|
||||||
context 'when the path is sensitive' do
|
context 'when the path is sensitive' do
|
||||||
let(:sensitive_path) { true }
|
let(:sensitive_path) { true }
|
||||||
|
|
||||||
|
before do
|
||||||
|
Flipflop::FeatureSet.current.test!.switch!(:bypass_email_login_token, false)
|
||||||
|
end
|
||||||
|
|
||||||
context 'when the instructeur is signed_in' do
|
context 'when the instructeur is signed_in' do
|
||||||
let(:instructeur_signed_in) { true }
|
let(:instructeur_signed_in) { true }
|
||||||
|
|
||||||
context 'when the feature is activated' do
|
context 'when the ip is not trusted' do
|
||||||
before do
|
let(:ip_trusted) { false }
|
||||||
Flipflop::FeatureSet.current.test!.switch!(:enable_email_login_token, true)
|
|
||||||
|
context 'when the device is trusted' do
|
||||||
|
let(:trusted_device) { true }
|
||||||
|
|
||||||
|
before { subject }
|
||||||
|
|
||||||
|
it { expect(@controller).not_to have_received(:redirect_to) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the ip is not trusted' do
|
context 'when the device is not trusted' do
|
||||||
let(:ip_trusted) { false }
|
let(:trusted_device) { false }
|
||||||
|
|
||||||
context 'when the device is trusted' do
|
before { subject }
|
||||||
let(:trusted_device) { true }
|
|
||||||
|
|
||||||
before { subject }
|
it { expect(@controller).to have_received(:redirect_to) }
|
||||||
|
it { expect(@controller).to have_received(:send_login_token_or_bufferize) }
|
||||||
it { expect(@controller).not_to have_received(:redirect_to) }
|
it { expect(@controller).to have_received(:store_location_for) }
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the feature is activated' do
|
context 'when the ip is trusted' do
|
||||||
before do
|
let(:ip_trusted) { true }
|
||||||
Flipflop::FeatureSet.current.test!.switch!(:enable_email_login_token, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the ip is untrusted' do
|
context 'when the device is not trusted' do
|
||||||
let(:ip_trusted) { false }
|
let(:trusted_device) { false }
|
||||||
|
|
||||||
context 'when the device is not trusted' do
|
before { subject }
|
||||||
let(:trusted_device) { false }
|
|
||||||
|
|
||||||
before { subject }
|
it { expect(@controller).not_to have_received(:redirect_to) }
|
||||||
|
|
||||||
it { expect(@controller).to have_received(:redirect_to) }
|
|
||||||
it { expect(@controller).to have_received(:send_login_token_or_bufferize) }
|
|
||||||
it { expect(@controller).to have_received(:store_location_for) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the ip is trusted' do
|
|
||||||
let(:ip_trusted) { true }
|
|
||||||
|
|
||||||
context 'when the device is not trusted' do
|
|
||||||
let(:trusted_device) { false }
|
|
||||||
|
|
||||||
before { subject }
|
|
||||||
|
|
||||||
it { expect(@controller).not_to have_received(:redirect_to) }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -184,13 +184,7 @@ describe Instructeurs::DossiersController, type: :controller do
|
||||||
expect(dossier.reload.state).to eq(Dossier.states.fetch(:accepte))
|
expect(dossier.reload.state).to eq(Dossier.states.fetch(:accepte))
|
||||||
expect(response).to have_http_status(:ok)
|
expect(response).to have_http_status(:ok)
|
||||||
end
|
end
|
||||||
context 'as administrateur' do
|
|
||||||
let (:current_user) { administrateur }
|
|
||||||
it 'it is not possible to go back to en_instruction' do
|
|
||||||
expect(dossier.reload.state).to eq(Dossier.states.fetch(:accepte))
|
|
||||||
expect(response).to have_http_status(:ok)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
context 'as superadmin' do
|
context 'as superadmin' do
|
||||||
let (:current_user) { administration }
|
let (:current_user) { administration }
|
||||||
it 'it is not possible to go back to en_instruction' do
|
it 'it is not possible to go back to en_instruction' do
|
||||||
|
|
|
@ -7,7 +7,7 @@ describe NewAdministrateur::MailTemplatesController, type: :controller do
|
||||||
let(:procedure) { create(:procedure, :with_logo, :with_service, administrateur: admin) }
|
let(:procedure) { create(:procedure, :with_logo, :with_service, administrateur: admin) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
get :preview, params: { id: "initiated_mail", procedure_id: procedure.id }
|
get :preview, params: { id: "initiated_mail", procedure_id: procedure.id }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ describe NewAdministrateur::ProceduresController, type: :controller do
|
||||||
let(:procedure) { create(:procedure) }
|
let(:procedure) { create(:procedure) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
get :apercu, params: { id: procedure.id }
|
get :apercu, params: { id: procedure.id }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ describe NewAdministrateur::ServicesController, type: :controller do
|
||||||
|
|
||||||
describe '#create' do
|
describe '#create' do
|
||||||
before do
|
before do
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
post :create, params: params
|
post :create, params: params
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ describe NewAdministrateur::ServicesController, type: :controller do
|
||||||
let(:service_params) { { nom: 'nom', type_organisme: Service.type_organismes.fetch(:association) } }
|
let(:service_params) { { nom: 'nom', type_organisme: Service.type_organismes.fetch(:association) } }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
params = {
|
params = {
|
||||||
id: service.id,
|
id: service.id,
|
||||||
service: service_params,
|
service: service_params,
|
||||||
|
@ -82,7 +82,7 @@ describe NewAdministrateur::ServicesController, type: :controller do
|
||||||
let!(:service) { create(:service, administrateur: admin) }
|
let!(:service) { create(:service, administrateur: admin) }
|
||||||
|
|
||||||
def post_add_to_procedure
|
def post_add_to_procedure
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
params = {
|
params = {
|
||||||
procedure: {
|
procedure: {
|
||||||
id: procedure.id,
|
id: procedure.id,
|
||||||
|
@ -114,7 +114,7 @@ describe NewAdministrateur::ServicesController, type: :controller do
|
||||||
|
|
||||||
context 'when a service has no related procedure' do
|
context 'when a service has no related procedure' do
|
||||||
before do
|
before do
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
delete :destroy, params: { id: service.id, procedure_id: 12 }
|
delete :destroy, params: { id: service.id, procedure_id: 12 }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ describe NewAdministrateur::ServicesController, type: :controller do
|
||||||
let!(:procedure) { create(:procedure, service: service) }
|
let!(:procedure) { create(:procedure, service: service) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
delete :destroy, params: { id: service.id, procedure_id: 12 }
|
delete :destroy, params: { id: service.id, procedure_id: 12 }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe NewAdministrateur::TypesDeChampController, type: :controller do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
admin.procedures << procedure
|
admin.procedures << procedure
|
||||||
sign_in admin
|
sign_in(admin.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:type_champ) { TypeDeChamp.type_champs.fetch(:text) }
|
let(:type_champ) { TypeDeChamp.type_champs.fetch(:text) }
|
||||||
|
|
|
@ -26,7 +26,7 @@ describe RootController, type: :controller do
|
||||||
|
|
||||||
context 'when Administrateur is connected' do
|
context 'when Administrateur is connected' do
|
||||||
before do
|
before do
|
||||||
sign_in create(:administrateur)
|
sign_in(create(:administrateur).user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(subject).to redirect_to(admin_procedures_path) }
|
it { expect(subject).to redirect_to(admin_procedures_path) }
|
||||||
|
|
|
@ -8,8 +8,6 @@ describe Sessions::SessionsController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:instructeur) { create(:instructeur) }
|
|
||||||
let(:administrateur) { create(:administrateur) }
|
|
||||||
|
|
||||||
describe '#create' do
|
describe '#create' do
|
||||||
before do
|
before do
|
||||||
|
@ -34,17 +32,4 @@ describe Sessions::SessionsController, type: :controller do
|
||||||
post :create
|
post :create
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#create with administrateur connected' do
|
|
||||||
before do
|
|
||||||
@request.env["devise.mapping"] = Devise.mappings[:administrateur]
|
|
||||||
|
|
||||||
allow_any_instance_of(described_class).to receive(:administrateur_signed_in?).and_return(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'calls sign out for administrateur' do
|
|
||||||
expect_any_instance_of(described_class).to receive(:sign_out).with(:administrateur)
|
|
||||||
post :create
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ describe Users::ProfilController, type: :controller do
|
||||||
describe 'POST #renew_api_token' do
|
describe 'POST #renew_api_token' do
|
||||||
let(:administrateur) { create(:administrateur) }
|
let(:administrateur) { create(:administrateur) }
|
||||||
|
|
||||||
before { sign_in(administrateur) }
|
before { sign_in(administrateur.user) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(administrateur).to receive(:renew_api_token)
|
allow(administrateur).to receive(:renew_api_token)
|
||||||
|
|
|
@ -17,7 +17,6 @@ describe Users::SessionsController, type: :controller do
|
||||||
let(:send_password) { password }
|
let(:send_password) { password }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Flipflop::FeatureSet.current.test!.switch!(:enable_email_login_token, true)
|
|
||||||
allow(controller).to receive(:trusted_device?).and_return(trusted_device)
|
allow(controller).to receive(:trusted_device?).and_return(trusted_device)
|
||||||
allow(InstructeurMailer).to receive(:send_login_token).and_return(double(deliver_later: true))
|
allow(InstructeurMailer).to receive(:send_login_token).and_return(double(deliver_later: true))
|
||||||
end
|
end
|
||||||
|
@ -28,6 +27,9 @@ describe Users::SessionsController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the device is not trusted' do
|
context 'when the device is not trusted' do
|
||||||
|
before do
|
||||||
|
Flipflop::FeatureSet.current.test!.switch!(:bypass_email_login_token, false)
|
||||||
|
end
|
||||||
let(:trusted_device) { false }
|
let(:trusted_device) { false }
|
||||||
|
|
||||||
it 'redirects to the send_linked_path' do
|
it 'redirects to the send_linked_path' do
|
||||||
|
@ -106,20 +108,6 @@ describe Users::SessionsController, type: :controller do
|
||||||
expect(response).to redirect_to(root_path)
|
expect(response).to redirect_to(root_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when associated administrateur" do
|
|
||||||
let(:administrateur) { create(:administrateur, user: user) }
|
|
||||||
|
|
||||||
it 'signs user + instructeur + administrateur out' do
|
|
||||||
sign_in user
|
|
||||||
sign_in administrateur
|
|
||||||
delete :destroy
|
|
||||||
expect(@response.redirect?).to be(true)
|
|
||||||
expect(subject.current_user).to be(nil)
|
|
||||||
expect(subject.current_instructeur).to be(nil)
|
|
||||||
expect(subject.current_administrateur).to be(nil)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#new' do
|
describe '#new' do
|
||||||
|
|
|
@ -2,18 +2,20 @@ FactoryBot.define do
|
||||||
sequence(:administrateur_email) { |n| "admin#{n}@admin.com" }
|
sequence(:administrateur_email) { |n| "admin#{n}@admin.com" }
|
||||||
factory :administrateur do
|
factory :administrateur do
|
||||||
email { generate(:administrateur_email) }
|
email { generate(:administrateur_email) }
|
||||||
password { 'mon chien aime les bananes' }
|
|
||||||
|
|
||||||
transient do
|
transient do
|
||||||
user { nil }
|
user { nil }
|
||||||
|
password { 'mon chien aime les bananes' }
|
||||||
end
|
end
|
||||||
|
|
||||||
after(:create) do |admin, evaluator|
|
after(:create) do |administrateur, evaluator|
|
||||||
if evaluator.user.present?
|
if evaluator.user.present?
|
||||||
create(:instructeur, email: admin.email, password: admin.password, user: evaluator.user)
|
user = evaluator.user
|
||||||
else
|
else
|
||||||
create(:instructeur, email: admin.email, password: admin.password)
|
user = create(:user, email: administrateur.email, password: evaluator.password, administrateur: administrateur)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create(:instructeur, email: administrateur.email, user: user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ feature 'As an administrateur I wanna clone a procedure', js: true do
|
||||||
let(:administrateur) { create(:administrateur) }
|
let(:administrateur) { create(:administrateur) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
login_as administrateur, scope: :administrateur
|
login_as administrateur.user, scope: :user
|
||||||
visit new_from_existing_admin_procedures_path
|
visit new_from_existing_admin_procedures_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ feature 'As an administrateur I wanna create a new procedure', js: true do
|
||||||
let(:administrateur) { create(:administrateur, :with_procedure) }
|
let(:administrateur) { create(:administrateur, :with_procedure) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
login_as administrateur, scope: :administrateur
|
login_as administrateur.user, scope: :user
|
||||||
visit root_path
|
visit root_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ feature 'Administrateurs can edit procedures', js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
login_as administrateur, scope: :administrateur
|
login_as administrateur.user, scope: :user
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the procedure is in draft' do
|
context 'when the procedure is in draft' do
|
||||||
|
|
|
@ -6,7 +6,7 @@ feature 'As an instructeur', js: true do
|
||||||
let(:instructeur_email) { 'new_instructeur@gouv.fr' }
|
let(:instructeur_email) { 'new_instructeur@gouv.fr' }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
login_as administrateur, scope: :administrateur
|
login_as administrateur.user, scope: :user
|
||||||
visit admin_procedure_assigns_path(procedure)
|
visit admin_procedure_assigns_path(procedure)
|
||||||
|
|
||||||
fill_in :instructeur_email, with: instructeur_email
|
fill_in :instructeur_email, with: instructeur_email
|
||||||
|
|
|
@ -9,10 +9,6 @@ feature 'The instructeur part' do
|
||||||
let!(:procedure) { create(:procedure, :published, instructeurs: [instructeur]) }
|
let!(:procedure) { create(:procedure, :published, instructeurs: [instructeur]) }
|
||||||
let!(:dossier) { create(:dossier, state: Dossier.states.fetch(:en_construction), procedure: procedure) }
|
let!(:dossier) { create(:dossier, state: Dossier.states.fetch(:en_construction), procedure: procedure) }
|
||||||
|
|
||||||
before do
|
|
||||||
Flipflop::FeatureSet.current.test!.switch!(:enable_email_login_token, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'the instructeur is also a user' do
|
context 'the instructeur is also a user' do
|
||||||
scenario 'a instructeur can fill a dossier' do
|
scenario 'a instructeur can fill a dossier' do
|
||||||
visit commencer_path(path: procedure.path)
|
visit commencer_path(path: procedure.path)
|
||||||
|
|
|
@ -5,8 +5,7 @@ feature 'As an administrateur I can edit types de champ', js: true do
|
||||||
let(:procedure) { create(:procedure) }
|
let(:procedure) { create(:procedure) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Flipflop::FeatureSet.current.test!.switch!(:champ_repetition, true)
|
login_as administrateur.user, scope: :user
|
||||||
login_as administrateur, scope: :administrateur
|
|
||||||
visit champs_procedure_path(procedure)
|
visit champs_procedure_path(procedure)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
57
spec/features/users/managing_password_spec.rb
Normal file
57
spec/features/users/managing_password_spec.rb
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
feature 'Managing password:' do
|
||||||
|
context 'for simple users' do
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
let(:new_password) { 'a simple password' }
|
||||||
|
|
||||||
|
scenario 'a simple user can reset their password' do
|
||||||
|
visit root_path
|
||||||
|
click_on 'Connexion'
|
||||||
|
click_on 'Mot de passe oublié ?'
|
||||||
|
expect(page).to have_current_path(new_user_password_path)
|
||||||
|
|
||||||
|
fill_in 'Email', with: user.email
|
||||||
|
perform_enqueued_jobs do
|
||||||
|
click_on 'Réinitialiser'
|
||||||
|
end
|
||||||
|
expect(page).to have_content 'vous allez recevoir un lien de réinitialisation par email'
|
||||||
|
|
||||||
|
click_reset_password_link_for user.email
|
||||||
|
expect(page).to have_content 'Changement de mot de passe'
|
||||||
|
|
||||||
|
fill_in 'user_password', with: new_password
|
||||||
|
fill_in 'user_password_confirmation', with: new_password
|
||||||
|
click_on 'Changer le mot de passe'
|
||||||
|
expect(page).to have_content('Votre mot de passe a été changé avec succès')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for admins' do
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
let(:administrateur) { create(:administrateur, user: user) }
|
||||||
|
let(:new_password) { 'a new, long, and complicated password!' }
|
||||||
|
|
||||||
|
scenario 'an admin can reset their password' do
|
||||||
|
visit root_path
|
||||||
|
click_on 'Connexion'
|
||||||
|
click_on 'Mot de passe oublié ?'
|
||||||
|
expect(page).to have_current_path(new_user_password_path)
|
||||||
|
|
||||||
|
fill_in 'Email', with: user.email
|
||||||
|
perform_enqueued_jobs do
|
||||||
|
click_on 'Réinitialiser'
|
||||||
|
end
|
||||||
|
expect(page).to have_content 'vous allez recevoir un lien de réinitialisation par email'
|
||||||
|
|
||||||
|
click_reset_password_link_for user.email
|
||||||
|
|
||||||
|
expect(page).to have_content 'Changement de mot de passe'
|
||||||
|
|
||||||
|
fill_in 'user_password', with: new_password
|
||||||
|
fill_in 'user_password_confirmation', with: new_password
|
||||||
|
click_on 'Changer le mot de passe'
|
||||||
|
expect(page).to have_content('Votre mot de passe a été changé avec succès')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
spec/features/users/sign_out_spec.rb
Normal file
17
spec/features/users/sign_out_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
feature 'Sign out' do
|
||||||
|
context 'when a user is logged in' do
|
||||||
|
let(:user) { create(:administrateur).user }
|
||||||
|
|
||||||
|
before { login_as user, scope: :user }
|
||||||
|
|
||||||
|
scenario 'he can sign out' do
|
||||||
|
visit dossiers_path
|
||||||
|
|
||||||
|
click_on 'Se déconnecter'
|
||||||
|
|
||||||
|
expect(page).to have_current_path(root_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -38,7 +38,7 @@ RSpec.describe Administrateurs::ActivateBeforeExpirationJob, type: :job do
|
||||||
subject
|
subject
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(AdministrateurMailer).to have_received(:activate_before_expiration).with(administrateur, kind_of(String)) }
|
it { expect(AdministrateurMailer).to have_received(:activate_before_expiration).with(administrateur.user, kind_of(String)) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,29 +8,6 @@ describe Administrateur, type: :model do
|
||||||
it { is_expected.to have_many(:procedures) }
|
it { is_expected.to have_many(:procedures) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'unified login' do
|
|
||||||
it 'syncs credentials to associated user' do
|
|
||||||
administrateur = create(:administrateur)
|
|
||||||
user = administrateur.instructeur.user
|
|
||||||
|
|
||||||
administrateur.update(email: 'whoami@plop.com', password: 'voilà un super mdp')
|
|
||||||
|
|
||||||
user.reload
|
|
||||||
expect(user.email).to eq('whoami@plop.com')
|
|
||||||
expect(user.valid_password?('voilà un super mdp')).to be(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'syncs credentials to associated administrateur' do
|
|
||||||
administrateur = create(:administrateur)
|
|
||||||
instructeur = administrateur.instructeur
|
|
||||||
|
|
||||||
administrateur.update(email: 'whoami@plop.com', password: 'et encore un autre mdp')
|
|
||||||
|
|
||||||
instructeur.reload
|
|
||||||
expect(instructeur.email).to eq('whoami@plop.com')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#renew_api_token" do
|
describe "#renew_api_token" do
|
||||||
let!(:administrateur) { create(:administrateur) }
|
let!(:administrateur) { create(:administrateur) }
|
||||||
let!(:token) { administrateur.renew_api_token }
|
let!(:token) { administrateur.renew_api_token }
|
||||||
|
@ -44,22 +21,6 @@ describe Administrateur, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#find_inactive_by_token' do
|
|
||||||
let(:administrateur) { create(:administration).invite_admin('paul@tps.fr') }
|
|
||||||
let(:reset_password_token) { administrateur.invite!(administration.id) }
|
|
||||||
|
|
||||||
it { expect(Administrateur.find_inactive_by_token(reset_password_token)).not_to be_nil }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#reset_password' do
|
|
||||||
let(:administrateur) { create(:administration).invite_admin('paul@tps.fr') }
|
|
||||||
let(:reset_password_token) { administrateur.invite!(administration.id) }
|
|
||||||
|
|
||||||
it { expect(Administrateur.reset_password(reset_password_token, "j'aime manger des radis").errors).to be_empty }
|
|
||||||
it { expect(Administrateur.reset_password('123', "j'aime manger des radis").errors).not_to be_empty }
|
|
||||||
it { expect(Administrateur.reset_password(reset_password_token, '').errors).not_to be_empty }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#feature_enabled?' do
|
describe '#feature_enabled?' do
|
||||||
let(:administrateur) { create(:administrateur) }
|
let(:administrateur) { create(:administrateur) }
|
||||||
|
|
||||||
|
@ -71,33 +32,33 @@ describe Administrateur, type: :model do
|
||||||
it { expect(administrateur.feature_enabled?(:test_a)).to be_truthy }
|
it { expect(administrateur.feature_enabled?(:test_a)).to be_truthy }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#password_complexity' do
|
# describe '#password_complexity' do
|
||||||
let(:email) { 'mail@beta.gouv.fr' }
|
# let(:email) { 'mail@beta.gouv.fr' }
|
||||||
let(:passwords) { ['pass', '12pass23', 'démarches ', 'démarches-simple', 'démarches-simplifiées-pwd'] }
|
# let(:passwords) { ['pass', '12pass23', 'démarches ', 'démarches-simple', 'démarches-simplifiées-pwd'] }
|
||||||
let(:administrateur) { build(:administrateur, email: email, password: password) }
|
# let(:administrateur) { build(:administrateur, email: email, password: password) }
|
||||||
let(:min_complexity) { PASSWORD_COMPLEXITY_FOR_ADMIN }
|
# let(:min_complexity) { PASSWORD_COMPLEXITY_FOR_ADMIN }
|
||||||
|
|
||||||
subject do
|
# subject do
|
||||||
administrateur.save
|
# administrateur.save
|
||||||
administrateur.errors.full_messages
|
# administrateur.errors.full_messages
|
||||||
end
|
# end
|
||||||
|
|
||||||
context 'when password is too short' do
|
# context 'when password is too short' do
|
||||||
let(:password) { 's' * (PASSWORD_MIN_LENGTH - 1) }
|
# let(:password) { 's' * (PASSWORD_MIN_LENGTH - 1) }
|
||||||
|
|
||||||
it { expect(subject).to eq(["Le mot de passe est trop court"]) }
|
# it { expect(subject).to eq(["Le mot de passe est trop court"]) }
|
||||||
end
|
# end
|
||||||
|
|
||||||
context 'when password is too simple' do
|
# context 'when password is too simple' do
|
||||||
let(:password) { passwords[min_complexity - 1] }
|
# let(:password) { passwords[min_complexity - 1] }
|
||||||
|
|
||||||
it { expect(subject).to eq(["Le mot de passe n'est pas assez complexe"]) }
|
# it { expect(subject).to eq(["Le mot de passe n'est pas assez complexe"]) }
|
||||||
end
|
# end
|
||||||
|
|
||||||
context 'when password is acceptable' do
|
# context 'when password is acceptable' do
|
||||||
let(:password) { passwords[min_complexity] }
|
# let(:password) { passwords[min_complexity] }
|
||||||
|
|
||||||
it { expect(subject).to eq([]) }
|
# it { expect(subject).to eq([]) }
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,13 +4,15 @@ describe Administration, type: :model do
|
||||||
describe '#invite_admin' do
|
describe '#invite_admin' do
|
||||||
let(:administration) { create :administration }
|
let(:administration) { create :administration }
|
||||||
let(:valid_email) { 'paul@tps.fr' }
|
let(:valid_email) { 'paul@tps.fr' }
|
||||||
|
|
||||||
subject { administration.invite_admin(valid_email) }
|
subject { administration.invite_admin(valid_email) }
|
||||||
|
|
||||||
it {
|
it {
|
||||||
expect(subject.errors).to be_empty
|
user = subject
|
||||||
expect(subject).to be_persisted
|
expect(user.errors).to be_empty
|
||||||
expect(administration.invite_admin(valid_email).errors).not_to be_empty
|
expect(user).to be_persisted
|
||||||
}
|
}
|
||||||
|
|
||||||
it { expect(administration.invite_admin(nil).errors).not_to be_empty }
|
it { expect(administration.invite_admin(nil).errors).not_to be_empty }
|
||||||
it { expect(administration.invite_admin('toto').errors).not_to be_empty }
|
it { expect(administration.invite_admin('toto').errors).not_to be_empty }
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,6 @@ describe Instructeur, type: :model do
|
||||||
assign(procedure_2)
|
assign(procedure_2)
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'default features' do
|
|
||||||
it { expect(instructeur.features).to eq({ "enable_email_login_token" => true }) }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#visible_procedures' do
|
describe '#visible_procedures' do
|
||||||
let(:procedure_not_assigned) { create :procedure, administrateur: admin }
|
let(:procedure_not_assigned) { create :procedure, administrateur: admin }
|
||||||
let(:procedure_with_default_path) { create :procedure, administrateur: admin }
|
let(:procedure_with_default_path) { create :procedure, administrateur: admin }
|
||||||
|
@ -141,18 +137,6 @@ describe Instructeur, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'unified login' do
|
|
||||||
it 'syncs credentials to associated administrateur' do
|
|
||||||
admin = create(:administrateur)
|
|
||||||
user = admin.instructeur.user
|
|
||||||
|
|
||||||
user.update(password: 'démarches-simplifiées-pwd')
|
|
||||||
|
|
||||||
admin.reload
|
|
||||||
expect(admin.valid_password?('démarches-simplifiées-pwd')).to be(true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'last_week_overview' do
|
describe 'last_week_overview' do
|
||||||
let!(:instructeur2) { create(:instructeur) }
|
let!(:instructeur2) { create(:instructeur) }
|
||||||
subject { instructeur2.last_week_overview }
|
subject { instructeur2.last_week_overview }
|
||||||
|
|
|
@ -100,18 +100,4 @@ describe User, type: :model do
|
||||||
it { is_expected.to be_falsey }
|
it { is_expected.to be_falsey }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'unified login' do
|
|
||||||
it 'syncs credentials to associated administrateur' do
|
|
||||||
admin = create(:administrateur)
|
|
||||||
user = admin.instructeur.user
|
|
||||||
|
|
||||||
user.update(email: 'whoami@plop.com', password: 'démarches-simplifiées2')
|
|
||||||
user.confirm
|
|
||||||
|
|
||||||
admin.reload
|
|
||||||
expect(admin.email).to eq('whoami@plop.com')
|
|
||||||
expect(admin.valid_password?('démarches-simplifiées2')).to be(true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,6 +21,10 @@ module FeatureHelpers
|
||||||
fill_in :user_email, with: email
|
fill_in :user_email, with: email
|
||||||
fill_in :user_password, with: password
|
fill_in :user_password, with: password
|
||||||
|
|
||||||
|
if sign_in_by_link
|
||||||
|
Flipflop::FeatureSet.current.test!.switch!(:bypass_email_login_token, false)
|
||||||
|
end
|
||||||
|
|
||||||
perform_enqueued_jobs do
|
perform_enqueued_jobs do
|
||||||
click_on 'Se connecter'
|
click_on 'Se connecter'
|
||||||
end
|
end
|
||||||
|
@ -74,6 +78,13 @@ module FeatureHelpers
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def click_reset_password_link_for(email)
|
||||||
|
reset_password_email = open_email(email)
|
||||||
|
token_params = reset_password_email.body.match(/reset_password_token=[^"]+/)
|
||||||
|
|
||||||
|
visit "/users/password/edit?#{token_params}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
|
|
|
@ -6,6 +6,7 @@ describe 'layouts/procedure_context.html.haml', type: :view do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow(view).to receive(:instructeur_signed_in?).and_return(false)
|
allow(view).to receive(:instructeur_signed_in?).and_return(false)
|
||||||
|
allow(view).to receive(:administrateur_signed_in?).and_return(false)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject do
|
subject do
|
||||||
|
|
Loading…
Reference in a new issue