Merge branch 'staging'

This commit is contained in:
Xavier J 2016-02-23 11:15:04 +01:00
commit e3b903b1b6
82 changed files with 726 additions and 256 deletions

View file

@ -74,6 +74,11 @@ gem 'mailjet'
gem "smart_listing" gem "smart_listing"
gem 'css_splitter'
gem 'bootstrap-wysihtml5-rails', '~> 0.3.3.8'
gem 'as_csv'
group :test do group :test do
gem 'capybara' gem 'capybara'
gem 'factory_girl' gem 'factory_girl'

View file

@ -48,6 +48,10 @@ GEM
tzinfo (~> 1.1) tzinfo (~> 1.1)
addressable (2.3.8) addressable (2.3.8)
arel (6.0.2) arel (6.0.2)
as_csv (2.0.2)
actionpack (>= 3.0)
activemodel (>= 3.0)
responders
ast (2.0.0) ast (2.0.0)
astrolabe (1.3.0) astrolabe (1.3.0)
parser (>= 2.2.0.pre.3, < 3.0) parser (>= 2.2.0.pre.3, < 3.0)
@ -64,6 +68,8 @@ GEM
bootstrap-sass (3.3.5) bootstrap-sass (3.3.5)
autoprefixer-rails (>= 5.0.0.1) autoprefixer-rails (>= 5.0.0.1)
sass (>= 3.2.19) sass (>= 3.2.19)
bootstrap-wysihtml5-rails (0.3.3.8)
railties (>= 3.0)
builder (3.2.2) builder (3.2.2)
byebug (5.0.0) byebug (5.0.0)
columnize (= 0.9.0) columnize (= 0.9.0)
@ -93,6 +99,8 @@ GEM
columnize (0.9.0) columnize (0.9.0)
crack (0.4.2) crack (0.4.2)
safe_yaml (~> 1.0.0) safe_yaml (~> 1.0.0)
css_splitter (0.4.4)
sprockets (>= 2.0.0)
database_cleaner (1.4.1) database_cleaner (1.4.1)
debug_inspector (0.0.2) debug_inspector (0.0.2)
devise (3.4.1) devise (3.4.1)
@ -445,13 +453,16 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
active_model_serializers active_model_serializers
as_csv
bootstrap-datepicker-rails bootstrap-datepicker-rails
bootstrap-sass (~> 3.3.5) bootstrap-sass (~> 3.3.5)
bootstrap-wysihtml5-rails (~> 0.3.3.8)
byebug byebug
capybara capybara
carrierwave carrierwave
chartkick chartkick
coffee-rails (~> 4.1.0) coffee-rails (~> 4.1.0)
css_splitter
database_cleaner database_cleaner
devise devise
draper draper

View file

@ -63,4 +63,7 @@ Pour éxécuter les tests de l'application, plusieurs possibilités :
rspec file_path/file_name_spec.rb rspec file_path/file_name_spec.rb
## Regénérer les binstubs
bundle binstub railties --force
rake rails:update:bin

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View file

@ -25,8 +25,10 @@
//= require graham_scan.min //= require graham_scan.min
//= require leaflet.freedraw //= require leaflet.freedraw
//= require smart_listing //= require smart_listing
//= require turf //= require turf-area
//= require franceconnect //= require franceconnect
//= require bootstrap-wysihtml5
//= require bootstrap-wysihtml5/locales/fr-FR
$(document).on('page:load', scroll_to); $(document).on('page:load', scroll_to);

View file

@ -0,0 +1,8 @@
$(document).ready(wysihtml5_active);
$(document).on('page:load', wysihtml5_active);
function wysihtml5_active (){
$('.wysihtml5').each(function(i, elem) {
$(elem).wysihtml5({ toolbar:{ "fa": true } });
});
}

View file

@ -57,7 +57,7 @@ function get_external_data(latLngs) {
cadastre_list = [{zoom_error: true}]; cadastre_list = [{zoom_error: true}];
if (turf.area(polygons) < 300000) if (turf_area(polygons) < 300000)
cadastre_list = get_cadastre(latLngs); cadastre_list = get_cadastre(latLngs);
display_cadastre(cadastre_list); display_cadastre(cadastre_list);

View file

@ -0,0 +1,17 @@
$(document).on('page:load', all_video);
$(document).ready(all_video);
function all_video() {
$(".all_video").on('click', function(event){
$("#all_video").slideToggle(200);
if (event.stopPropagation) {
event.stopPropagation();
}
event.cancelBubble = true;
return false;
});
}

View file

@ -21,6 +21,7 @@
*/ */
@import "bootstrap-sprockets"; @import "bootstrap-sprockets";
@import "bootstrap"; @import "bootstrap";
@import "bootstrap-wysihtml5/bootstrap3-wysihtml5";
body { body {
background-color: rgb(255, 255, 255); background-color: rgb(255, 255, 255);

View file

@ -0,0 +1,3 @@
/*
*= require 'application'
*/

View file

@ -51,7 +51,7 @@
.simplifier { .simplifier {
ul { ul {
margin-top: 16%; margin-top: 13%;
} }
} }
@ -74,24 +74,51 @@
//border-bottom: none; //border-bottom: none;
ul { ul {
margin-top: 11%; margin-top: 10%;
} }
} }
.open_admin_compte { .news {
border-bottom: none;
padding-top: 25px; padding-top: 25px;
padding-bottom: 25px; padding-bottom: 25px;
ol { .latest_release {
margin-top: 1%; .body {
margin-left: 3%;
}
} }
}
.btn-lg { .demo_account {
font-size: 20px; img {
padding: 12px 18px; margin-left: 0;
padding-top: 10px;
padding-bottom: 0;
}
padding-top: 25px;
padding-bottom: 25px;
.btn {
margin-top: 10%;
}
}
.documentation {
border-bottom: none;
padding-top: 15px;
padding-bottom: 15px;
a {
margin-top: 16%; margin-top: 16%;
} }
ul{
margin-top: 14%;
}
img {
margin-left: 0;
width: 22%;
}
} }
} }

View file

@ -0,0 +1,31 @@
@media print {
html, body {
width: 900px;
margin: 0;
}
#main_div{
margin-left: 50px;
margin-right: 0;
}
#commentaire_new {
display: none;
}
#commentaires_flux {
margin-top: -50px;
}
#infos_dossier .row:last-child {
display: none;
}
#infos_dossier {
margin-bottom: -70px;
}
#backoffice_dossier_show .nav-tabs {
display: none;
}
}

View file

@ -4,6 +4,6 @@
padding-right:13%; padding-right:13%;
padding-bottom:20px; padding-bottom:20px;
padding-top:15px; padding-top:15px;
margin-left:-13%; margin-left:-10rem;
margin-right:-13%; margin-right:-10rem;
} }

View file

@ -11,10 +11,4 @@
li:last-child { li:last-child {
border: none; border: none;
} }
li a {
text-decoration: none;
color: #000;
display: block;
}
} }

View file

@ -12,12 +12,11 @@ class Admin::GestionnairesController < AdminController
def create def create
gestionnaire_params = create_gestionnaire_params @gestionnaire = Gestionnaire.create(create_gestionnaire_params)
@gestionnaire = Gestionnaire.create(gestionnaire_params)
if @gestionnaire.errors.messages.empty? if @gestionnaire.errors.messages.empty?
flash.notice = 'Gestionnaire ajouté' flash.notice = 'Gestionnaire ajouté'
GestionnaireMailer.new_gestionnaire(gestionnaire_params[:email], gestionnaire_params[:password]).deliver_now! GestionnaireMailer.new_gestionnaire(@gestionnaire.email, @gestionnaire.password).deliver_now!
else else
flash.alert = @gestionnaire.errors.full_messages.join('<br />').html_safe flash.alert = @gestionnaire.errors.full_messages.join('<br />').html_safe
end end

View file

@ -1,4 +1,10 @@
class Administrateurs::SessionsController < Sessions::SessionsController class Administrateurs::SessionsController < Sessions::SessionsController
def demo
return redirect_to root_path if Rails.env.production?
@administrateur = Administrateur.new(email: 'admin@tps.fr', password: 'password')
render 'new'
end
def new def new
@administrateur = Administrateur.new @administrateur = Administrateur.new

View file

@ -11,7 +11,10 @@ class API::V1::DossiersController < APIController
def show def show
procedure = current_administrateur.procedures.find(params[:procedure_id]) procedure = current_administrateur.procedures.find(params[:procedure_id])
dossier = procedure.dossiers.find(params[:id]) dossier = procedure.dossiers.find(params[:id])
render json: dossier, status: 200 respond_to do |format|
format.json { render json: dossier, status: 200 }
format.csv { render csv: dossier, status: 200 }
end
rescue ActiveRecord::RecordNotFound => e rescue ActiveRecord::RecordNotFound => e
render json: {}, status: 404 render json: {}, status: 404
end end

View file

@ -1,5 +1,6 @@
class APIController < ApplicationController class APIController < ApplicationController
before_action :authenticate_user before_action :authenticate_user
before_filter :default_format_json
def authenticate_user def authenticate_user
render json: {}, status: 401 unless valid_token? render json: {}, status: 401 unless valid_token?
@ -14,4 +15,8 @@ class APIController < ApplicationController
def current_administrateur def current_administrateur
@administrateur ||= Administrateur.find_by_api_token(params[:token]) @administrateur ||= Administrateur.find_by_api_token(params[:token])
end end
def default_format_json
request.format = "json" unless request.params[:format]
end
end end

View file

@ -18,7 +18,7 @@ class CommentairesController < ApplicationController
NotificationMailer.new_answer(@commentaire.dossier).deliver_now! NotificationMailer.new_answer(@commentaire.dossier).deliver_now!
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'])
elsif current_user.email != @commentaire.dossier.user.email elsif current_user.email != @commentaire.dossier.user.email
invite = Invite.find_by_email current_user.email invite = Invite.where(dossier: @commentaire.dossier, user: current_user).first
redirect_to url_for(controller: 'users/dossiers/invites', action: :show, id: invite.id) redirect_to url_for(controller: 'users/dossiers/invites', action: :show, id: invite.id)
else else
redirect_to url_for(controller: :recapitulatif, action: :show, dossier_id: params['dossier_id']) redirect_to url_for(controller: :recapitulatif, action: :show, dossier_id: params['dossier_id'])

View file

@ -3,6 +3,8 @@ class DemoController < ApplicationController
helper SmartListing::Helper helper SmartListing::Helper
def index def index
return root_path if Rails.env.production?
smart_listing_create :procedures, smart_listing_create :procedures,
Procedure.where(archived: false), Procedure.where(archived: false),
partial: "demo/list", partial: "demo/list",

View file

@ -1,5 +1,10 @@
class Gestionnaires::SessionsController < Sessions::SessionsController class Gestionnaires::SessionsController < Sessions::SessionsController
def demo
return redirect_to root_path if Rails.env.production?
@gestionnaire = Gestionnaire.new(email: 'gestionnaire@apientreprise.fr', password: 'password')
render 'new'
end
def new def new
@gestionnaire = Gestionnaire.new @gestionnaire = Gestionnaire.new

View file

@ -3,7 +3,7 @@ class InvitesController < ApplicationController
email_sender = current_gestionnaire.email email_sender = current_gestionnaire.email
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], email_sender: email_sender) invite = Invite.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?

View file

@ -11,6 +11,7 @@ class RootController < ApplicationController
redirect_to admin_procedures_path redirect_to admin_procedures_path
else else
@latest_release = Github::Releases.latest
render 'landing' render 'landing'
end end
end end

View file

@ -37,7 +37,10 @@ class Users::DescriptionController < UsersController
unless params[:cerfa_pdf].nil? unless params[:cerfa_pdf].nil?
cerfa = @dossier.cerfa cerfa = @dossier.cerfa
cerfa.content = params[:cerfa_pdf] cerfa.content = params[:cerfa_pdf]
cerfa.save unless cerfa.save
flash.now.alert = cerfa.errors.full_messages.join('<br />').html_safe
return render 'show'
end
end end
end end
@ -51,7 +54,10 @@ class Users::DescriptionController < UsersController
@dossier.pieces_justificatives.each do |piece_justificative| @dossier.pieces_justificatives.each do |piece_justificative|
unless params["piece_justificative_#{piece_justificative.type}"].nil? unless params["piece_justificative_#{piece_justificative.type}"].nil?
piece_justificative.content = params["piece_justificative_#{piece_justificative.type}"] piece_justificative.content = params["piece_justificative_#{piece_justificative.type}"]
piece_justificative.save unless piece_justificative.save
flash.now.alert = piece_justificative.errors.full_messages.join('<br />').html_safe
return render 'show'
end
end end
end end

View file

@ -1,4 +1,12 @@
class Users::Dossiers::InvitesController < UsersController class Users::Dossiers::InvitesController < UsersController
def authenticate_user!
session["user_return_to"] = request.fullpath
return redirect_to new_user_registration_path(user_email: params[:email]) if !params[:email].blank? && User.find_by_email(params[:email]).nil?
super
end
def show def show
@facade = InviteDossierFacades.new params[:id], current_user.email @facade = InviteDossierFacades.new params[:id], current_user.email

View file

@ -1,10 +1,18 @@
class Users::SessionsController < Sessions::SessionsController class Users::SessionsController < Sessions::SessionsController
# before_filter :configure_sign_in_params, only: [:create] # before_filter :configure_sign_in_params, only: [:create]
def demo
return redirect_to root_path if Rails.env.production?
@user = User.new(email: 'demo@tps.fr', password: 'password')
render 'new'
end
# GET /resource/sign_in # GET /resource/sign_in
# def new def new
# super @user = User.new
# end end
#POST /resource/sign_in #POST /resource/sign_in
def create def create
@ -13,7 +21,7 @@ class Users::SessionsController < Sessions::SessionsController
current_user.update_attributes(loged_in_with_france_connect: '') current_user.update_attributes(loged_in_with_france_connect: '')
end end
# DELETE /resource/sign_out # DELETE /resource/sign_out
def destroy def destroy
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: '') current_user.update_attributes(loged_in_with_france_connect: '')

View file

@ -0,0 +1,12 @@
class ChampDecorator < Draper::Decorator
def value
if type_champ == 'checkbox'
return object.value == 'on' ? 'Oui' : 'Non'
end
end
def type_champ
object.type_de_champ.type_champ
end
end

View file

@ -2,6 +2,7 @@ class Cerfa < ActiveRecord::Base
belongs_to :dossier belongs_to :dossier
mount_uploader :content, CerfaUploader mount_uploader :content, CerfaUploader
validates :content, :file_size => { :maximum => 3.megabytes }
def empty? def empty?
content.blank? content.blank?

View file

@ -1,4 +1,5 @@
class Dossier < ActiveRecord::Base class Dossier < ActiveRecord::Base
enum state: {draft: 'draft', enum state: {draft: 'draft',
initiated: 'initiated', initiated: 'initiated',
replied: 'replied', replied: 'replied',
@ -192,6 +193,13 @@ class Dossier < ActiveRecord::Base
procedure.cerfa_flag? && !cerfa.empty? procedure.cerfa_flag? && !cerfa.empty?
end end
def as_csv(options={})
dossier_attr = DossierSerializer.new(self).attributes
etablissement_attr = EtablissementSerializer.new(self.etablissement).attributes.map {|k, v| ["etablissement.#{k}", v] }.to_h
entreprise_attr = EntrepriseSerializer.new(self.entreprise).attributes.map {|k, v| ["entreprise.#{k}", v] }.to_h
dossier_attr.merge(etablissement_attr).merge(entreprise_attr)
end
private private
def build_default_cerfa def build_default_cerfa

View file

@ -1,17 +0,0 @@
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

@ -7,6 +7,7 @@ class PieceJustificative < ActiveRecord::Base
alias_attribute :type, :type_de_piece_justificative_id alias_attribute :type, :type_de_piece_justificative_id
mount_uploader :content, PieceJustificativeUploader mount_uploader :content, PieceJustificativeUploader
validates :content, :file_size => { :maximum => 3.megabytes }
def empty? def empty?
content.blank? content.blank?

View file

@ -2,7 +2,8 @@ class TypeDeChamp < ActiveRecord::Base
enum type_champs: {text: 'text', enum type_champs: {text: 'text',
textarea: 'textarea', textarea: 'textarea',
datetime: 'datetime', datetime: 'datetime',
number: 'number' number: 'number',
checkbox: 'checkbox'
} }
belongs_to :procedure belongs_to :procedure

View file

@ -39,7 +39,7 @@ class PieceJustificativeUploader < CarrierWave::Uploader::Base
# Add a white list of extensions which are allowed to be uploaded. # Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this: # For images you might use something like this:
def extension_white_list def extension_white_list
%w(pdf) %w(pdf xlsx xls doc docx)
end end
# Override the filename of the uploaded files: # Override the filename of the uploaded files:

View file

@ -22,4 +22,4 @@
- else - else
%h4.center %h4.center
Aucun gestionnaire Aucun accompagnateur

View file

@ -1,4 +1,4 @@
%h1 Gestion des gestionnaires %h1 Gestion des accompagnateurs
%br %br
.row .row

View file

@ -19,7 +19,7 @@
.input-group .input-group
.input-group-addon .input-group-addon
%span.glyphicon.glyphicon-asterisk %span.glyphicon.glyphicon-asterisk
= f.password_field :password, autocomplete: "off", class: 'form-control' = f.password_field :password, class: 'form-control', value: @administrateur.password
%br %br
%br %br
.actions .actions

View file

@ -7,12 +7,7 @@
= @facade.dossier.procedure.libelle = @facade.dossier.procedure.libelle
.description .description
- begin = @facade.dossier.description.html_safe
- @facade.dossier.description.split(/(?:\n\r?|\r\n?')/).each do |line|
= line
%br
- rescue
=''
- if @facade.dossier.mandataire_social && gestionnaire_signed_in? - if @facade.dossier.mandataire_social && gestionnaire_signed_in?
.mandataire_social.text-success.center .mandataire_social.text-success.center
@ -45,7 +40,7 @@
%th{ style: 'width:25%' } %th{ style: 'width:25%' }
=champ.libelle =champ.libelle
%td %td
=champ.value =champ.decorate.value
.col-lg-6.col-md-6 .col-lg-6.col-md-6
=render partial: '/dossiers/pieces_justificatives' =render partial: '/dossiers/pieces_justificatives'
%br %br

View file

@ -1,9 +1,9 @@
.col-md-12 .col-md-12.col-xs-12
%h4 %h4
= @facade.entreprise.raison_sociale_or_name = @facade.entreprise.raison_sociale_or_name
.row#infos_entreprise .row#infos_entreprise
.col-lg-6.col-md-6 .col-lg-6.col-md-6.col-xs-12.col-sm-12
%dl.dl-horizontal %dl.dl-horizontal
%dt Siret : %dt Siret :
%dd.text-success= @facade.etablissement.siret %dd.text-success= @facade.etablissement.siret
@ -34,7 +34,7 @@
%dd= @facade.entreprise.numero_tva_intracommunautaire %dd= @facade.entreprise.numero_tva_intracommunautaire
.col-lg-6.col-md-6 .col-lg-6.col-md-6.col-xs-12.col-sm-12
%dl.dl-horizontal %dl.dl-horizontal
%dt Adresse : %dt Adresse :
%dd %dd

View file

@ -3,7 +3,7 @@
-#%br -#%br
%table.table %table.table
-if @facade.procedure.lien_demarche != nil -if @facade.procedure.cerfa_flag?
%tr{id: "piece_justificative_0"} %tr{id: "piece_justificative_0"}
%th{class:'col-lg-6'} %th{class:'col-lg-6'}
='Formulaire' ='Formulaire'

View file

@ -19,7 +19,7 @@
.input-group .input-group
.input-group-addon .input-group-addon
%span.glyphicon.glyphicon-asterisk %span.glyphicon.glyphicon-asterisk
= f.password_field :password, autocomplete: "off", class: 'form-control' = f.password_field :password, autocomplete: "off", class: 'form-control', value: @gestionnaire.password
%br %br
%br %br
.actions .actions

View file

@ -4,7 +4,7 @@ L'utilisateur <%= @invite.email_sender %> souhaite que vous participiez à l'él
Cette plateforme permet à ses utilisateurs d'établir des dossiers 100% en ligne et de dialoguer avec plusieurs interlocuteurs privilégiés avant d'instruire un dépot. Cette plateforme permet à ses utilisateurs d'établir des dossiers 100% en ligne et de dialoguer avec plusieurs interlocuteurs privilégiés avant d'instruire un dépot.
Afin de répondre à cette invitation, merci de vous inscrit avec l'adresse email <%= @invite.email %> sur <%= users_dossiers_invite_url(@invite.id) %>. Afin de répondre à cette invitation, merci de vous inscrit avec l'adresse email <%= @invite.email %> sur <%= users_dossiers_invite_url(@invite.id)+"?email=#{@invite.email}" %>.
Bonne journée. Bonne journée.

View file

@ -6,6 +6,7 @@
%meta{'http-equiv' => "X-UA-Compatible", :content => "IE=edge"} %meta{'http-equiv' => "X-UA-Compatible", :content => "IE=edge"}
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
= stylesheet_link_tag 'application_split2', media: 'all', 'data-turbolinks-track' => true
= javascript_include_tag 'application', 'data-turbolinks-track' => true = javascript_include_tag 'application', 'data-turbolinks-track' => true
= csrf_meta_tags = csrf_meta_tags
%body %body
@ -52,7 +53,7 @@
.alert.alert-danger .alert.alert-danger
= flash.alert = flash.alert
%div.main_div #main_div.main_div
= yield = yield
%br %br

View file

@ -12,8 +12,8 @@
%br %br
%br %br
.center .center
%button.js-scrollTo.btn.btn-lg.btn-success{cible: '.open_admin_compte'} %button.js-scrollTo.btn.btn-lg.btn-success{cible: '.demo_account'}
Ouvrir un compte TPS Envie d'essayer ?
#suite.max-size #suite.max-size
@ -23,23 +23,16 @@
.col-md-6.col-lg-6 .col-md-6.col-lg-6
%ul.dynamic_ul %ul.dynamic_ul
%li %li
%a Générateur simplifiée de démarches en ligne pour les administrations Générateur simplifiée de démarches en ligne pour les administrations
%li %li
%a Ne demander que les informations strictement nécessaires Ne demander que les informations strictement nécessaires
.row.word.securiser
.col-md-6.col-lg-6
%ul.dynamic_ul
%li %li
Profiter dune identification simplifiée grâce à FranceConnect Profiter dune identification simplifiée grâce à
%li %a{href: 'http://www.modernisation.gouv.fr/ladministration-change-avec-le-numerique/par-son-systeme-dinformation/france-connect-un-acces-universel-aux-administrations-en-ligne',
Évoluer sur une plateforme de l'État totalement sécurisée target: '_blank'}
.col-md-6.col-lg-6 FranceConnect
= image_tag image_url('keywords/securiser.png')
.row.word.echanger .row.word.echanger
.col-md-6.col-lg-6
= image_tag image_url('keywords/echanger.png')
.col-md-6.col-lg-6 .col-md-6.col-lg-6
%ul.dynamic_ul %ul.dynamic_ul
%li %li
@ -50,32 +43,77 @@
Accompagner les usagers dans leur démarche Accompagner les usagers dans leur démarche
%li %li
Vérifier les pièces au fur et à mesure Vérifier les pièces au fur et à mesure
.col-md-6.col-lg-6
= image_tag image_url('keywords/echanger.png')
.row.word.profiter .row.word.profiter
.col-md-6.col-lg-6
= image_tag image_url('keywords/profiter.png')
.col-md-6.col-lg-6 .col-md-6.col-lg-6
%ul.dynamic_ul %ul.dynamic_ul
%li %li
Profiter des ressources cartographiques directement mobilisées, si nécessaire Profiter des ressources cartographiques directement mobilisées, si nécessaire
%li %li
Récupérer des informations officielles collectées directement auprès des administrations Récupérer des informations officielles collectées directement auprès des administrations
.col-md-6.col-lg-6
= image_tag image_url('keywords/profiter.png')
.row.word.open_admin_compte .row.word.news
.col-md-6.col-lg-6 .latest_release.col-md-7.col-lg-7
%h3.text-info
= "Dernière version (#{@latest_release.tag_name} - #{@latest_release.published_at})"
.body
=@latest_release.body.html_safe
.center .center
=link_to 'Ouvrir un compte TPS', 'https://tps.apientreprise.fr/users/dossiers/new?procedure_id=31', {class: 'btn btn-lg btn-success', target: '_blank'} \-
.col-md-6.col-lg-6 %br
%h3 Envie d'essayer ? Rien de plus simple %a{href: 'https://github.com/sgmap/tps/releases', target: '_blank'}
%br = 'Voir toutes les versions'
%ol.dynamic_ul
.col-md-5.col-lg-5
#video.center
%iframe{:allowfullscreen => "", :frameborder => "0", :height => "270", :src => "//www.dailymotion.com/embed/video/x3lp4cs", :width => "480"}
%br
=link_to 'Toutes les vidéos', '#', {style: 'text-decoration: none', class: 'all_video btn btn-default btn-sm'}
#all_video{style:'display: none'}
%br
%ul
%li
=link_to "Création d'une démarche avec TPS (Téléprocédure Simplifiée)", "http://dai.ly/x3s2o65", {target: '_blank'}
%li
=link_to "Etape 2 avec TPS : saisine de l'administration par un usager avec France Connect", "http://dai.ly/x3s2oj6", {target: '_blank'}
%li
=link_to "Etape 3 avec TPS : l'accompagnement par les services et l'invitation d'autres partenaires publics à co-instruire", "http://dai.ly/x3s2oqp", {target: '_blank'}
%li
=link_to "TPS: dernière étape, la validation du dossier et notification", "http://dai.ly/x3s2p6k", {target: '_blank'}
.row.word.demo_account.center
.col-md-4.col-lg-4
%h3.text-primary Acteurs publics
%h4 Créez des démarches en ligne simplifiées et sécurisées.
=link_to 'Démonstration', 'https://tps-dev.apientreprise.fr/administrateurs/sign_in/demo', {class: 'btn btn-lg btn-primary'}
.col-md-4.col-lg-4
%h3.text-warning Agents et services
%h4 Accompagnez et co-traitez les projets avec les usagers.
=link_to 'Démonstration', 'https://tps-dev.apientreprise.fr/gestionnaires/sign_in/demo', {class: 'btn btn-lg btn-warning'}
.col-md-4.col-lg-4
%h3.text-success Usagers
%h4 Profitez de démarches simplifiées et déchanges continus avec les services traitants.
=link_to 'Démonstration', 'https://tps-dev.apientreprise.fr/users/sign_in/demo', {class: 'btn btn-lg btn-success'}
.row.word.documentation
.col-md-4.col-lg-4.center
= image_tag image_url('keywords/documentation.png')
.col-md-4.col-lg-4
%ul.dynamic_ul
%li %li
Cliquez sur le bouton vert à gauche =link_to 'Dépliant de présentation', '/data/TPS_Trois_volets.pdf', {target: '_blank'}
%li %li
Inscrivez-vous avec votre email professionnel =link_to 'Documentation dutilisation', '/data/TPS_documentations_v1_1.pdf', {target: '_blank'}
%li -#%li
Entrez le SIRET de votre organisme -# = link_to 'Documentation des APIs (béta)', '/docs', {target: '_blank'}
%li .col-md-4.col-lg-4.center
Composez un dossier en trois clics et VOILÀ ! = link_to 'Demander un accès administrateur', 'https://tps.apientreprise.fr/users/dossiers/new?procedure_id=31', {class: 'btn btn-lg btn-primary', target: '_blank'}
%br
%h4 Après, nos équipes prendrons rapidement contact avec vous via la plateforme.

View file

@ -13,29 +13,35 @@
.row .row
.col-md-12 .col-md-12
%h4 Description de votre projet * %h4 Description de votre projet *
= text_area_tag :description, @dossier.description, rows: '6', placeholder: 'Description du projet', class: 'form-control' = text_area_tag :description, @dossier.description, rows: '6', placeholder: 'Description du projet', class: 'form-control wysihtml5'
#liste_champs #liste_champs
-unless @champs.nil? -unless @champs.nil?
-@champs.each do |champ| -@champs.each do |champ|
.row .row
%div{class: "type_champ-#{champ.type_champ}"} %div{class: "type_champ-#{champ.type_champ}"}
%h4 -if champ.type_champ == 'checkbox'
= champ.libelle %h4{style:'margin-left:15px;'}
= champ.libelle
-if champ.type_champ == 'textarea' %input{type: 'hidden', name:"champs['#{champ.id}']", id: "champs_#{champ.id}", value: ''}
%textarea.form-control{name:"champs['#{champ.id}']", %input{type: 'checkbox', style:'margin-left: 15px;', name:"champs['#{champ.id}']", id: "champs_#{champ.id}", checked: ('checked' if champ.value == 'on')}
placeholder: champ.libelle,
id: "champs_#{champ.id}"}
=champ.value
-else -else
%input.form-control{name:"champs['#{champ.id}']", %h4
placeholder: champ.libelle, = champ.libelle
id: "champs_#{champ.id}",
value: champ.value, -if champ.type_champ == 'textarea'
type:"#{champ.type_champ}", %textarea.form-control{name:"champs['#{champ.id}']",
'data-provide' => ('datepicker' if champ.type_champ == 'datetime'), placeholder: champ.libelle,
'data-date-format' => ('dd/mm/yyyy' if champ.type_champ == 'datetime')} id: "champs_#{champ.id}"}
=champ.value
-else
%input.form-control{name:"champs['#{champ.id}']",
placeholder: champ.libelle,
id: "champs_#{champ.id}",
value: champ.value,
type:"#{champ.type_champ}",
'data-provide' => ('datepicker' if champ.type_champ == 'datetime'),
'data-date-format' => ('dd/mm/yyyy' if champ.type_champ == 'datetime')}
-if !@procedure.lien_demarche.blank? || @procedure.cerfa_flag || @dossier.pieces_justificatives.size > 1 -if !@procedure.lien_demarche.blank? || @procedure.cerfa_flag || @dossier.pieces_justificatives.size > 1
%br %br
@ -53,15 +59,15 @@
- if @procedure.cerfa_flag - if @procedure.cerfa_flag
%tr %tr
%th{class:'col-lg-6'} %th{class:'col-lg-6'}
='Formulaire (.pdf / .doc)' ='Formulaire (.pdf / .doc / .docx / .xls / .xlsx)'
%td{class:'col-lg-5'} %td{class:'col-lg-5'}
-if @dossier.cerfa_available? -if @dossier.cerfa_available?
%span.btn.btn-sm.btn-file.btn-success %span.btn.btn-sm.btn-file.btn-success
Modifier Modifier
%input{type: 'file', name:'cerfa_pdf', id:'cerfa_pdf', accept: ".pdf"} %input{type: 'file', name:'cerfa_pdf', id:'cerfa_pdf', accept: "application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document", :max_file_size => 3.megabytes }
-else -else
%input{type: 'file', name:'cerfa_pdf', id:'cerfa_pdf', accept: ".pdf"} %input{type: 'file', name:'cerfa_pdf', id:'cerfa_pdf', accept: "application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document", :max_file_size => 3.megabytes }
- @dossier.pieces_justificatives.each do |piece_justificative| - @dossier.pieces_justificatives.each do |piece_justificative|
%tr %tr
@ -72,11 +78,11 @@
%span.text-success{ id: "piece_justificative_#{piece_justificative.type}" } Nous l'avons récupéré pour vous. %span.text-success{ id: "piece_justificative_#{piece_justificative.type}" } Nous l'avons récupéré pour vous.
-else -else
-if piece_justificative.empty? -if piece_justificative.empty?
= file_field_tag "piece_justificative_#{piece_justificative.type}", accept: '.pdf' = file_field_tag "piece_justificative_#{piece_justificative.type}", accept: 'application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document', :max_file_size => 3.megabytes
-else -else
%span.btn.btn-sm.btn-file.btn-success %span.btn.btn-sm.btn-file.btn-success
Modifier Modifier
= file_field_tag "piece_justificative_#{piece_justificative.type}", accept: '.pdf' = file_field_tag "piece_justificative_#{piece_justificative.type}", accept: 'application/pdf,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document', :max_file_size => 3.megabytes
%div{style: 'text-align:right'} %div{style: 'text-align:right'}
%h6 Tous les champs portant un * sont obligatoires. %h6 Tous les champs portant un * sont obligatoires.

View file

@ -1,7 +1,7 @@
.content#commentaires_flux{style:'width:100%;'} .content#commentaires_flux{style:'width:100%;'}
%div#commentaire_new{style: 'width:80%; margin-left:auto; margin-right:auto'} %div#commentaire_new{style: 'width:80%; margin-left:auto; margin-right:auto'}
= form_tag(url_for({ controller: 'commentaires', action: :create, dossier_id: @facade.dossier.id }), class: 'form-inline', method: 'POST') do = form_tag(url_for({ controller: 'commentaires', action: :create, dossier_id: @facade.dossier.id }), class: 'form-inline', method: 'POST') do
%textarea.form-control{id: 'texte_commentaire', name: 'texte_commentaire', style: 'width: 100%; margin-bottom:2%', rows: '5', placeholder:"Dialoguer avec votre interlocuteur privilégié en charge de votre dossier."} %textarea.form-control{id: 'texte_commentaire', class: 'wysihtml5', name: 'texte_commentaire', style: 'width: 100%; margin-bottom:2%', rows: '5', placeholder:"Dialoguer avec votre interlocuteur privilégié en charge de votre dossier."}
%input.form-control.btn.btn-success{:type => 'submit', :value => 'Poster', style: 'float:right'} %input.form-control.btn.btn-success{:type => 'submit', :value => 'Poster', style: 'float:right'}
%br %br
%br %br
@ -14,5 +14,5 @@
=com.created_at_fr =com.created_at_fr
%br %br
.description#body .description#body
=com.body =com.body.html_safe
%br %br

View file

@ -42,7 +42,7 @@
.input-group .input-group
.input-group-addon .input-group-addon
%span.glyphicon.glyphicon-user %span.glyphicon.glyphicon-user
= f.email_field :email, class: 'form-control', placeholder: 'Email' = f.email_field :email, class: 'form-control', placeholder: 'Email', value: params[:user_email]
%br %br
%h4 %h4
= f.label :password = f.label :password

View file

@ -11,7 +11,7 @@
Quest-ce que FranceConnect ? Quest-ce que FranceConnect ?
%hr %hr
= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| = form_for @user, url: user_session_path, method: :post do |f|
%h4 %h4
= f.label :email = f.label :email
.input-group .input-group
@ -24,7 +24,7 @@
.input-group .input-group
.input-group-addon .input-group-addon
%span.fa.fa-asterisk %span.fa.fa-asterisk
= f.password_field :password, autocomplete: "off", class: 'form-control' = f.password_field :password, class: 'form-control', value: "#{@user.password}"
%br %br
%br %br
.actions .actions
@ -32,19 +32,4 @@
%br %br
= render "users/shared/links" = render "users/shared/links"
%br
%div{style:'text-align:center'}
-#\-
-#%br
-#%a{href: '/gestionnaires/sign_in'}
-# = 'Accompagnateur'
-#%br
-#%a{href: '/administrateurs/sign_in'}
-# = 'Administrateur'
\-
%br
%a{href: 'https://github.com/sgmap/tps/releases', target: '_blank'}
= 'Nouveautés'

View file

@ -23,6 +23,7 @@ module TPS
config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/validators #{config.root}/app/facades) config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/validators #{config.root}/app/facades)
config.assets.paths << Rails.root.join('app', 'assets', 'javascript') config.assets.paths << Rails.root.join('app', 'assets', 'javascript')
config.assets.precompile += %w( application_split2.css )
# Do not swallow errors in after_commit/after_rollback callbacks. # Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true config.active_record.raise_in_transactional_callbacks = true

View file

@ -41,6 +41,14 @@ fr:
activerecord: activerecord:
errors: errors:
models: models:
piece_justificative:
attributes:
content:
size_too_big: "La taille du fichier joint est trop importante. Elle doit être inférieure à 3Mo."
cerfa:
attributes:
content:
size_too_big: "La taille du fichier joint est trop importante. Elle doit être inférieure à 3Mo."
user: user:
attributes: attributes:
email: email:
@ -130,5 +138,5 @@ fr:
procedure_not_found: "La procédure n'existe pas" procedure_not_found: "La procédure n'existe pas"
france_connect: france_connect:
connexion: "Erreur lors de la connexion à France Connect." connexion: "Erreur lors de la connexion à France Connect."
extension_white_list_error: "Le format de fichier de la pièce jointe n'est pas valide."

View file

@ -14,6 +14,18 @@ Rails.application.routes.draw do
passwords: 'users/passwords' passwords: 'users/passwords'
} }
devise_scope :user do
get '/users/sign_in/demo' => 'users/sessions#demo'
end
devise_scope :gestionnaire do
get '/gestionnaires/sign_in/demo' => 'gestionnaires/sessions#demo'
end
devise_scope :administrateur do
get '/administrateurs/sign_in/demo' => 'administrateurs/sessions#demo'
end
root 'root#index' root 'root#index'
namespace :france_connect do namespace :france_connect do

View file

@ -0,0 +1,74 @@
# Source: https://github.com/gitlabhq/gitlabhq/blob/master/lib/file_size_validator.rb
class FileSizeValidator < ActiveModel::EachValidator
MESSAGES = { is: :wrong_size, minimum: :size_too_small, maximum: :size_too_big }.freeze
CHECKS = { is: :==, minimum: :>=, maximum: :<= }.freeze
DEFAULT_TOKENIZER = lambda { |value| value.split(//) }
RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long]
def initialize(options)
if range = (options.delete(:in) || options.delete(:within))
raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
options[:minimum], options[:maximum] = range.begin, range.end
options[:maximum] -= 1 if range.exclude_end?
end
super
end
def check_validity!
keys = CHECKS.keys & options.keys
if keys.empty?
raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
end
keys.each do |key|
value = options[key]
unless (value.is_a?(Integer) && value >= 0) || value.is_a?(Symbol)
raise ArgumentError, ":#{key} must be a nonnegative Integer or symbol"
end
end
end
def validate_each(record, attribute, value)
raise(ArgumentError, "A CarrierWave::Uploader::Base object was expected") unless value.kind_of? CarrierWave::Uploader::Base
value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.kind_of?(String)
CHECKS.each do |key, validity_check|
next unless check_value = options[key]
check_value =
case check_value
when Integer
check_value
when Symbol
record.send(check_value)
end
value ||= [] if key == :maximum
value_size = value.size
next if value_size.send(validity_check, check_value)
errors_options = options.except(*RESERVED_OPTIONS)
errors_options[:file_size] = help.number_to_human_size check_value
default_message = options[MESSAGES[key]]
errors_options[:message] ||= default_message if default_message
record.errors.add(attribute, MESSAGES[key], errors_options)
end
end
def help
Helper.instance
end
class Helper
include Singleton
include ActionView::Helpers::NumberHelper
end
end

18
lib/github/api.rb Normal file
View file

@ -0,0 +1,18 @@
class Github::API
def self.base_uri
'https://api.github.com'
end
def self.latest_release
call '/repos/sgmap/tps/releases/latest'
end
private
def self.call(end_point, params = {})
RestClient::Resource.new(
base_uri+end_point
).get(params: params)
end
end

9
lib/github/releases.rb Normal file
View file

@ -0,0 +1,9 @@
class Github::Releases
def self.latest
release = Hashie::Mash.new JSON.parse(Github::API.latest_release)
release.published_at = release.published_at.to_date.strftime('%d/%m/%Y')
release
end
end

View file

@ -43,5 +43,7 @@ class SIADE::API
else else
'https://api-dev.apientreprise.fr' 'https://api-dev.apientreprise.fr'
end end
'https://apientreprise.fr'
end end
end end

View file

@ -22,7 +22,7 @@ EOF
task :generate_franceconnect_file do task :generate_franceconnect_file do
file = File.new('config/france_connect.yml', 'w+') file = File.new('config/france_connect.yml', 'w+')
comment = <<EOF comment = <<EOF
particulier_identifier: plop particulier_identifier: plop
particulier_secret: plip particulier_secret: plip
particulier_redirect_uri: 'http://localhost:3000/france_connect/particulier/callback' particulier_redirect_uri: 'http://localhost:3000/france_connect/particulier/callback'

Binary file not shown.

Binary file not shown.

View file

@ -91,16 +91,19 @@ describe Admin::GestionnairesController, type: :controller do
describe 'DELETE #destroy' do describe 'DELETE #destroy' do
let(:email) { 'test@plop.com' } let(:email) { 'test@plop.com' }
before do let!(:gestionnaire) { create :gestionnaire, email: email }
post :create, gestionnaire: { email: email } subject { delete :destroy, id: gestionnaire.id }
context "when gestionaire_id is valid" do
before do
subject
end
it { expect(response.status).to eq(302) }
it { expect(response).to redirect_to admin_gestionnaires_path }
it { expect{Gestionnaire.find(gestionnaire.id)}.to raise_error ActiveRecord::RecordNotFound}
end end
let(:gestionnaire) { Gestionnaire.last }
let(:response) { delete :destroy, id: gestionnaire.id } it { expect{subject}.to change(Gestionnaire, :count).by(-1) }
it { expect(response.status).to eq(302) }
it { expect(response).to redirect_to admin_gestionnaires_path }
it { expect{response}.to change(Gestionnaire, :count).by(-1) }
end end
end end

View file

@ -5,6 +5,18 @@ describe Gestionnaires::SessionsController, type: :controller do
@request.env["devise.mapping"] = Devise.mappings[:gestionnaire] @request.env["devise.mapping"] = Devise.mappings[:gestionnaire]
end end
describe '.demo' do
context 'when server is on env production' do
before do
allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new("production"))
end
subject { get :demo }
it { expect(subject).to redirect_to root_path }
end
end
describe '.create' do describe '.create' do
it { expect(described_class).to be < Sessions::SessionsController } it { expect(described_class).to be < Sessions::SessionsController }
end end

View file

@ -22,6 +22,15 @@ describe InvitesController, type: :controller do
subject subject
end end
describe 'Invite information' do
let(:email) { 'PLIP@octo.com' }
let(:invite) { Invite.last }
it 'email is on lower case' do
expect(invite.email).to eq 'plip@octo.com'
end
end
it { expect(invite.user).to eq user } it { expect(invite.user).to eq user }
it { expect(flash[:notice]).to be_present } it { expect(flash[:notice]).to be_present }

View file

@ -32,6 +32,9 @@ describe RootController, type: :controller do
render_views render_views
before do before do
stub_request(:get, "https://api.github.com/repos/sgmap/tps/releases/latest").
to_return(:status => 200, :body => '{"tag_name": "plip", "body": "blabla", "published_at": "2016-02-09T16:46:47Z"}', :headers => {})
subject subject
end end

View file

@ -43,20 +43,5 @@ describe Users::CommentairesController, type: :controller do
end end
end end
end end
context 'when invite is connected' do
let(:invite) { create(:invite, :with_user, dossier: dossier) }
before do
sign_in invite.user
dossier.replied!
post :create, dossier_id: dossier_id, texte_commentaire: texte_commentaire
dossier.reload
end
it { is_expected.to redirect_to users_dossiers_invite_path(invite.id) }
it { expect(dossier.state).to eq 'replied' }
end
end end
end end

View file

@ -0,0 +1,23 @@
require 'spec_helper'
describe Users::Dossiers::CommentairesController, type: :controller do
let(:dossier) { create(:dossier) }
let(:texte_commentaire) { 'Commentaire de test' }
describe '#POST create' do
context 'when invite is connected' do
let!(:invite) { create(:invite, :with_user, dossier: dossier) }
before do
sign_in invite.user
dossier.replied!
post :create, dossier_id: dossier.id, texte_commentaire: texte_commentaire
dossier.reload
end
it { is_expected.to redirect_to users_dossiers_invite_path(invite.id) }
it { expect(dossier.state).to eq 'replied' }
end
end
end

View file

@ -0,0 +1,56 @@
RSpec.describe Users::Dossiers::InvitesController, type: :controller do
describe '#authenticate_user!' do
let(:user) { create :user }
let(:invite) { create :invite }
context 'when email is not set' do
context 'when user is not connected' do
before do
get :show, id: invite.id
end
it { is_expected.to redirect_to new_user_session_path }
end
context 'when user is connected' do
let!(:invite) { create :invite, user: user }
before do
sign_in invite.user
get :show, id: invite.id
end
# it { expect(response.status).to eq 200 }
end
end
context 'when email is set' do
before do
get :show, id: invite.id, email: email
end
context 'when email is blank' do
let(:email) { '' }
it { is_expected.to redirect_to new_user_session_path }
end
context 'when email is not blank' do
context 'when email is affected at an user' do
let(:email) { user.email }
it { is_expected.to redirect_to new_user_session_path }
end
context 'when email is not affected at an user' do
let(:email) { 'new_user@octo.com' }
it { is_expected.to redirect_to new_user_registration_path(user_email: email) }
end
end
end
end
end

View file

@ -84,19 +84,19 @@ describe Users::DossiersController, type: :controller do
describe 'POST #create' do describe 'POST #create' do
before do before do
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/etablissements/#{siret_not_found}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/etablissements/#{siret_not_found}?token=#{SIADETOKEN}")
.to_return(status: 404, body: 'fake body') .to_return(status: 404, body: 'fake body')
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/etablissements/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/etablissements/#{siret}?token=#{SIADETOKEN}")
.to_return(status: 200, body: File.read('spec/support/files/etablissement.json')) .to_return(status: 200, body: File.read('spec/support/files/etablissement.json'))
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/entreprises/#{siren}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/entreprises/#{siren}?token=#{SIADETOKEN}")
.to_return(status: 200, body: File.read('spec/support/files/entreprise.json')) .to_return(status: 200, body: File.read('spec/support/files/entreprise.json'))
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/etablissements/exercices/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/etablissements/exercices/#{siret}?token=#{SIADETOKEN}")
.to_return(status: exercices_status, body: exercices_body) .to_return(status: exercices_status, body: exercices_body)
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/associations/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/associations/#{siret}?token=#{SIADETOKEN}")
.to_return(status: rna_status, body: rna_body) .to_return(status: rna_status, body: rna_body)
end end

View file

@ -1,13 +1,25 @@
require 'spec_helper' require 'spec_helper'
describe Users::SessionsController, type: :controller do describe Users::SessionsController, type: :controller do
let(:loged_in_with_france_connect) { 'entreprise' } let(:loged_in_with_france_connect) { 'particulier' }
let(:user) { create(:user, loged_in_with_france_connect: loged_in_with_france_connect) } let(:user) { create(:user, loged_in_with_france_connect: loged_in_with_france_connect) }
before do before do
@request.env["devise.mapping"] = Devise.mappings[:user] @request.env["devise.mapping"] = Devise.mappings[:user]
end end
describe '.demo' do
context 'when server is on env production' do
before do
allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new("production"))
end
subject { get :demo }
it { expect(subject).to redirect_to root_path }
end
end
describe '.create' do describe '.create' do
it { expect(described_class).to be < Sessions::SessionsController } it { expect(described_class).to be < Sessions::SessionsController }
@ -38,13 +50,8 @@ describe Users::SessionsController, type: :controller do
expect(user.loged_in_with_france_connect?).to be_falsey expect(user.loged_in_with_france_connect?).to be_falsey
end end
context 'when user is connect with france connect entreprise' do
it 'redirect to france connect logout page' do
expect(response).to redirect_to(FRANCE_CONNECT.entreprise_logout_endpoint)
end
end
context 'when user is connect with france connect entreprise' do context 'when user is connect with france connect particulier' do
let(:loged_in_with_france_connect) { 'particulier' } let(:loged_in_with_france_connect) { 'particulier' }
it 'redirect to france connect logout page' do it 'redirect to france connect logout page' do

View file

@ -1,4 +1,5 @@
FactoryGirl.define do FactoryGirl.define do
factory :commentaire do factory :commentaire do
body 'plop'
end end
end end

View file

@ -29,6 +29,9 @@ feature 'Administrator connection' do
end end
context 'when clicking on sign_out' do context 'when clicking on sign_out' do
before do before do
stub_request(:get, "https://api.github.com/repos/sgmap/tps/releases/latest").
to_return(:status => 200, :body => '{"tag_name": "plip", "body": "blabla", "published_at": "2016-02-09T16:46:47Z"}', :headers => {})
page.find_by_id('admin_sign_out').click page.find_by_id('admin_sign_out').click
end end
scenario 'admin is redireted to home page' do scenario 'admin is redireted to home page' do

View file

@ -27,14 +27,14 @@ feature 'user path for dossier creation' do
end end
context 'sets siret' do context 'sets siret' do
before do before do
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/etablissements/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/etablissements/#{siret}?token=#{SIADETOKEN}")
.to_return(body: File.read('spec/support/files/etablissement.json', status: 200)) .to_return(body: File.read('spec/support/files/etablissement.json', status: 200))
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/entreprises/#{siren}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/entreprises/#{siren}?token=#{SIADETOKEN}")
.to_return(status: 200, body: File.read('spec/support/files/entreprise.json')) .to_return(status: 200, body: File.read('spec/support/files/entreprise.json'))
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/etablissements/exercices/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/etablissements/exercices/#{siret}?token=#{SIADETOKEN}")
.to_return(status: 200, body: File.read('spec/support/files/exercices.json')) .to_return(status: 200, body: File.read('spec/support/files/exercices.json'))
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/associations/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/associations/#{siret}?token=#{SIADETOKEN}")
.to_return(status: 404, body: '') .to_return(status: 404, body: '')
page.find_by_id('dossier_siret').set siret page.find_by_id('dossier_siret').set siret

View file

@ -26,13 +26,13 @@ feature 'user arrive on siret page' do
end end
context 'when enter a siret' do context 'when enter a siret' do
before do before do
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/etablissements/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/etablissements/#{siret}?token=#{SIADETOKEN}")
.to_return(status: 200, body: File.read('spec/support/files/etablissement.json')) .to_return(status: 200, body: File.read('spec/support/files/etablissement.json'))
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/entreprises/#{siren}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/entreprises/#{siren}?token=#{SIADETOKEN}")
.to_return(status: 200, body: File.read('spec/support/files/entreprise.json')) .to_return(status: 200, body: File.read('spec/support/files/entreprise.json'))
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/etablissements/exercices/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/etablissements/exercices/#{siret}?token=#{SIADETOKEN}")
.to_return(status: 200, body: File.read('spec/support/files/exercices.json')) .to_return(status: 200, body: File.read('spec/support/files/exercices.json'))
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/associations/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/associations/#{siret}?token=#{SIADETOKEN}")
.to_return(status: 404, body: '') .to_return(status: 404, body: '')
page.find_by_id('dossier_siret').set siret page.find_by_id('dossier_siret').set siret

View file

@ -4,7 +4,7 @@ describe SIADE::API do
describe '.entreprise' do describe '.entreprise' do
subject { described_class.entreprise(siren) } subject { described_class.entreprise(siren) }
before do before do
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/entreprises/#{siren}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/entreprises/#{siren}?token=#{SIADETOKEN}")
.to_return(status: status, body: body) .to_return(status: status, body: body)
end end
context 'when siren does not exist' do context 'when siren does not exist' do
@ -30,7 +30,7 @@ describe SIADE::API do
describe '.etablissement' do describe '.etablissement' do
subject { described_class.etablissement(siret) } subject { described_class.etablissement(siret) }
before do before do
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/etablissements/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/etablissements/#{siret}?token=#{SIADETOKEN}")
.to_return(status: status, body: body) .to_return(status: status, body: body)
end end
@ -57,7 +57,7 @@ describe SIADE::API do
describe '.exercices' do describe '.exercices' do
before do before do
stub_request(:get, /https:\/\/api-dev.apientreprise.fr\/api\/v1\/etablissements\/exercices\/.*token=/) stub_request(:get, /https:\/\/apientreprise.fr\/api\/v1\/etablissements\/exercices\/.*token=/)
.to_return(status: status, body: body) .to_return(status: status, body: body)
end end
@ -88,7 +88,7 @@ describe SIADE::API do
describe '.rna' do describe '.rna' do
before do before do
stub_request(:get, /https:\/\/api-dev.apientreprise.fr\/api\/v1\/associations\/.*token=/) stub_request(:get, /https:\/\/apientreprise.fr\/api\/v1\/associations\/.*token=/)
.to_return(status: status, body: body) .to_return(status: status, body: body)
end end

View file

@ -4,7 +4,7 @@ describe SIADE::EntrepriseAdapter do
subject { described_class.new('418166096').to_params } subject { described_class.new('418166096').to_params }
before do before do
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/entreprises/418166096?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/entreprises/418166096?token=#{SIADETOKEN}")
.to_return(body: File.read('spec/support/files/entreprise.json', status: 200)) .to_return(body: File.read('spec/support/files/entreprise.json', status: 200))
end end

View file

@ -6,7 +6,7 @@ describe SIADE::EtablissementAdapter do
subject { described_class.new(siret).to_params } subject { described_class.new(siret).to_params }
before do before do
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/etablissements/#{siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/etablissements/#{siret}?token=#{SIADETOKEN}")
.to_return(body: File.read('spec/support/files/etablissement.json', status: 200)) .to_return(body: File.read('spec/support/files/etablissement.json', status: 200))
end end
@ -73,7 +73,7 @@ describe SIADE::EtablissementAdapter do
subject { described_class.new(bad_siret).to_params } subject { described_class.new(bad_siret).to_params }
before do before do
stub_request(:get, "https://api-dev.apientreprise.fr/api/v1/etablissements/#{bad_siret}?token=#{SIADETOKEN}") stub_request(:get, "https://apientreprise.fr/api/v1/etablissements/#{bad_siret}?token=#{SIADETOKEN}")
.to_return(body: 'Fake body', status: 404) .to_return(body: 'Fake body', status: 404)
end end

View file

@ -5,7 +5,7 @@ describe SIADE::ExercicesAdapter do
subject { described_class.new(siret).to_params } subject { described_class.new(siret).to_params }
before do before do
stub_request(:get, /https:\/\/api-dev.apientreprise.fr\/api\/v1\/etablissements\/exercices\/.*token=/) stub_request(:get, /https:\/\/apientreprise.fr\/api\/v1\/etablissements\/exercices\/.*token=/)
.to_return(body: File.read('spec/support/files/exercices.json', status: 200)) .to_return(body: File.read('spec/support/files/exercices.json', status: 200))
end end

View file

@ -8,7 +8,7 @@ describe SIADE::RNAAdapter do
subject { described_class.new(siret).to_params } subject { described_class.new(siret).to_params }
before do before do
stub_request(:get, /https:\/\/api-dev.apientreprise.fr\/api\/v1\/associations\/.*token=/) stub_request(:get, /https:\/\/apientreprise.fr\/api\/v1\/associations\/.*token=/)
.to_return(body: body, status: status) .to_return(body: body, status: status)
end end

View file

@ -543,4 +543,39 @@ describe Dossier do
it { expect(dossier.cerfa_available?).to be_falsey } it { expect(dossier.cerfa_available?).to be_falsey }
end end
end end
describe '#as_csv?' do
let(:procedure) { create(:procedure) }
let(:dossier) { create(:dossier, :with_entreprise, user: user, procedure: procedure) }
subject { dossier.as_csv }
it { expect(subject[:nom_projet]).to eq("Demande de subvention dans le cadre d'accompagnement d'enfant à l'étranger") }
it { expect(subject[:description]).to eq("Ma super description") }
it { expect(subject[:archived]).to be_falsey }
it { expect(subject['etablissement.siret']).to eq('44011762001530') }
it { expect(subject['etablissement.siege_social']).to be_truthy }
it { expect(subject['etablissement.naf']).to eq('4950Z') }
it { expect(subject['etablissement.libelle_naf']).to eq('Transports par conduites') }
it { expect(subject['etablissement.adresse']).to eq("GRTGAZ\r IMMEUBLE BORA\r 6 RUE RAOUL NORDLING\r 92270 BOIS COLOMBES\r") }
it { expect(subject['etablissement.numero_voie']).to eq('6') }
it { expect(subject['etablissement.type_voie']).to eq('RUE') }
it { expect(subject['etablissement.nom_voie']).to eq('RAOUL NORDLING') }
it { expect(subject['etablissement.complement_adresse']).to eq('IMMEUBLE BORA') }
it { expect(subject['etablissement.code_postal']).to eq('92270') }
it { expect(subject['etablissement.localite']).to eq('BOIS COLOMBES') }
it { expect(subject['etablissement.code_insee_localite']).to eq('92009') }
it { expect(subject['entreprise.siren']).to eq('440117620') }
it { expect(subject['entreprise.capital_social']).to eq(537100000) }
it { expect(subject['entreprise.numero_tva_intracommunautaire']).to eq('FR27440117620') }
it { expect(subject['entreprise.forme_juridique']).to eq("SA à conseil d'administration (s.a.i.)") }
it { expect(subject['entreprise.forme_juridique_code']).to eq('5599') }
it { expect(subject['entreprise.nom_commercial']).to eq('GRTGAZ') }
it { expect(subject['entreprise.raison_sociale']).to eq('GRTGAZ') }
it { expect(subject['entreprise.siret_siege_social']).to eq('44011762001530') }
it { expect(subject['entreprise.code_effectif_entreprise']).to eq('51') }
it { expect(subject['entreprise.date_creation']).to eq('Thu, 28 Jan 2016 10:16:29 UTC +00:0') }
it { expect(subject['entreprise.nom']).to be_nil }
it { expect(subject['entreprise.prenom']).to be_nil }
end
end end

View file

@ -1,17 +0,0 @@
require 'spec_helper'
describe FranceConnectEntrepriseClient do
describe '.initialize' do
it 'create an openid client' do
expect(described_class).to be < OpenIDConnect::Client
end
context 'when given code in params' do
let(:code) { 'plop' }
subject { described_class.new(code: code) }
it 'set authorisation code' do
expect_any_instance_of(described_class).to receive(:authorization_code=).with(code)
described_class.new(code: code)
end
end
end
end

View file

@ -28,6 +28,7 @@ describe TypeDeChamp do
it { is_expected.to allow_value('textarea').for(:type_champ) } it { is_expected.to allow_value('textarea').for(:type_champ) }
it { is_expected.to allow_value('datetime').for(:type_champ) } it { is_expected.to allow_value('datetime').for(:type_champ) }
it { is_expected.to allow_value('number').for(:type_champ) } it { is_expected.to allow_value('number').for(:type_champ) }
it { is_expected.to allow_value('checkbox').for(:type_champ) }
end end
context 'order_place' do context 'order_place' do

View file

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

View file

@ -16,10 +16,10 @@ describe 'admin/gestionnaires/index.html.haml', type: :view do
before do before do
render render
end end
it { expect(rendered).to have_content('Aucun gestionnaire') } it { expect(rendered).to have_content('Aucun accompagnateur') }
end end
context 'Ajout d\'un gestionnaire' do context 'Ajout d\'un accompagnateur' do
before do before do
create(:gestionnaire, administrateur: admin) create(:gestionnaire, administrateur: admin)
admin.reload admin.reload

92
vendor/assets/javascripts/turf-area.js vendored Normal file
View file

@ -0,0 +1,92 @@
var geometryArea = geometry;
turf_area = function(_) {
if (_.type === 'FeatureCollection') {
for (var i = 0, sum = 0; i < _.features.length; i++) {
if (_.features[i].geometry) {
sum += geometryArea(_.features[i].geometry);
}
}
return sum;
} else if (_.type === 'Feature') {
return geometryArea(_.geometry);
} else {
return geometryArea(_);
}
};
RADIUS = 6378137;
FLATTENING = 1/298.257223563;
POLAR_RADIUS = 6356752.3142;
ring = ringArea;
function geometry(_) {
var area = 0, i;
switch (_.type) {
case 'Polygon':
return polygonArea(_.coordinates);
case 'MultiPolygon':
for (i = 0; i < _.coordinates.length; i++) {
area += polygonArea(_.coordinates[i]);
}
return area;
case 'Point':
case 'MultiPoint':
case 'LineString':
case 'MultiLineString':
return 0;
case 'GeometryCollection':
for (i = 0; i < _.geometries.length; i++) {
area += geometry(_.geometries[i]);
}
return area;
}
}
function polygonArea(coords) {
var area = 0;
if (coords && coords.length > 0) {
area += Math.abs(ringArea(coords[0]));
for (var i = 1; i < coords.length; i++) {
area -= Math.abs(ringArea(coords[i]));
}
}
return area;
}
function ringArea(coords) {
var p1, p2, p3, lowerIndex, middleIndex, upperIndex,
area = 0,
coordsLength = coords.length;
if (coordsLength > 2) {
for (i = 0; i < coordsLength; i++) {
if (i === coordsLength - 2) {// i = N-2
lowerIndex = coordsLength - 2;
middleIndex = coordsLength -1;
upperIndex = 0;
} else if (i === coordsLength - 1) {// i = N-1
lowerIndex = coordsLength - 1;
middleIndex = 0;
upperIndex = 1;
} else { // i = 0 to N-3
lowerIndex = i;
middleIndex = i+1;
upperIndex = i+2;
}
p1 = coords[lowerIndex];
p2 = coords[middleIndex];
p3 = coords[upperIndex];
area += ( rad(p3[0]) - rad(p1[0]) ) * Math.sin( rad(p2[1]));
}
area = area * RADIUS * RADIUS / 2;
}
return area;
}
function rad(_) {
return _ * Math.PI / 180;
}

File diff suppressed because one or more lines are too long