Merge branch 'develop' into staging

This commit is contained in:
Xavier J 2016-06-10 17:00:36 +02:00
commit a87201b741
63 changed files with 3667 additions and 146 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View file

@ -0,0 +1,22 @@
function address_type_init() {
display = 'label';
var bloodhound = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace(display),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/ban/search?request=%QUERY',
wildcard: '%QUERY'
}
});
bloodhound.initialize();
$("input[type='address']").typeahead({
minLength: 1
}, {
display: display,
source: bloodhound,
limit: 5
});
}

View file

@ -29,8 +29,7 @@
//= require franceconnect //= require franceconnect
//= require bootstrap-wysihtml5 //= require bootstrap-wysihtml5
//= require bootstrap-wysihtml5/locales/fr-FR //= require bootstrap-wysihtml5/locales/fr-FR
//= require typeahead.bundle
$(document).on('page:load', scroll_to); $(document).on('page:load', scroll_to);
$(document).ready(scroll_to); $(document).ready(scroll_to);

View file

@ -14,6 +14,17 @@ function initCarto() {
layers: [OSM] layers: [OSM]
}); });
icon = L.icon({
iconUrl: '/assets/marker-icon.png',
//shadowUrl: 'leaf-shadow.png',
iconSize: [34.48, 40], // size of the icon
//shadowSize: [50, 64], // size of the shadow
iconAnchor: [20, 20] // point of the icon which will correspond to marker's location
//shadowAnchor: [4, 62], // the same for the shadow
//popupAnchor: [-3, -76] // point from which the popup should open relative to the iconAnchor
});
if (qp_active()) if (qp_active())
display_qp(JSON.parse($("#quartier_prioritaires").val())); display_qp(JSON.parse($("#quartier_prioritaires").val()));
@ -39,6 +50,7 @@ function initCarto() {
map.setView(new L.LatLng(position.lat, position.lon), position.zoom); map.setView(new L.LatLng(position.lat, position.lon), position.zoom);
add_event_freeDraw(); add_event_freeDraw();
add_event_search_address();
} }
function default_gestionnaire_position() { function default_gestionnaire_position() {
@ -111,8 +123,32 @@ function get_position() {
return position; return position;
} }
function get_address_point(request) {
$.ajax({
url: '/ban/address_point?request=' + request,
dataType: 'json',
async: true
}).done(function (data) {
if (data.lat != null) {
map.setView(new L.LatLng(data.lat, data.lon), data.zoom);
L.marker([data.lat, data.lon], {icon: icon}).addTo(map);
}
});
}
function jsObject_to_array(qp_list) { function jsObject_to_array(qp_list) {
return Object.keys(qp_list).map(function (v) { return Object.keys(qp_list).map(function (v) {
return qp_list[v]; return qp_list[v];
}); });
} }
function add_event_search_address() {
$("#search_by_address input[type='address']").bind('typeahead:select', function (ev, seggestion) {
get_address_point(seggestion['label']);
});
$("#search_by_address input[type='address']").keypress(function (e) {
if (e.which == 13)
get_address_point($(this).val());
});
}

View file

@ -13,6 +13,16 @@ function action_type_de_champs() {
toggleErrorClass(this, validatePhone(val)); toggleErrorClass(this, validatePhone(val));
}); });
$("#liste_champs input").on('focus', function (){
$("#description_"+this.id).slideDown();
});
$("#liste_champs input").on('blur', function (){
$("#description_"+this.id).slideUp();
});
address_type_init();
} }
function toggleErrorClass(node, boolean) { function toggleErrorClass(node, boolean) {
@ -34,4 +44,4 @@ function validateEmail(email) {
function validateInput(input, regex) { function validateInput(input, regex) {
return regex.test(input); return regex.test(input);
} }

View file

@ -182,6 +182,10 @@ div.pagination {
text-align: center; text-align: center;
} }
.alert{
margin-bottom: 0px;
}
.alert.alert-success.move_up { .alert.alert-success.move_up {
position: absolute; position: absolute;
top: 0px; top: 0px;

View file

@ -21,6 +21,15 @@
} }
} }
.type_champ-address {
@extend .col-md-6;
@extend .col-lg-6;
input[type='address'] {
width: 100%;
}
}
.type_champ-email { .type_champ-email {
@extend .col-md-4; @extend .col-md-4;
@extend .col-lg-4; @extend .col-lg-4;
@ -76,3 +85,10 @@
width: 100%; width: 100%;
} }
} }
.description_div {
margin-top: 5px;
margin-left: 5px;
color: dimgrey;
display: none;
}

View file

@ -0,0 +1,35 @@
.tt-menu {
width: 555px;
padding: 8px 0;
background-color: #fff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.2);
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
}
.tt-suggestion {
padding: 3px 20px;
font-size: 18px;
line-height: 24px;
}
.twitter-typeahead {
width: 555px;
}
.tt-suggestion:hover {
cursor: pointer;
color: #fff;
background-color: #0097cf;
}
.tt-suggestion.tt-cursor {
color: #fff;
background-color: #0097cf;
}

View file

@ -22,6 +22,23 @@ class Admin::PiecesJustificativesController < AdminController
def update_params def update_params
params params
.require(:procedure) .require(:procedure)
.permit(types_de_piece_justificative_attributes: [:libelle, :description, :id]) .permit(types_de_piece_justificative_attributes: [:libelle, :description, :id, :order_place])
end
def move_up
index = params[:index].to_i - 1
if @procedure.switch_types_de_piece_justificative index
render 'show', format: :js
else
render json: {}, status: 400
end
end
def move_down
if @procedure.switch_types_de_piece_justificative params[:index].to_i
render 'show', format: :js
else
render json: {}, status: 400
end
end end
end end

View file

@ -7,7 +7,7 @@ class Admin::ProceduresController < AdminController
def index def index
@procedures = smart_listing_create :procedures, @procedures = smart_listing_create :procedures,
current_administrateur.procedures.where(archived: false), current_administrateur.procedures.where(published: true, archived: false),
partial: "admin/procedures/list", partial: "admin/procedures/list",
array: true array: true
@ -25,6 +25,18 @@ class Admin::ProceduresController < AdminController
render 'index' render 'index'
end end
def draft
@procedures = smart_listing_create :procedures,
current_administrateur.procedures.where(published: false, archived: false),
partial: "admin/procedures/draft_list",
array: true
draft_class
render 'index'
end
def show def show
@facade = AdminProceduresShowFacades.new @procedure.decorate @facade = AdminProceduresShowFacades.new @procedure.decorate
end end
@ -63,16 +75,12 @@ class Admin::ProceduresController < AdminController
redirect_to edit_admin_procedure_path(id: @procedure.id) redirect_to edit_admin_procedure_path(id: @procedure.id)
end end
def publish
change_status({published: params[:published]})
end
def archive def archive
@procedure = current_administrateur.procedures.find(params[:procedure_id]) change_status({archived: params[:archive]})
@procedure.update_attributes({archived: params[:archive]})
flash.notice = 'Procédure éditée'
redirect_to admin_procedures_path
rescue ActiveRecord::RecordNotFound
flash.alert = 'Procédure inéxistante'
redirect_to admin_procedures_path
end end
def active_class def active_class
@ -83,6 +91,10 @@ class Admin::ProceduresController < AdminController
@archived_class = 'active' @archived_class = 'active'
end end
def draft_class
@draft_class = 'active'
end
private private
def create_procedure_params def create_procedure_params
@ -92,4 +104,16 @@ class Admin::ProceduresController < AdminController
def create_module_api_carto_params def create_module_api_carto_params
params.require(:procedure).require(:module_api_carto_attributes).permit(:id, :use_api_carto, :quartiers_prioritaires, :cadastre) params.require(:procedure).require(:module_api_carto_attributes).permit(:id, :use_api_carto, :quartiers_prioritaires, :cadastre)
end end
def change_status(status_options)
@procedure = current_administrateur.procedures.find(params[:procedure_id])
@procedure.update_attributes(status_options)
flash.notice = 'Procédure éditée'
redirect_to admin_procedures_path
rescue ActiveRecord::RecordNotFound
flash.alert = 'Procédure inéxistante'
redirect_to admin_procedures_path
end
end end

View file

@ -1,7 +1,7 @@
class Admin::TypesDeChampController < AdminController class Admin::TypesDeChampController < AdminController
before_action :retrieve_procedure before_action :retrieve_procedure
before_action :procedure_locked? before_action :procedure_locked?
def destroy def destroy
@procedure.types_de_champ.destroy(params[:id]) @procedure.types_de_champ.destroy(params[:id])
render 'show', format: :js render 'show', format: :js
@ -19,7 +19,9 @@ class Admin::TypesDeChampController < AdminController
end end
def update_params def update_params
params.require(:procedure).permit(types_de_champ_attributes: [:libelle, :description, :order_place, :type_champ, :id, :mandatory]) params
.require(:procedure)
.permit(types_de_champ_attributes: [:libelle, :description, :order_place, :type_champ, :id, :mandatory])
end end
def move_up def move_up

View file

@ -0,0 +1,20 @@
class Ban::SearchController < ApplicationController
def get
request = params[:request]
render json: Carto::Bano::AddressRetriever.new(request).list.inject([]) {
|acc, value| acc.push({label: value})
}.to_json
end
def get_address_point
point = Carto::Geocodeur.convert_adresse_to_point(params[:request])
unless point.nil?
lon = point.x.to_s
lat = point.y.to_s
end
render json: {lon: lon, lat: lat, zoom: '14', dossier_id: params[:dossier_id]}
end
end

View file

@ -23,7 +23,7 @@ class Users::DossiersController < UsersController
end end
def new def new
procedure = Procedure.where(archived: false).find(params[:procedure_id]) procedure = Procedure.where(archived: false, published: true).find(params[:procedure_id])
@dossier = Dossier.new(procedure: procedure) @dossier = Dossier.new(procedure: procedure)
@siret = params[:siret] || current_user.siret @siret = params[:siret] || current_user.siret

View file

@ -12,7 +12,7 @@ class Users::SessionsController < Sessions::SessionsController
# GET /resource/sign_in # GET /resource/sign_in
def new def new
unless user_return_to_procedure_id.nil? unless user_return_to_procedure_id.nil?
@dossier = Dossier.new(procedure: Procedure.not_archived(user_return_to_procedure_id)) @dossier = Dossier.new(procedure: Procedure.active(user_return_to_procedure_id))
end end
@user = User.new @user = User.new

View file

@ -0,0 +1,37 @@
class TypeDePieceJustificativeDecorator < Draper::Decorator
delegate_all
def button_up params
h.link_to '', params[:url], class: up_classes, id: "btn_up_#{params[:index]}", remote: true, method: :post if display_up_button?(params[:index])
end
def button_down params
h.link_to '', params[:url], class: down_classes, id: "btn_down_#{params[:index]}", remote: true, method: :post if display_down_button?(params[:index])
end
private
def up_classes
base_classes << 'fa-chevron-up'
end
def down_classes
base_classes << 'fa-chevron-down'
end
def base_classes
%w(btn btn-default form-control fa)
end
def display_up_button?(index)
!(index == 0 || count_type_de_piece_justificative < 2)
end
def display_down_button?(index)
(index + 1) < count_type_de_piece_justificative
end
def count_type_de_piece_justificative
@count_type_de_piece_justificative ||= procedure.types_de_piece_justificative.count
end
end

View file

@ -2,9 +2,14 @@ class Champ < ActiveRecord::Base
belongs_to :dossier belongs_to :dossier
belongs_to :type_de_champ belongs_to :type_de_champ
delegate :libelle, :type_champ, :order_place, :mandatory, to: :type_de_champ delegate :libelle, :type_champ, :order_place, :mandatory, :description, to: :type_de_champ
def mandatory? def mandatory?
mandatory mandatory
end end
def data_provide
return 'datepicker' if type_champ == 'datetime'
return 'typeahead' if type_champ == 'address'
end
end end

View file

@ -5,7 +5,7 @@ class PieceJustificative < ActiveRecord::Base
belongs_to :user belongs_to :user
delegate :api_entreprise, :libelle, to: :type_de_piece_justificative delegate :api_entreprise, :libelle, :order_place, to: :type_de_piece_justificative
alias_attribute :type, :type_de_piece_justificative_id alias_attribute :type, :type_de_piece_justificative_id

View file

@ -25,22 +25,37 @@ class Procedure < ActiveRecord::Base
types_de_champ.order(:order_place) types_de_champ.order(:order_place)
end end
def types_de_piece_justificative_ordered
types_de_piece_justificative.order(:order_place)
end
def self.not_archived id def self.not_archived id
Procedure.where(archived: false).find(id) Procedure.where(archived: false).find(id)
end end
def self.active id
Procedure.where(archived: false, published: true).find(id)
end
def switch_types_de_champ index_of_first_element def switch_types_de_champ index_of_first_element
switch_list_order(types_de_champ_ordered, index_of_first_element)
end
def switch_types_de_piece_justificative index_of_first_element
switch_list_order(types_de_piece_justificative_ordered, index_of_first_element)
end
def switch_list_order(list, index_of_first_element)
return false if index_of_first_element < 0 return false if index_of_first_element < 0
types_de_champ_tmp = types_de_champ_ordered return false if index_of_first_element == list.count - 1
nb_types_de_champ = types_de_champ_tmp.count return false if list.count < 1
return false if index_of_first_element == nb_types_de_champ - 1 list[index_of_first_element].update_attributes(order_place: index_of_first_element + 1)
return false if types_de_champ_ordered.count < 1 list[index_of_first_element + 1].update_attributes(order_place: index_of_first_element)
types_de_champ_tmp[index_of_first_element].update_attributes(order_place: index_of_first_element + 1)
types_de_champ_tmp[index_of_first_element + 1].update_attributes(order_place: index_of_first_element)
true true
end end
def locked? def locked?
dossiers.where.not(state: :draft).count > 0 published?
end end
end end

View file

@ -1,12 +1,14 @@
class TypeDeChamp < ActiveRecord::Base class TypeDeChamp < ActiveRecord::Base
enum type_champs: {text: 'text', enum type_champs: {
email: 'email', text: 'text',
phone: 'phone', textarea: 'textarea',
civilite: 'civilite', datetime: 'datetime',
textarea: 'textarea', number: 'number',
datetime: 'datetime', checkbox: 'checkbox',
number: 'number', civilite: 'civilite',
checkbox: 'checkbox' email: 'email',
phone: 'phone',
address: 'address'
} }
belongs_to :procedure belongs_to :procedure

View file

@ -1,6 +1,6 @@
class TypeDePieceJustificativeSerializer < ActiveModel::Serializer class TypeDePieceJustificativeSerializer < ActiveModel::Serializer
attributes :id, attributes :id,
:libelle, :libelle,
:description :description,
:order_place
end end

View file

@ -1,14 +1,21 @@
= f.fields_for :types_de_piece_justificative, types_de_piece_justificative, remote: true do |ff|
= f.fields_for :types_de_piece_justificative, types_de_piece_justificative do |ff|
.form-inline .form-inline
.form-group .form-group
%h4 Libellé %h4 Libellé
=ff.text_field :libelle, class: 'form-control libelle', placeholder: 'Libellé' =ff.text_field :libelle, class: 'form-control libelle', placeholder: 'Libellé'
.form-group .form-group
%h4 Description %h4 Description
=ff.text_area :description, class: 'form-control description', placeholder: 'Description' =ff.text_area :description, class: 'form-control description', placeholder: 'Description'
.form-group
= ff.hidden_field :order_place, value: ff.index
= ff.hidden_field :id
- unless ff.object.id.nil?
.form-group
%br &nbsp;
= ff.object.button_up(index: ff.index, url: move_up_admin_procedure_pieces_justificatives_path(@procedure, ff.index))
= ff.object.button_down(index: ff.index, url: move_down_admin_procedure_pieces_justificatives_path(@procedure, ff.index))
.form-group .form-group
%br &nbsp; %br &nbsp;

View file

@ -1,8 +1,7 @@
= form_for [:admin, @procedure], url: admin_procedure_pieces_justificatives_path(@procedure) , remote: true do |f| = form_for [:admin, @procedure], url: admin_procedure_pieces_justificatives_path(@procedure) , remote: true do |f|
#liste_piece_justificative #liste_piece_justificative
= render partial: 'fields', locals:{ types_de_piece_justificative: @procedure.types_de_piece_justificative, f: f } = render partial: 'fields', locals:{ types_de_piece_justificative: @procedure.types_de_piece_justificative_ordered.decorate, f: f }
= f.submit "Enregistrer", class: 'btn btn-success', id: :save = f.submit "Enregistrer", class: 'btn btn-success', id: :save
%hr %hr
#new_type_de_piece_justificative #new_type_de_piece_justificative
= render partial: 'fields', locals:{ types_de_piece_justificative: TypeDePieceJustificative.new, f: f } = render partial: 'fields', locals:{ types_de_piece_justificative: TypeDePieceJustificative.new.decorate, f: f }

View file

@ -1,4 +1,4 @@
<% flash.each do |type, message| %> <% flash.each do |type, message| %>
$("#flash_message").html("<div class=\"alert alert-success move_up\" style=\"display: block:\"> <%= message.html_safe %></div>").children().fadeOut(5000) $("#flash_message").html("<div class=\"alert alert-success move_up\" style=\"display: block:\"> <%= message.html_safe %></div>").children().fadeOut(5000)
<% end %> <% end %>
$('#piece_justificative_form').html("<%= escape_javascript(render partial: 'form', locals: { procedure: @procedure } ) %>"); $('#piece_justificative_form').html("<%= escape_javascript(render partial: 'form', locals: { procedure: @procedure } ) %>");

View file

@ -0,0 +1,19 @@
- unless smart_listing.empty?
%table.table
%thead
%th#ID= smart_listing.sortable 'ID', 'id'
%th#libelle= smart_listing.sortable 'Libellé', 'libelle'
- @procedures.each do |procedure|
- procedure = procedure.decorate
%tr
%td.col-md-1.col-lg-1= procedure.id
%td.col-md-6.col-lg-6
= link_to(procedure.libelle, "/admin/procedures/#{procedure.id}")
= smart_listing.paginate
= smart_listing.pagination_per_page_links
- else
%h4.center
Aucune procédure

View file

@ -1,5 +1,10 @@
#onglets #onglets
%ul.nav.nav-tabs %ul.nav.nav-tabs
%li{class: @draft_class}
%a{:href => "#{url_for :admin_procedures_draft}"}
%h5{style: 'color: black'}
="Brouillons"
%li{class: @active_class} %li{class: @active_class}
%a{:href => "#{url_for :admin_procedures}"} %a{:href => "#{url_for :admin_procedures}"}
%h5.text-success %h5.text-success

View file

@ -1,30 +1,48 @@
#procedure_show #procedure_show
=render partial: 'head', locals: {active: 'Informations'} =render partial: 'head', locals: {active: 'Informations'}
= form_tag admin_procedure_archive_path(procedure_id: @facade.procedure.id, archive: !@facade.procedure.archived?), method: :put, style:'float: right; margin-top: 10px' do -if ! @facade.procedure.published?
%button#archive.btn.btn-small.btn-default.text-info{type: :button} = form_tag admin_procedure_publish_path(procedure_id: @facade.procedure.id, publish: true), method: :put, style:'float: right; margin-top: 10px' do
%i.fa.fa-eraser %button#archive.btn.btn-small.btn-success.text-info{type: :button}
- if @facade.procedure.archived %i.fa.fa-eraser
= 'Réactiver' Publier
- else #confirm
= 'Archiver' %button#valid.btn.btn-small.btn-success{type: :submit}
#confirm %i.fa.fa-check
%button#valid.btn.btn-small.btn-success{type: :submit} Valider
%i.fa.fa-check %button#cancel.btn.btn-small.btn-danger{type: :button}
Valider %i.fa.fa-remove
%button#cancel.btn.btn-small.btn-danger{type: :button} Annuler
%i.fa.fa-remove
Annuler -else
= form_tag admin_procedure_archive_path(procedure_id: @facade.procedure.id, archive: !@facade.procedure.archived?), method: :put, style:'float: right; margin-top: 10px' do
%button#archive.btn.btn-small.btn-default.text-info{type: :button}
%i.fa.fa-eraser
- if @facade.procedure.archived
= 'Réactiver'
- else
= 'Archiver'
#confirm
%button#valid.btn.btn-small.btn-success{type: :submit}
%i.fa.fa-check
Valider
%button#cancel.btn.btn-small.btn-danger{type: :button}
%i.fa.fa-remove
Annuler
- if @facade.procedure.locked? - if @facade.procedure.locked?
#procedure_locked.center #procedure_locked.center
%h5 %h5
.label.label-info La procédure ne peut plus être modifiée car un usagé a déjà déposé un dossier .label.label-info La procédure ne peut plus être modifiée car elle a été publiée
%div %div
%h3 Lien procédure %h3 Lien procédure
%div{style:'margin-left:3%'} %div{style:'margin-left:3%'}
= @facade.procedure.lien -if @facade.procedure.published?
= @facade.procedure.lien
-else
%b
Cette procédure n'a pas encore été publiée et n'est donc pas accessible par le public.
%br %br
%h3 Détails %h3 Détails

View file

@ -0,0 +1,33 @@
#beta
Beta
= image_tag('marianne_small.png', class: 'logo')
%a{href: '/'}
= image_tag('logo-tps.png', class: 'logo')
%a{href: '/', class: 'btn btn-md'}
-if gestionnaire_signed_in? || user_signed_in?
Mes Dossiers
-elsif administrateur_signed_in?
Mes Procédures
#sign_out
-if gestionnaire_signed_in?
= render partial: 'gestionnaires/login_banner'
-elsif administrateur_signed_in?
= render partial: 'administrateurs/login_banner'
- elsif user_signed_in?
%div.user
-if current_user.loged_in_with_france_connect?
%div{ id: "fconnect-profile", "data-fc-logout-url" => '/users/sign_out" data-method="delete' }
%a.text-info{ href: "#" }
= "#{current_user.given_name} #{current_user.family_name}"
= link_to "", '/users/sign_out', method: :delete, :class => 'btn fa fa-power-off off-fc-link'
-else
%i.fa.fa-user
= current_user.email
= link_to "Déconnexion", '/users/sign_out', method: :delete, :class => 'btn btn-md'
- else
= link_to "Utilisateur", '/users/sign_in', method: :get, :class => 'btn btn-md'
= link_to "Accompagnateur", '/gestionnaires/sign_in', method: :get, :class => 'btn btn-md'
= link_to "Administrateur", '/administrateurs/sign_in', method: :get, :class => 'btn btn-md'

View file

@ -12,36 +12,7 @@
%body %body
%div#wrap %div#wrap
%div#header.navbar %div#header.navbar
=render partial: "layouts/navbar"
#beta
Beta
= image_tag('marianne_small.png', class: 'logo')
%a{href: '/'}
= image_tag('logo-tps.png', class: 'logo')
#sign_out
-if gestionnaire_signed_in?
= render partial: 'gestionnaires/login_banner'
-elsif administrateur_signed_in?
= render partial: 'administrateurs/login_banner'
- elsif user_signed_in?
%div.user
-if current_user.loged_in_with_france_connect?
%div{ id: "fconnect-profile", "data-fc-logout-url" => '/users/sign_out" data-method="delete' }
%a.text-info{ href: "#" }
= "#{current_user.given_name} #{current_user.family_name}"
= link_to "", '/users/sign_out', method: :delete, :class => 'btn fa fa-power-off off-fc-link'
-else
%i.fa.fa-user
= current_user.email
= link_to "Déconnexion", '/users/sign_out', method: :delete, :class => 'btn btn-md'
- else
= link_to "Utilisateur", '/users/sign_in', method: :get, :class => 'btn btn-md'
= link_to "Accompagnateur", '/gestionnaires/sign_in', method: :get, :class => 'btn btn-md'
= link_to "Administrateur", '/administrateurs/sign_in', method: :get, :class => 'btn btn-md'
#flash_message.center #flash_message.center
- if flash.notice - if flash.notice
@ -50,7 +21,6 @@
- if flash.alert - if flash.alert
.alert.alert-danger .alert.alert-danger
= flash.alert = flash.alert
#main_div.main_div #main_div.main_div
= yield = yield

View file

@ -58,10 +58,14 @@
.row.word.news .row.word.news
.latest_release.col-md-7.col-lg-7 .latest_release.col-md-7.col-lg-7
%h3.text-info - if @latest_release.nil?
= "Dernière version (#{@latest_release.tag_name} - #{@latest_release.published_at})" %p
.body Erreur dans la récupération des données
=@latest_release.body.html_safe -else
%h3.text-info
= "Dernière version (#{@latest_release.tag_name} - #{@latest_release.published_at})"
.body
=@latest_release.body.html_safe
.center .center
\- \-

View file

@ -9,6 +9,8 @@
\- \-
%button#delete.btn.btn-sm.btn-danger{type:'button'} Supprimer %button#delete.btn.btn-sm.btn-danger{type:'button'} Supprimer
%span#search_by_address{style: 'margin-left: 20px'}
%input.form-control{type: :address, placeholder: 'Rechercher une adresse'}
%br %br
%br %br
#carte_page.row #carte_page.row
@ -24,7 +26,6 @@
%h3.text-warning Cadastres %h3.text-warning Cadastres
%ul %ul
= form_tag(url_for({controller: :carte, action: :save, dossier_id: @dossier.id}), class: 'form-inline', method: 'POST') do = form_tag(url_for({controller: :carte, action: :save, dossier_id: @dossier.id}), class: 'form-inline', method: 'POST') do
%br %br
%input{type: 'hidden', value: "#{@dossier.json_latlngs}", name: 'json_latlngs', id: 'json_latlngs'} %input{type: 'hidden', value: "#{@dossier.json_latlngs}", name: 'json_latlngs', id: 'json_latlngs'}

View file

@ -34,5 +34,9 @@
id: "champs_#{champ.id}", id: "champs_#{champ.id}",
value: champ.value, value: champ.value,
type: champ.type_champ, type: champ.type_champ,
'data-provide' => ('datepicker' if champ.type_champ == 'datetime'), 'data-provide' => champ.data_provide,
'data-date-format' => ('dd/mm/yyyy' if champ.type_champ == 'datetime')} 'data-date-format' => ('dd/mm/yyyy' if champ.type_champ == 'datetime')}
- unless champ.description.empty?
.row
.col-lg-8.col-md-8{class: 'description_div', id:"description_champs_#{champ.id}"}
= champ.description

View file

@ -82,6 +82,7 @@ Rails.application.routes.draw do
namespace :admin do namespace :admin do
get 'sign_in' => '/administrateurs/sessions#new' get 'sign_in' => '/administrateurs/sessions#new'
get 'procedures/archived' => 'procedures#archived' get 'procedures/archived' => 'procedures#archived'
get 'procedures/draft' => 'procedures#draft'
get 'profile' => 'profile#show', as: :profile get 'profile' => 'profile#show', as: :profile
resources :procedures do resources :procedures do
@ -89,8 +90,13 @@ Rails.application.routes.draw do
post '/:index/move_up' => 'types_de_champ#move_up', as: :move_up post '/:index/move_up' => 'types_de_champ#move_up', as: :move_up
post '/:index/move_down' => 'types_de_champ#move_down', as: :move_down post '/:index/move_down' => 'types_de_champ#move_down', as: :move_down
end end
resource :pieces_justificatives, only: [:show, :update] do
post '/:index/move_up' => 'pieces_justificatives#move_up', as: :move_up
post '/:index/move_down' => 'pieces_justificatives#move_down', as: :move_down
end
put 'archive' => 'procedures#archive', as: :archive put 'archive' => 'procedures#archive', as: :archive
put 'publish' => 'procedures#publish', as: :publish
resource :accompagnateurs, only: [:show, :update] resource :accompagnateurs, only: [:show, :update]
@ -108,6 +114,11 @@ Rails.application.routes.draw do
resources :gestionnaires, only: [:index, :create, :destroy] resources :gestionnaires, only: [:index, :create, :destroy]
end end
namespace :ban do
get 'search' => 'search#get'
get 'address_point' => 'search#get_address_point'
end
get 'backoffice' => 'backoffice#index' get 'backoffice' => 'backoffice#index'
namespace :backoffice do namespace :backoffice do

View file

@ -0,0 +1,9 @@
class AddOrderPlaceInTypeDePieceJustificative < ActiveRecord::Migration
def up
add_column :types_de_piece_justificative, :order_place, :integer
end
def down
remove_column :types_de_piece_justificative, :order_place
end
end

View file

@ -0,0 +1,12 @@
class AddProcedureStatus < ActiveRecord::Migration
class Procedure < ActiveRecord::Base
end
def change
add_column :procedures, :published, :boolean, default: false, null: false
Procedure.all.each do |procedure|
procedure.published = true
procedure.save!
end
end
end

View file

@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160524093540) do ActiveRecord::Schema.define(version: 20160609125949) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -242,6 +242,7 @@ ActiveRecord::Schema.define(version: 20160524093540) do
t.string "logo" t.string "logo"
t.boolean "cerfa_flag", default: false t.boolean "cerfa_flag", default: false
t.string "logo_secure_token" t.string "logo_secure_token"
t.boolean "published", default: false, null: false
end end
create_table "quartier_prioritaires", force: :cascade do |t| create_table "quartier_prioritaires", force: :cascade do |t|
@ -278,6 +279,7 @@ ActiveRecord::Schema.define(version: 20160524093540) do
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.integer "procedure_id" t.integer "procedure_id"
t.integer "order_place"
end end
create_table "users", force: :cascade do |t| create_table "users", force: :cascade do |t|

View file

@ -0,0 +1,36 @@
module Carto
module Bano
# input : address
# output : Array List label address
class AddressRetriever
def initialize(address)
@address = address
end
def list
@list ||= convert_driver_result_to_full_address
end
private
def driver
@driver ||= Carto::Bano::Driver.new @address, 5
end
def convert_driver_result_to_full_address
result = JSON.parse(driver.call)
if result['features'].size == 0
Rails.logger.error "unable to find location for address #{@address}"
return []
end
result['features'].inject([]) do |acc, feature|
acc.push feature['properties']['label']
end
rescue TypeError, JSON::ParserError
[]
end
end
end
end

View file

@ -3,12 +3,15 @@ module Carto
# input : string (address) # input : string (address)
# output : json # output : json
class Driver class Driver
def initialize(address) def initialize(address, limit = 1)
@address = address @address = address
@limit = limit
end end
def call def call
RestClient.get api_url, params: { q: @address, limit: 1 } RestClient.get api_url, params: { q: @address, limit: @limit }
rescue RestClient::ServiceUnavailable
nil
end end
def api_url def api_url

View file

@ -12,7 +12,9 @@ class Github::API
def self.call(end_point, params = {}) def self.call(end_point, params = {})
RestClient::Resource.new( RestClient::Resource.new(
base_uri+end_point base_uri+end_point, timeout: 5
).get(params: params) ).get(params: params)
rescue RestClient::Forbidden
nil
end end
end end

View file

@ -2,8 +2,10 @@ class Github::Releases
def self.latest def self.latest
release = Hashie::Mash.new JSON.parse(Github::API.latest_release) release = Hashie::Mash.new JSON.parse(Github::API.latest_release)
release.published_at = release.published_at.to_date.strftime('%d/%m/%Y')
return nil if release.nil?
release.published_at = release.published_at.to_date.strftime('%d/%m/%Y')
release release
end end
end end

View file

@ -2,12 +2,13 @@ require 'spec_helper'
describe Admin::PiecesJustificativesController, type: :controller do describe Admin::PiecesJustificativesController, type: :controller do
let(:admin) { create(:administrateur) } let(:admin) { create(:administrateur) }
let(:published) { false }
let(:procedure) { create(:procedure, administrateur: admin, published: published) }
before do before do
sign_in admin sign_in admin
end end
describe 'GET #show' do describe 'GET #show' do
let(:procedure) { create(:procedure, administrateur: admin) }
let(:procedure_id) { procedure.id } let(:procedure_id) { procedure.id }
subject { get :show, procedure_id: procedure_id } subject { get :show, procedure_id: procedure_id }
@ -17,8 +18,8 @@ describe Admin::PiecesJustificativesController, type: :controller do
it { expect(subject.status).to eq(404) } it { expect(subject.status).to eq(404) }
end end
context 'when procedure have at least a file' do context 'when procedure is published' do
let!(:dossier) { create(:dossier, procedure: procedure, state: :initiated) } let(:published) { true }
it { is_expected.to redirect_to admin_procedure_path id: procedure_id } it { is_expected.to redirect_to admin_procedure_path id: procedure_id }
end end
@ -30,7 +31,6 @@ describe Admin::PiecesJustificativesController, type: :controller do
end end
describe 'PUT #update' do describe 'PUT #update' do
let(:procedure) { create(:procedure, administrateur: admin) }
let(:procedure_id) { procedure.id } let(:procedure_id) { procedure.id }
let(:libelle) { 'RIB' } let(:libelle) { 'RIB' }
let(:description) { "relevé d'identité bancaire" } let(:description) { "relevé d'identité bancaire" }
@ -72,7 +72,6 @@ describe Admin::PiecesJustificativesController, type: :controller do
end end
describe 'DELETE #destroy' do describe 'DELETE #destroy' do
let(:procedure) { create(:procedure, administrateur: admin) }
let!(:pj) { create(:type_de_piece_justificative, procedure: procedure) } let!(:pj) { create(:type_de_piece_justificative, procedure: procedure) }
let(:procedure_id) { procedure.id } let(:procedure_id) { procedure.id }
let(:pj_id) { pj.id } let(:pj_id) { pj.id }
@ -97,4 +96,76 @@ describe Admin::PiecesJustificativesController, type: :controller do
it { expect{ subject }.to change(TypeDePieceJustificative, :count).by(-1) } it { expect{ subject }.to change(TypeDePieceJustificative, :count).by(-1) }
end end
end end
describe 'POST #move_up' do
subject { post :move_up, procedure_id: procedure.id, index: index, format: :js }
context 'when procedure have no type de champ' do
let(:index) { 0 }
it { expect(subject.status).to eq(400) }
end
context 'when procedure have only one type de champ' do
let(:index) { 1 }
let!(:type_de_piece_justificative) { create(:type_de_piece_justificative, procedure: procedure) }
it { expect(subject.status).to eq(400) }
end
context 'when procedure have tow type de champs' do
context 'when index == 0' do
let(:index) { 0 }
let!(:type_de_piece_justificative_1) { create(:type_de_piece_justificative, procedure: procedure) }
let!(:type_de_piece_justificative_2) { create(:type_de_piece_justificative, procedure: procedure) }
it { expect(subject.status).to eq(400) }
end
context 'when index > 0' do
let(:index) { 1 }
let!(:type_de_piece_justificative_0) { create(:type_de_piece_justificative, procedure: procedure, order_place: 0) }
let!(:type_de_piece_justificative_1) { create(:type_de_piece_justificative, procedure: procedure, order_place: 1) }
it { expect(subject.status).to eq(200) }
it { expect(subject).to render_template('show') }
it 'changes order places' do
post :move_up, procedure_id: procedure.id, index: index, format: :js
type_de_piece_justificative_0.reload
type_de_piece_justificative_1.reload
expect(type_de_piece_justificative_0.order_place).to eq(1)
expect(type_de_piece_justificative_1.order_place).to eq(0)
end
end
end
end
describe 'POST #move_down' do
let(:request) { post :move_down, procedure_id: procedure.id, index: index, format: :js }
let(:index) { 0 }
subject { request }
context 'when procedure have no type de champ' do
it { expect(subject.status).to eq(400) }
end
context 'when procedure have only one type de champ' do
let!(:type_de_piece_justificative_0) { create(:type_de_piece_justificative, procedure: procedure) }
it { expect(subject.status).to eq(400) }
end
context 'when procedure have 2 type de champ' do
let!(:type_de_piece_justificative_0) { create(:type_de_piece_justificative, procedure: procedure, order_place: 0) }
let!(:type_de_piece_justificative_1) { create(:type_de_piece_justificative, procedure: procedure, order_place: 1) }
context 'when index represent last type_de_piece_justificative' do
let(:index) { 1 }
it { expect(subject.status).to eq(400) }
end
context 'when index does not represent last type_de_piece_justificative' do
let(:index) { 0 }
it { expect(subject.status).to eq(200) }
it { expect(subject).to render_template('show') }
it 'changes order place' do
request
type_de_piece_justificative_0.reload
type_de_piece_justificative_1.reload
expect(type_de_piece_justificative_0.order_place).to eq(1)
expect(type_de_piece_justificative_1.order_place).to eq(0)
end
end
end
end
end end

View file

@ -46,8 +46,15 @@ describe Admin::ProceduresController, type: :controller do
it { expect(response.status).to eq(200) } it { expect(response.status).to eq(200) }
end end
describe 'GET #published' do
subject { get :published }
it { expect(response.status).to eq(200) }
end
describe 'GET #edit' do describe 'GET #edit' do
let(:procedure) { create(:procedure, administrateur: admin) } let(:published) { false }
let(:procedure) { create(:procedure, administrateur: admin, published: published) }
let(:procedure_id) { procedure.id } let(:procedure_id) { procedure.id }
subject { get :edit, id: procedure_id } subject { get :edit, id: procedure_id }
@ -66,8 +73,8 @@ describe Admin::ProceduresController, type: :controller do
it { expect(subject).to have_http_status(:success) } it { expect(subject).to have_http_status(:success) }
end end
context 'when procedure have at least a file' do context 'when procedure is published' do
let!(:dossier) { create(:dossier, procedure: procedure, state: :initiated) } let(:published) { true }
it { is_expected.to redirect_to admin_procedure_path id: procedure_id } it { is_expected.to redirect_to admin_procedure_path id: procedure_id }
end end

View file

@ -9,7 +9,8 @@ describe Admin::TypesDeChampController, type: :controller do
end end
describe 'GET #show' do describe 'GET #show' do
let(:procedure) { create(:procedure, administrateur: admin) } let(:published) { false }
let(:procedure) { create(:procedure, administrateur: admin, published: published) }
let(:procedure_id) { procedure.id } let(:procedure_id) { procedure.id }
subject { get :show, procedure_id: procedure_id } subject { get :show, procedure_id: procedure_id }
@ -19,8 +20,8 @@ describe Admin::TypesDeChampController, type: :controller do
it { expect(subject.status).to eq(404) } it { expect(subject.status).to eq(404) }
end end
context 'when procedure have at least a file' do context 'when procedure is published' do
let!(:dossier) { create(:dossier, procedure: procedure, state: :initiated) } let(:published) { true }
it { is_expected.to redirect_to admin_procedure_path id: procedure_id } it { is_expected.to redirect_to admin_procedure_path id: procedure_id }
end end

View file

@ -0,0 +1,16 @@
require 'spec_helper'
describe Ban::SearchController, type: :controller do
describe '#GET' do
let (:request) { '' }
before do
stub_request(:get, "http://api-adresse.data.gouv.fr/search?limit=5&q=").
to_return(:status => 200, :body => 'Missing query', :headers => {})
get :get, request: request
end
it { expect(response.status).to eq 200 }
end
end

View file

@ -3,7 +3,7 @@ require 'spec_helper'
describe Users::DossiersController, type: :controller do describe Users::DossiersController, type: :controller do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure, :published) }
let(:procedure_id) { procedure.id } let(:procedure_id) { procedure.id }
let(:dossier) { create(:dossier, :with_entreprise, user: user, procedure: procedure) } let(:dossier) { create(:dossier, :with_entreprise, user: user, procedure: procedure) }
let(:dossier_id) { dossier.id } let(:dossier_id) { dossier.id }
@ -80,6 +80,16 @@ describe Users::DossiersController, type: :controller do
it { is_expected.to redirect_to users_dossiers_path } it { is_expected.to redirect_to users_dossiers_path }
end end
context 'when procedure is not published' do
let(:procedure) { create(:procedure, published: false) }
before do
sign_in create(:user)
end
it { is_expected.to redirect_to users_dossiers_path }
end
end end
end end

View file

@ -85,8 +85,18 @@ describe Users::SessionsController, type: :controller do
it { expect(subject).to redirect_to root_path } it { expect(subject).to redirect_to root_path }
end end
context 'when procedure is not published' do
let(:procedure) { create :procedure, published: false }
before do
session["user_return_to"] = "?procedure_id=#{procedure.id}"
end
it { expect(subject.status).to eq 302}
it { expect(subject).to redirect_to root_path }
end
context 'when procedure_id exist' do context 'when procedure_id exist' do
let(:procedure) { create :procedure } let(:procedure) { create :procedure, published: true }
before do before do
session["user_return_to"] = "?procedure_id=#{procedure.id}" session["user_return_to"] = "?procedure_id=#{procedure.id}"

View file

@ -0,0 +1,55 @@
require 'spec_helper'
describe TypeDeChampDecorator do
let(:procedure) { create(:procedure) }
let(:url) { 'http://localhost' }
let(:params) { { url: url, index: index } }
let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) }
let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) }
let!(:type_de_champ_2) { create(:type_de_champ, procedure: procedure, order_place: 2) }
describe '#button_up' do
describe 'with first piece justificative' do
let(:index) { 0 }
subject { type_de_champ_0.decorate }
let(:button_up) { type_de_champ_.decorate }
it 'returns a button up' do
expect(subject.button_up(params)).to be(nil)
end
it 'returns a button down' do
expect(subject.button_down(params)).to match(/fa-chevron-down/)
end
end
describe 'with second out of three piece justificative' do
let(:index) { 1 }
subject { type_de_champ_1.decorate }
let(:button_up) { type_de_champ_1.decorate }
it 'returns a button up' do
expect(subject.button_up(params)).to match(/fa-chevron-up/)
end
it 'returns a button down' do
expect(subject.button_down(params)).to match(/fa-chevron-down/)
end
end
describe 'with last piece justificative' do
let(:index) { 2 }
subject { type_de_champ_2.decorate }
let(:button_up) { type_de_champ_1.decorate }
it 'returns a button up' do
expect(subject.button_up(params)).to match(/fa-chevron-up/)
end
it 'returns a button down' do
expect(subject.button_down(params)).to be(nil)
end
end
end
end

View file

@ -0,0 +1,54 @@
require 'spec_helper'
describe TypeDePieceJustificativeDecorator do
let(:procedure) { create(:procedure) }
let(:url) { 'http://localhost' }
let(:params) { { url: url, index: index } }
let!(:type_de_piece_justificative_0) { create(:type_de_piece_justificative, procedure: procedure, order_place: 0) }
let!(:type_de_piece_justificative_1) { create(:type_de_piece_justificative, procedure: procedure, order_place: 1) }
let!(:type_de_piece_justificative_2) { create(:type_de_piece_justificative, procedure: procedure, order_place: 2) }
describe '#button_up' do
describe 'with first piece justificative' do
let(:index) { 0 }
subject { type_de_piece_justificative_0.decorate }
let(:button_up) { type_de_piece_justificative_.decorate }
it 'returns a button up' do
expect(subject.button_up(params)).to be(nil)
end
it 'returns a button down' do
expect(subject.button_down(params)).to match(/fa-chevron-down/)
end
end
describe 'with second out of three piece justificative' do
let(:index) { 1 }
subject { type_de_piece_justificative_1.decorate }
let(:button_up) { type_de_piece_justificative_1.decorate }
it 'returns a button up' do
expect(subject.button_up(params)).to match(/fa-chevron-up/)
end
it 'returns a button down' do
expect(subject.button_down(params)).to match(/fa-chevron-down/)
end
end
describe 'with last piece justificative' do
let(:index) { 2 }
subject { type_de_piece_justificative_2.decorate }
let(:button_up) { type_de_piece_justificative_1.decorate }
it 'returns a button up' do
expect(subject.button_up(params)).to match(/fa-chevron-up/)
end
it 'returns a button down' do
expect(subject.button_down(params)).to be(nil)
end
end
end
end

4
spec/factories/champ.rb Normal file
View file

@ -0,0 +1,4 @@
FactoryGirl.define do
factory :champ do
end
end

View file

@ -5,6 +5,7 @@ FactoryGirl.define do
description "Demande de subvention à l'intention des associations" description "Demande de subvention à l'intention des associations"
organisation "Orga SGMAP" organisation "Orga SGMAP"
direction "direction SGMAP" direction "direction SGMAP"
published false
after(:build) do |procedure, _evaluator| after(:build) do |procedure, _evaluator|
if procedure.module_api_carto.nil? if procedure.module_api_carto.nil?
@ -44,5 +45,11 @@ FactoryGirl.define do
procedure.types_de_piece_justificative << msa procedure.types_de_piece_justificative << msa
end end
end end
trait :published do
after(:build) do |procedure, _evaluator|
procedure.published = true
end
end
end end
end end

View file

@ -3,26 +3,27 @@ require 'spec_helper'
feature 'procedure locked' do feature 'procedure locked' do
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }
let(:procedure) { create(:procedure, administrateur: administrateur) } let(:published) { false }
let(:procedure) { create(:procedure, administrateur: administrateur, published: published) }
before do before do
login_as administrateur, scope: :administrateur login_as administrateur, scope: :administrateur
visit admin_procedure_path(procedure) visit admin_procedure_path(procedure)
end end
context 'when procedure have no file' do context 'when procedure is not published' do
scenario 'info label is not present' do scenario 'info label is not present' do
expect(page).not_to have_content('La procédure ne peut plus être modifiée car un usagé a déjà déposé un dossier') expect(page).not_to have_content('La procédure ne peut plus être modifiée car elle a été publiée')
end end
end end
context 'when procedure have at least a file' do context 'when procedure is published' do
let(:published) { true }
before do before do
create(:dossier, procedure: procedure, state: :initiated)
visit admin_procedure_path(procedure) visit admin_procedure_path(procedure)
end end
scenario 'info label is present' do scenario 'info label is present' do
expect(page).to have_content('La procédure ne peut plus être modifiée car un usagé a déjà déposé un dossier') expect(page).to have_content('La procédure ne peut plus être modifiée car elle a été publiée')
end end
context 'when user click on Description tab' do context 'when user click on Description tab' do
@ -45,7 +46,7 @@ feature 'procedure locked' do
end end
end end
context 'when user click on Pieces Justificatiives tab' do context 'when user click on Pieces Justificatives tab' do
before do before do
page.click_on 'Pièces justificatives' page.click_on 'Pièces justificatives'
end end

View file

@ -2,9 +2,10 @@ require 'spec_helper'
feature 'user path for dossier creation' do feature 'user path for dossier creation' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure, :published) }
let(:siret) { '53272417600013' } let(:siret) { '53272417600013' }
let(:siren) { siret[0...9] } let(:siren) { siret[0...9] }
context 'user arrives on siret page' do context 'user arrives on siret page' do
before do before do
visit new_users_dossiers_path(procedure_id: procedure.id) visit new_users_dossiers_path(procedure_id: procedure.id)
@ -65,4 +66,15 @@ feature 'user path for dossier creation' do
end end
end end
end end
context 'user cannot access non-published procedures' do
let(:procedure) { create(:procedure) }
before do
visit new_users_dossiers_path(procedure_id: procedure.id)
end
scenario 'user is on home page', vcr: { cassette_name: 'complete_demande_spec' } do
expect(page).to have_content('La procédure n\'existe pas')
end
end
end end

View file

@ -1,7 +1,7 @@
require 'spec_helper' require 'spec_helper'
feature 'user arrive on siret page' do feature 'user arrive on siret page' do
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure, :published) }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:siret) { '42149333900020' } let(:siret) { '42149333900020' }
let(:siren) { siret[0...9] } let(:siren) { siret[0...9] }

View file

@ -0,0 +1,101 @@
---
http_interactions:
- request:
method: get
uri: https://api.github.com/repos/sgmap/tps/releases/latest
body:
encoding: US-ASCII
string: ''
headers:
Accept:
- "*/*; q=0.5, application/xml"
Accept-Encoding:
- gzip, deflate
User-Agent:
- Ruby
response:
status:
code: 200
message: OK
headers:
Server:
- GitHub.com
Date:
- Thu, 09 Jun 2016 14:42:08 GMT
Content-Type:
- application/json; charset=utf-8
Transfer-Encoding:
- chunked
Status:
- 200 OK
X-Ratelimit-Limit:
- '60'
X-Ratelimit-Remaining:
- '43'
X-Ratelimit-Reset:
- '1465485629'
Cache-Control:
- public, max-age=60, s-maxage=60
Vary:
- Accept
- Accept-Encoding
Etag:
- W/"0962b5ade3f87b4e0092d56f4719512e"
Last-Modified:
- Fri, 03 Jun 2016 10:05:19 GMT
X-Github-Media-Type:
- github.v3
Access-Control-Expose-Headers:
- ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset,
X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
Access-Control-Allow-Origin:
- "*"
Content-Security-Policy:
- default-src 'none'
Strict-Transport-Security:
- max-age=31536000; includeSubdomains; preload
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- deny
X-Xss-Protection:
- 1; mode=block
X-Served-By:
- c6c65e5196703428e7641f7d1e9bc353
Content-Encoding:
- gzip
X-Github-Request-Id:
- B918B84A:B215:2AB0D00D:5759803F
body:
encoding: ASCII-8BIT
string: !binary |-
H4sIAAAAAAAAA6VW7WobRxR9lWH/+I/jlSrjEuE2mEAhYEogTiltihjtXq0m
zM5s5mMjR/hdQn9Fz7Ev1nNHK1lSZAdRsJFXe++Ze88994yXWXQ6G2fzEBo/
znPZqItKhXmcXhS2zh011ue+qmWTIwDPmqQnn49GV1ejwc/ZeSa9p+An/wsm
X4MALTbayvIAbf2lP6WwHnH5ysiazrWckn4A/DzU+gB8p9sjfQZZ5e3wYoRc
VWbjvu3zDN9PGBrU9a+DdBWFCVirVVB+jje19IEcUncixVjczGZUBBmUNaIk
L2SBpEZWRgaKzgsKolHdtwKvPkYf1EwVCG7xWN4DSX2K5AFaOjkL2XgmtSeM
IYa5ddl4mWlbKYPT//wY9ZthX/hwNBhevrwaILCVKPVwXunLDcPRkyusCWRC
UkHMN+mv2l+Yisr1KMxJxmN7TkQM5/NtOc/PYBs2s1rbz8g8LHVfobvg+TYH
Ja3/VqY6OR85y9yGOYEllM66qZT/kcb3Cknxy5w/JqpkBA9+HR0q+2Dd9jD6
DJTy2aCKZVrGBBWnvnCqYQGdws5eHnCsq6RRX5IQT8FBHusvecMJ5KZ45FEL
XZ2SuE5Y5o1TrSzumQJHBWEjysnJYAeZwAr3Da/xe4yayVWBJrKseYXSaj2c
Z42j3vi261Y4wraWE4kNzH4aDK9eDPAzuhu8HA/xM/gLUE2cahjBkajhYDy4
HF+OOKq3vvHf/7CruKnUhw71A0/ukzY29UU1p2P0SRuMqS3v0df1fPTr7za2
BHPpVv46x/MH98FcR73+1Cp9vjdCGjiUchFuZqS+9yRqqdhB8EKQEYHqxgvX
rUiLYBGm2c5sEWsWg/gUFaKCw6/w0QktRaNB8My6mi7SmXl/2PXm0KDA7qNl
HrpoQygccHt1tPaeXDLdx7NLBU2gPg4uqYmKixMzHRd4FOzneCMRhCQ8zyX8
F+neK3Ln3Fuj0Q9jPuXaVEtTonVEWDTHbq+7Fa4GPqhHOt7kLXiQFYK4EGNo
wXdGAolGxEcGBPm9TpN7L0KUoAgHi+5rotTZoluV0ZHwShSko3pR9MQn2u/e
vhOV6/4tUgaO0Ar94XCzVsHzxbIMeHFgek7yVSYaintlyXTzoe+ETrsFHbsI
fdOtClx/fOEx0TNriv7WFPgnREzJW2X8hWCB3J7tK0AAvyXnWEmYDw9trbk0
uH5gW0Kg27hAjOYYpROf62q71cFo8o36sQ03dbfSyqJdDGa7H8d25Ba4OwNj
KXjffSsPJMqstCjVK2gErfPwtqIEo71a1hogs9HzekCp+OMiPC6vOxsDUp5O
Ex5C2l2hOYZrXRIVcwpdp0EmfeB4ZtyzRpm/VB43gH9osPObk/oQuAGC0tIp
31ijplwGpqxVZZ7Y+T26MUJcAQ5C2PeHzXzSt5jRa4uLN+nm0cGOTegxjhWv
z2SJApORaZaCKuZpGNKAsDNaNNYF8frdH6I8w6Js5tIqibc3b9/wLh0nHWuy
u7m8BrwmSaXSFXPVdiuu4KgxpMJ7B/xNLcQ0Vj0N3/vm97RkD/8BJlYZoPAL
AAA=
http_version:
recorded_at: Thu, 09 Jun 2016 14:42:08 GMT
recorded_with: VCR 3.0.1

View file

@ -0,0 +1,44 @@
require 'spec_helper'
describe Carto::Bano::AddressRetriever do
describe '#list' do
let(:request) { 'Paris' }
let(:response) { File.open('spec/support/files/ban_address_search.json') }
let(:status) { 200 }
subject { described_class.new(request).list }
before do
stub_request(:get, "http://api-adresse.data.gouv.fr/search?&q=#{request}&limit=5")
.to_return(status: status, body: response, headers: {})
end
context 'when address return a list of address' do
it { expect(subject.size).to eq 5 }
it { is_expected.to be_an_instance_of Array }
end
context 'when address return an empty list' do
let(:response) { File.open('spec/support/files/ban_address_search_no_result.json') }
it { expect(subject.size).to eq 0 }
it { is_expected.to be_an_instance_of Array }
end
context 'when BAN is unavailable' do
let(:status) { 503 }
let(:response) { '' }
it { expect(subject.size).to eq 0 }
it { is_expected.to be_an_instance_of Array }
end
context 'when request is empty' do
let(:response) { 'Missing query' }
let(:request) { '' }
it { expect(subject.size).to eq 0 }
it { is_expected.to be_an_instance_of Array }
end
end
end

View file

@ -15,4 +15,26 @@ describe Champ do
it { is_expected.to delegate_method(:type_champ).to(:type_de_champ) } it { is_expected.to delegate_method(:type_champ).to(:type_de_champ) }
it { is_expected.to delegate_method(:order_place).to(:type_de_champ) } it { is_expected.to delegate_method(:order_place).to(:type_de_champ) }
end end
describe 'data_provide' do
let(:champ) { create :champ }
subject { champ.data_provide }
context 'when type_champ is datetime' do
before do
champ.type_de_champ = create :type_de_champ, type_champ: 'datetime'
end
it { is_expected.to eq 'datepicker' }
end
context 'when type_champ is address' do
before do
champ.type_de_champ = create :type_de_champ, type_champ: 'address'
end
it { is_expected.to eq 'typeahead' }
end
end
end end

View file

@ -79,28 +79,47 @@ describe Procedure do
end end
describe 'locked?' do describe 'locked?' do
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure, published: published) }
subject { procedure.locked? } subject { procedure.locked? }
context 'when procedure does not have dossier' do context 'when procedure is in draft status' do
let(:published) { false }
it { is_expected.to be_falsey } it { is_expected.to be_falsey }
end end
context 'when procedure have dossier with state draft' do context 'when procedure is in draft status' do
before do let(:published) { true }
create(:dossier, procedure: procedure, state: :draft)
end
it { is_expected.to be_falsey }
end
context 'when procedure have dossier with state initiated' do
before do
create(:dossier, procedure: procedure, state: :initiated)
end
it { is_expected.to be_truthy } it { is_expected.to be_truthy }
end end
end end
describe 'active' do
let(:procedure) { create(:procedure, published: published, archived: archived) }
subject { Procedure.active(procedure.id) }
context 'when procedure is in draft status and not archived' do
let(:published) { false }
let(:archived) { false }
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
end
context 'when procedure is published and not archived' do
let(:published) { true }
let(:archived) { false }
it { is_expected.to be_truthy }
end
context 'when procedure is published and archived' do
let(:published) { true }
let(:archived) { true }
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
end
context 'when procedure is in draft status and archived' do
let(:published) { false }
let(:archived) { true }
it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
end
end
end end

View file

@ -9,6 +9,7 @@ describe TypeDePieceJustificative do
it { is_expected.to have_db_column(:api_entreprise) } it { is_expected.to have_db_column(:api_entreprise) }
it { is_expected.to have_db_column(:created_at) } it { is_expected.to have_db_column(:created_at) }
it { is_expected.to have_db_column(:updated_at) } it { is_expected.to have_db_column(:updated_at) }
it { is_expected.to have_db_column(:order_place) }
end end
describe 'associations' do describe 'associations' do
@ -22,5 +23,11 @@ describe TypeDePieceJustificative do
it { is_expected.not_to allow_value('').for(:libelle) } it { is_expected.not_to allow_value('').for(:libelle) }
it { is_expected.to allow_value('RIB').for(:libelle) } it { is_expected.to allow_value('RIB').for(:libelle) }
end end
context 'order_place' do
# it { is_expected.not_to allow_value(nil).for(:order_place) }
# it { is_expected.not_to allow_value('').for(:order_place) }
it { is_expected.to allow_value(1).for(:order_place) }
end
end end
end end

View file

@ -0,0 +1,117 @@
{
"limit": 5,
"attribution": "BAN",
"version": "draft",
"licence": "ODbL 1.0",
"query": "Paris",
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type": "Point",
"coordinates": [
2.3469,
48.8589
]
},
"properties": {
"adm_weight": "6",
"citycode": "75056",
"name": "Paris",
"city": "Paris",
"postcode": "75000",
"context": "75, \u00cele-de-France",
"score": 1.0,
"label": "Paris",
"id": "75056",
"type": "city",
"population": "2244"
},
"type": "Feature"
},
{
"geometry": {
"type": "Point",
"coordinates": [
4.366801,
44.425528
]
},
"properties": {
"citycode": "07330",
"postcode": "07150",
"name": "Paris",
"id": "07330_B095_bd3524",
"context": "07, Ard\u00e8che, Rh\u00f4ne-Alpes",
"score": 0.8291454545454544,
"label": "Paris 07150 Vallon-Pont-d'Arc",
"city": "Vallon-Pont-d'Arc",
"type": "locality"
},
"type": "Feature"
},
{
"geometry": {
"type": "Point",
"coordinates": [
3.564293,
45.766413
]
},
"properties": {
"citycode": "63125",
"postcode": "63120",
"name": "Paris",
"city": "Courpi\u00e8re",
"context": "63, Puy-de-D\u00f4me, Auvergne",
"score": 0.8255363636363636,
"label": "Paris 63120 Courpi\u00e8re",
"id": "63125_B221_03549b",
"type": "locality"
},
"type": "Feature"
},
{
"geometry": {
"type": "Point",
"coordinates": [
1.550208,
44.673592
]
},
"properties": {
"citycode": "46138",
"postcode": "46240",
"name": "PARIS (Vaillac)",
"city": "C\u0153ur de Causse",
"context": "46, Lot, Midi-Pyr\u00e9n\u00e9es",
"score": 0.824090909090909,
"label": "PARIS (Vaillac) 46240 C\u0153ur de Causse",
"id": "46138_XXXX_6ee4ec",
"type": "street"
},
"type": "Feature"
},
{
"geometry": {
"type": "Point",
"coordinates": [
-0.526884,
43.762253
]
},
"properties": {
"citycode": "40282",
"postcode": "40500",
"name": "Paris",
"city": "Saint-Sever",
"context": "40, Landes, Aquitaine",
"score": 0.8236181818181818,
"label": "Paris 40500 Saint-Sever",
"id": "40282_B237_2364e3",
"type": "locality"
},
"type": "Feature"
}
]
}

View file

@ -0,0 +1,9 @@
{
"limit": 5,
"attribution": "BAN",
"version": "draft",
"licence": "ODbL 1.0",
"query": "Paris",
"type": "FeatureCollection",
"features": []
}

View file

@ -1,7 +1,9 @@
require 'spec_helper' require 'spec_helper'
describe 'admin/procedures/show.html.haml', type: :view do describe 'admin/procedures/show.html.haml', type: :view do
let(:procedure) { create(:procedure) } let(:archived) { false }
let(:published) { false }
let(:procedure) { create(:procedure, published: published, archived: archived) }
before do before do
assign(:facade, AdminProceduresShowFacades.new(procedure.decorate)) assign(:facade, AdminProceduresShowFacades.new(procedure.decorate))
@ -9,19 +11,32 @@ describe 'admin/procedures/show.html.haml', type: :view do
render render
end end
describe 'publish button' do
it { expect(rendered).to have_content('Publier') }
end
describe 'archive and unarchive button' do describe 'archive and unarchive button' do
context 'when procedure is active' do let(:published) { true }
context 'when procedure is published' do
it { expect(rendered).to have_content('Archiver') } it { expect(rendered).to have_content('Archiver') }
end end
context 'when procedure is archived' do context 'when procedure is archived' do
let(:procedure) { create(:procedure, archived: true) } let(:archived) { true }
it { expect(rendered).to have_content('Réactiver') } it { expect(rendered).to have_content('Réactiver') }
end end
end end
describe 'procedure link is present' do describe 'procedure link' do
it { expect(rendered).to have_content(new_users_dossiers_url(procedure_id: procedure.id)) }
context 'is not present when not published' do
it { expect(rendered).to have_content('Cette procédure n\'a pas encore été publiée et n\'est donc pas accessible par le public.') }
end
context 'is present when already published' do
let(:published) { true }
it { expect(rendered).to have_content(new_users_dossiers_url(procedure_id: procedure.id)) }
end
end end
end end

View file

@ -0,0 +1,48 @@
require 'spec_helper'
describe 'admin/pieces_justificatives/show.html.haml', type: :view do
let(:procedure) { create(:procedure) }
describe 'fields sorted' do
let(:first_libelle) { 'salut la compagnie' }
let(:last_libelle) { 'je suis bien sur la page' }
let!(:type_de_piece_justificative_1) { create(:type_de_piece_justificative, procedure: procedure, order_place: 1, libelle: last_libelle) }
let!(:type_de_piece_justificative_0) { create(:type_de_piece_justificative, procedure: procedure, order_place: 0, libelle: first_libelle) }
before do
procedure.reload
assign(:procedure, procedure)
render
end
it 'sorts by order place' do
expect(rendered).to match(/#{first_libelle}.*#{last_libelle}/m)
end
end
describe 'arrow button' do
subject do
procedure.reload
assign(:procedure, procedure)
render
rendered
end
context 'when there is no field in database' do
it { expect(subject).not_to have_css('.fa-chevron-down') }
it { expect(subject).not_to have_css('.fa-chevron-up') }
end
context 'when there is only one field in database' do
let!(:type_de_piece_justificative_0) { create(:type_de_piece_justificative, procedure: procedure, order_place: 0) }
it { expect(subject).not_to have_css('#btn_down_0') }
it { expect(subject).not_to have_css('#btn_up_0') }
it { expect(subject).not_to have_css('#btn_up_1') }
it { expect(subject).not_to have_css('#btn_down_1') }
end
context 'when there are 2 fields in database' do
let!(:type_de_piece_justificative_0) { create(:type_de_piece_justificative, procedure: procedure, order_place: 0) }
let!(:type_de_piece_justificative_1) { create(:type_de_piece_justificative, procedure: procedure, order_place: 1) }
it { expect(subject).to have_css('#btn_down_0') }
it { expect(subject).not_to have_css('#btn_up_0') }
it { expect(subject).to have_css('#btn_up_1') }
it { expect(subject).not_to have_css('#btn_down_1') }
end
end
end

View file

@ -0,0 +1,59 @@
require 'spec_helper'
describe 'layouts/_navbar.html.haml', type: :view do
let(:administrateur) { create(:administrateur) }
let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) }
let!(:procedure) { create(:procedure, administrateur: administrateur) }
describe 'navbar entries' do
context 'when disconnected' do
before do
render
end
subject { rendered }
it { is_expected.to match(/href="\/users\/sign_in">Utilisateur/) }
it { is_expected.to match(/href="\/gestionnaires\/sign_in">Accompagnateur/) }
it { is_expected.to match(/href="\/administrateurs\/sign_in">Administrateur/) }
it { is_expected.not_to match(/Mes Dossiers/) }
it { is_expected.not_to match(/Mes Procédures/) }
it { is_expected.not_to match(/Se déconnecter/) }
end
context 'when administrateur is connected' do
before do
@request.env["devise.mapping"] = Devise.mappings[:administrateur]
@current_user = administrateur
sign_in @current_user
render
end
subject { rendered }
it { is_expected.not_to match(/href="\/users\/sign_in">Utilisateur/) }
it { is_expected.not_to match(/href="\/gestionnaires\/sign_in">Accompagnateur/) }
it { is_expected.not_to match(/href="\/administrateurs\/sign_in">Administrateur/) }
it { is_expected.not_to match(/Mes Dossiers/) }
it { is_expected.to match(/Mes Procédures/) }
it { is_expected.to match(/Se déconnecter/) }
end
context 'when gestionnaire is connected' do
before do
@request.env["devise.mapping"] = Devise.mappings[:gestionnaire]
@current_user = gestionnaire
sign_in @current_user
render
end
subject { rendered }
it { is_expected.not_to match(/href="\/users\/sign_in">Utilisateur/) }
it { is_expected.not_to match(/href="\/gestionnaires\/sign_in">Accompagnateur/) }
it { is_expected.not_to match(/href="\/administrateurs\/sign_in">Administrateur/) }
it { is_expected.not_to match(/Mes Procédures/) }
it { is_expected.to match(/Mes Dossiers/) }
it { is_expected.to match(/Se déconnecter/) }
end
end
end

File diff suppressed because it is too large Load diff