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 'css_splitter'
gem 'bootstrap-wysihtml5-rails', '~> 0.3.3.8'
gem 'as_csv'
group :test do
gem 'capybara'
gem 'factory_girl'

View file

@ -48,6 +48,10 @@ GEM
tzinfo (~> 1.1)
addressable (2.3.8)
arel (6.0.2)
as_csv (2.0.2)
actionpack (>= 3.0)
activemodel (>= 3.0)
responders
ast (2.0.0)
astrolabe (1.3.0)
parser (>= 2.2.0.pre.3, < 3.0)
@ -64,6 +68,8 @@ GEM
bootstrap-sass (3.3.5)
autoprefixer-rails (>= 5.0.0.1)
sass (>= 3.2.19)
bootstrap-wysihtml5-rails (0.3.3.8)
railties (>= 3.0)
builder (3.2.2)
byebug (5.0.0)
columnize (= 0.9.0)
@ -93,6 +99,8 @@ GEM
columnize (0.9.0)
crack (0.4.2)
safe_yaml (~> 1.0.0)
css_splitter (0.4.4)
sprockets (>= 2.0.0)
database_cleaner (1.4.1)
debug_inspector (0.0.2)
devise (3.4.1)
@ -445,13 +453,16 @@ PLATFORMS
DEPENDENCIES
active_model_serializers
as_csv
bootstrap-datepicker-rails
bootstrap-sass (~> 3.3.5)
bootstrap-wysihtml5-rails (~> 0.3.3.8)
byebug
capybara
carrierwave
chartkick
coffee-rails (~> 4.1.0)
css_splitter
database_cleaner
devise
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
## 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 leaflet.freedraw
//= require smart_listing
//= require turf
//= require turf-area
//= require franceconnect
//= require bootstrap-wysihtml5
//= require bootstrap-wysihtml5/locales/fr-FR
$(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}];
if (turf.area(polygons) < 300000)
if (turf_area(polygons) < 300000)
cadastre_list = get_cadastre(latLngs);
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";
@import "bootstrap-wysihtml5/bootstrap3-wysihtml5";
body {
background-color: rgb(255, 255, 255);

View file

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

View file

@ -51,7 +51,7 @@
.simplifier {
ul {
margin-top: 16%;
margin-top: 13%;
}
}
@ -74,24 +74,51 @@
//border-bottom: none;
ul {
margin-top: 11%;
margin-top: 10%;
}
}
.open_admin_compte {
border-bottom: none;
.news {
padding-top: 25px;
padding-bottom: 25px;
ol {
margin-top: 1%;
.latest_release {
.body {
margin-left: 3%;
}
}
}
.btn-lg {
font-size: 20px;
padding: 12px 18px;
.demo_account {
img {
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%;
}
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-bottom:20px;
padding-top:15px;
margin-left:-13%;
margin-right:-13%;
margin-left:-10rem;
margin-right:-10rem;
}

View file

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

View file

@ -12,12 +12,11 @@ class Admin::GestionnairesController < AdminController
def create
gestionnaire_params = create_gestionnaire_params
@gestionnaire = Gestionnaire.create(gestionnaire_params)
@gestionnaire = Gestionnaire.create(create_gestionnaire_params)
if @gestionnaire.errors.messages.empty?
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
flash.alert = @gestionnaire.errors.full_messages.join('<br />').html_safe
end

View file

@ -1,4 +1,10 @@
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
@administrateur = Administrateur.new

View file

@ -11,7 +11,10 @@ class API::V1::DossiersController < APIController
def show
procedure = current_administrateur.procedures.find(params[:procedure_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
render json: {}, status: 404
end

View file

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

View file

@ -18,7 +18,7 @@ class CommentairesController < ApplicationController
NotificationMailer.new_answer(@commentaire.dossier).deliver_now!
redirect_to url_for(controller: 'backoffice/dossiers', action: :show, id: params['dossier_id'])
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)
else
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
def index
return root_path if Rails.env.production?
smart_listing_create :procedures,
Procedure.where(archived: false),
partial: "demo/list",

View file

@ -1,5 +1,10 @@
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
@gestionnaire = Gestionnaire.new

View file

@ -3,7 +3,7 @@ class InvitesController < ApplicationController
email_sender = current_gestionnaire.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?
InviteMailer.invite_user(invite).deliver_now! unless invite.user.nil?

View file

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

View file

@ -37,7 +37,10 @@ class Users::DescriptionController < UsersController
unless params[:cerfa_pdf].nil?
cerfa = @dossier.cerfa
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
@ -51,7 +54,10 @@ class Users::DescriptionController < UsersController
@dossier.pieces_justificatives.each do |piece_justificative|
unless params["piece_justificative_#{piece_justificative.type}"].nil?
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

View file

@ -1,4 +1,12 @@
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
@facade = InviteDossierFacades.new params[:id], current_user.email

View file

@ -1,10 +1,18 @@
class Users::SessionsController < Sessions::SessionsController
# 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
# def new
# super
# end
def new
@user = User.new
end
#POST /resource/sign_in
def create
@ -13,7 +21,7 @@ class Users::SessionsController < Sessions::SessionsController
current_user.update_attributes(loged_in_with_france_connect: '')
end
# DELETE /resource/sign_out
# DELETE /resource/sign_out
def destroy
connected_with_france_connect = current_user.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
mount_uploader :content, CerfaUploader
validates :content, :file_size => { :maximum => 3.megabytes }
def empty?
content.blank?

View file

@ -1,4 +1,5 @@
class Dossier < ActiveRecord::Base
enum state: {draft: 'draft',
initiated: 'initiated',
replied: 'replied',
@ -192,6 +193,13 @@ class Dossier < ActiveRecord::Base
procedure.cerfa_flag? && !cerfa.empty?
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
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
mount_uploader :content, PieceJustificativeUploader
validates :content, :file_size => { :maximum => 3.megabytes }
def empty?
content.blank?

View file

@ -2,7 +2,8 @@ class TypeDeChamp < ActiveRecord::Base
enum type_champs: {text: 'text',
textarea: 'textarea',
datetime: 'datetime',
number: 'number'
number: 'number',
checkbox: 'checkbox'
}
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.
# For images you might use something like this:
def extension_white_list
%w(pdf)
%w(pdf xlsx xls doc docx)
end
# Override the filename of the uploaded files:

View file

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

View file

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

View file

@ -19,7 +19,7 @@
.input-group
.input-group-addon
%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
.actions

View file

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

View file

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

View file

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

View file

@ -19,7 +19,7 @@
.input-group
.input-group-addon
%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
.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.
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.

View file

@ -6,6 +6,7 @@
%meta{'http-equiv' => "X-UA-Compatible", :content => "IE=edge"}
= 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
= csrf_meta_tags
%body
@ -52,7 +53,7 @@
.alert.alert-danger
= flash.alert
%div.main_div
#main_div.main_div
= yield
%br

View file

@ -12,8 +12,8 @@
%br
%br
.center
%button.js-scrollTo.btn.btn-lg.btn-success{cible: '.open_admin_compte'}
Ouvrir un compte TPS
%button.js-scrollTo.btn.btn-lg.btn-success{cible: '.demo_account'}
Envie d'essayer ?
#suite.max-size
@ -23,23 +23,16 @@
.col-md-6.col-lg-6
%ul.dynamic_ul
%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
%a Ne demander que les informations strictement nécessaires
.row.word.securiser
.col-md-6.col-lg-6
%ul.dynamic_ul
Ne demander que les informations strictement nécessaires
%li
Profiter dune identification simplifiée grâce à FranceConnect
%li
Évoluer sur une plateforme de l'État totalement sécurisée
.col-md-6.col-lg-6
= image_tag image_url('keywords/securiser.png')
Profiter dune identification simplifiée grâce à
%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',
target: '_blank'}
FranceConnect
.row.word.echanger
.col-md-6.col-lg-6
= image_tag image_url('keywords/echanger.png')
.col-md-6.col-lg-6
%ul.dynamic_ul
%li
@ -50,32 +43,77 @@
Accompagner les usagers dans leur démarche
%li
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
.col-md-6.col-lg-6
= image_tag image_url('keywords/profiter.png')
.col-md-6.col-lg-6
%ul.dynamic_ul
%li
Profiter des ressources cartographiques directement mobilisées, si nécessaire
%li
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
.col-md-6.col-lg-6
.row.word.news
.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
=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
%h3 Envie d'essayer ? Rien de plus simple
%br
%ol.dynamic_ul
\-
%br
%a{href: 'https://github.com/sgmap/tps/releases', target: '_blank'}
= 'Voir toutes les versions'
.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
Cliquez sur le bouton vert à gauche
=link_to 'Dépliant de présentation', '/data/TPS_Trois_volets.pdf', {target: '_blank'}
%li
Inscrivez-vous avec votre email professionnel
%li
Entrez le SIRET de votre organisme
%li
Composez un dossier en trois clics et VOILÀ !
%br
%h4 Après, nos équipes prendrons rapidement contact avec vous via la plateforme.
=link_to 'Documentation dutilisation', '/data/TPS_documentations_v1_1.pdf', {target: '_blank'}
-#%li
-# = link_to 'Documentation des APIs (béta)', '/docs', {target: '_blank'}
.col-md-4.col-lg-4.center
= 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'}

View file

@ -13,29 +13,35 @@
.row
.col-md-12
%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
-unless @champs.nil?
-@champs.each do |champ|
.row
%div{class: "type_champ-#{champ.type_champ}"}
%h4
= champ.libelle
-if champ.type_champ == 'textarea'
%textarea.form-control{name:"champs['#{champ.id}']",
placeholder: champ.libelle,
id: "champs_#{champ.id}"}
=champ.value
-if champ.type_champ == 'checkbox'
%h4{style:'margin-left:15px;'}
= champ.libelle
%input{type: 'hidden', name:"champs['#{champ.id}']", id: "champs_#{champ.id}", value: ''}
%input{type: 'checkbox', style:'margin-left: 15px;', name:"champs['#{champ.id}']", id: "champs_#{champ.id}", checked: ('checked' if champ.value == 'on')}
-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')}
%h4
= champ.libelle
-if champ.type_champ == 'textarea'
%textarea.form-control{name:"champs['#{champ.id}']",
placeholder: champ.libelle,
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
%br
@ -53,15 +59,15 @@
- if @procedure.cerfa_flag
%tr
%th{class:'col-lg-6'}
='Formulaire (.pdf / .doc)'
='Formulaire (.pdf / .doc / .docx / .xls / .xlsx)'
%td{class:'col-lg-5'}
-if @dossier.cerfa_available?
%span.btn.btn-sm.btn-file.btn-success
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
%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|
%tr
@ -72,11 +78,11 @@
%span.text-success{ id: "piece_justificative_#{piece_justificative.type}" } Nous l'avons récupéré pour vous.
-else
-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
%span.btn.btn-sm.btn-file.btn-success
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'}
%h6 Tous les champs portant un * sont obligatoires.

View file

@ -1,7 +1,7 @@
.content#commentaires_flux{style:'width:100%;'}
%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
%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'}
%br
%br
@ -14,5 +14,5 @@
=com.created_at_fr
%br
.description#body
=com.body
=com.body.html_safe
%br

View file

@ -42,7 +42,7 @@
.input-group
.input-group-addon
%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
%h4
= f.label :password

View file

@ -11,7 +11,7 @@
Quest-ce que FranceConnect ?
%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
= f.label :email
.input-group
@ -24,7 +24,7 @@
.input-group
.input-group-addon
%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
.actions
@ -32,19 +32,4 @@
%br
= 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.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.
config.active_record.raise_in_transactional_callbacks = true

View file

@ -41,6 +41,14 @@ fr:
activerecord:
errors:
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:
attributes:
email:
@ -130,5 +138,5 @@ fr:
procedure_not_found: "La procédure n'existe pas"
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'
}
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'
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
'https://api-dev.apientreprise.fr'
end
'https://apientreprise.fr'
end
end

View file

@ -22,7 +22,7 @@ EOF
task :generate_franceconnect_file do
file = File.new('config/france_connect.yml', 'w+')
comment = <<EOF
particulier_identifier: plop
particulier_identifier: plop
particulier_secret: plip
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
let(:email) { 'test@plop.com' }
before do
post :create, gestionnaire: { email: email }
let!(:gestionnaire) { 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
let(:gestionnaire) { Gestionnaire.last }
let(:response) { delete :destroy, id: gestionnaire.id }
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) }
it { expect{subject}.to change(Gestionnaire, :count).by(-1) }
end
end

View file

@ -5,6 +5,18 @@ describe Gestionnaires::SessionsController, type: :controller do
@request.env["devise.mapping"] = Devise.mappings[:gestionnaire]
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
it { expect(described_class).to be < Sessions::SessionsController }
end

View file

@ -22,6 +22,15 @@ describe InvitesController, type: :controller do
subject
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(flash[:notice]).to be_present }

View file

@ -32,6 +32,9 @@ describe RootController, type: :controller do
render_views
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
end

View file

@ -43,20 +43,5 @@ describe Users::CommentairesController, type: :controller do
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

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
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')
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'))
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'))
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)
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)
end

View file

@ -1,13 +1,25 @@
require 'spec_helper'
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) }
before do
@request.env["devise.mapping"] = Devise.mappings[:user]
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
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
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' }
it 'redirect to france connect logout page' do

View file

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

View file

@ -29,6 +29,9 @@ feature 'Administrator connection' do
end
context 'when clicking on sign_out' 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
end
scenario 'admin is redireted to home page' do

View file

@ -27,14 +27,14 @@ feature 'user path for dossier creation' do
end
context 'sets siret' 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))
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'))
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'))
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: '')
page.find_by_id('dossier_siret').set siret

View file

@ -26,13 +26,13 @@ feature 'user arrive on siret page' do
end
context 'when enter a siret' 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'))
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'))
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'))
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: '')
page.find_by_id('dossier_siret').set siret

View file

@ -4,7 +4,7 @@ describe SIADE::API do
describe '.entreprise' do
subject { described_class.entreprise(siren) }
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)
end
context 'when siren does not exist' do
@ -30,7 +30,7 @@ describe SIADE::API do
describe '.etablissement' do
subject { described_class.etablissement(siret) }
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)
end
@ -57,7 +57,7 @@ describe SIADE::API do
describe '.exercices' 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)
end
@ -88,7 +88,7 @@ describe SIADE::API do
describe '.rna' 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)
end

View file

@ -4,7 +4,7 @@ describe SIADE::EntrepriseAdapter do
subject { described_class.new('418166096').to_params }
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))
end

View file

@ -6,7 +6,7 @@ describe SIADE::EtablissementAdapter do
subject { described_class.new(siret).to_params }
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))
end
@ -73,7 +73,7 @@ describe SIADE::EtablissementAdapter do
subject { described_class.new(bad_siret).to_params }
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)
end

View file

@ -5,7 +5,7 @@ describe SIADE::ExercicesAdapter do
subject { described_class.new(siret).to_params }
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))
end

View file

@ -8,7 +8,7 @@ describe SIADE::RNAAdapter do
subject { described_class.new(siret).to_params }
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)
end

View file

@ -543,4 +543,39 @@ describe Dossier do
it { expect(dossier.cerfa_available?).to be_falsey }
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

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('datetime').for(:type_champ) }
it { is_expected.to allow_value('number').for(:type_champ) }
it { is_expected.to allow_value('checkbox').for(:type_champ) }
end
context 'order_place' do

View file

@ -1,31 +1,6 @@
require 'spec_helper'
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
let(:code) { 'plop' }
let(:access_token) { 'my access_token' }

View file

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