Merge branch 'develop' of github.com:sgmap/tps into develop

This commit is contained in:
Tanguy PATTE 2015-12-21 17:52:00 +01:00
commit 3ea381413f
45 changed files with 345 additions and 162 deletions

View file

@ -106,6 +106,10 @@ group :development, :test do
gem 'rubocop-checkstyle_formatter', require: false gem 'rubocop-checkstyle_formatter', require: false
gem 'rubocop-rspec', require: false gem 'rubocop-rspec', require: false
gem "nyan-cat-formatter"
gem 'parallel_tests'
# Deploy # Deploy
gem 'mina', git: 'https://github.com/mina-deploy/mina.git' gem 'mina', git: 'https://github.com/mina-deploy/mina.git'
end end

View file

@ -213,6 +213,8 @@ GEM
notiffany (0.0.8) notiffany (0.0.8)
nenv (~> 0.1) nenv (~> 0.1)
shellany (~> 0.0) shellany (~> 0.0)
nyan-cat-formatter (0.11)
rspec (>= 2.99, >= 2.14.2, < 4)
open4 (1.3.4) open4 (1.3.4)
openid_connect (0.9.2) openid_connect (0.9.2)
activemodel activemodel
@ -226,6 +228,9 @@ GEM
validate_url validate_url
webfinger (>= 1.0.1) webfinger (>= 1.0.1)
orm_adapter (0.5.0) orm_adapter (0.5.0)
parallel (1.6.1)
parallel_tests (1.9.0)
parallel
parser (2.2.2.2) parser (2.2.2.2)
ast (>= 1.1, < 3.0) ast (>= 1.1, < 3.0)
pg (0.18.2) pg (0.18.2)
@ -455,7 +460,9 @@ DEPENDENCIES
logstasher logstasher
mailjet mailjet
mina! mina!
nyan-cat-formatter
openid_connect openid_connect
parallel_tests
pg pg
poltergeist poltergeist
pry-byebug pry-byebug

View file

@ -23,11 +23,4 @@ class Admin::PiecesJustificativesController < AdminController
.require(:procedure) .require(:procedure)
.permit(types_de_piece_justificative_attributes: [:libelle, :description, :id]) .permit(types_de_piece_justificative_attributes: [:libelle, :description, :id])
end end
def retrieve_procedure
@procedure = current_administrateur.procedures.find(params[:procedure_id])
rescue ActiveRecord::RecordNotFound
render json: { message: 'Procedure not found' }, status: 404
end
end end

View file

@ -1,5 +1,7 @@
class Admin::ProceduresController < AdminController class Admin::ProceduresController < AdminController
before_action :retrieve_procedure, only: :edit
def index def index
@procedures = current_administrateur.procedures.where(archived: false) @procedures = current_administrateur.procedures.where(archived: false)
.paginate(:page => params[:page]).decorate .paginate(:page => params[:page]).decorate

View file

@ -1,5 +1,4 @@
class Admin::TypesDeChampController < AdminController class Admin::TypesDeChampController < AdminController
before_action :retrieve_procedure before_action :retrieve_procedure
def destroy def destroy
@ -38,12 +37,4 @@ class Admin::TypesDeChampController < AdminController
render json: {}, status: 400 render json: {}, status: 400
end end
end end
private
def retrieve_procedure
@procedure = Procedure.find(params[:procedure_id])
rescue ActiveRecord::RecordNotFound
render json: { message: 'Procedure not found' }, status: 404
end
end end

View file

@ -4,4 +4,17 @@ class AdminController < ApplicationController
def index def index
redirect_to (admin_procedures_path) redirect_to (admin_procedures_path)
end end
def retrieve_procedure
id = params[:procedure_id] || params[:id ]
@procedure = current_administrateur.procedures.find(id)
if @procedure.locked?
render json: {message: 'Procedure locked'}, status: 403
end
rescue ActiveRecord::RecordNotFound
render json: {message: 'Procedure not found'}, status: 404
end
end end

View file

@ -1,6 +1,6 @@
class FranceConnectController < ApplicationController class FranceConnect::EntrepriseController < ApplicationController
def login def login
client = FranceConnectClient.new client = FranceConnectEntrepriseClient.new
session[:state] = SecureRandom.hex(16) session[:state] = SecureRandom.hex(16)
session[:nonce] = SecureRandom.hex(16) session[:nonce] = SecureRandom.hex(16)
@ -16,7 +16,7 @@ class FranceConnectController < ApplicationController
def callback def callback
return redirect_to new_user_session_path unless params.has_key?(:code) return redirect_to new_user_session_path unless params.has_key?(:code)
user_infos = FranceConnectService.retrieve_user_informations(params[:code]) user_infos = FranceConnectService.retrieve_user_informations_entreprise(params[:code])
unless user_infos.nil? unless user_infos.nil?
@user = User.find_for_france_connect(user_infos.email, user_infos.siret) @user = User.find_for_france_connect(user_infos.email, user_infos.siret)

View file

@ -29,6 +29,8 @@ class Users::RecapitulatifController < UsersController
@dossier.next_step! 'user', 'submit' @dossier.next_step! 'user', 'submit'
flash.notice = 'Dossier déposé avec succès.' flash.notice = 'Dossier déposé avec succès.'
NotificationMailer.dossier_submitted(@dossier).deliver_now!
render 'show' render 'show'
end end
end end

View file

@ -18,14 +18,12 @@ class Users::SessionsController < Sessions::SessionsController
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_attributes(loged_in_with_france_connect: false) current_user.update_attributes(loged_in_with_france_connect: false)
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)) signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
set_flash_message :notice, :signed_out if signed_out && is_flashing_format? set_flash_message :notice, :signed_out if signed_out && is_flashing_format?
yield if block_given? yield if block_given?
if connected_with_france_connect if connected_with_france_connect
redirect_to FRANCE_CONNECT.logout_endpoint redirect_to FRANCE_CONNECT.entreprise_logout_endpoint
else else
respond_to_on_destroy respond_to_on_destroy
end end

View file

@ -7,6 +7,10 @@ class NotificationMailer < ApplicationMailer
send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été validé" send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été validé"
end end
def dossier_submitted dossier
send_mail dossier, "Votre dossier TPS N°#{dossier.id} a été déposé"
end
private private
def vars_mailer dossier def vars_mailer dossier

View file

@ -1,17 +0,0 @@
class FranceConnectClient < OpenIDConnect::Client
def initialize params={}
super(
identifier: FRANCE_CONNECT.identifier,
secret: FRANCE_CONNECT.secret,
redirect_uri: FRANCE_CONNECT.redirect_uri,
authorization_endpoint: FRANCE_CONNECT.authorization_endpoint,
token_endpoint: FRANCE_CONNECT.token_endpoint,
userinfo_endpoint: FRANCE_CONNECT.userinfo_endpoint,
logout_endpoint: FRANCE_CONNECT.logout_endpoint
)
self.authorization_code = params[:code] if params.has_key? :code
end
end

View file

@ -0,0 +1,17 @@
class FranceConnectEntrepriseClient < OpenIDConnect::Client
def initialize params={}
super(
identifier: FRANCE_CONNECT.entreprise_identifier,
secret: FRANCE_CONNECT.entreprise_secret,
redirect_uri: FRANCE_CONNECT.entreprise_redirect_uri,
authorization_endpoint: FRANCE_CONNECT.entreprise_authorization_endpoint,
token_endpoint: FRANCE_CONNECT.entreprise_token_endpoint,
userinfo_endpoint: FRANCE_CONNECT.entreprise_userinfo_endpoint,
logout_endpoint: FRANCE_CONNECT.entreprise_logout_endpoint
)
self.authorization_code = params[:code] if params.has_key? :code
end
end

View file

@ -27,4 +27,8 @@ class Procedure < ActiveRecord::Base
types_de_champ_tmp[index_of_first_element + 1].update_attributes(order_place: index_of_first_element) types_de_champ_tmp[index_of_first_element + 1].update_attributes(order_place: index_of_first_element)
true true
end end
def locked?
dossiers.where.not(state: :draft).count > 0
end
end end

View file

@ -1,6 +1,6 @@
class FranceConnectService class FranceConnectService
def self.retrieve_user_informations code def self.retrieve_user_informations_entreprise code
client = FranceConnectClient.new code: code client = FranceConnectEntrepriseClient.new code: code
access_token = client.access_token!(client_auth_method: :secret) access_token = client.access_token!(client_auth_method: :secret)
user_info = access_token.userinfo! user_info = access_token.userinfo!

View file

@ -13,7 +13,7 @@ class CerfaUploader < CarrierWave::Uploader::Base
# Override the directory where uploaded files will be stored. # Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted: # This is a sensible default for uploaders that are meant to be mounted:
def store_dir def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" "../uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end end
# Provide a default URL as a default if there hasn't been a file uploaded: # Provide a default URL as a default if there hasn't been a file uploaded:

View file

@ -13,7 +13,7 @@ class PieceJustificativeUploader < CarrierWave::Uploader::Base
# Override the directory where uploaded files will be stored. # Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted: # This is a sensible default for uploaders that are meant to be mounted:
def store_dir def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" "../uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end end
# Provide a default URL as a default if there hasn't been a file uploaded: # Provide a default URL as a default if there hasn't been a file uploaded:

View file

@ -3,10 +3,14 @@
%br %br
%ul.nav.nav-tabs %ul.nav.nav-tabs
%li= link_to('Informations', admin_procedure_path(@procedure)) %li
%li= link_to('Description', edit_admin_procedure_path(@procedure)) = link_to('Informations', admin_procedure_path(@procedure))
%li= link_to('Champs', admin_procedure_types_de_champ_path(@procedure)) %li
%li.active= link_to('Pièces justificatives', admin_procedure_pieces_justificatives_path(@procedure)) = link_to('Description', edit_admin_procedure_path(@procedure))
%li
= link_to('Champs', admin_procedure_types_de_champ_path(@procedure))
%li.active
= link_to('Pièces justificatives', admin_procedure_pieces_justificatives_path(@procedure))
#piece_justificative_form #piece_justificative_form
= render 'form' = render 'form'

View file

@ -1,78 +1,89 @@
%h2.text-info #procedure_show
=@procedure.libelle %h2.text-info
%br =@procedure.libelle
%br
%ul.nav.nav-tabs %ul.nav.nav-tabs
%li.active %li.active
= link_to('Informations', admin_procedure_path(@procedure)) = link_to('Informations', admin_procedure_path(@procedure))
%li
= link_to('Description', edit_admin_procedure_path(@procedure)) %li{ class: ('disabled' if @procedure.locked?) }
%li = link_to_unless(@procedure.locked?, 'Description', edit_admin_procedure_path(@procedure)) do
= link_to('Champs', admin_procedure_types_de_champ_path(@procedure)) = link_to('Description', '#')
%li
= link_to('Pièces justificatives', admin_procedure_pieces_justificatives_path(@procedure)) %li{ class: ('disabled' if @procedure.locked?) }
%li{style:'float:right'} = link_to_unless(@procedure.locked?, 'Champs', admin_procedure_types_de_champ_path(@procedure)) do
= form_tag admin_procedure_archive_path(procedure_id: @procedure.id, archive: !@procedure.archived?), method: :put do = link_to('Champs', '#')
%button#archive.btn.btn-nav.text-info{type: :button}
%i.fa.fa-eraser %li{ class: ('disabled' if @procedure.locked?) }
- if @procedure.archived = link_to_unless(@procedure.locked?, 'Pièces justificatives', admin_procedure_pieces_justificatives_path(@procedure)) do
= 'Réactiver' = link_to('Pièces justificatives', '#')
- else
= 'Archiver'
#confirm
%button#valid.btn.btn-nav.text-success{type: :submit}
%i.fa.fa-check
Valider
%button#cancel.btn.btn-nav.text-danger{type: :button}
%i.fa.fa-remove
Annuler
%br %li{style:'float:right'}
%div = form_tag admin_procedure_archive_path(procedure_id: @procedure.id, archive: !@procedure.archived?), method: :put do
%button#archive.btn.btn-nav.text-info{type: :button}
%i.fa.fa-eraser
- if @procedure.archived
= 'Réactiver'
- else
= 'Archiver'
#confirm
%button#valid.btn.btn-nav.text-success{type: :submit}
%i.fa.fa-check
Valider
%button#cancel.btn.btn-nav.text-danger{type: :button}
%i.fa.fa-remove
Annuler
%h3 Lien procédure - if @procedure.locked?
%div{style:'margin-left:3%'} #procedure_locked.center
= @procedure.lien %h5
.label.label-info La procédure ne peut plus être modifiée car un usagé a déjà déposé un dossier
%br %div
%h3 Dossiers %h3 Lien procédure
%div{style:'margin-left:3%'}
= @procedure.lien
.row %br
.col-md-6.col-lg-6{style:'margin-left:3%'} %h3 Dossiers
%h4 Total
%div
= @facade.dossiers_total
%h4.text-danger Attente Gestionnaire .row
%div .col-md-6.col-lg-6{style:'margin-left:3%'}
= @facade.dossiers_waiting_gestionnaire_total %h4 Total
%div
= @facade.dossiers_total
%h4.text-info Attente User %h4.text-danger Attente Accompagnateur
%div %div
= @facade.dossiers_waiting_user_total = @facade.dossiers_waiting_gestionnaire_total
%h4.text-success Terminé %h4.text-info Attente Utilisateur
%div %div
= @facade.dossiers_termine_total = @facade.dossiers_waiting_user_total
%h4 Archivé %h4.text-success Terminé
%div
= @facade.dossiers_termine_total
- unless @facade.dossiers_archived_total == 0 %h4 Archivé
%ul
- @facade.dossiers_archived_by_state_total.each do |dossier|
%li
= dossier.state_fr
\:
= dossier.total
- else
%p
0
.col-md-5.col-lg-5 - unless @facade.dossiers_archived_total == 0
%h4 Non archivés %ul
= javascript_include_tag "https://code.highcharts.com/highcharts.js", "chartkick" - @facade.dossiers_archived_by_state_total.each do |dossier|
- if @facade.dossiers_for_pie_highchart.blank? %li
Aucune statistique pour le moment = dossier.state_fr
-else \:
=pie_chart @facade.dossiers_for_pie_highchart = dossier.total
- else
%p
0
.col-md-5.col-lg-5
%h4 Non archivés
= javascript_include_tag "https://code.highcharts.com/highcharts.js", "chartkick"
- if @facade.dossiers_for_pie_highchart.blank?
Aucune statistique pour le moment
-else
=pie_chart @facade.dossiers_for_pie_highchart

View file

@ -1,6 +1,6 @@
%div{ style: "decorate:none; display: flex;box-shadow:none; float:right; display: flex" } %div{ style: "decorate:none; display: flex;box-shadow:none; float:right; display: flex" }
%div{ style: "vertical-align: middle; margin-right: 10px; margin-top: auto; margin-bottom: auto;" } %div{ style: "vertical-align: middle; margin-right: 10px; margin-top: auto; margin-bottom: auto;" }
mps-test@apientreprise.fr = current_administrateur.email
.dropdown#admin_menu .dropdown#admin_menu
%button.btn.btn-default.dropdown-toggle#dropdownMenuAdmin{ type: :button, 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false} %button.btn.btn-default.dropdown-toggle#dropdownMenuAdmin{ type: :button, 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false}
%i.fa.fa-cog %i.fa.fa-cog

View file

@ -4,7 +4,8 @@
.col-lg-6.col-md-6 .col-lg-6.col-md-6
%h3.text-info %h3.text-info
= @dossier.nom_projet = @dossier.nom_projet
%h4
= @dossier.procedure.libelle
.description .description
- begin - begin
- @dossier.description.split(/(?:\n\r?|\r\n?')/).each do |line| - @dossier.description.split(/(?:\n\r?|\r\n?')/).each do |line|

View file

@ -24,7 +24,7 @@
%dt Date de création : %dt Date de création :
%dd= Time.at(@entreprise.date_creation).strftime "%d-%m-%Y" %dd= Time.at(@entreprise.date_creation).strftime "%d-%m-%Y"
%dt Effectif entreprise : %dt Effectif organisation :
%dd= @entreprise.effectif %dd= @entreprise.effectif
%dt Code effectif : %dt Code effectif :

View file

@ -8,6 +8,6 @@
= form_for @dossier, url: { controller: '/users/dossiers', action: :update } do |f| = form_for @dossier, url: { controller: '/users/dossiers', action: :update } do |f|
%label{ style:'font-weight:normal' } %label{ style:'font-weight:normal' }
= f.check_box :autorisation_donnees = f.check_box :autorisation_donnees
J'autorise les organismes publics à vérifier les informations de mon entreprise auprès des administrations concernées. Ces informations resteront strictement confidentielles. J'autorise les décideurs publics à vérifier les informations de mon organisation auprès des administrations concernées. Ces informations resteront strictement confidentielles.
%br %br
= f.submit 'Etape suivante', class: "btn btn btn-info", style: 'float:right', id: 'etape_suivante' = f.submit 'Etape suivante', class: "btn btn btn-info", style: 'float:right', id: 'etape_suivante'

View file

@ -1,7 +1,7 @@
#form_login #form_login
= image_tag('logo-tps.png') = image_tag('logo-tps.png')
%br %br
%h2#gestionnaire_login Gestionnaire %h2#gestionnaire_login Accompagnateur
%br %br
%br %br

View file

@ -0,0 +1,8 @@
Bonjour <%= @user.email %>
Nous vous confirmons que votre dossier N°<%=@dossier.id%> a été déposé aurpès de <%= @dossier.procedure.organisation %> avec succès ce jour à <%= @dossier.updated_at %>.
Bonne journée
---
L'équide TPS - tps@apientreprise.fr

View file

@ -1,6 +1,6 @@
Bonjour <%= @user.email %>! Bonjour <%= @user.email %>
Votre dossier N°<%=@dossier.id%> a été validé par votre gestionnaire. Votre dossier N°<%=@dossier.id%> a été validé par votre accompagnateur.
Afin de finaliser son dépot, merci de vous rendre sur <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%> Afin de finaliser son dépot, merci de vous rendre sur <%=users_dossier_recapitulatif_url(dossier_id: @dossier.id)%>

View file

@ -1,4 +1,4 @@
Bonjour <%= @user.email %>! Bonjour <%= @user.email %>
Un nouveau commentaire est disponible dans votre espace TPS. Un nouveau commentaire est disponible dans votre espace TPS.

View file

@ -37,7 +37,7 @@
\- \-
%br %br
%a{href: '/gestionnaires/sign_in'} %a{href: '/gestionnaires/sign_in'}
= 'Gestionnaire' = 'Accompagnateur'
%br %br
%a{href: '/administrateurs/sign_in'} %a{href: '/administrateurs/sign_in'}
= 'Administrateur' = 'Administrateur'

View file

@ -12,7 +12,7 @@ development:
test: test:
adapter: postgresql adapter: postgresql
encoding: unicode encoding: unicode
database: tps_test database: tps_test<%= ENV['TEST_ENV_NUMBER'] %>
host: localhost host: localhost
pool: 5 pool: 5
username: tps username: tps

View file

@ -15,8 +15,10 @@ Rails.application.routes.draw do
root 'root#index' root 'root#index'
get 'france_connect' => 'france_connect#login' namespace :france_connect do
get 'france_connect/callback' => 'france_connect#callback' get 'entreprise' => 'entreprise#login'
get 'entreprise/callback' => 'entreprise#callback'
end
get 'demo' => 'demo#index' get 'demo' => 'demo#index'

View file

@ -9,11 +9,19 @@ describe Admin::PiecesJustificativesController, type: :controller do
describe 'GET #show' do describe 'GET #show' do
let(:procedure) { create(:procedure, administrateur: admin) } let(:procedure) { create(:procedure, administrateur: admin) }
let(:procedure_id) { procedure.id } let(:procedure_id) { procedure.id }
subject { get :show, procedure_id: procedure_id } subject { get :show, procedure_id: procedure_id }
context 'when procedure is not found' do context 'when procedure is not found' do
let(:procedure_id) { 9_999_999 } let(:procedure_id) { 9_999_999 }
it { expect(subject.status).to eq(404) } it { expect(subject.status).to eq(404) }
end end
context 'when procedure have at least a file' do
let!(:dossier) { create(:dossier, :with_user, procedure: procedure, state: :initiated) }
it { expect(subject.status).to eq(403) }
end
context 'when procedure does not belong to admin' do context 'when procedure does not belong to admin' do
let(:admin_2) { create(:administrateur) } let(:admin_2) { create(:administrateur) }
let(:procedure) { create(:procedure, administrateur: admin_2) } let(:procedure) { create(:procedure, administrateur: admin_2) }

View file

@ -66,10 +66,15 @@ describe Admin::ProceduresController, type: :controller do
it { expect(subject).to have_http_status(:success) } it { expect(subject).to have_http_status(:success) }
end end
context 'when procedure have at least a file' do
let!(:dossier) { create(:dossier, :with_user, procedure: procedure, state: :initiated) }
it { expect(subject.status).to eq(403) }
end
context "when procedure doesn't exist" do context "when procedure doesn't exist" do
let(:procedure_id) { bad_procedure_id } let(:procedure_id) { bad_procedure_id }
it { expect(subject).to redirect_to admin_procedures_path } it { expect(subject).to have_http_status(404) }
end end
end end
end end

View file

@ -2,12 +2,36 @@ require 'spec_helper'
describe Admin::TypesDeChampController, type: :controller do describe Admin::TypesDeChampController, type: :controller do
let(:admin) { create(:administrateur) } let(:admin) { create(:administrateur) }
let(:procedure) { create(:procedure, administrateur: admin) }
before do before do
sign_in admin sign_in admin
end end
describe 'GET #show' do
let(:procedure) { create(:procedure, administrateur: admin) }
let(:procedure_id) { procedure.id }
subject { get :show, procedure_id: procedure_id }
context 'when procedure is not found' do
let(:procedure_id) { 9_999_999 }
it { expect(subject.status).to eq(404) }
end
context 'when procedure have at least a file' do
let!(:dossier) { create(:dossier, :with_user, procedure: procedure, state: :initiated) }
it { expect(subject.status).to eq(403) }
end
context 'when procedure does not belong to admin' do
let(:admin_2) { create(:administrateur) }
let(:procedure) { create(:procedure, administrateur: admin_2) }
it { expect(subject.status).to eq(404) }
end
end
describe '#update' do describe '#update' do
let(:procedure) { create(:procedure) }
let(:libelle) { 'mon libelle' } let(:libelle) { 'mon libelle' }
let(:type_champ) { 'text' } let(:type_champ) { 'text' }
let(:description) { 'titi' } let(:description) { 'titi' }
@ -47,7 +71,7 @@ describe Admin::TypesDeChampController, type: :controller do
end end
context 'when type_de_champ already exist' do context 'when type_de_champ already exist' do
let(:procedure) { create(:procedure, :with_type_de_champ) } let(:procedure) { create(:procedure, :with_type_de_champ, administrateur: admin) }
let(:type_de_champ) { procedure.types_de_champ.first } let(:type_de_champ) { procedure.types_de_champ.first }
let(:types_de_champ_id) { type_de_champ.id } let(:types_de_champ_id) { type_de_champ.id }
let(:libelle) { 'toto' } let(:libelle) { 'toto' }
@ -77,13 +101,13 @@ describe Admin::TypesDeChampController, type: :controller do
before do before do
delete :destroy, procedure_id: procedure.id, id: type_de_champ_id, format: :js delete :destroy, procedure_id: procedure.id, id: type_de_champ_id, format: :js
end end
context 'when type de champs does not exist' do context 'when type de champs does not exist' do
let(:type_de_champ_id) { 99999999 } let(:type_de_champ_id) { 99999999 }
let(:procedure) { create(:procedure) }
it { expect(subject.status).to eq(404) } it { expect(subject.status).to eq(404) }
end end
context 'when types_de_champ exists' do context 'when types_de_champ exists' do
let(:procedure) { create(:procedure, :with_type_de_champ) } let(:procedure) { create(:procedure, :with_type_de_champ, administrateur: admin) }
let(:type_de_champ_id) { procedure.types_de_champ.first.id } let(:type_de_champ_id) { procedure.types_de_champ.first.id }
it { expect(subject.status).to eq(200) } it { expect(subject.status).to eq(200) }
it 'destroy type de champ' do it 'destroy type de champ' do
@ -92,7 +116,6 @@ describe Admin::TypesDeChampController, type: :controller do
end end
end end
context 'when procedure and type de champs are not linked' do context 'when procedure and type de champs are not linked' do
let(:procedure) { create(:procedure) }
let(:type_de_champ) { create(:type_de_champ) } let(:type_de_champ) { create(:type_de_champ) }
let(:type_de_champ_id) { type_de_champ.id } let(:type_de_champ_id) { type_de_champ.id }
it { expect(subject.status).to eq(404) } it { expect(subject.status).to eq(404) }
@ -101,28 +124,25 @@ describe Admin::TypesDeChampController, type: :controller do
describe 'POST #move_up' do describe 'POST #move_up' do
subject { post :move_up, procedure_id: procedure.id, index: index, format: :js } subject { post :move_up, procedure_id: procedure.id, index: index, format: :js }
context 'when procedure have no type de champ' do context 'when procedure have no type de champ' do
let(:index) { 0 } let(:index) { 0 }
let(:procedure) { create(:procedure) }
it { expect(subject.status).to eq(400) } it { expect(subject.status).to eq(400) }
end end
context 'when procedure have only one type de champ' do context 'when procedure have only one type de champ' do
let(:index) { 1 } let(:index) { 1 }
let(:procedure) { create(:procedure) }
let!(:type_de_champ) { create(:type_de_champ, procedure: procedure) } let!(:type_de_champ) { create(:type_de_champ, procedure: procedure) }
it { expect(subject.status).to eq(400) } it { expect(subject.status).to eq(400) }
end end
context 'when procedure have tow type de champs' do context 'when procedure have tow type de champs' do
context 'when index == 0' do context 'when index == 0' do
let(:index) { 0 } let(:index) { 0 }
let(:procedure) { create(:procedure) }
let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure) } let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure) }
let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure) } let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure) }
it { expect(subject.status).to eq(400) } it { expect(subject.status).to eq(400) }
end end
context 'when index > 0' do context 'when index > 0' do
let(:index) { 1 } let(:index) { 1 }
let(:procedure) { create(:procedure) }
let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) }
let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) }
@ -141,9 +161,10 @@ describe Admin::TypesDeChampController, type: :controller do
describe 'POST #move_down' do describe 'POST #move_down' do
let(:request) { post :move_down, procedure_id: procedure.id, index: index, format: :js } let(:request) { post :move_down, procedure_id: procedure.id, index: index, format: :js }
subject { request }
let(:index) { 0 } let(:index) { 0 }
let(:procedure) { create(:procedure) }
subject { request }
context 'when procedure have no type de champ' do context 'when procedure have no type de champ' do
it { expect(subject.status).to eq(400) } it { expect(subject.status).to eq(400) }
end end

View file

@ -1,6 +1,6 @@
require 'spec_helper' require 'spec_helper'
describe FranceConnectController, type: :controller do describe FranceConnect::EntrepriseController, type: :controller do
describe '.login' do describe '.login' do
it 'redirect to france connect serveur' do it 'redirect to france connect serveur' do
@ -26,7 +26,7 @@ describe FranceConnectController, type: :controller do
let(:current_user) { User.find_by_email(email) } let(:current_user) { User.find_by_email(email) }
before do before do
allow(FranceConnectService).to receive(:retrieve_user_informations).and_return(user_info) allow(FranceConnectService).to receive(:retrieve_user_informations_entreprise).and_return(user_info)
get :callback, code: code get :callback, code: code
end end
@ -43,7 +43,7 @@ describe FranceConnectController, type: :controller do
context 'when code is not correct' do context 'when code is not correct' do
before do before do
allow(FranceConnectService).to receive(:retrieve_user_informations) { raise Rack::OAuth2::Client::Error.new(500, error: 'Unknown') } allow(FranceConnectService).to receive(:retrieve_user_informations_entreprise) { raise Rack::OAuth2::Client::Error.new(500, error: 'Unknown') }
get :callback, code: code get :callback, code: code
end end

View file

@ -1,7 +1,7 @@
require 'spec_helper' require 'spec_helper'
describe Users::RecapitulatifController, type: :controller do describe Users::RecapitulatifController, type: :controller do
let(:dossier) { create(:dossier, :with_user) } let(:dossier) { create(:dossier, :with_user, :with_procedure) }
let(:bad_dossier_id) { Dossier.count + 100000 } let(:bad_dossier_id) { Dossier.count + 100000 }
before do before do
@ -55,6 +55,15 @@ describe Users::RecapitulatifController, type: :controller do
it 'a message informe user what his dossier is initiated' do it 'a message informe user what his dossier is initiated' do
expect(flash[:notice]).to include('Dossier déposé avec succès.') expect(flash[:notice]).to include('Dossier déposé avec succès.')
end end
it 'Notification email is send' do
expect(NotificationMailer).to receive(:dossier_submitted).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_now!)
dossier.validated!
post :submit, dossier_id: dossier.id
end
end end
end end

View file

@ -40,7 +40,7 @@ describe Users::SessionsController, type: :controller do
context 'when user is connect with france connect' do context 'when user is connect with france connect' do
it 'redirect to france connect logout page' do it 'redirect to france connect logout page' do
expect(response).to redirect_to(FRANCE_CONNECT.logout_endpoint) expect(response).to redirect_to(FRANCE_CONNECT.entreprise_logout_endpoint)
end end
end end

View file

@ -3,7 +3,7 @@ require 'spec_helper'
feature 'add a new type de champs', js: true do feature 'add a new type de champs', js: true do
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure, administrateur: administrateur) }
before do before do
login_as administrateur, scope: :administrateur login_as administrateur, scope: :administrateur

View file

@ -7,7 +7,7 @@ feature 'move down button type de champs', js: true do
login_as administrateur, scope: :administrateur login_as administrateur, scope: :administrateur
end end
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure, administrateur: administrateur) }
let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) }
let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) }
let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure, order_place: 2) } let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure, order_place: 2) }

View file

@ -7,7 +7,7 @@ feature 'move up button type de champs', js: true do
login_as administrateur, scope: :administrateur login_as administrateur, scope: :administrateur
end end
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure, administrateur: administrateur) }
let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) }
let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) }
let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure, order_place: 2) } let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure, order_place: 2) }

View file

@ -0,0 +1,58 @@
require 'spec_helper'
feature 'procedure locked' do
let(:administrateur) { create(:administrateur) }
let(:procedure) { create(:procedure, administrateur: administrateur) }
before do
login_as administrateur, scope: :administrateur
visit admin_procedure_path(procedure)
end
context 'when procedure have no file' do
scenario 'info label is not present' do
expect(page).not_to have_content('La procédure ne peut plus être modifiée car un usagé a déjà déposé un dossier')
end
end
context 'when procedure have at least a file' do
before do
create(:dossier, :with_user, procedure: procedure, state: :initiated)
visit admin_procedure_path(procedure)
end
scenario 'info label is present' do
expect(page).to have_content('La procédure ne peut plus être modifiée car un usagé a déjà déposé un dossier')
end
context 'when user click on Description tab' do
before do
page.click_on 'Description'
end
scenario 'page doest not change' do
expect(page).to have_css('#procedure_show')
end
end
context 'when user click on Champs tab' do
before do
page.click_on 'Champs'
end
scenario 'page doest not change' do
expect(page).to have_css('#procedure_show')
end
end
context 'when user click on Pieces Justificatiives tab' do
before do
page.click_on 'Pièces justificatives'
end
scenario 'page doest not change' do
expect(page).to have_css('#procedure_show')
end
end
end
end

View file

@ -16,8 +16,8 @@ feature 'France Connect Connexion' do
# #
# context 'when authentification is ok' do # context 'when authentification is ok' do
# before do # before do
# allow_any_instance_of(FranceConnectClient).to receive(:authorization_uri).and_return(france_connect_callback_path(code: code)) # allow_any_instance_of(FranceConnectEntrepriseClient).to receive(:authorization_uri).and_return(france_connect_callback_path(code: code))
# allow(FranceConnectService).to receive(:retrieve_user_informations).and_return(Hashie::Mash.new(email: 'patator@cake.com')) # allow(FranceConnectService).to receive(:retrieve_user_informations_entreprise).and_return(Hashie::Mash.new(email: 'patator@cake.com'))
# page.find_by_id('btn_fc').click # page.find_by_id('btn_fc').click
# end # end
# #
@ -28,8 +28,8 @@ feature 'France Connect Connexion' do
# #
# context 'when authentification is not ok' do # context 'when authentification is not ok' do
# before do # before do
# allow_any_instance_of(FranceConnectClient).to receive(:authorization_uri).and_return(france_connect_callback_path(code: code)) # allow_any_instance_of(FranceConnectEntrepriseClient).to receive(:authorization_uri).and_return(france_connect_callback_path(code: code))
# allow(FranceConnectService).to receive(:retrieve_user_informations) { raise Rack::OAuth2::Client::Error.new(500, error: 'Unknown') } # allow(FranceConnectService).to receive(:retrieve_user_informations_entreprise) { raise Rack::OAuth2::Client::Error.new(500, error: 'Unknown') }
# page.find_by_id('btn_fc').click # page.find_by_id('btn_fc').click
# end # end
# #
@ -55,8 +55,8 @@ feature 'France Connect Connexion' do
# let(:siret) { '00000000000000' } # let(:siret) { '00000000000000' }
# let(:user_infos) { Hashie::Mash.new(email: email, siret: siret) } # let(:user_infos) { Hashie::Mash.new(email: email, siret: siret) }
# before do # before do
# allow_any_instance_of(FranceConnectClient).to receive(:authorization_uri).and_return(france_connect_callback_path(code: code)) # allow_any_instance_of(FranceConnectEntrepriseClient).to receive(:authorization_uri).and_return(france_connect_callback_path(code: code))
# allow(FranceConnectService).to receive(:retrieve_user_informations).and_return(user_infos) # allow(FranceConnectService).to receive(:retrieve_user_informations_entreprise).and_return(user_infos)
# page.find_by_id('btn_fc').click # page.find_by_id('btn_fc').click
# end # end
# context 'when starting page is dossiers list' do # context 'when starting page is dossiers list' do

View file

@ -18,8 +18,20 @@ RSpec.describe NotificationMailer, type: :mailer do
subject(:subject) { described_class.dossier_validated(dossier) } subject(:subject) { described_class.dossier_validated(dossier) }
it { expect(subject.body).to match("Votre dossier N°#{dossier.id} a été validé par votre gestionnaire.") } it { expect(subject.body).to match("Votre dossier N°#{dossier.id} a été validé par votre accompagnateur.") }
it { expect(subject.body).to include("Afin de finaliser son dépot, merci de vous rendre sur #{users_dossier_recapitulatif_url(dossier_id: dossier.id)}") } it { expect(subject.body).to include("Afin de finaliser son dépot, merci de vous rendre sur #{users_dossier_recapitulatif_url(dossier_id: dossier.id)}") }
it { expect(subject.subject).to eq("Votre dossier TPS N°#{dossier.id} a été validé") } it { expect(subject.subject).to eq("Votre dossier TPS N°#{dossier.id} a été validé") }
end end
describe ".dossier_submitted" do
let(:user) { create(:user) }
let(:dossier) { create(:dossier, :with_procedure, user: user) }
subject(:subject) { described_class.dossier_submitted(dossier) }
it { expect(subject.body).to match("Nous vous confirmons que votre dossier N°#{dossier.id} a été déposé") }
it { expect(subject.body).to match("aurpès de #{dossier.procedure.organisation} avec succès") }
it { expect(subject.body).to match("ce jour à #{dossier.updated_at}.") }
it { expect(subject.subject).to eq("Votre dossier TPS N°#{dossier.id} a été déposé") }
end
end end

View file

@ -1,6 +1,6 @@
require 'spec_helper' require 'spec_helper'
describe FranceConnectClient do describe FranceConnectEntrepriseClient do
describe '.initialize' do describe '.initialize' do
it 'create an openid client' do it 'create an openid client' do
expect(described_class).to be < OpenIDConnect::Client expect(described_class).to be < OpenIDConnect::Client

View file

@ -51,7 +51,7 @@ describe Procedure do
describe '#switch_types_de_champ' do describe '#switch_types_de_champ' do
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure) }
let(:index) { 0 } let(:index) { 0 }
subject { procedure.switch_types_de_champ index} subject { procedure.switch_types_de_champ index }
context 'when procedure have no types_de_champ' do context 'when procedure have no types_de_champ' do
it { expect(subject).to eq(false) } it { expect(subject).to eq(false) }
@ -74,5 +74,31 @@ describe Procedure do
it { expect(subject).to eq(false) } it { expect(subject).to eq(false) }
end end
end end
end end
describe 'locked?' do
let(:procedure) { create(:procedure) }
subject { procedure.locked? }
context 'when procedure does not have dossier' do
it { is_expected.to be_falsey }
end
context 'when procedure have dossier with state draft' do
before do
create(:dossier, :with_user, procedure: procedure, state: :draft)
end
it { is_expected.to be_falsey }
end
context 'when procedure have dossier with state initiated' do
before do
create(:dossier, :with_user, procedure: procedure, state: :initiated)
end
it { is_expected.to be_truthy }
end
end
end end

View file

@ -1,7 +1,7 @@
require 'spec_helper' require 'spec_helper'
describe FranceConnectService do describe FranceConnectService do
describe '.retrieve_user_informations' do describe '.retrieve_user_informations_entreprise' do
let(:code) { 'plop' } let(:code) { 'plop' }
let(:access_token) { 'my access_token' } let(:access_token) { 'my access_token' }
@ -10,15 +10,15 @@ describe FranceConnectService do
let(:user_info_hash) { {'email' => email, 'siret' => siret} } let(:user_info_hash) { {'email' => email, 'siret' => siret} }
let(:user_info) { instance_double('OpenIDConnect::ResponseObject::UserInfo', raw_attributes: user_info_hash, email: email) } let(:user_info) { instance_double('OpenIDConnect::ResponseObject::UserInfo', raw_attributes: user_info_hash, email: email) }
subject { described_class.retrieve_user_informations code } subject { described_class.retrieve_user_informations_entreprise code }
before do before do
allow_any_instance_of(FranceConnectClient).to receive(:access_token!).and_return(access_token) allow_any_instance_of(FranceConnectEntrepriseClient).to receive(:access_token!).and_return(access_token)
allow(access_token).to receive(:userinfo!).and_return(user_info) allow(access_token).to receive(:userinfo!).and_return(user_info)
end end
it 'set code for FranceConnectClient' do it 'set code for FranceConnectEntrepriseClient' do
expect_any_instance_of(FranceConnectClient).to receive(:authorization_code=).with(code) expect_any_instance_of(FranceConnectEntrepriseClient).to receive(:authorization_code=).with(code)
described_class.retrieve_user_informations code described_class.retrieve_user_informations_entreprise code
end end
it 'returns user informations in a object' do it 'returns user informations in a object' do

View file

@ -25,7 +25,7 @@ describe 'dossiers/show.html.haml', type: :view do
end end
it "le texte d'information des droits est correct" do it "le texte d'information des droits est correct" do
expect(rendered).to have_content("J'autorise les organismes publics à vérifier les informations de mon entreprise auprès des administrations concernées. Ces informations resteront strictement confidentielles.") expect(rendered).to have_content("J'autorise les décideurs publics à vérifier les informations de mon organisation auprès des administrations concernées. Ces informations resteront strictement confidentielles.")
end end
it "les informations de l'entreprise sont présents" do it "les informations de l'entreprise sont présents" do