Merge branch 'develop' into staging

This commit is contained in:
Xavier J 2016-09-14 16:36:42 +02:00
commit 36cc7c0dbf
22 changed files with 880 additions and 678 deletions

View file

@ -1,9 +1,13 @@
class InvitesController < ApplicationController class InvitesController < ApplicationController
before_action :gestionnaire_or_user?
def create def create
email_sender = current_gestionnaire.email email_sender = @current_devise_profil.email
class_var = @current_devise_profil.class == User ? InviteUser : InviteGestionnaire
user = User.find_by_email(params[:email]) user = User.find_by_email(params[:email])
invite = Invite.create(dossier_id: params[:dossier_id], user: user, email: params[:email].downcase, email_sender: email_sender) invite = class_var.create(dossier_id: params[:dossier_id], user: user, email: params[:email].downcase, email_sender: email_sender)
if invite.valid? if invite.valid?
InviteMailer.invite_user(invite).deliver_now! unless invite.user.nil? InviteMailer.invite_user(invite).deliver_now! unless invite.user.nil?
@ -16,8 +20,17 @@ class InvitesController < ApplicationController
if gestionnaire_signed_in? if gestionnaire_signed_in?
redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id']) redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id'])
# else else
# redirect_to url_for(controller: :recapitulatif, action: :show, dossier_id: params['dossier_id']) redirect_to url_for(controller: 'users/recapitulatif', action: :show, dossier_id: params['dossier_id'])
end end
end end
private
def gestionnaire_or_user?
return redirect_to root_path unless user_signed_in? || gestionnaire_signed_in?
@current_devise_profil = current_user if user_signed_in?
@current_devise_profil = current_gestionnaire if gestionnaire_signed_in?
end
end end

View file

@ -10,8 +10,10 @@ class Users::DossiersController < UsersController
end end
def index def index
cookies[:liste] = params[:liste] || cookies[:liste] || 'a_traiter' liste = params[:liste] || cookies[:liste] || 'a_traiter'
@dossiers_list_facade = DossiersListFacades.new current_user, cookies[:liste] cookies[:liste] = liste
@dossiers_list_facade = DossiersListFacades.new current_user, liste
@dossiers = smart_listing_create :dossiers, @dossiers = smart_listing_create :dossiers,
@dossiers_list_facade.dossiers_to_display, @dossiers_list_facade.dossiers_to_display,

View file

@ -8,7 +8,11 @@ class UsersController < ApplicationController
def current_user_dossier dossier_id=nil def current_user_dossier dossier_id=nil
dossier_id ||= params[:dossier_id] || params[:id] dossier_id ||= params[:dossier_id] || params[:id]
current_user.dossiers.find(dossier_id) dossier = Dossier.find(dossier_id)
return dossier if dossier.owner?(current_user.email) || dossier.invite_by_user?(current_user.email)
raise ActiveRecord::RecordNotFound
end end
def authorized_routes? controller def authorized_routes? controller

View file

@ -24,6 +24,7 @@ class Dossier < ActiveRecord::Base
has_many :cadastres, dependent: :destroy has_many :cadastres, dependent: :destroy
has_many :commentaires, dependent: :destroy has_many :commentaires, dependent: :destroy
has_many :invites, dependent: :destroy has_many :invites, dependent: :destroy
has_many :invites_user, class_name: 'InviteUser', dependent: :destroy
has_many :follows has_many :follows
belongs_to :procedure belongs_to :procedure
@ -307,4 +308,16 @@ class Dossier < ActiveRecord::Base
next_step! 'user', 'submit' next_step! 'user', 'submit'
NotificationMailer.dossier_submitted(self).deliver_now! NotificationMailer.dossier_submitted(self).deliver_now!
end end
def read_only?
validated? || received? || submitted? || closed? || refused? || without_continuation?
end
def owner? email
user.email == email
end
def invite_by_user? email
(invites_user.pluck :email).include? email
end
end end

View file

@ -0,0 +1,3 @@
class InviteGestionnaire < Invite
end

View file

@ -0,0 +1,3 @@
class InviteUser < Invite
end

View file

@ -41,10 +41,10 @@
%br %br
.row{style: 'text-align:right'} .row{style: 'text-align:right'}
- if !@facade.dossier.validated? && !@facade.dossier.received? && !@facade.dossier.submitted? && !@facade.dossier.closed? && !@facade.dossier.refused? && !@facade.dossier.without_continuation? - unless @facade.dossier.read_only?
- if user_signed_in? && (current_user.email == @facade.dossier.user.email) - if user_signed_in? && (@facade.dossier.owner?(current_user.email) || @facade.dossier.invite_by_user?(current_user.email))
- if @facade.procedure.cerfa_flag? || @facade.dossier.types_de_piece_justificative.size > 0 - if @facade.procedure.cerfa_flag? || @facade.dossier.types_de_piece_justificative.size > 0
%a.btn.btn-success{"data-target" => "#UploadPJmodal", %a#maj_pj.btn.btn-success{"data-target" => "#UploadPJmodal",
"data-toggle" => "modal", "data-toggle" => "modal",
:type => "button", :type => "button",
style: 'margin-bottom: 15px; margin-top: -30px'} style: 'margin-bottom: 15px; margin-top: -30px'}
@ -55,12 +55,12 @@
-if @facade.dossier.procedure.module_api_carto.use_api_carto -if @facade.dossier.procedure.module_api_carto.use_api_carto
%a#maj_carte.btn.btn-primary{href: "/users/dossiers/#{@facade.dossier.id}/carte"} %a#maj_carte.btn.btn-primary{href: "/users/dossiers/#{@facade.dossier.id}/carte"}
= 'Modifier ma carte' = 'Modifier la carte'
%a#maj_infos.btn.btn-info{href: "/users/dossiers/#{@facade.dossier.id}/description"} %a#maj_infos.btn.btn-info{href: "/users/dossiers/#{@facade.dossier.id}/description"}
= 'Modifier mon dossier' = 'Modifier le dossier'
-if gestionnaire_signed_in? -if gestionnaire_signed_in?
-if !@facade.dossier.validated? && !@facade.dossier.received? && !@facade.dossier.submitted? && !@facade.dossier.closed? && !@facade.dossier.refused? && !@facade.dossier.without_continuation? -if !@facade.dossier.read_only?
= form_tag(url_for({controller: 'backoffice/dossiers', action: :valid, dossier_id: @facade.dossier.id}), class: 'form-inline', method: 'POST') do = form_tag(url_for({controller: 'backoffice/dossiers', action: :valid, dossier_id: @facade.dossier.id}), class: 'form-inline', method: 'POST') do
%button#action_button.btn.btn-success %button#action_button.btn.btn-success
= 'Valider le dossier' = 'Valider le dossier'

View file

@ -12,7 +12,7 @@
Aucune personne invité Aucune personne invité
.col-md-3.col-lg-3 .col-md-3.col-lg-3
=form_tag backoffice_dossier_invites_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do =form_tag invites_dossier_path(dossier_id: @facade.dossier.id), method: :post, class: 'form-inline' do
=text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation' =text_field_tag :email, '', class: 'form-control', placeholder: 'Envoyer une invitation'
=submit_tag 'Ajouter', class: 'btn btn-success' =submit_tag 'Ajouter', class: 'btn btn-success'

View file

@ -6,10 +6,12 @@
%a{href: "#commentaires_files", 'aria-controls' => "commentaires_files", role: "tab", 'data-toggle' => "tab"} %a{href: "#commentaires_files", 'aria-controls' => "commentaires_files", role: "tab", 'data-toggle' => "tab"}
Fichiers Fichiers
- if gestionnaire_signed_in? - if gestionnaire_signed_in? || @facade.dossier.owner?(current_user.email)
%li{role: "presentation"} %li{role: "presentation"}
%a{href: "#invites", 'aria-controls' => "invites", role: "tab", 'data-toggle' => "tab"} %a{href: "#invites", 'aria-controls' => "invites", role: "tab", 'data-toggle' => "tab"}
Invités Invités
- if gestionnaire_signed_in?
%li{role: "presentation"} %li{role: "presentation"}
%a{href: "#followers", 'aria-controls' => "followers", role: "tab", 'data-toggle' => "tab"} %a{href: "#followers", 'aria-controls' => "followers", role: "tab", 'data-toggle' => "tab"}
Abonnés Abonnés
@ -25,9 +27,10 @@
%div{role: "tabpanel", class: "tab-pane fade", id:"commentaires_files"} %div{role: "tabpanel", class: "tab-pane fade", id:"commentaires_files"}
= render partial: '/dossiers/commentaires_files' = render partial: '/dossiers/commentaires_files'
- if gestionnaire_signed_in? - if gestionnaire_signed_in? || @facade.dossier.owner?(current_user.email)
%div{role: "tabpanel", class: "tab-pane fade", id:"invites"} %div{role: "tabpanel", class: "tab-pane fade", id:"invites"}
= render partial: '/dossiers/invites' = render partial: '/dossiers/invites'
- if gestionnaire_signed_in?
%div{role: "tabpanel", class: "tab-pane fade", id:"followers"} %div{role: "tabpanel", class: "tab-pane fade", id:"followers"}
= render partial: 'followers' = render partial: 'followers'
%div{role: "tabpanel", class: "tab-pane fade", id:"champs_private"} %div{role: "tabpanel", class: "tab-pane fade", id:"champs_private"}

View file

@ -6,9 +6,9 @@
%th.col-md-2.col-lg-2= smart_listing.sortable 'État', 'state' %th.col-md-2.col-lg-2= smart_listing.sortable 'État', 'state'
%th.col-md-2.col-lg-2= smart_listing.sortable 'Date de mise à jour', 'updated_at' %th.col-md-2.col-lg-2= smart_listing.sortable 'Date de mise à jour', 'updated_at'
- @dossiers.each do |dossier| - @dossiers.each do |dossier|
- if dossier.class == Invite - if dossier.kind_of? Invite
-invite = dossier -invite = dossier
-dossier = dossier.dossier.decorate -dossier = invite.dossier.decorate
- else - else
- dossier = dossier.decorate - dossier = dossier.decorate
%tr %tr

View file

@ -1,4 +1,5 @@
Rails.application.routes.draw do Rails.application.routes.draw do
default_url_options protocol: :https
get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/} get "/ping" => "ping#index", :constraints => {:ip => /127.0.0.1/}
@ -140,6 +141,10 @@ Rails.application.routes.draw do
get 'address_point' => 'search#get_address_point' get 'address_point' => 'search#get_address_point'
end end
namespace :invites do
post 'dossier/:dossier_id' => '/invites#create', as: 'dossier'
end
namespace :backoffice do namespace :backoffice do
get 'sign_in' => '/gestionnaires/sessions#new' get 'sign_in' => '/gestionnaires/sessions#new'
get 'dossiers/search' => 'dossiers#search' get 'dossiers/search' => 'dossiers#search'
@ -154,8 +159,6 @@ Rails.application.routes.draw do
post 'without_continuation' => 'dossiers#without_continuation' post 'without_continuation' => 'dossiers#without_continuation'
post 'close' => 'dossiers#close' post 'close' => 'dossiers#close'
post 'invites' => '/invites#create'
put 'follow' => 'dossiers#follow' put 'follow' => 'dossiers#follow'
end end

View file

@ -0,0 +1,5 @@
class AddTypeAttrInInviteTable < ActiveRecord::Migration
def change
add_column :invites, :type, :string, default: 'InviteGestionnaire'
end
end

View file

@ -11,7 +11,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: 20160906134155) do ActiveRecord::Schema.define(version: 20160913093948) 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"
@ -225,6 +225,7 @@ ActiveRecord::Schema.define(version: 20160906134155) do
t.string "email_sender" t.string "email_sender"
t.integer "dossier_id" t.integer "dossier_id"
t.integer "user_id" t.integer "user_id"
t.string "type", default: "InviteGestionnaire"
end end
create_table "mail_templates", force: :cascade do |t| create_table "mail_templates", force: :cascade do |t|

View file

@ -13,7 +13,15 @@ describe InvitesController, type: :controller do
subject { post :create, dossier_id: dossier.id, email: email } subject { post :create, dossier_id: dossier.id, email: email }
it { expect { subject }.to change(Invite, :count).by(1) } it { expect { subject }.to change(InviteGestionnaire, :count).by(1) }
context 'when is a user who is loged' do
before do
sign_in create(:user)
end
it { expect { subject }.to change(InviteGestionnaire, :count).by(1) }
end
context 'when email is assign to an user' do context 'when email is assign to an user' do
let! (:user) { create(:user, email: email) } let! (:user) { create(:user, email: email) }

View file

@ -0,0 +1,43 @@
shared_examples 'current_user_dossier_spec' do
context 'when no dossier_id is filled' do
it { expect { subject.current_user_dossier }.to raise_error }
end
context 'when dossier_id is given as a param' do
context 'when dossier id is valid' do
it 'returns current user dossier' do
expect(subject.current_user_dossier dossier.id).to eq(dossier)
end
end
context 'when dossier id is incorrect' do
it { expect { subject.current_user_dossier 1 }.to raise_error }
end
end
context 'when no params[] is given' do
context 'when dossier id is valid' do
before do
subject.params[:dossier_id] = dossier.id
end
it 'returns current user dossier' do
expect(subject.current_user_dossier).to eq(dossier)
end
end
context 'when dossier id is incorrect' do
it { expect { subject.current_user_dossier }.to raise_error }
end
context 'when dossier_id is given as a param' do
before do
subject.params[:dossier_id] = 1
end
it 'returns dossier with the id on params past' do
expect(subject.current_user_dossier dossier.id).to eq(dossier)
end
end
end
end

View file

@ -0,0 +1,256 @@
shared_examples 'carte_controller_spec' do
describe 'GET #show' do
describe 'before_action authorized_routes?' do
context 'when dossiers procedure have api carto actived' do
context 'when dossier does not have a valid state' do
before do
dossier.state = 'validated'
dossier.save
get :show, dossier_id: dossier.id
end
it { is_expected.to redirect_to root_path}
end
end
context 'when dossiers procedure does not have api carto actived' do
let(:dossier) { create(:dossier) }
before do
get :show, dossier_id: dossier.id
end
it { is_expected.to redirect_to(root_path) }
end
end
context 'user is not connected' do
before do
sign_out user
end
it 'redirects to users/sign_in' do
get :show, dossier_id: dossier.id
expect(response).to redirect_to('/users/sign_in')
end
end
it 'returns http success if carto is activated' do
get :show, dossier_id: dossier.id
expect(response).to have_http_status(:success)
end
context 'when procedure not have activate api carto' do
it 'redirection on user dossier list' do
get :show, dossier_id: dossier_with_no_carto.id
expect(response).to redirect_to(root_path)
end
end
context 'when dossier id not exist' do
it 'redirection on user dossier list' do
get :show, dossier_id: bad_dossier_id
expect(response).to redirect_to(root_path)
end
end
it_behaves_like "not owner of dossier", :show
end
describe 'POST #save' do
context 'Aucune localisation n\'a jamais été enregistrée' do
it do
post :save, dossier_id: dossier.id, json_latlngs: ''
expect(response).to redirect_to("/users/dossiers/#{dossier.id}/description")
end
end
context 'En train de modifier la localisation' do
let(:dossier) { create(:dossier, state: 'initiated') }
before do
post :save, dossier_id: dossier.id, json_latlngs: ''
end
it 'Redirection vers la page récapitulatif' do
expect(response).to redirect_to("/users/dossiers/#{dossier.id}/recapitulatif")
end
end
describe 'Save quartier prioritaire' do
let(:module_api_carto) { create(:module_api_carto, :with_quartiers_prioritaires) }
before do
allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter).
to receive(:to_params).
and_return({"QPCODE1234" => {:code => "QPCODE1234", :nom => "QP de test", :commune => "Paris", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}})
post :save, dossier_id: dossier.id, json_latlngs: json_latlngs
end
context 'when json_latlngs params is empty' do
context 'when dossier have quartier prioritaire in database' do
let!(:dossier) { create(:dossier, :with_two_quartier_prioritaires) }
before do
dossier.reload
end
context 'when value is empty' do
let(:json_latlngs) { '' }
it { expect(dossier.quartier_prioritaires.size).to eq(0) }
end
context 'when value is empty array' do
let(:json_latlngs) { '[]' }
it { expect(dossier.quartier_prioritaires.size).to eq(0) }
end
end
end
context 'when json_latlngs params is informed' do
let(:json_latlngs) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' }
it { expect(dossier.quartier_prioritaires.size).to eq(1) }
describe 'Quartier Prioritaire' do
subject { QuartierPrioritaire.last }
it { expect(subject.code).to eq('QPCODE1234') }
it { expect(subject.commune).to eq('Paris') }
it { expect(subject.nom).to eq('QP de test') }
it { expect(subject.dossier_id).to eq(dossier.id) }
end
end
end
describe 'Save cadastre' do
let(:module_api_carto) { create(:module_api_carto, :with_cadastre) }
before do
allow_any_instance_of(CARTO::SGMAP::Cadastre::Adapter).
to receive(:to_params).
and_return([{:surface_intersection => "0.0006", :surface_parcelle => 11252.692583090324, :numero => "0013", :feuille => 1, :section => "CD", :code_dep => "30", :nom_com => "Le Grau-du-Roi", :code_com => "133", :code_arr => "000", :geometry => {:type => "MultiPolygon", :coordinates => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]]}}])
post :save, dossier_id: dossier.id, json_latlngs: json_latlngs
end
context 'when json_latlngs params is empty' do
context 'when dossier have cadastres in database' do
let!(:dossier) { create(:dossier, :with_two_cadastres) }
before do
dossier.reload
end
context 'when value is empty' do
let(:json_latlngs) { '' }
it { expect(dossier.cadastres.size).to eq(0) }
end
context 'when value is empty array' do
let(:json_latlngs) { '[]' }
it { expect(dossier.cadastres.size).to eq(0) }
end
end
end
context 'when json_latlngs params is informed' do
let(:json_latlngs) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' }
it { expect(dossier.cadastres.size).to eq(1) }
describe 'Cadastre' do
subject { Cadastre.last }
it { expect(subject.surface_intersection).to eq('0.0006') }
it { expect(subject.surface_parcelle).to eq(11252.6925830903) }
it { expect(subject.numero).to eq('0013') }
it { expect(subject.feuille).to eq(1) }
it { expect(subject.section).to eq('CD') }
it { expect(subject.code_dep).to eq('30') }
it { expect(subject.nom_com).to eq('Le Grau-du-Roi') }
it { expect(subject.code_com).to eq('133') }
it { expect(subject.code_arr).to eq('000') }
it { expect(subject.geometry).to eq({"type" => "MultiPolygon", "coordinates" => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]]}) }
end
end
end
end
describe '#get_position' do
context 'Geocodeur renvoie les positions par defaut' do
let(:etablissement) { create(:etablissement, adresse: bad_adresse, numero_voie: 'dzj', type_voie: 'fzjfk', nom_voie: 'hdidjkz', complement_adresse: 'fjef', code_postal: 'fjeiefk', localite: 'zjfkfz') }
let(:dossier) { create(:dossier, etablissement: etablissement) }
before do
stub_request(:get, /http:\/\/api-adresse[.]data[.]gouv[.]fr\/search[?]limit=1&q=/)
.to_return(status: 200, body: '{"query": "babouba", "version": "draft", "licence": "ODbL 1.0", "features": [], "type": "FeatureCollection", "attribution": "BAN"}', headers: {})
get :get_position, dossier_id: dossier.id
end
subject { JSON.parse(response.body) }
it 'on enregistre des coordonnées lat et lon avec les valeurs par defaut' do
expect(subject['lat']).to eq('46.538192')
expect(subject['lon']).to eq('2.428462')
end
end
context 'retour d\'un fichier JSON avec 3 attributs' do
before do
stub_request(:get, "http://api-adresse.data.gouv.fr/search?limit=1&q=#{adresse}")
.to_return(status: 200, body: '{"query": "50 avenue des champs u00e9lysu00e9es Paris 75008", "version": "draft", "licence": "ODbL 1.0", "features": [{"geometry": {"coordinates": [2.306888, 48.870374], "type": "Point"}, "type": "Feature", "properties": {"city": "Paris", "label": "50 Avenue des Champs u00c9lysu00e9es 75008 Paris", "housenumber": "50", "id": "ADRNIVX_0000000270748251", "postcode": "75008", "name": "50 Avenue des Champs u00c9lysu00e9es", "citycode": "75108", "context": "75, u00cele-de-France", "score": 0.9054545454545454, "type": "housenumber"}}], "type": "FeatureCollection", "attribution": "BAN"}', headers: {})
get :get_position, dossier_id: dossier.id
end
subject { JSON.parse(response.body) }
it 'format JSON valide' do
expect(response.content_type).to eq('application/json')
end
it 'latitude' do
expect(subject['lat']).to eq('48.870374')
end
it 'longitude' do
expect(subject['lon']).to eq('2.306888')
end
it 'dossier_id' do
expect(subject['dossier_id']).to eq(dossier.id.to_s)
end
end
end
describe 'POST #get_qp' do
before do
allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter).
to receive(:to_params).
and_return({"QPCODE1234" => {:code => "QPCODE1234", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}})
post :get_qp, dossier_id: dossier.id, coordinates: coordinates
end
context 'when coordinates are empty' do
let(:coordinates) { '[]' }
subject { JSON.parse(response.body) }
it 'Quartier Prioritaire Adapter does not call' do
expect(subject['quartier_prioritaires']).to eq({})
end
end
context 'when coordinates are informed' do
let(:coordinates) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' }
subject { JSON.parse(response.body)['quartier_prioritaires'] }
it { expect(subject).not_to be_nil }
it { expect(subject['QPCODE1234']['code']).to eq('QPCODE1234') }
it { expect(subject['QPCODE1234']['geometry']['type']).to eq('MultiPolygon') }
it { expect(subject['QPCODE1234']['geometry']['coordinates']).to eq([[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]) }
end
end
end

View file

@ -1,4 +1,5 @@
require 'spec_helper' require 'spec_helper'
require 'controllers/users/carte_controller_shared_example'
RSpec.describe Users::CarteController, type: :controller do RSpec.describe Users::CarteController, type: :controller do
let(:bad_adresse) { 'babouba' } let(:bad_adresse) { 'babouba' }
@ -7,6 +8,9 @@ RSpec.describe Users::CarteController, type: :controller do
let(:procedure) { create(:procedure, module_api_carto: module_api_carto) } let(:procedure) { create(:procedure, module_api_carto: module_api_carto) }
let(:dossier) { create(:dossier, procedure: procedure) } let(:dossier) { create(:dossier, procedure: procedure) }
let(:owner_user) { dossier.user }
let(:invite_by_user) { create :user, email: 'invite@plop.com' }
let(:dossier_with_no_carto) { create(:dossier) } let(:dossier_with_no_carto) { create(:dossier) }
let!(:entreprise) { create(:entreprise, dossier: dossier) } let!(:entreprise) { create(:entreprise, dossier: dossier) }
let!(:etablissement) { create(:etablissement, dossier: dossier) } let!(:etablissement) { create(:etablissement, dossier: dossier) }
@ -14,262 +18,20 @@ RSpec.describe Users::CarteController, type: :controller do
let(:adresse) { etablissement.geo_adresse } let(:adresse) { etablissement.geo_adresse }
before do before do
sign_in dossier.user create :invite, dossier: dossier, user: invite_by_user, email: invite_by_user.email, type: 'InviteUser'
sign_in user
end end
describe 'GET #show' do context 'when sign in user is the owner' do
let(:user) { owner_user }
describe 'before_action authorized_routes?' do it_should_behave_like "carte_controller_spec"
context 'when dossiers procedure have api carto actived' do
context 'when dossier does not have a valid state' do
before do
dossier.state = 'validated'
dossier.save
get :show, dossier_id: dossier.id
end end
it { is_expected.to redirect_to root_path} context 'when sign in user is an invite by owner' do
end let(:user) { invite_by_user }
end
context 'when dossiers procedure does not have api carto actived' do it_should_behave_like "carte_controller_spec"
let(:dossier) { create(:dossier) }
before do
get :show, dossier_id: dossier.id
end
it { is_expected.to redirect_to(root_path) }
end
end
context 'user is not connected' do
before do
sign_out dossier.user
end
it 'redirects to users/sign_in' do
get :show, dossier_id: dossier.id
expect(response).to redirect_to('/users/sign_in')
end
end
it 'returns http success if carto is activated' do
get :show, dossier_id: dossier.id
expect(response).to have_http_status(:success)
end
context 'when procedure not have activate api carto' do
it 'redirection on user dossier list' do
get :show, dossier_id: dossier_with_no_carto.id
expect(response).to redirect_to(root_path)
end
end
context 'when dossier id not exist' do
it 'redirection on user dossier list' do
get :show, dossier_id: bad_dossier_id
expect(response).to redirect_to(root_path)
end
end
it_behaves_like "not owner of dossier", :show
end
describe 'POST #save' do
context 'Aucune localisation n\'a jamais été enregistrée' do
it do
post :save, dossier_id: dossier.id, json_latlngs: ''
expect(response).to redirect_to("/users/dossiers/#{dossier.id}/description")
end
end
context 'En train de modifier la localisation' do
let(:dossier) { create(:dossier, state: 'initiated') }
before do
post :save, dossier_id: dossier.id, json_latlngs: ''
end
it 'Redirection vers la page récapitulatif' do
expect(response).to redirect_to("/users/dossiers/#{dossier.id}/recapitulatif")
end
end
describe 'Save quartier prioritaire' do
let(:module_api_carto) { create(:module_api_carto, :with_quartiers_prioritaires) }
before do
allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter).
to receive(:to_params).
and_return({"QPCODE1234" => {:code => "QPCODE1234", :nom => "QP de test", :commune => "Paris", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}})
post :save, dossier_id: dossier.id, json_latlngs: json_latlngs
end
context 'when json_latlngs params is empty' do
context 'when dossier have quartier prioritaire in database' do
let!(:dossier) { create(:dossier, :with_two_quartier_prioritaires) }
before do
dossier.reload
end
context 'when value is empty' do
let(:json_latlngs) { '' }
it { expect(dossier.quartier_prioritaires.size).to eq(0) }
end
context 'when value is empty array' do
let(:json_latlngs) { '[]' }
it { expect(dossier.quartier_prioritaires.size).to eq(0) }
end
end
end
context 'when json_latlngs params is informed' do
let(:json_latlngs) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' }
it { expect(dossier.quartier_prioritaires.size).to eq(1) }
describe 'Quartier Prioritaire' do
subject { QuartierPrioritaire.last }
it { expect(subject.code).to eq('QPCODE1234') }
it { expect(subject.commune).to eq('Paris') }
it { expect(subject.nom).to eq('QP de test') }
it { expect(subject.dossier_id).to eq(dossier.id) }
end
end
end
describe 'Save cadastre' do
let(:module_api_carto) { create(:module_api_carto, :with_cadastre) }
before do
allow_any_instance_of(CARTO::SGMAP::Cadastre::Adapter).
to receive(:to_params).
and_return([{:surface_intersection => "0.0006", :surface_parcelle => 11252.692583090324, :numero => "0013", :feuille => 1, :section => "CD", :code_dep => "30", :nom_com => "Le Grau-du-Roi", :code_com => "133", :code_arr => "000", :geometry => {:type => "MultiPolygon", :coordinates => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]]}}])
post :save, dossier_id: dossier.id, json_latlngs: json_latlngs
end
context 'when json_latlngs params is empty' do
context 'when dossier have cadastres in database' do
let!(:dossier) { create(:dossier, :with_two_cadastres) }
before do
dossier.reload
end
context 'when value is empty' do
let(:json_latlngs) { '' }
it { expect(dossier.cadastres.size).to eq(0) }
end
context 'when value is empty array' do
let(:json_latlngs) { '[]' }
it { expect(dossier.cadastres.size).to eq(0) }
end
end
end
context 'when json_latlngs params is informed' do
let(:json_latlngs) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' }
it { expect(dossier.cadastres.size).to eq(1) }
describe 'Cadastre' do
subject { Cadastre.last }
it { expect(subject.surface_intersection).to eq('0.0006') }
it { expect(subject.surface_parcelle).to eq(11252.6925830903) }
it { expect(subject.numero).to eq('0013') }
it { expect(subject.feuille).to eq(1) }
it { expect(subject.section).to eq('CD') }
it { expect(subject.code_dep).to eq('30') }
it { expect(subject.nom_com).to eq('Le Grau-du-Roi') }
it { expect(subject.code_com).to eq('133') }
it { expect(subject.code_arr).to eq('000') }
it { expect(subject.geometry).to eq({"type" => "MultiPolygon", "coordinates" => [[[[4.134084, 43.5209193], [4.1346615, 43.5212035], [4.1346984, 43.521189], [4.135096, 43.5213848], [4.1350839, 43.5214122], [4.1352697, 43.521505], [4.1356278, 43.5211065], [4.1357402, 43.5207188], [4.1350935, 43.5203936], [4.135002, 43.5204366], [4.1346051, 43.5202412], [4.134584, 43.5202472], [4.1345572, 43.5202551], [4.134356, 43.5203137], [4.1342488, 43.5203448], [4.134084, 43.5209193]]]]}) }
end
end
end
end
describe '#get_position' do
context 'Geocodeur renvoie les positions par defaut' do
let(:etablissement) { create(:etablissement, adresse: bad_adresse, numero_voie: 'dzj', type_voie: 'fzjfk', nom_voie: 'hdidjkz', complement_adresse: 'fjef', code_postal: 'fjeiefk', localite: 'zjfkfz') }
let(:dossier) { create(:dossier, etablissement: etablissement) }
before do
stub_request(:get, /http:\/\/api-adresse[.]data[.]gouv[.]fr\/search[?]limit=1&q=/)
.to_return(status: 200, body: '{"query": "babouba", "version": "draft", "licence": "ODbL 1.0", "features": [], "type": "FeatureCollection", "attribution": "BAN"}', headers: {})
get :get_position, dossier_id: dossier.id
end
subject { JSON.parse(response.body) }
it 'on enregistre des coordonnées lat et lon avec les valeurs par defaut' do
expect(subject['lat']).to eq('46.538192')
expect(subject['lon']).to eq('2.428462')
end
end
context 'retour d\'un fichier JSON avec 3 attributs' do
before do
stub_request(:get, "http://api-adresse.data.gouv.fr/search?limit=1&q=#{adresse}")
.to_return(status: 200, body: '{"query": "50 avenue des champs u00e9lysu00e9es Paris 75008", "version": "draft", "licence": "ODbL 1.0", "features": [{"geometry": {"coordinates": [2.306888, 48.870374], "type": "Point"}, "type": "Feature", "properties": {"city": "Paris", "label": "50 Avenue des Champs u00c9lysu00e9es 75008 Paris", "housenumber": "50", "id": "ADRNIVX_0000000270748251", "postcode": "75008", "name": "50 Avenue des Champs u00c9lysu00e9es", "citycode": "75108", "context": "75, u00cele-de-France", "score": 0.9054545454545454, "type": "housenumber"}}], "type": "FeatureCollection", "attribution": "BAN"}', headers: {})
get :get_position, dossier_id: dossier.id
end
subject { JSON.parse(response.body) }
it 'format JSON valide' do
expect(response.content_type).to eq('application/json')
end
it 'latitude' do
expect(subject['lat']).to eq('48.870374')
end
it 'longitude' do
expect(subject['lon']).to eq('2.306888')
end
it 'dossier_id' do
expect(subject['dossier_id']).to eq(dossier.id.to_s)
end
end
end
describe 'POST #get_qp' do
before do
allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter).
to receive(:to_params).
and_return({"QPCODE1234" => {:code => "QPCODE1234", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}})
post :get_qp, dossier_id: dossier.id, coordinates: coordinates
end
context 'when coordinates are empty' do
let(:coordinates) { '[]' }
subject { JSON.parse(response.body) }
it 'Quartier Prioritaire Adapter does not call' do
expect(subject['quartier_prioritaires']).to eq({})
end
end
context 'when coordinates are informed' do
let(:coordinates) { '[[{"lat":48.87442541960633,"lng":2.3859214782714844},{"lat":48.87273183590832,"lng":2.3850631713867183},{"lat":48.87081237174292,"lng":2.3809432983398438},{"lat":48.8712640169951,"lng":2.377510070800781},{"lat":48.87510283703279,"lng":2.3778533935546875},{"lat":48.87544154230615,"lng":2.382831573486328},{"lat":48.87442541960633,"lng":2.3859214782714844}]]' }
subject { JSON.parse(response.body)['quartier_prioritaires'] }
it { expect(subject).not_to be_nil }
it { expect(subject['QPCODE1234']['code']).to eq('QPCODE1234') }
it { expect(subject['QPCODE1234']['geometry']['type']).to eq('MultiPolygon') }
it { expect(subject['QPCODE1234']['geometry']['coordinates']).to eq([[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]) }
end
end end
end end

View file

@ -0,0 +1,345 @@
shared_examples 'description_controller_spec' do
describe 'GET #show' do
context 'user is not connected' do
before do
sign_out dossier.user
end
it 'redirects to users/sign_in' do
get :show, dossier_id: dossier_id
expect(response).to redirect_to('/users/sign_in')
end
end
it 'returns http success' do
get :show, dossier_id: dossier_id
expect(response).to have_http_status(:success)
end
it 'redirection vers start si mauvais dossier ID' do
get :show, dossier_id: bad_dossier_id
expect(response).to redirect_to(root_path)
end
it_behaves_like "not owner of dossier", :show
describe 'before_action authorized_routes?' do
context 'when dossier does not have a valid state' do
before do
dossier.state = 'validated'
dossier.save
get :show, dossier_id: dossier.id
end
it { is_expected.to redirect_to root_path }
end
end
end
describe 'POST #create' do
let(:timestamp) { Time.now }
let(:description) { 'Description de test Coucou, je suis un saut à la ligne Je suis un double saut la ligne.' }
context 'Tous les attributs sont bons' do
describe 'Premier enregistrement des données' do
before do
dossier.draft!
post :create, dossier_id: dossier_id
dossier.reload
end
it "redirection vers la page recapitulative" do
expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif")
end
it 'etat du dossier est soumis' do
expect(dossier.state).to eq('initiated')
end
end
context 'En train de manipuler un dossier non brouillon' do
before do
dossier.initiated!
post :create, dossier_id: dossier_id
dossier.reload
end
it 'Redirection vers la page récapitulatif' do
expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif")
end
it 'etat du dossier n\'est pas soumis' do
expect(dossier.state).not_to eq('draft')
end
end
end
context 'Quand la procédure accepte les CERFA' do
context 'Sauvegarde du CERFA PDF', vcr: {cassette_name: 'controllers_users_description_controller_save_cerfa'} do
before do
post :create, dossier_id: dossier_id,
cerfa_pdf: cerfa_pdf
dossier.reload
end
context 'when a CERFA PDF is sent', vcr: {cassette_name: 'controllers_users_description_controller_cerfa_is_sent'} do
subject { dossier.cerfa.first }
it 'content' do
if Features.remote_storage
expect(subject['content']).to eq('cerfa-3dbb3535-5388-4a37-bc2d-778327b9f999.pdf')
else
expect(subject['content']).to eq('cerfa.pdf')
end
end
it 'dossier_id' do
expect(subject.dossier_id).to eq(dossier_id)
end
it { expect(subject.user).to eq user }
end
context 'les anciens CERFA PDF ne sont pas écrasées' do
let(:cerfas) { Cerfa.where(dossier_id: dossier_id) }
before do
post :create, dossier_id: dossier_id, cerfa_pdf: cerfa_pdf
end
it "il y a deux CERFA PDF pour ce dossier" do
expect(cerfas.size).to eq 2
end
end
end
end
context 'Quand la procédure n\'accepte pas les CERFA' do
context 'Sauvegarde du CERFA PDF' do
let!(:procedure) { create(:procedure) }
before do
post :create, dossier_id: dossier_id,
cerfa_pdf: cerfa_pdf
dossier.reload
end
context 'un CERFA PDF est envoyé' do
it { expect(dossier.cerfa_available?).to be_falsey }
end
end
end
describe 'Sauvegarde des champs' do
let(:champs_dossier) { dossier.champs }
let(:dossier_champs_first) { 'test value' }
let(:dossier_date_value) { '23/06/2016' }
let(:dossier_hour_value) { '17' }
let(:dossier_minute_value) { '00' }
before do
post :create, {dossier_id: dossier_id,
champs: {
"'#{dossier.champs.first.id}'" => dossier_champs_first,
"'#{dossier.champs.second.id}'" => dossier_date_value
},
time_hour: {
"'#{dossier.champs.second.id}'" => dossier_hour_value,
},
time_minute: {
"'#{dossier.champs.second.id}'" => dossier_minute_value,
}
}
dossier.reload
end
it { expect(dossier.champs.first.value).to eq(dossier_champs_first) }
it { expect(response).to redirect_to users_dossier_recapitulatif_path }
context 'when champs is type_de_champ datetime' do
it { expect(dossier.champs.second.value).to eq(dossier_date_value+' '+dossier_hour_value+':'+dossier_minute_value) }
end
context 'when champs value is empty' do
let(:dossier_champs_first) { '' }
it { expect(dossier.champs.first.value).to eq(dossier_champs_first) }
it { expect(response).to redirect_to users_dossier_recapitulatif_path }
context 'when champs is mandatory' do
let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ_mandatory, :with_datetime, cerfa_flag: true) }
it { expect(response).not_to redirect_to users_dossier_recapitulatif_path }
it { expect(flash[:alert]).to be_present }
end
end
end
context 'Sauvegarde des pièces justificatives', vcr: {cassette_name: 'controllers_users_description_controller_sauvegarde_pj'} do
let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids }
before do
post :create, {dossier_id: dossier_id,
'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0,
'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1}
dossier.reload
end
describe 'clamav anti-virus presence', vcr: {cassette_name: 'controllers_users_description_controller_clamav_presence'} do
it 'ClamavService safe_file? is call' do
expect(ClamavService).to receive(:safe_file?).twice
post :create, {dossier_id: dossier_id,
'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0,
'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1}
end
end
context 'for piece 0' do
subject { dossier.retrieve_last_piece_justificative_by_type all_pj_type[0].to_s }
it { expect(subject.content).not_to be_nil }
it { expect(subject.user).to eq user }
end
context 'for piece 1' do
subject { dossier.retrieve_last_piece_justificative_by_type all_pj_type[1].to_s }
it { expect(subject.content).not_to be_nil }
it { expect(subject.user).to eq user }
end
end
end
describe 'POST #pieces_justificatives', vcr: {cassette_name: 'controllers_users_description_controller_pieces_justificatives'} do
let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids }
subject { patch :pieces_justificatives, {dossier_id: dossier.id,
'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0,
'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} }
context 'when user is a guest' do
let(:guest) { create :user }
before do
create :invite, dossier: dossier, email: guest.email, user: guest
sign_in guest
end
context 'when PJ have no documents' do
it { expect(dossier.pieces_justificatives.size).to eq 0 }
context 'when upload two PJ' do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 2 }
it { expect(flash[:notice]).to be_present }
it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) }
end
end
context 'when PJ have already a document' do
before do
create :piece_justificative, :rib, dossier: dossier, type_de_piece_justificative_id: all_pj_type[0]
create :piece_justificative, :contrat, dossier: dossier, type_de_piece_justificative_id: all_pj_type[1]
end
it { expect(dossier.pieces_justificatives.size).to eq 2 }
context 'when upload two PJ', vcr: {cassette_name: 'controllers_users_description_controller_upload_2pj'} do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 4 }
it { expect(flash[:notice]).to be_present }
it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) }
end
end
context 'when one of PJs is not valid' do
let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/entreprise.json", 'application/json') }
it { expect(dossier.pieces_justificatives.size).to eq 0 }
context 'when upload two PJ' do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 1 }
it { expect(flash[:alert]).to be_present }
it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) }
end
end
end
end
end
shared_examples 'description_controller_spec_POST_piece_justificatives_for_owner' do
let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids }
subject { patch :pieces_justificatives, {dossier_id: dossier.id,
'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0,
'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} }
context 'when user is the owner' do
before do
sign_in user
end
context 'when PJ have no documents' do
it { expect(dossier.pieces_justificatives.size).to eq 0 }
context 'when upload two PJ' do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 2 }
it { expect(flash[:notice]).to be_present }
it { is_expected.to redirect_to recapitulatif_path }
end
end
context 'when PJ have already a document', vcr: {cassette_name: 'controllers_users_description_controller_pj_already_exist'} do
before do
create :piece_justificative, :rib, dossier: dossier, type_de_piece_justificative_id: all_pj_type[0]
create :piece_justificative, :contrat, dossier: dossier, type_de_piece_justificative_id: all_pj_type[1]
end
it { expect(dossier.pieces_justificatives.size).to eq 2 }
context 'when upload two PJ', vcr: {cassette_name: 'controllers_users_description_controller_pj_already_exist_upload_2pj'} do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 4 }
it { expect(flash[:notice]).to be_present }
it { is_expected.to redirect_to recapitulatif_path }
end
end
context 'when one of PJs is not valid' do
let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/entreprise.json", 'application/json') }
it { expect(dossier.pieces_justificatives.size).to eq 0 }
context 'when upload two PJ' do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 1 }
it { expect(flash[:alert]).to be_present }
it { is_expected.to redirect_to recapitulatif_path }
end
end
end
end

View file

@ -1,10 +1,13 @@
require 'spec_helper' require 'spec_helper'
require 'controllers/users/description_controller_shared_example'
describe Users::DescriptionController, type: :controller, vcr: {cassette_name: 'controllers_users_description_controller'} do describe Users::DescriptionController, type: :controller, vcr: {cassette_name: 'controllers_users_description_controller'} do
let(:user) { create(:user) } let(:owner_user) { create(:user) }
let(:invite_by_user) { create :user, email: 'invite@plop.com' }
let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, :with_datetime, cerfa_flag: true) } let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, :with_datetime, cerfa_flag: true) }
let(:dossier) { create(:dossier, procedure: procedure, user: user) } let(:dossier) { create(:dossier, procedure: procedure, user: owner_user) }
let(:dossier_id) { dossier.id } let(:dossier_id) { dossier.id }
let(:bad_dossier_id) { Dossier.count + 10000 } let(:bad_dossier_id) { Dossier.count + 10000 }
@ -20,342 +23,23 @@ describe Users::DescriptionController, type: :controller, vcr: {cassette_name: '
before do before do
allow(ClamavService).to receive(:safe_file?).and_return(true) allow(ClamavService).to receive(:safe_file?).and_return(true)
sign_in dossier.user create :invite, dossier: dossier, user: invite_by_user, email: invite_by_user.email, type: 'InviteUser'
end
describe 'GET #show' do
context 'user is not connected' do
before do
sign_out dossier.user
end
it 'redirects to users/sign_in' do
get :show, dossier_id: dossier_id
expect(response).to redirect_to('/users/sign_in')
end
end
it 'returns http success' do
get :show, dossier_id: dossier_id
expect(response).to have_http_status(:success)
end
it 'redirection vers start si mauvais dossier ID' do
get :show, dossier_id: bad_dossier_id
expect(response).to redirect_to(root_path)
end
it_behaves_like "not owner of dossier", :show
describe 'before_action authorized_routes?' do
context 'when dossier does not have a valid state' do
before do
dossier.state = 'validated'
dossier.save
get :show, dossier_id: dossier.id
end
it { is_expected.to redirect_to root_path }
end
end
end
describe 'POST #create' do
let(:timestamp) { Time.now }
let(:description) { 'Description de test Coucou, je suis un saut à la ligne Je suis un double saut la ligne.' }
context 'Tous les attributs sont bons' do
describe 'Premier enregistrement des données' do
before do
dossier.draft!
post :create, dossier_id: dossier_id
dossier.reload
end
it "redirection vers la page recapitulative" do
expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif")
end
it 'etat du dossier est soumis' do
expect(dossier.state).to eq('initiated')
end
end
context 'En train de manipuler un dossier non brouillon' do
before do
dossier.initiated!
post :create, dossier_id: dossier_id
dossier.reload
end
it 'Redirection vers la page récapitulatif' do
expect(response).to redirect_to("/users/dossiers/#{dossier_id}/recapitulatif")
end
it 'etat du dossier n\'est pas soumis' do
expect(dossier.state).not_to eq('draft')
end
end
end
context 'Quand la procédure accepte les CERFA' do
context 'Sauvegarde du CERFA PDF', vcr: {cassette_name: 'controllers_users_description_controller_save_cerfa'} do
before do
post :create, dossier_id: dossier_id,
cerfa_pdf: cerfa_pdf
dossier.reload
end
context 'when a CERFA PDF is sent', vcr: {cassette_name: 'controllers_users_description_controller_cerfa_is_sent'} do
subject { dossier.cerfa.first }
it 'content' do
if Features.remote_storage
expect(subject['content']).to eq('cerfa-3dbb3535-5388-4a37-bc2d-778327b9f999.pdf')
else
expect(subject['content']).to eq('cerfa.pdf')
end
end
it 'dossier_id' do
expect(subject.dossier_id).to eq(dossier_id)
end
it { expect(subject.user).to eq user }
end
context 'les anciens CERFA PDF ne sont pas écrasées' do
let(:cerfas) { Cerfa.where(dossier_id: dossier_id) }
before do
post :create, dossier_id: dossier_id, cerfa_pdf: cerfa_pdf
end
it "il y a deux CERFA PDF pour ce dossier" do
expect(cerfas.size).to eq 2
end
end
end
end
context 'Quand la procédure n\'accepte pas les CERFA' do
context 'Sauvegarde du CERFA PDF' do
let!(:procedure) { create(:procedure) }
before do
post :create, dossier_id: dossier_id,
cerfa_pdf: cerfa_pdf
dossier.reload
end
context 'un CERFA PDF est envoyé' do
it { expect(dossier.cerfa_available?).to be_falsey }
end
end
end
describe 'Sauvegarde des champs' do
let(:champs_dossier) { dossier.champs }
let(:dossier_champs_first) { 'test value' }
let(:dossier_date_value) { '23/06/2016' }
let(:dossier_hour_value) { '17' }
let(:dossier_minute_value) { '00' }
before do
post :create, {dossier_id: dossier_id,
champs: {
"'#{dossier.champs.first.id}'" => dossier_champs_first,
"'#{dossier.champs.second.id}'" => dossier_date_value
},
time_hour: {
"'#{dossier.champs.second.id}'" => dossier_hour_value,
},
time_minute: {
"'#{dossier.champs.second.id}'" => dossier_minute_value,
}
}
dossier.reload
end
it { expect(dossier.champs.first.value).to eq(dossier_champs_first) }
it { expect(response).to redirect_to users_dossier_recapitulatif_path }
context 'when champs is type_de_champ datetime' do
it { expect(dossier.champs.second.value).to eq(dossier_date_value+' '+dossier_hour_value+':'+dossier_minute_value) }
end
context 'when champs value is empty' do
let(:dossier_champs_first) { '' }
it { expect(dossier.champs.first.value).to eq(dossier_champs_first) }
it { expect(response).to redirect_to users_dossier_recapitulatif_path }
context 'when champs is mandatory' do
let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ_mandatory, :with_datetime, cerfa_flag: true) }
it { expect(response).not_to redirect_to users_dossier_recapitulatif_path }
it { expect(flash[:alert]).to be_present }
end
end
end
context 'Sauvegarde des pièces justificatives', vcr: {cassette_name: 'controllers_users_description_controller_sauvegarde_pj'} do
let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids }
before do
post :create, {dossier_id: dossier_id,
'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0,
'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1}
dossier.reload
end
describe 'clamav anti-virus presence', vcr: {cassette_name: 'controllers_users_description_controller_clamav_presence'} do
it 'ClamavService safe_file? is call' do
expect(ClamavService).to receive(:safe_file?).twice
post :create, {dossier_id: dossier_id,
'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0,
'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1}
end
end
context 'for piece 0' do
subject { dossier.retrieve_last_piece_justificative_by_type all_pj_type[0].to_s }
it { expect(subject.content).not_to be_nil }
it { expect(subject.user).to eq user }
end
context 'for piece 1' do
subject { dossier.retrieve_last_piece_justificative_by_type all_pj_type[1].to_s }
it { expect(subject.content).not_to be_nil }
it { expect(subject.user).to eq user }
end
end
end
describe 'POST #pieces_justificatives', vcr: {cassette_name: 'controllers_users_description_controller_pieces_justificatives'} do
let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids }
subject { patch :pieces_justificatives, {dossier_id: dossier.id,
'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0,
'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} }
context 'when user is the owner' do
before do
sign_in user sign_in user
end end
context 'when PJ have no documents' do context 'when sign in user is the owner' do
it { expect(dossier.pieces_justificatives.size).to eq 0 } let(:user) { owner_user }
let(:recapitulatif_path) { users_dossier_recapitulatif_path }
context 'when upload two PJ' do it_should_behave_like "description_controller_spec"
before do it_should_behave_like "description_controller_spec_POST_piece_justificatives_for_owner"
subject
dossier.reload
end end
it { expect(dossier.pieces_justificatives.size).to eq 2 } context 'when sign in user is an invite by owner' do
it { expect(flash[:notice]).to be_present } let(:user) { invite_by_user }
it { is_expected.to redirect_to users_dossier_recapitulatif_path } let(:recapitulatif_path) { users_dossiers_invite_path(id: dossier_id) }
end
end
context 'when PJ have already a document', vcr: {cassette_name: 'controllers_users_description_controller_pj_already_exist'} do it_should_behave_like "description_controller_spec"
before do
create :piece_justificative, :rib, dossier: dossier, type_de_piece_justificative_id: all_pj_type[0]
create :piece_justificative, :contrat, dossier: dossier, type_de_piece_justificative_id: all_pj_type[1]
end
it { expect(dossier.pieces_justificatives.size).to eq 2 }
context 'when upload two PJ', vcr: {cassette_name: 'controllers_users_description_controller_pj_already_exist_upload_2pj'} do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 4 }
it { expect(flash[:notice]).to be_present }
it { is_expected.to redirect_to users_dossier_recapitulatif_path }
end
end
context 'when one of PJs is not valid' do
let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/entreprise.json", 'application/json') }
it { expect(dossier.pieces_justificatives.size).to eq 0 }
context 'when upload two PJ' do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 1 }
it { expect(flash[:alert]).to be_present }
it { is_expected.to redirect_to users_dossier_recapitulatif_path }
end
end
end
context 'when user is a guest' do
let(:guest) { create :user }
before do
create :invite, dossier: dossier, email: guest.email, user: guest
sign_in guest
end
context 'when PJ have no documents' do
it { expect(dossier.pieces_justificatives.size).to eq 0 }
context 'when upload two PJ' do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 2 }
it { expect(flash[:notice]).to be_present }
it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) }
end
end
context 'when PJ have already a document' do
before do
create :piece_justificative, :rib, dossier: dossier, type_de_piece_justificative_id: all_pj_type[0]
create :piece_justificative, :contrat, dossier: dossier, type_de_piece_justificative_id: all_pj_type[1]
end
it { expect(dossier.pieces_justificatives.size).to eq 2 }
context 'when upload two PJ', vcr: {cassette_name: 'controllers_users_description_controller_upload_2pj'} do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 4 }
it { expect(flash[:notice]).to be_present }
it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) }
end
end
context 'when one of PJs is not valid' do
let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/entreprise.json", 'application/json') }
it { expect(dossier.pieces_justificatives.size).to eq 0 }
context 'when upload two PJ' do
before do
subject
dossier.reload
end
it { expect(dossier.pieces_justificatives.size).to eq 1 }
it { expect(flash[:alert]).to be_present }
it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) }
end
end
end
end end
end end

View file

@ -1,55 +1,31 @@
require 'spec_helper' require 'spec_helper'
require 'controllers/user_controller_shared_example'
describe UsersController, type: :controller do describe UsersController, type: :controller do
describe '#current_user_dossier' do describe '#current_user_dossier' do
let(:user) { create(:user) } let(:owner_user) { create(:user) }
let(:dossier) { create(:dossier, user: user)} let(:invite_user) { create :user, email: 'invite@plop.com' }
let(:not_invite_user) { create :user, email: 'not_invite@plop.com' }
let(:dossier) { create(:dossier, user: owner_user) }
context 'when user is the owner' do
before do before do
sign_in user sign_in owner_user
end end
context 'when no dossier_id is filled' do it_should_behave_like "current_user_dossier_spec"
it { expect{ subject.current_user_dossier }.to raise_error }
end end
context 'when dossier_id is given as a param' do context 'when user is invite by the owner' do
context 'when dossier id is valid' do
it 'returns current user dossier' do
expect(subject.current_user_dossier dossier.id).to eq(dossier)
end
end
context 'when dossier id is incorrect' do
it { expect{ subject.current_user_dossier 1 }.to raise_error }
end
end
context 'when no params[] is given' do
context 'when dossier id is valid' do
before do before do
subject.params[:dossier_id] = dossier.id create :invite, email: invite_user.email, dossier: dossier, user: invite_user, type: 'InviteUser'
sign_in invite_user
end end
it 'returns current user dossier' do it_should_behave_like "current_user_dossier_spec"
expect(subject.current_user_dossier).to eq(dossier) end
end end
end end
context 'when dossier id is incorrect' do
it { expect{ subject.current_user_dossier }.to raise_error }
end
context 'when dossier_id is given as a param' do
before do
subject.params[:dossier_id] = 1
end
it 'returns dossier with the id on params past' do
expect(subject.current_user_dossier dossier.id).to eq(dossier)
end
end
end
end
end

View file

@ -829,4 +829,31 @@ describe Dossier do
it { expect(subject).to eq 2 } it { expect(subject).to eq 2 }
end end
end end
describe '#invite_by_user?' do
let(:dossier) { create :dossier }
let(:invite_user) { create :user, email: user_invite_email }
let(:invite_gestionnaire) { create :user, email: gestionnaire_invite_email }
let(:user_invite_email) { 'plup@plop.com' }
let(:gestionnaire_invite_email) { 'plap@plip.com' }
before do
create :invite, dossier: dossier, user: invite_user, email: invite_user.email, type: 'InviteUser'
create :invite, dossier: dossier, user: invite_gestionnaire, email: invite_gestionnaire.email, type: 'InviteGestionnaire'
end
subject { dossier.invite_by_user? email }
context 'when email is present on invite list' do
let(:email) { user_invite_email }
it { is_expected.to be_truthy }
end
context 'when email is present on invite list' do
let(:email) { gestionnaire_invite_email }
it { is_expected.to be_falsey }
end
end
end end

View file

@ -40,6 +40,12 @@ describe 'users/recapitulatif/show.html.haml', type: :view do
end end
end end
context 'lien carte' do
it 'le lien vers carte est présent' do
expect(rendered).to have_css('#maj_pj')
end
end
context 'lien carte' do context 'lien carte' do
it 'le lien vers carte est présent' do it 'le lien vers carte est présent' do
expect(rendered).to have_css('#maj_carte') expect(rendered).to have_css('#maj_carte')
@ -169,14 +175,14 @@ describe 'users/recapitulatif/show.html.haml', type: :view do
end end
context 'when invite is logged' do context 'when invite is logged' do
context 'when invite is by Gestionnaire' do
let!(:invite_user) { create(:user, email: 'invite@octo.com') } let!(:invite_user) { create(:user, email: 'invite@octo.com') }
before do before do
create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier) } create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier) }
sign_out dossier.user sign_out dossier.user
sign_in invite_user sign_in invite_user
render render
end end
@ -189,6 +195,10 @@ describe 'users/recapitulatif/show.html.haml', type: :view do
expect(rendered).not_to have_css('#maj_carte') expect(rendered).not_to have_css('#maj_carte')
end end
it 'PJ link is not present' do
expect(rendered).not_to have_css('#maj_pj')
end
it 'archive link is not present' do it 'archive link is not present' do
expect(rendered).not_to have_content('Archiver') expect(rendered).not_to have_content('Archiver')
end end
@ -205,7 +215,48 @@ describe 'users/recapitulatif/show.html.haml', type: :view do
expect(rendered).not_to have_content('Déposer mon dossier') expect(rendered).not_to have_content('Déposer mon dossier')
end end
end end
end
context 'invite is by User' do
let!(:invite_user) { create(:user, email: 'invite@octo.com') }
before do
create(:invite) { create(:invite, email: invite_user.email, user: invite_user, dossier: dossier, type: 'InviteUser') }
sign_out dossier.user
sign_in invite_user
render
end
describe 'les liens de modifications' do
it 'describe link is not present' do
expect(rendered).to have_css('#maj_infos')
end
it 'map link is present' do
expect(rendered).to have_css('#maj_carte')
end
it 'PJ link is present' do
expect(rendered).to have_css('#maj_pj')
end
it 'archive link is present' do
expect(rendered).not_to have_content('Archiver')
end
end
context 'when dossier is validated' do
let(:state) { 'validated' }
before do
render
end
it 'submitted link is not present' do
expect(rendered).not_to have_content('Déposer mon dossier')
end
end
end
end end
end end
end end