Merge branch 'dev'

This commit is contained in:
simon lehericey 2018-05-23 13:54:16 +02:00
commit a0d3f2c818
65 changed files with 808 additions and 190 deletions

View file

@ -79,6 +79,9 @@ Layout/EmptyLineBetweenDefs:
Layout/EmptyLines: Layout/EmptyLines:
Enabled: true Enabled: true
Layout/EmptyLineAfterGuardClause:
Enabled: false
Layout/EmptyLinesAroundAccessModifier: Layout/EmptyLinesAroundAccessModifier:
Enabled: true Enabled: true
@ -899,9 +902,6 @@ Style/EmptyElse:
Style/EmptyLambdaParameter: Style/EmptyLambdaParameter:
Enabled: true Enabled: true
Style/EmptyLineAfterGuardClause:
Enabled: false
Style/EmptyLiteral: Style/EmptyLiteral:
Enabled: false Enabled: false
@ -995,7 +995,7 @@ Style/MethodCalledOnDoEndBlock:
Style/MethodDefParentheses: Style/MethodDefParentheses:
Enabled: true Enabled: true
Style/MethodMissing: Style/MethodMissingSuper:
Enabled: false Enabled: false
Style/MinMax: Style/MinMax:
@ -1004,6 +1004,9 @@ Style/MinMax:
Style/MissingElse: Style/MissingElse:
Enabled: false Enabled: false
Style/MissingRespondToMissing:
Enabled: false
Style/MixinGrouping: Style/MixinGrouping:
Enabled: false Enabled: false

View file

@ -95,7 +95,7 @@ GEM
sass-rails (~> 5.0) sass-rails (~> 5.0)
selectize-rails (~> 0.6) selectize-rails (~> 0.6)
aes_key_wrap (1.0.1) aes_key_wrap (1.0.1)
apipie-rails (0.5.7) apipie-rails (0.5.8)
rails (>= 4.1) rails (>= 4.1)
arel (9.0.0) arel (9.0.0)
ast (2.4.0) ast (2.4.0)
@ -114,7 +114,7 @@ GEM
sass (>= 3.3.4) sass (>= 3.3.4)
bootstrap-wysihtml5-rails (0.3.3.8) bootstrap-wysihtml5-rails (0.3.3.8)
railties (>= 3.0) railties (>= 3.0)
brakeman (4.2.1) brakeman (4.3.0)
browser (2.5.3) browser (2.5.3)
builder (3.2.3) builder (3.2.3)
byebug (10.0.2) byebug (10.0.2)
@ -178,9 +178,9 @@ GEM
diff-lcs (1.3) diff-lcs (1.3)
domain_name (0.5.20170404) domain_name (0.5.20170404)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.3.0) dotenv (2.4.0)
dotenv-rails (2.3.0) dotenv-rails (2.4.0)
dotenv (= 2.3.0) dotenv (= 2.4.0)
railties (>= 3.2, < 6.0) railties (>= 3.2, < 6.0)
draper (3.0.1) draper (3.0.1)
actionpack (~> 5.0) actionpack (~> 5.0)
@ -420,12 +420,10 @@ GEM
railties (>= 4.2.0) railties (>= 4.2.0)
thor (>= 0.14, < 2.0) thor (>= 0.14, < 2.0)
json (2.1.0) json (2.1.0)
json-jwt (1.9.2) json-jwt (1.9.4)
activesupport activesupport
aes_key_wrap aes_key_wrap
bindata bindata
securecompare
url_safe_base64
jsonapi-renderer (0.2.0) jsonapi-renderer (0.2.0)
jwt (1.5.6) jwt (1.5.6)
kaminari (1.1.1) kaminari (1.1.1)
@ -486,7 +484,7 @@ GEM
mustermann (1.0.2) mustermann (1.0.2)
nenv (0.3.0) nenv (0.3.0)
netrc (0.11.0) netrc (0.11.0)
nio4r (2.3.0) nio4r (2.3.1)
nokogiri (1.8.2) nokogiri (1.8.2)
mini_portile2 (~> 2.3.0) mini_portile2 (~> 2.3.0)
notiffany (0.1.1) notiffany (0.1.1)
@ -508,7 +506,7 @@ GEM
oauth2 (~> 1.1) oauth2 (~> 1.1)
omniauth (~> 1.2) omniauth (~> 1.2)
open4 (1.3.4) open4 (1.3.4)
openid_connect (1.1.5) openid_connect (1.1.6)
activemodel activemodel
attr_required (>= 1.0.0) attr_required (>= 1.0.0)
json-jwt (>= 1.5.0) json-jwt (>= 1.5.0)
@ -518,7 +516,7 @@ GEM
validate_email validate_email
validate_url validate_url
webfinger (>= 1.0.1) webfinger (>= 1.0.1)
openstack (3.3.17) openstack (3.3.18)
json json
orm_adapter (0.5.0) orm_adapter (0.5.0)
parallel (1.12.1) parallel (1.12.1)
@ -540,12 +538,12 @@ GEM
byebug (~> 10.0) byebug (~> 10.0)
pry (~> 0.10) pry (~> 0.10)
public_suffix (3.0.2) public_suffix (3.0.2)
rack (2.0.4) rack (2.0.5)
rack-handlers (0.7.3) rack-handlers (0.7.3)
rack rack
rack-mini-profiler (0.10.7) rack-mini-profiler (1.0.0)
rack (>= 1.2.0) rack (>= 1.2.0)
rack-oauth2 (1.9.0) rack-oauth2 (1.9.2)
activesupport activesupport
attr_required attr_required
httpclient httpclient
@ -641,7 +639,7 @@ GEM
rspec-support (3.7.1) rspec-support (3.7.1)
rspec_junit_formatter (0.3.0) rspec_junit_formatter (0.3.0)
rspec-core (>= 2, < 4, != 2.12.0) rspec-core (>= 2, < 4, != 2.12.0)
rubocop (0.55.0) rubocop (0.56.0)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 2.5) parser (>= 2.5)
powerpack (~> 0.1) powerpack (~> 0.1)
@ -674,14 +672,13 @@ GEM
scss_lint (0.57.0) scss_lint (0.57.0)
rake (>= 0.9, < 13) rake (>= 0.9, < 13)
sass (~> 3.5.5) sass (~> 3.5.5)
securecompare (1.0.0)
select2-rails (4.0.3) select2-rails (4.0.3)
thor (~> 0.14) thor (~> 0.14)
selectize-rails (0.12.4.1) selectize-rails (0.12.4.1)
selenium-webdriver (3.8.0) selenium-webdriver (3.8.0)
childprocess (~> 0.5) childprocess (~> 0.5)
rubyzip (~> 1.0) rubyzip (~> 1.0)
sentry-raven (2.7.2) sentry-raven (2.7.3)
faraday (>= 0.7.6, < 1.0) faraday (>= 0.7.6, < 1.0)
sexp_processor (4.11.0) sexp_processor (4.11.0)
shellany (0.0.1) shellany (0.0.1)
@ -695,8 +692,10 @@ GEM
rack (~> 2.0) rack (~> 2.0)
rack-protection (= 2.0.1) rack-protection (= 2.0.1)
tilt (~> 2.0) tilt (~> 2.0)
skylight (1.6.1) skylight (2.0.1)
activesupport (>= 3.0.0) skylight-core (= 2.0.1)
skylight-core (2.0.1)
activesupport (>= 4.2.0)
smart_listing (1.2.2) smart_listing (1.2.2)
coffee-rails coffee-rails
jquery-rails jquery-rails
@ -743,12 +742,11 @@ GEM
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.7.5) unf_ext (0.0.7.5)
unicode-display_width (1.3.0) unicode-display_width (1.3.2)
unicode_utils (1.4.0) unicode_utils (1.4.0)
unicorn (5.4.0) unicorn (5.4.0)
kgio (~> 2.6) kgio (~> 2.6)
raindrops (~> 0.7) raindrops (~> 0.7)
url_safe_base64 (0.2.2)
validate_email (0.1.6) validate_email (0.1.6)
activemodel (>= 3.0) activemodel (>= 3.0)
mail (>= 2.2.5) mail (>= 2.2.5)
@ -756,7 +754,7 @@ GEM
activemodel (>= 3.0.0) activemodel (>= 3.0.0)
addressable addressable
vcr (4.0.0) vcr (4.0.0)
web-console (3.6.1) web-console (3.6.2)
actionview (>= 5.0) actionview (>= 5.0)
activemodel (>= 5.0) activemodel (>= 5.0)
bindex (>= 0.4.0) bindex (>= 0.4.0)
@ -764,7 +762,7 @@ GEM
webfinger (1.1.0) webfinger (1.1.0)
activesupport activesupport
httpclient (>= 2.4) httpclient (>= 2.4)
webmock (3.3.0) webmock (3.4.1)
addressable (>= 2.3.6) addressable (>= 2.3.6)
crack (>= 0.3.2) crack (>= 0.3.2)
hashdiff hashdiff

View file

@ -19,17 +19,6 @@
margin-bottom: 2 * $default-padding; margin-bottom: 2 * $default-padding;
} }
.accompagnateur-header {
background-color: $light-grey;
padding-top: $default-padding;
margin-bottom: 3 * $default-spacer;
border-bottom: 1px solid $border-grey;
.container {
margin-bottom: -1px;
}
}
.mixed-buttons-bar { .mixed-buttons-bar {
flex-shrink: 0; flex-shrink: 0;

View file

@ -2,7 +2,7 @@
@import "fonts"; @import "fonts";
.new-header, .new-header,
.accompagnateur-header, .sub-header,
footer { footer {
display: none; display: none;
} }

View file

@ -0,0 +1,7 @@
@import "constants";
#services-index {
h1 {
margin-top: 2 * $default-padding;
}
}

View file

@ -0,0 +1,13 @@
@import "colors";
@import "constants";
.sub-header {
background-color: $light-grey;
padding-top: $default-padding;
margin-bottom: 3 * $default-spacer;
border-bottom: 1px solid $border-grey;
.container {
margin-bottom: -1px;
}
}

View file

@ -0,0 +1,9 @@
@import "constants";
.table-service {
.change {
text-align: center;
width: 200px;
padding-left: $default-padding;
}
}

View file

@ -63,11 +63,6 @@ class Admin::ProceduresController < AdminController
def hide def hide
procedure = current_administrateur.procedures.find(params[:id]) procedure = current_administrateur.procedures.find(params[:id])
procedure.hide! procedure.hide!
# procedure should no longer be reachable so we delete its procedure_path
# that way it is also available for another procedure
# however, sometimes the path has already been deleted (ex: stolen by another procedure),
# so we're not certain the procedure has a procedure_path anymore
procedure.procedure_path.try(:destroy)
flash.notice = "Procédure supprimée, en cas d'erreur contactez nous : contact@demarches-simplifiees.fr" flash.notice = "Procédure supprimée, en cas d'erreur contactez nous : contact@demarches-simplifiees.fr"
redirect_to admin_procedures_draft_path redirect_to admin_procedures_draft_path
@ -232,15 +227,15 @@ class Admin::ProceduresController < AdminController
def path_list def path_list
json_path_list = ProcedurePath json_path_list = ProcedurePath
.joins(', procedures') .joins(:procedure)
.where("procedures.id = procedure_paths.procedure_id") .where(procedures: { archived_at: nil })
.where("procedures.archived_at" => nil)
.where("path LIKE ?", "%#{params[:request]}%") .where("path LIKE ?", "%#{params[:request]}%")
.order(:id)
.pluck(:path, :administrateur_id) .pluck(:path, :administrateur_id)
.map do |value| .map do |path, administrateur_id|
{ {
label: value.first, label: path,
mine: value.second == current_administrateur.id mine: administrateur_id == current_administrateur.id
} }
end.to_json end.to_json

View file

@ -10,6 +10,7 @@ class ApplicationController < ActionController::Base
before_action :reject, if: -> { Flipflop.maintenance_mode? } before_action :reject, if: -> { Flipflop.maintenance_mode? }
before_action :staging_authenticate before_action :staging_authenticate
before_action :set_active_storage_host
def staging_authenticate def staging_authenticate
if StagingAuthService.enabled? && !authenticate_with_http_basic { |username, password| StagingAuthService.authenticate(username, password) } if StagingAuthService.enabled? && !authenticate_with_http_basic { |username, password| StagingAuthService.authenticate(username, password) }
@ -57,6 +58,10 @@ class ApplicationController < ActionController::Base
private private
def set_active_storage_host
ActiveStorage::Current.host = request.base_url
end
def logged_users def logged_users
@logged_users ||= [ @logged_users ||= [
current_user, current_user,

View file

@ -0,0 +1,92 @@
module NewAdministrateur
class ServicesController < AdministrateurController
def index
@services = services.ordered
@procedure = procedure
end
def new
@procedure = procedure
end
def create
new_service = Service.new(service_params)
new_service.administrateur = current_administrateur
if new_service.save
redirect_to services_path(procedure_id: params[:procedure_id]),
notice: "#{new_service.nom} créé"
else
flash[:alert] = new_service.errors.full_messages
render :new
end
end
def edit
@service = service
@procedure = procedure
end
def update
@service = service
if @service.update(service_params)
redirect_to services_path(procedure_id: params[:procedure_id]),
notice: "#{@service.nom} modifié"
else
flash[:alert] = @service.errors.full_messages
render :edit
end
end
def add_to_procedure
procedure = current_administrateur.procedures.find(procedure_params[:id])
service = services.find(procedure_params[:service_id])
procedure.update(service: service)
redirect_to admin_procedure_path(procedure.id),
notice: "service affecté : #{procedure.service.nom}"
end
def destroy
service_to_destroy = service
if service_to_destroy.procedures.present?
if service_to_destroy.procedures.count == 1
message = "la procédure #{service_to_destroy.procedures.first.libelle} utilise encore le service #{service_to_destroy.nom}. Veuillez l'affecter à un autre service avant de pouvoir le supprimer"
else
message = "les procédures #{service_to_destroy.procedures.map(&:libelle).join(', ')} utilisent encore le service #{service.nom}. Veuillez les affecter à un autre service avant de pouvoir le supprimer"
end
flash[:alert] = message
redirect_to services_path(procedure_id: params[:procedure_id])
else
service_to_destroy.destroy
redirect_to services_path(procedure_id: params[:procedure_id]),
notice: "#{service_to_destroy.nom} est supprimé"
end
end
private
def service_params
params.require(:service).permit(:nom, :organisme, :type_organisme, :email, :telephone, :horaires, :adresse)
end
def service
services.find(params[:id])
end
def services
current_administrateur.services
end
def procedure_params
params.require(:procedure).permit(:id, :service_id)
end
def procedure
current_administrateur.procedures.find(params[:procedure_id])
end
end
end

View file

@ -41,28 +41,34 @@ class Users::DossiersController < UsersController
array: true array: true
end end
def commencer def commencer_test
if params[:procedure_path].present? procedure_path = ProcedurePath.find_by(path: params[:procedure_path])
procedure_path = ProcedurePath.where(path: params[:procedure_path]).last procedure = procedure_path.test_procedure
if procedure_path.nil? || procedure_path.procedure.nil? if procedure.present?
flash.alert = "Procédure inconnue" redirect_to new_users_dossier_path(procedure_id: procedure.id)
return redirect_to root_path
else else
flash.alert = "Procédure inconnue"
redirect_to root_path
end
end
def commencer
procedure_path = ProcedurePath.find_by(path: params[:procedure_path])
procedure = procedure_path.procedure procedure = procedure_path.procedure
end
end
if procedure.present?
if procedure.archivee? if procedure.archivee?
@dossier = Dossier.new(procedure: procedure) @dossier = Dossier.new(procedure: procedure)
return render 'commencer/archived' render 'commencer/archived'
end else
redirect_to new_users_dossier_path(procedure_id: procedure.id) redirect_to new_users_dossier_path(procedure_id: procedure.id)
rescue ActiveRecord::RecordNotFound end
error_procedure else
flash.alert = "Procédure inconnue"
redirect_to root_path
end
end end
def new def new

View file

@ -12,7 +12,6 @@ class ProcedureDashboard < Administrate::BaseDashboard
types_de_champ: TypesDeChampCollectionField, types_de_champ: TypesDeChampCollectionField,
path: ProcedureLinkField, path: ProcedureLinkField,
dossiers: Field::HasMany, dossiers: Field::HasMany,
procedure_path: Field::HasOne,
administrateur: Field::BelongsTo, administrateur: Field::BelongsTo,
id: Field::Number, id: Field::Number,
libelle: Field::String, libelle: Field::String,

View file

@ -2,25 +2,19 @@ module Carto
module GeoAPI module GeoAPI
class Driver class Driver
def self.regions def self.regions
call regions_url url = [API_GEO_URL, "regions"].join("/")
call(url)
end end
def self.departements def self.departements
call departements_url url = [API_GEO_URL, "departements"].join("/")
call(url)
end end
def self.pays def self.pays
File.open('app/lib/carto/geo_api/pays.json').read File.open('app/lib/carto/geo_api/pays.json').read
end end
def self.departements_url
'https://geo.api.gouv.fr/departements'
end
def self.regions_url
'https://geo.api.gouv.fr/regions'
end
private private
def self.call(api_url) def self.call(api_url)

View file

@ -3,13 +3,13 @@ class CARTO::SGMAP::API
end end
def self.search_qp(geojson) def self.search_qp(geojson)
endpoint = "/quartiers-prioritaires/search" url = [API_CARTO_URL, "quartiers-prioritaires", "search"].join("/")
call(base_url + endpoint, { geojson: geojson.to_s }) call(url, { geojson: geojson.to_s })
end end
def self.search_cadastre(geojson) def self.search_cadastre(geojson)
endpoint = "/cadastre/geometrie" url = [API_CARTO_URL, "cadastre", "geometrie"].join("/")
call(base_url + endpoint, { geojson: geojson.to_s }) call(url, { geojson: geojson.to_s })
end end
private private
@ -25,8 +25,4 @@ class CARTO::SGMAP::API
rescue RestClient::InternalServerError rescue RestClient::InternalServerError
raise RestClient::ResourceNotFound raise RestClient::ResourceNotFound
end end
def self.base_url
'https://apicarto.sgmap.fr'
end
end end

View file

@ -9,6 +9,7 @@ class Administrateur < ApplicationRecord
has_many :procedures has_many :procedures
has_many :administrateurs_procedures has_many :administrateurs_procedures
has_many :admin_procedures, through: :administrateurs_procedures, source: :procedure has_many :admin_procedures, through: :administrateurs_procedures, source: :procedure
has_many :services
before_validation -> { sanitize_email(:email) } before_validation -> { sanitize_email(:email) }
before_save :ensure_api_token before_save :ensure_api_token

View file

@ -4,13 +4,12 @@ class Procedure < ApplicationRecord
has_many :types_de_champ_private, -> { private_only }, class_name: 'TypeDeChamp', dependent: :destroy has_many :types_de_champ_private, -> { private_only }, class_name: 'TypeDeChamp', dependent: :destroy
has_many :dossiers has_many :dossiers
has_one :procedure_path, dependent: :destroy
has_one :module_api_carto, dependent: :destroy has_one :module_api_carto, dependent: :destroy
has_one :attestation_template, dependent: :destroy has_one :attestation_template, dependent: :destroy
belongs_to :administrateur belongs_to :administrateur
belongs_to :parent_procedure, class_name: 'Procedure' belongs_to :parent_procedure, class_name: 'Procedure'
belongs_to :service
has_many :assign_to, dependent: :destroy has_many :assign_to, dependent: :destroy
has_many :administrateurs_procedures has_many :administrateurs_procedures
@ -45,7 +44,6 @@ class Procedure < ApplicationRecord
validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :libelle, presence: true, allow_blank: false, allow_nil: false
validates :description, presence: true, allow_blank: false, allow_nil: false validates :description, presence: true, allow_blank: false, allow_nil: false
validates :organisation, presence: true, allow_blank: false, allow_nil: false
# Warning: dossier after_save build_default_champs must be removed # Warning: dossier after_save build_default_champs must be removed
# to save a dossier created from this method # to save a dossier created from this method
@ -61,10 +59,15 @@ class Procedure < ApplicationRecord
Dossier.new(procedure: self, champs: champs, champs_private: champs_private) Dossier.new(procedure: self, champs: champs, champs_private: champs_private)
end end
def procedure_path
ProcedurePath.find_with_procedure(self)
end
def hide! def hide!
now = DateTime.now now = DateTime.now
self.update(hidden_at: now, aasm_state: :hidden) update(hidden_at: now, aasm_state: :hidden)
self.dossiers.update_all(hidden_at: now) procedure_path&.hide!(self)
dossiers.update_all(hidden_at: now)
end end
def path def path
@ -135,6 +138,16 @@ class Procedure < ApplicationRecord
procedure.logo_secure_token = nil procedure.logo_secure_token = nil
procedure.remote_logo_url = self.logo_url procedure.remote_logo_url = self.logo_url
if notice.attached?
response = Typhoeus.get(notice.service_url, timeout: 5)
if response.success?
procedure.notice.attach(
io: StringIO.new(response.body),
filename: notice.filename
)
end
end
procedure.administrateur = admin procedure.administrateur = admin
procedure.initiated_mail = initiated_mail.try(:dup) procedure.initiated_mail = initiated_mail.try(:dup)
procedure.received_mail = received_mail.try(:dup) procedure.received_mail = received_mail.try(:dup)

View file

@ -3,6 +3,23 @@ class ProcedurePath < ApplicationRecord
validates :administrateur_id, presence: true, allow_blank: false, allow_nil: false validates :administrateur_id, presence: true, allow_blank: false, allow_nil: false
validates :procedure_id, presence: true, allow_blank: false, allow_nil: false validates :procedure_id, presence: true, allow_blank: false, allow_nil: false
belongs_to :test_procedure, class_name: 'Procedure'
belongs_to :procedure belongs_to :procedure
belongs_to :administrateur belongs_to :administrateur
def self.find_with_procedure(procedure)
where(procedure: procedure).or(where(test_procedure: procedure)).last
end
def hide!(procedure)
if self.procedure == procedure
update(procedure: nil)
end
if self.test_procedure == procedure
update(test_procedure: nil)
end
if procedure.nil? && test_procedure.nil?
destroy
end
end
end end

27
app/models/service.rb Normal file
View file

@ -0,0 +1,27 @@
class Service < ApplicationRecord
has_many :procedures
belongs_to :administrateur
scope :ordered, -> { order(nom: :asc) }
enum type_organisme: {
administration_centrale: 'administration_centrale',
association: 'association',
commune: 'commune',
departement: 'departement',
etablissement_enseignement: 'etablissement_enseignement',
prefecture: 'prefecture',
region: 'region',
autre: 'autre'
}
validates :nom, presence: { message: 'doit être renseigné' }, allow_nil: false
validates :nom, uniqueness: { scope: :administrateur, message: 'existe déjà' }
validates :organisme, presence: { message: 'doit être renseigné' }, allow_nil: false
validates :type_organisme, presence: { message: 'doit être renseigné' }, allow_nil: false
validates :email, presence: { message: 'doit être renseigné' }, allow_nil: false
validates :telephone, presence: { message: 'doit être renseigné' }, allow_nil: false
validates :horaires, presence: { message: 'doivent être renseignés' }, allow_nil: false
validates :adresse, presence: { message: 'doit être renseignée' }, allow_nil: false
validates :administrateur, presence: { message: 'doit être renseigné' }, allow_nil: false
end

View file

@ -2,19 +2,24 @@
.alert.alert-info .alert.alert-info
Cette procédure est publiée, certains éléments de la description ne sont plus modifiables Cette procédure est publiée, certains éléments de la description ne sont plus modifiables
- { libelle: 'Libellé*', description: 'Description*', organisation: 'Organisme*', direction: 'Direction', lien_site_web: 'Lien site internet', web_hook_url: 'Lien de rappel HTTP' }.each do |key, value|
- if key != :web_hook_url || Flipflop.web_hook?
.form-group .form-group
%h4 %h4 Libellé*
= value = f.text_field :libelle, class: 'form-control', placeholder: 'Libellé de la procédure'
- if key == :web_hook_url
.form-group
%h4 Description*
= f.text_area :description, rows: '6', placeholder: 'Description du projet', class: 'form-control'
.form-group
%h4 Lien site internet
= f.text_field :lien_site_web, class: 'form-control', placeholder: 'https://www.exemple.fr/'
- if Flipflop.web_hook?
.form-group
%h4 Lien de rappel HTTP
%p %p
Un lien de rappel HTTP (aussi appelé webhook) est utilisé pour notifier un service tiers du changement de l'état dun dossier sur demarches-simplifiees.fr. À chaque changement détat d'un dossier, notre site va effectuer une requête sur le lien renseigné avec en paramètres : le nouvel état du dossier, lidentifiant de la procédure, l'identifiant dossier et la date du changement. Vous pourrez alors utiliser notre API pour récupérer les nouvelles informations du dossier concerné. Un lien de rappel HTTP (aussi appelé webhook) est utilisé pour notifier un service tiers du changement de l'état dun dossier sur demarches-simplifiees.fr. À chaque changement détat d'un dossier, notre site va effectuer une requête sur le lien renseigné avec en paramètres : le nouvel état du dossier, lidentifiant de la procédure, l'identifiant dossier et la date du changement. Vous pourrez alors utiliser notre API pour récupérer les nouvelles informations du dossier concerné.
- if key == :description = f.text_field :web_hook_url, class: 'form-control', placeholder: 'https://callback.exemple.fr/'
= f.text_area key, rows: '6', placeholder: 'Description du projet', class: 'form-control'
- else
= f.text_field key, class: 'form-control', placeholder: value
.form-group .form-group
%h4 Notice explicative de la procédure %h4 Notice explicative de la procédure

View file

@ -1,9 +1,16 @@
- procedure = @facade.procedure
= render partial: 'admin/closed_mail_template_attestation_inconsistency_alert' = render partial: 'admin/closed_mail_template_attestation_inconsistency_alert'
.row.white-back .row.white-back
#procedure_show #procedure_show
- if @facade.procedure.brouillon? - if procedure.brouillon?
- if @facade.procedure.gestionnaires.size == 0 - if procedure.gestionnaires.empty? || procedure.service.nil?
%a.action_button.btn.btn-success#publish-procedure{ style: 'float: right; margin-top: 10px;', disabled: 'disabled', 'data-toggle' => :tooltip, title: 'Vous ne pouvez pas publier une procédure sans qu\'aucun accompagnateur ne soit affecté à celle-ci.' } - message = ''
- if procedure.gestionnaires.empty?
- message += 'Affectez des accompagnateurs à votre procédure.'
- if procedure.service.nil?
- message += 'Affectez un service à votre procédure.'
%a.action_button.btn.btn-success#publish-procedure{ style: 'float: right; margin-top: 10px;', disabled: 'disabled', 'data-toggle' => :tooltip, title: message }
%i.fa.fa-eraser %i.fa.fa-eraser
Publier Publier
- else - else
@ -19,15 +26,15 @@
= render partial: '/admin/procedures/modal_transfer' = render partial: '/admin/procedures/modal_transfer'
- if @facade.procedure.archivee? - if procedure.archivee?
%a#reenable.btn.btn-small.btn-default.text-info{ "data-target" => "#publish-modal", "data-toggle" => "modal", :type => "button", style: 'float: right; margin-top: 10px;' } %a#reenable.btn.btn-small.btn-default.text-info{ "data-target" => "#publish-modal", "data-toggle" => "modal", :type => "button", style: 'float: right; margin-top: 10px;' }
%i.fa.fa-eraser %i.fa.fa-eraser
Réactiver Réactiver
= render partial: '/admin/procedures/modal_publish' = render partial: '/admin/procedures/modal_publish'
- elsif @facade.procedure.publiee? - elsif procedure.publiee?
= form_tag admin_procedure_archive_path(procedure_id: @facade.procedure.id, archive: !@facade.procedure.archivee?), method: :put, style: 'float: right; margin-top: 10px;' do = form_tag admin_procedure_archive_path(procedure_id: procedure.id, archive: !procedure.archivee?), method: :put, style: 'float: right; margin-top: 10px;' do
%button#archive.btn.btn-small.btn-default.text-info{ type: :button } %button#archive.btn.btn-small.btn-default.text-info{ type: :button }
%i.fa.fa-eraser %i.fa.fa-eraser
Archiver Archiver
@ -39,7 +46,7 @@
%i.fa.fa-remove %i.fa.fa-remove
Annuler Annuler
- if @facade.procedure.locked? - if procedure.locked?
#procedure_locked #procedure_locked
.alert.alert-info .alert.alert-info
Cette procédure a été publiée, certains éléments ne peuvent plus être modifiés. Cette procédure a été publiée, certains éléments ne peuvent plus être modifiés.
@ -47,8 +54,8 @@
%div %div
%h3 Lien procédure %h3 Lien procédure
%div{ style: 'margin-left: 3%;' } %div{ style: 'margin-left: 3%;' }
- if @facade.procedure.publiee_ou_archivee? - if procedure.publiee_ou_archivee?
= link_to @facade.procedure.lien, sanitize_url(@facade.procedure.lien), target: :blank = link_to procedure.lien, sanitize_url(procedure.lien), target: :blank
- else - else
%b %b
Cette procédure n'a pas encore été publiée et n'est donc pas accessible par le public. Cette procédure n'a pas encore été publiée et n'est donc pas accessible par le public.
@ -59,34 +66,34 @@
.row{ style: 'margin-right: 3%; margin-left: 3%;' } .row{ style: 'margin-right: 3%; margin-left: 3%;' }
.description.col-xs-6.col-md-3.procedure-description .description.col-xs-6.col-md-3.procedure-description
%h4.text-info %h4.text-info
= @facade.procedure.libelle = procedure.libelle
= h sanitize(@facade.procedure.description) = h sanitize(procedure.description)
.champs.col-xs-6.col-md-3 .champs.col-xs-6.col-md-3
%h4.text-info %h4.text-info
Champs Champs
.badge.progress-bar-info .badge.progress-bar-info
= @facade.procedure.types_de_champ.size = procedure.types_de_champ.size
%ul %ul
- @facade.procedure.types_de_champ.order(:order_place).each do |champ| - procedure.types_de_champ.order(:order_place).each do |champ|
%li= champ.libelle %li= champ.libelle
.champs_private.col-xs-6.col-md-3 .champs_private.col-xs-6.col-md-3
%h4.text-info %h4.text-info
Annotations privées Annotations privées
.badge.progress-bar-info .badge.progress-bar-info
= @facade.procedure.types_de_champ_private.size = procedure.types_de_champ_private.size
%ul %ul
- @facade.procedure.types_de_champ_private.order(:order_place).each do |champ| - procedure.types_de_champ_private.order(:order_place).each do |champ|
%li= champ.libelle %li= champ.libelle
.pieces-justificatives.col-xs-6.col-md-3 .pieces-justificatives.col-xs-6.col-md-3
%h4.text-info %h4.text-info
Pièces jointes Pièces jointes
.badge.progress-bar-info .badge.progress-bar-info
= @facade.procedure.types_de_piece_justificative.size = procedure.types_de_piece_justificative.size
- @facade.procedure.types_de_piece_justificative.each do |piece_justificative| - procedure.types_de_piece_justificative.each do |piece_justificative|
= piece_justificative.libelle = piece_justificative.libelle
%br %br
%br %br
@ -123,19 +130,19 @@
- else - else
= pie_chart @facade.dossiers_for_pie_highchart = pie_chart @facade.dossiers_for_pie_highchart
- if @facade.procedure.publiee_ou_archivee? - if procedure.publiee_ou_archivee?
%h3 Supprimer la procédure %h3 Supprimer la procédure
.alert.alert-danger .alert.alert-danger
%p %p
Attention : la suppression d'une procédure est définitive. Attention : la suppression d'une procédure est définitive.
- dossiers_count = @facade.procedure.dossiers.count - dossiers_count = procedure.dossiers.count
- if dossiers_count > 0 - if dossiers_count > 0
%p %p
= pluralize(dossiers_count, "dossier est rattaché", "dossiers sont rattachés") = pluralize(dossiers_count, "dossier est rattaché", "dossiers sont rattachés")
à cette procédure, la suppression de cette procédure entrainera également leur suppression. à cette procédure, la suppression de cette procédure entrainera également leur suppression.
%p.text-right %p.text-right
= link_to "J'ai compris, je supprime la procédure", = link_to "J'ai compris, je supprime la procédure",
hide_admin_procedure_path(@facade.procedure), hide_admin_procedure_path(procedure),
method: :post, method: :post,
class: "btn btn-danger", class: "btn btn-danger",
data: { confirm: "Voulez-vous supprimer la procédure ?", disable_with: "Suppression..." } data: { confirm: "Voulez-vous supprimer la procédure ?", disable_with: "Suppression..." }

View file

@ -16,7 +16,7 @@ Vous pouvez me joindre au numéro suivant : 01 76 42 02 87.
%br %br
%br %br
Je vous invite également à consulter notre site de documentation qui regroupe l'ensemble des informations relatives à demarches-simplifiees.fr ainsi que des tutoriels dutilisation : Je vous invite également à consulter notre site de documentation qui regroupe l'ensemble des informations relatives à demarches-simplifiees.fr ainsi que des tutoriels dutilisation :
= link_to('https://demarches-simplifiees.gitbook.io/demarches-simplifiees/', 'https://demarches-simplifiees.gitbook.io/demarches-simplifiees/') = link_to(DOC_URL, DOC_URL)
%br %br
%br %br
= render partial: "layouts/mailers/bizdev_signature" = render partial: "layouts/mailers/bizdev_signature"

View file

@ -10,7 +10,7 @@ Votre compte a été créé pour l'adresse email #{@gestionnaire.email}. Pour l
%br %br
%br %br
Par ailleurs, notre site de documentation qui regroupe l'ensemble des informations relatives à demarches-simplifiees.fr ainsi que des tutoriels dutilisation est à votre disposition :  Par ailleurs, notre site de documentation qui regroupe l'ensemble des informations relatives à demarches-simplifiees.fr ainsi que des tutoriels dutilisation est à votre disposition : 
= link_to('https://demarches-simplifiees.gitbook.io/demarches-simplifiees/', 'https://demarches-simplifiees.gitbook.io/demarches-simplifiees/') = link_to(DOC_URL, DOC_URL)
%br %br
%br %br
Bonne journée, Bonne journée,

View file

@ -24,7 +24,7 @@
%li.footer-link %li.footer-link
= link_to "CGU", CGU_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer" = link_to "CGU", CGU_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
%li.footer-link %li.footer-link
= link_to "Mentions légales", "https://demarches-simplifiees.gitbook.io/demarches-simplifiees/cgu#4.-mentions-legales", :class => "footer-link", :target => "_blank", rel: "noopener noreferrer" = link_to "Mentions légales", MENTIONS_LEGALES_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
%li.footer-column %li.footer-column
%ul.footer-links %ul.footer-links
@ -33,10 +33,10 @@
"mailto:#{t('dynamics.contact_email')}", "mailto:#{t('dynamics.contact_email')}",
:class => "footer-link" :class => "footer-link"
%li.footer-link %li.footer-link
= link_to "Documentation", "https://demarches-simplifiees.gitbook.io/demarches-simplifiees/", :class => "footer-link", :target => "_blank", rel: "noopener noreferrer" = link_to "Documentation", DOC_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
%li.footer-link %li.footer-link
= link_to "Documentation de l'API", "/docs", :class => "footer-link", :target => "_blank", rel: "noopener noreferrer" = link_to "Documentation de l'API", "/docs", :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
%li.footer-link %li.footer-link
= link_to "FAQ", "http://demarches-simplifiees.helpscoutdocs.com/", :class => "footer-link", :target => "_blank", rel: "noopener noreferrer" = link_to "FAQ", FAQ_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer"
%li.footer-link %li.footer-link
= link_to "Accessibilité", accessibilite_index_path, :class => "footer-link" = link_to "Accessibilité", accessibilite_index_path, :class => "footer-link"

View file

@ -10,38 +10,42 @@
#menu-block #menu-block
.split-hr-left .split-hr-left
#procedure-list #procedure-list
%a#onglet-infos{ :href => "#{url_for admin_procedure_path(@procedure)}" } %a#onglet-infos{ href: url_for(admin_procedure_path(@procedure)) }
.procedure-list-element{ class: ('active' if active == 'Informations') } .procedure-list-element{ class: ('active' if active == 'Informations') }
Informations Informations
%a#onglet-accompagnateurs{ :href => "#{url_for admin_procedure_accompagnateurs_path(@procedure)}" } %a#onglet-services{ href: current_administrateur.services.present? ? url_for(services_path(procedure_id: @procedure.id)) : url_for(new_service_path(procedure_id: @procedure.id)) }
.procedure-list-element
Services
%a#onglet-accompagnateurs{ href: url_for(admin_procedure_accompagnateurs_path(@procedure)) }
.procedure-list-element{ class: ('active' if active == 'Accompagnateurs') } .procedure-list-element{ class: ('active' if active == 'Accompagnateurs') }
= t('dynamics.admin.procedure.onglets.accompagnateurs') = t('dynamics.admin.procedure.onglets.accompagnateurs')
%a#onglet-description{ :href => "#{url_for edit_admin_procedure_path(@procedure)}" } %a#onglet-description{ href: url_for(edit_admin_procedure_path(@procedure)) }
.procedure-list-element{ class: ('active' if active == 'Description') } .procedure-list-element{ class: ('active' if active == 'Description') }
Description Description
- if !@procedure.locked? - if !@procedure.locked?
%a#onglet-champs{ :href => "#{url_for admin_procedure_types_de_champ_path(@procedure)}" } %a#onglet-champs{ href: url_for(admin_procedure_types_de_champ_path(@procedure)) }
.procedure-list-element{ class: ('active' if active == 'Champs') } .procedure-list-element{ class: ('active' if active == 'Champs') }
Champs Champs
- if !@procedure.locked? - if !@procedure.locked?
%a#onglet-pieces{ :href => "#{url_for admin_procedure_pieces_justificatives_path(@procedure)}" } %a#onglet-pieces{ href: url_for(admin_procedure_pieces_justificatives_path(@procedure)) }
.procedure-list-element{ class: ('active' if active == 'Pieces') } .procedure-list-element{ class: ('active' if active == 'Pieces') }
Pièces jointes Pièces jointes
- if !@procedure.locked? - if !@procedure.locked?
%a#onglet-private-champs{ :href => "#{url_for admin_procedure_types_de_champ_private_path(@procedure)}" } %a#onglet-private-champs{ href: url_for(admin_procedure_types_de_champ_private_path(@procedure)) }
.procedure-list-element{ class: ('active' if active == 'Annotations privées') } .procedure-list-element{ class: ('active' if active == 'Annotations privées') }
Annotations privées Annotations privées
%a#onglet-inemailsfos{ :href => "#{url_for admin_procedure_mail_templates_path(@procedure)}" } %a#onglet-inemailsfos{ href: url_for(admin_procedure_mail_templates_path(@procedure)) }
.procedure-list-element{ class: ('active' if active == 'E-mails') } .procedure-list-element{ class: ('active' if active == 'E-mails') }
E-mails E-mails
%a#onglet-preview{ :href => "#{url_for admin_procedure_previsualisation_path(@procedure)}" } %a#onglet-preview{ href: url_for(admin_procedure_previsualisation_path(@procedure)) }
.procedure-list-element{ class: ('active' if active == 'Prévisualisation') } .procedure-list-element{ class: ('active' if active == 'Prévisualisation') }
Prévisualisation Prévisualisation

View file

@ -0,0 +1,5 @@
.sub-header
.container
%ul.breadcrumbs
- steps.each do |step|
%li= step

View file

@ -1,4 +1,4 @@
.dossiers-headers.accompagnateur-header .dossiers-headers.sub-header
.container .container
%h1.page-title Prévisualisation de la procédure #{@dossier.procedure.libelle} %h1.page-title Prévisualisation de la procédure #{@dossier.procedure.libelle}

View file

@ -0,0 +1,43 @@
= form_for service, html: { class: 'form' } do |f|
= f.label :nom do
Nom
%span.mandatory *
= f.text_field :nom, placeholder: 'service jeunesse et prévention, direction des affaires maritimes', required: true
= f.label :organisme do
Organisme
%span.mandatory *
= f.text_field :organisme, placeholder: "mairie de Mours, préfecture de l'Oise, ministère de la Culture", required: true
= f.label :type_organisme do
Type dorganisme
%span.mandatory *
= f.select :type_organisme, Service.type_organismes.keys.map { |key| [ I18n.t("type_organisme.#{key}"), key] }
= f.label :email do
Courriel
%span.mandatory *
= f.email_field :email, placeholder: 'contact@mon-service.fr', required: true
= f.label :telephone do
Numéro de téléphone
%span.mandatory *
= f.telephone_field :telephone, placeholder: '04 12 24 42 37', required: true
= f.label :horaires do
Horaires
%span.mandatory *
= f.text_area :horaires, placeholder: "Du lundi au vendredi de 9 h 30 à 17 h 30\nLe samedi de 9 h 30 à 12 h", required: true
= f.label :adresse do
Adresse
%span.mandatory *
= f.text_area :adresse, placeholder: "20 avenue de Ségur\n75007 Paris", required: true
- if procedure_id.present?
= hidden_field_tag :procedure_id, procedure_id
.send-wrapper
= f.submit "Valider", class: 'button send'

View file

@ -0,0 +1,11 @@
= render partial: 'new_administrateur/breadcrumbs',
locals: { steps: [link_to('Procedures', admin_procedures_path),
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
link_to('choix du service', services_path(procedure_id: @procedure.id)),
'modifier le service'] }
.container
%h1 Modifier le service
= render partial: 'form',
locals: { service: @service, procedure_id: @procedure.id }

View file

@ -0,0 +1,39 @@
= render partial: 'new_administrateur/breadcrumbs',
locals: { steps: [link_to('Procedures', admin_procedures_path),
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
'choix du service'] }
#services-index.container
%h1 Choix du service pour la procédure
= form_for @procedure, url: { controller: "new_administrateur/services", action: :add_to_procedure } , html: { class: 'form' } do |f|
= f.label :service_id, "La procédure #{@procedure.libelle} est affectée au service"
= f.select :service_id,
current_administrateur.services.map { |s| [ s.nom, s.id ] },
{ prompt: 'choisir un service', selected: @procedure.service&.id },
required: true
= f.hidden_field :id
= f.submit 'valider', class: 'button primary'
%h1 Liste des Services
%table.table.table-service.hoverable
%thead
%tr
%th
nom
%th.change
= link_to('Nouveau service', new_service_path(procedure_id: @procedure.id), class: 'button')
%tbody
- @services.each do |service|
%tr
%td
= service.nom
%td.change
= link_to('modifier', edit_service_path(service, procedure_id: @procedure.id))
= link_to 'supprimer',
service_path(service, procedure_id: @procedure.id),
method: :delete,
data: { confirm: "Confirmez vous la suppression de #{service.nom}" }

View file

@ -0,0 +1,11 @@
= render partial: 'new_administrateur/breadcrumbs',
locals: { steps: [link_to('Procedures', admin_procedures_path),
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
link_to('choix du service', services_path(procedure_id: @procedure.id)),
'nouveau service'] }
.container
%h1 Nouveau Service
= render partial: 'form',
locals: { service: Service.new, procedure_id: @procedure.id }

View file

@ -1,4 +1,4 @@
.accompagnateur-header .sub-header
.container .container
%ul.breadcrumbs %ul.breadcrumbs
%li= link_to('Avis', gestionnaire_avis_index_path) %li= link_to('Avis', gestionnaire_avis_index_path)

View file

@ -1,7 +1,7 @@
- avis_statut = (@statut == NewGestionnaire::AvisController::A_DONNER_STATUS) ? 'à donner' : 'rendus' - avis_statut = (@statut == NewGestionnaire::AvisController::A_DONNER_STATUS) ? 'à donner' : 'rendus'
- content_for(:title, "Avis #{avis_statut}") - content_for(:title, "Avis #{avis_statut}")
.accompagnateur-header .sub-header
.container.flex .container.flex
.width-100 .width-100
%h1.tab-title Avis %h1.tab-title Avis

View file

@ -1,4 +1,4 @@
.accompagnateur-header .sub-header
.container .container
.flex.justify-between .flex.justify-between
%ul.breadcrumbs %ul.breadcrumbs

View file

@ -1,7 +1,7 @@
- content_for(:title, "#{@procedure.libelle}") - content_for(:title, "#{@procedure.libelle}")
#procedure-show #procedure-show
.accompagnateur-header .sub-header
.container.flex .container.flex
.procedure-logo{ style: @procedure.logo.present? ? "background-image: url(#{@procedure.logo.url})" : nil, .procedure-logo{ style: @procedure.logo.present? ? "background-image: url(#{@procedure.logo.url})" : nil,

View file

@ -1,4 +1,4 @@
.dossiers-headers.accompagnateur-header .dossiers-headers.sub-header
.container .container
%h1.page-title Les dossiers %h1.page-title Les dossiers

View file

@ -51,7 +51,7 @@
class: "role-panel-button-primary" class: "role-panel-button-primary"
= link_to "Voir les démarches disponibles", = link_to "Voir les démarches disponibles",
"https://demarches-simplifiees.gitbook.io/demarches-simplifiees/listes-des-demarches", LISTE_DES_DEMARCHES_URL,
target: "_blank", target: "_blank",
rel: "noopener noreferrer", rel: "noopener noreferrer",
class: "role-panel-button-secondary" class: "role-panel-button-secondary"
@ -74,7 +74,7 @@
onclick: "javascript: ga('send', 'pageview', '/demander-une-demo')" onclick: "javascript: ga('send', 'pageview', '/demander-une-demo')"
= link_to "Voir la documentation", = link_to "Voir la documentation",
"https://demarches-simplifiees.gitbook.io/demarches-simplifiees/", DOC_URL,
target: "_blank", target: "_blank",
rel: "noopener noreferrer", rel: "noopener noreferrer",
class: "role-panel-button-secondary" class: "role-panel-button-secondary"

View file

@ -131,7 +131,7 @@
%td Table Data 3 %td Table Data 3
%h1 Header %h1 Header
.accompagnateur-header .sub-header
.container .container
Titre Titre
%ul.tabs %ul.tabs

3
bin/rspec Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
load Gem.bin_path('rspec-core', 'rspec')

View file

@ -1,10 +1,9 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'pathname'
require 'fileutils' require 'fileutils'
include FileUtils include FileUtils
# path to your application root. # path to your application root.
APP_ROOT = Pathname.new File.expand_path('../', __dir__) APP_ROOT = File.expand_path('..', __dir__)
def system!(*args) def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==") system(*args) || abort("\n== Command #{args} failed ==")
@ -18,8 +17,11 @@ chdir APP_ROOT do
system! 'gem install bundler --conservative' system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install') system('bundle check') || system!('bundle install')
# Install JavaScript dependencies if using Yarn
# system('bin/yarn')
# puts "\n== Copying sample files ==" # puts "\n== Copying sample files =="
# if !File.exist?('config/database.yml') # unless File.exist?('config/database.yml')
# cp 'config/database.yml.sample', 'config/database.yml' # cp 'config/database.yml.sample', 'config/database.yml'
# end # end

View file

@ -1,10 +1,9 @@
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'pathname'
require 'fileutils' require 'fileutils'
include FileUtils include FileUtils
# path to your application root. # path to your application root.
APP_ROOT = Pathname.new File.expand_path('../', __dir__) APP_ROOT = File.expand_path('..', __dir__)
def system!(*args) def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==") system(*args) || abort("\n== Command #{args} failed ==")
@ -18,6 +17,9 @@ chdir APP_ROOT do
system! 'gem install bundler --conservative' system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install') system('bundle check') || system!('bundle install')
# Install JavaScript dependencies if using Yarn
# system('bin/yarn')
puts "\n== Updating database ==" puts "\n== Updating database =="
system! 'bin/rails db:migrate' system! 'bin/rails db:migrate'

11
bin/yarn Executable file
View file

@ -0,0 +1,11 @@
#!/usr/bin/env ruby
APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do
begin
exec "yarnpkg", *ARGV
rescue Errno::ENOENT
warn "Yarn executable was not detected in the system."
warn "Download Yarn at https://yarnpkg.com/en/docs/install"
exit 1
end
end

View file

@ -1 +0,0 @@
CGU_URL = "https://demarches-simplifiees.gitbook.io/demarches-simplifiees/cgu"

View file

@ -1,3 +1,14 @@
API_CARTO_URL = "https://apicarto.sgmap.fr"
API_ENTREPRISE_URL = 'https://entreprise.api.gouv.fr/v2' API_ENTREPRISE_URL = 'https://entreprise.api.gouv.fr/v2'
API_GEO_URL = "https://geo.api.gouv.fr"
PIPEDRIVE_API_URL = 'https://api.pipedrive.com/v1' PIPEDRIVE_API_URL = 'https://api.pipedrive.com/v1'
DOC_URL = "https://doc.demarches-simplifiees.fr"
LISTE_DES_DEMARCHES_URL = [DOC_URL, "listes-des-demarches"].join("/")
CGU_URL = [DOC_URL, "cgu"].join("/")
MENTIONS_LEGALES_URL = [CGU_URL, "4-mentions-legales"].join("#")
FAQ_URL = "https://faq.demarches-simplifiees.fr"

View file

@ -0,0 +1,10 @@
# These translations are used in the manager interface, which is in English,
# so we use English translations
fr:
flipflop:
title: "%{application} features"
feature_states:
enabled: "On"
disabled: "Off"

View file

@ -0,0 +1,10 @@
fr:
type_organisme:
administration_centrale: 'administration centrale'
association: 'association'
commune: 'commune'
departement: 'département'
etablissement_enseignement: 'établissement denseignement'
prefecture: 'préfecture'
region: 'région'
autre: 'autre'

View file

@ -211,6 +211,7 @@ Rails.application.routes.draw do
end end
namespace :commencer do namespace :commencer do
get '/test/:procedure_path' => '/users/dossiers#commencer_test', as: :test
get '/:procedure_path' => '/users/dossiers#commencer' get '/:procedure_path' => '/users/dossiers#commencer'
end end
@ -286,6 +287,12 @@ Rails.application.routes.draw do
get 'apercu' get 'apercu'
end end
end end
resources :services, except: [:show] do
collection do
patch 'add_to_procedure'
end
end
end end
apipie apipie

View file

@ -0,0 +1,10 @@
class CreateServices < ActiveRecord::Migration[5.2]
def change
create_table :services do |t|
t.string :type_organisme, null: false
t.string :nom, null: false
t.timestamps
end
end
end

View file

@ -0,0 +1,5 @@
class AddServiceToProcedures < ActiveRecord::Migration[5.2]
def change
add_reference :procedures, :service, foreign_key: true
end
end

View file

@ -0,0 +1,5 @@
class AddAdministrateurToServices < ActiveRecord::Migration[5.2]
def change
add_reference :services, :administrateur, foreign_key: true
end
end

View file

@ -0,0 +1,5 @@
class AddUniqueIndexToServices < ActiveRecord::Migration[5.2]
def change
add_index :services, [:administrateur_id, :nom], unique: true
end
end

View file

@ -0,0 +1,9 @@
class AddColumnsToService < ActiveRecord::Migration[5.2]
def change
add_column :services, :organisme, :string
add_column :services, :email, :string
add_column :services, :telephone, :string
add_column :services, :horaires, :text
add_column :services, :adresse, :text
end
end

View file

@ -0,0 +1,5 @@
class AllowProcedureOrganismeToBeNull < ActiveRecord::Migration[5.2]
def change
change_column_null :procedures, :organisation, true
end
end

View file

@ -0,0 +1,5 @@
class AddTestProcedureToProcedurePaths < ActiveRecord::Migration[5.2]
def change
add_reference :procedure_paths, :test_procedure
end
end

View file

@ -10,7 +10,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: 2018_05_15_135415) do ActiveRecord::Schema.define(version: 2018_05_16_155238) 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"
@ -425,7 +425,9 @@ ActiveRecord::Schema.define(version: 2018_05_15_135415) do
t.integer "administrateur_id" t.integer "administrateur_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.bigint "test_procedure_id"
t.index ["path"], name: "index_procedure_paths_on_path" t.index ["path"], name: "index_procedure_paths_on_path"
t.index ["test_procedure_id"], name: "index_procedure_paths_on_test_procedure_id"
end end
create_table "procedure_presentations", id: :serial, force: :cascade do |t| create_table "procedure_presentations", id: :serial, force: :cascade do |t|
@ -441,7 +443,7 @@ ActiveRecord::Schema.define(version: 2018_05_15_135415) do
create_table "procedures", id: :serial, force: :cascade do |t| create_table "procedures", id: :serial, force: :cascade do |t|
t.string "libelle" t.string "libelle"
t.string "description" t.string "description"
t.string "organisation", null: false t.string "organisation"
t.string "direction" t.string "direction"
t.string "lien_demarche" t.string "lien_demarche"
t.datetime "created_at", null: false t.datetime "created_at", null: false
@ -466,8 +468,10 @@ ActiveRecord::Schema.define(version: 2018_05_15_135415) do
t.bigint "parent_procedure_id" t.bigint "parent_procedure_id"
t.datetime "test_started_at" t.datetime "test_started_at"
t.string "aasm_state", default: "brouillon" t.string "aasm_state", default: "brouillon"
t.bigint "service_id"
t.index ["hidden_at"], name: "index_procedures_on_hidden_at" t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id" t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id"
t.index ["service_id"], name: "index_procedures_on_service_id"
end end
create_table "quartier_prioritaires", id: :serial, force: :cascade do |t| create_table "quartier_prioritaires", id: :serial, force: :cascade do |t|
@ -511,6 +515,21 @@ ActiveRecord::Schema.define(version: 2018_05_15_135415) do
t.index ["entreprise_id"], name: "index_rna_informations_on_entreprise_id" t.index ["entreprise_id"], name: "index_rna_informations_on_entreprise_id"
end end
create_table "services", force: :cascade do |t|
t.string "type_organisme", null: false
t.string "nom", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.bigint "administrateur_id"
t.string "organisme"
t.string "email"
t.string "telephone"
t.text "horaires"
t.text "adresse"
t.index ["administrateur_id", "nom"], name: "index_services_on_administrateur_id_and_nom", unique: true
t.index ["administrateur_id"], name: "index_services_on_administrateur_id"
end
create_table "types_de_champ", id: :serial, force: :cascade do |t| create_table "types_de_champ", id: :serial, force: :cascade do |t|
t.string "libelle" t.string "libelle"
t.string "type_champ" t.string "type_champ"
@ -576,8 +595,10 @@ ActiveRecord::Schema.define(version: 2018_05_15_135415) do
add_foreign_key "procedure_paths", "administrateurs" add_foreign_key "procedure_paths", "administrateurs"
add_foreign_key "procedure_paths", "procedures" add_foreign_key "procedure_paths", "procedures"
add_foreign_key "procedure_presentations", "assign_tos" add_foreign_key "procedure_presentations", "assign_tos"
add_foreign_key "procedures", "services"
add_foreign_key "received_mails", "procedures" add_foreign_key "received_mails", "procedures"
add_foreign_key "refused_mails", "procedures" add_foreign_key "refused_mails", "procedures"
add_foreign_key "services", "administrateurs"
add_foreign_key "without_continuation_mails", "procedures" add_foreign_key "without_continuation_mails", "procedures"
create_view "searches", sql_definition: <<-SQL create_view "searches", sql_definition: <<-SQL

View file

@ -455,10 +455,15 @@ describe Admin::ProceduresController, type: :controller do
end end
describe 'PUT #clone' do describe 'PUT #clone' do
let!(:procedure) { create(:procedure, administrateur: admin) } let!(:procedure) { create(:procedure, :with_notice, administrateur: admin) }
let(:params) { { procedure_id: procedure.id } } let(:params) { { procedure_id: procedure.id } }
subject { put :clone, params: params } subject { put :clone, params: params }
before do
response = Typhoeus::Response.new(code: 200, body: 'Hello world')
Typhoeus.stub(/active_storage\/disk/).and_return(response)
end
it { expect { subject }.to change(Procedure, :count).by(1) } it { expect { subject }.to change(Procedure, :count).by(1) }
context 'when admin is the owner of the procedure' do context 'when admin is the owner of the procedure' do
@ -466,7 +471,8 @@ describe Admin::ProceduresController, type: :controller do
it 'creates a new procedure and redirect to it' do it 'creates a new procedure and redirect to it' do
expect(response).to redirect_to edit_admin_procedure_path(id: Procedure.last.id) expect(response).to redirect_to edit_admin_procedure_path(id: Procedure.last.id)
expect(Procedure.last.cloned_from_library).to be(false) expect(Procedure.last.cloned_from_library).to be_falsey
expect(Procedure.last.notice.attached?).to be_truthy
expect(flash[:notice]).to have_content 'Procédure clonée' expect(flash[:notice]).to have_content 'Procédure clonée'
end end
@ -541,7 +547,7 @@ describe Admin::ProceduresController, type: :controller do
end end
end end
describe 'POST transfer' do describe 'POST #transfer' do
let!(:procedure) { create :procedure, administrateur: admin } let!(:procedure) { create :procedure, administrateur: admin }
subject { post :transfer, params: { email_admin: email_admin, procedure_id: procedure.id } } subject { post :transfer, params: { email_admin: email_admin, procedure_id: procedure.id } }
@ -581,17 +587,17 @@ describe Admin::ProceduresController, type: :controller do
end end
end end
describe "POST hide" do describe "POST #hide" do
subject { post :hide, params: { id: procedure.id } } subject { post :hide, params: { id: procedure.id } }
context "when procedure is not owned by administrateur" do context "when procedure is not owned by administrateur" do
let!(:procedure) { create :procedure, administrateur: create(:administrateur) } let(:procedure) { create :procedure, administrateur: create(:administrateur) }
it { expect{ subject }.to raise_error(ActiveRecord::RecordNotFound) } it { expect{ subject }.to raise_error(ActiveRecord::RecordNotFound) }
end end
context "when procedure is owned by administrateur" do context "when procedure is owned by administrateur" do
let!(:procedure) { create :procedure, :published, administrateur: admin } let(:procedure) { create :procedure, :published, administrateur: admin }
before do before do
subject subject
@ -599,11 +605,11 @@ describe Admin::ProceduresController, type: :controller do
end end
it { expect(procedure.hidden_at).not_to be_nil } it { expect(procedure.hidden_at).not_to be_nil }
it { expect(procedure.procedure_path).to be_nil } it { expect(procedure.procedure_path.procedure).to be_nil }
end end
context "when procedure has no path" do context "when procedure has no path" do
let!(:procedure) { create :procedure, administrateur: admin } let(:procedure) { create :procedure, administrateur: admin }
it { expect{ subject }.not_to raise_error } it { expect{ subject }.not_to raise_error }
it do it do

View file

@ -186,7 +186,7 @@ describe API::V1::DossiersController do
describe 'first type de piece justificative' do describe 'first type de piece justificative' do
subject { super().first } subject { super().first }
it { expect(subject.keys.include?(:id)).to be_truthy } it { expect(subject.key?(:id)).to be_truthy }
it { expect(subject[:libelle]).to eq('RIB') } it { expect(subject[:libelle]).to eq('RIB') }
it { expect(subject[:description]).to eq('Releve identité bancaire') } it { expect(subject[:description]).to eq('Releve identité bancaire') }
end end
@ -200,11 +200,11 @@ describe API::V1::DossiersController do
let(:field_list) { [:url, :created_at, :type_de_piece_justificative_id] } let(:field_list) { [:url, :created_at, :type_de_piece_justificative_id] }
subject { super()[:pieces_justificatives].first } subject { super()[:pieces_justificatives].first }
it { expect(subject.keys.include?(:content_url)).to be_truthy } it { expect(subject.key?(:content_url)).to be_truthy }
it { expect(subject[:created_at]).not_to be_nil } it { expect(subject[:created_at]).not_to be_nil }
it { expect(subject[:type_de_piece_justificative_id]).not_to be_nil } it { expect(subject[:type_de_piece_justificative_id]).not_to be_nil }
it { expect(subject.keys.include?(:user)).to be_truthy } it { expect(subject.key?(:user)).to be_truthy }
describe 'user' do describe 'user' do
subject { super()[:user] } subject { super()[:user] }
@ -222,8 +222,8 @@ describe API::V1::DossiersController do
describe 'first champs' do describe 'first champs' do
subject { super().first } subject { super().first }
it { expect(subject.keys.include?(:value)).to be_truthy } it { expect(subject.key?(:value)).to be_truthy }
it { expect(subject.keys.include?(:type_de_champ)).to be_truthy } it { expect(subject.key?(:type_de_champ)).to be_truthy }
describe 'type de champ' do describe 'type de champ' do
let(:field_list) { let(:field_list) {
@ -237,10 +237,10 @@ describe API::V1::DossiersController do
} }
subject { super()[:type_de_champ] } subject { super()[:type_de_champ] }
it { expect(subject.keys.include?(:id)).to be_truthy } it { expect(subject.key?(:id)).to be_truthy }
it { expect(subject[:libelle]).to include('Libelle du champ') } it { expect(subject[:libelle]).to include('Libelle du champ') }
it { expect(subject[:description]).to include('description du champ') } it { expect(subject[:description]).to include('description du champ') }
it { expect(subject.keys.include?(:order_place)).to be_truthy } it { expect(subject.key?(:order_place)).to be_truthy }
it { expect(subject[:type_champ]).to eq('text') } it { expect(subject[:type_champ]).to eq('text') }
end end
end end
@ -295,8 +295,8 @@ describe API::V1::DossiersController do
describe 'first champs' do describe 'first champs' do
subject { super().first } subject { super().first }
it { expect(subject.keys.include?(:value)).to be_truthy } it { expect(subject.key?(:value)).to be_truthy }
it { expect(subject.keys.include?(:type_de_champ)).to be_truthy } it { expect(subject.key?(:type_de_champ)).to be_truthy }
describe 'type de champ' do describe 'type de champ' do
let(:field_list) { let(:field_list) {
@ -310,10 +310,10 @@ describe API::V1::DossiersController do
} }
subject { super()[:type_de_champ] } subject { super()[:type_de_champ] }
it { expect(subject.keys.include?(:id)).to be_truthy } it { expect(subject.key?(:id)).to be_truthy }
it { expect(subject[:libelle]).to include('Libelle champ privé') } it { expect(subject[:libelle]).to include('Libelle champ privé') }
it { expect(subject[:description]).to include('description du champ privé') } it { expect(subject[:description]).to include('description du champ privé') }
it { expect(subject.keys.include?(:order_place)).to be_truthy } it { expect(subject.key?(:order_place)).to be_truthy }
it { expect(subject[:type_champ]).to eq('text') } it { expect(subject[:type_champ]).to eq('text') }
end end
end end

View file

@ -0,0 +1,137 @@
describe NewAdministrateur::ServicesController, type: :controller do
let(:admin) { create(:administrateur) }
describe '#create' do
before do
sign_in admin
post :create, params: params
end
context 'when submitting a new service' do
let(:params) do
{
service: {
nom: 'super service',
organisme: 'organisme',
type_organisme: 'region',
email: 'email@toto.com',
telephone: '1234',
horaires: 'horaires',
adresse: 'adresse'
},
procedure_id: 12
}
end
it { expect(flash.alert).to be_nil }
it { expect(flash.notice).to eq('super service créé') }
it { expect(Service.last.nom).to eq('super service') }
it { expect(Service.last.organisme).to eq('organisme') }
it { expect(Service.last.type_organisme).to eq('region') }
it { expect(Service.last.email).to eq('email@toto.com') }
it { expect(Service.last.telephone).to eq('1234') }
it { expect(Service.last.horaires).to eq('horaires') }
it { expect(Service.last.adresse).to eq('adresse') }
it { expect(response).to redirect_to(services_path(procedure_id: 12)) }
end
context 'when submitting an invalid service' do
let(:params) { { service: { nom: 'super service' } } }
it { expect(flash.alert).not_to be_nil }
it { expect(response).to render_template(:new) }
end
end
describe '#update' do
let!(:service) { create(:service, administrateur: admin) }
let(:service_params) { { nom: 'nom', type_organisme: 'region' } }
before do
sign_in admin
params = {
id: service.id,
service: service_params,
procedure_id: 12
}
patch :update, params: params
end
context 'when updating a service' do
it { expect(flash.alert).to be_nil }
it { expect(flash.notice).to eq('nom modifié') }
it { expect(Service.last.nom).to eq('nom') }
it { expect(Service.last.type_organisme).to eq('region') }
it { expect(response).to redirect_to(services_path(procedure_id: 12)) }
end
context 'when updating a service with invalid data' do
let(:service_params) { { nom: '', type_organisme: 'region' } }
it { expect(flash.alert).not_to be_nil }
it { expect(response).to render_template(:edit) }
end
end
describe '#add_to_procedure' do
let!(:procedure) { create(:procedure, administrateur: admin) }
let!(:service) { create(:service, administrateur: admin) }
def post_add_to_procedure
sign_in admin
params = {
procedure: {
id: procedure.id,
service_id: service.id
}
}
patch :add_to_procedure, params: params
procedure.reload
end
context 'when adding a service to a procedure' do
before { post_add_to_procedure }
it { expect(flash.alert).to be_nil }
it { expect(flash.notice).to eq("service affecté : #{service.nom}") }
it { expect(procedure.service_id).to eq(service.id) }
it { expect(response).to redirect_to(admin_procedure_path(procedure.id)) }
end
context 'when stealing a service to add it to a procedure' do
let!(:service) { create(:service) }
it { expect { post_add_to_procedure }.to raise_error(ActiveRecord::RecordNotFound) }
end
end
describe '#destroy' do
let!(:service) { create(:service, administrateur: admin) }
context 'when a service has no related procedure' do
before do
sign_in admin
delete :destroy, params: { id: service.id, procedure_id: 12 }
end
it { expect{ service.reload }.to raise_error(ActiveRecord::RecordNotFound) }
it { expect(flash.alert).to be_nil }
it { expect(flash.notice).to eq("#{service.nom} est supprimé") }
it { expect(response).to redirect_to(services_path(procedure_id: 12)) }
end
context 'when a service still has some related procedures' do
let!(:procedure) { create(:procedure, service: service) }
before do
sign_in admin
delete :destroy, params: { id: service.id, procedure_id: 12 }
end
it { expect(service.reload).not_to be_nil }
it { expect(flash.alert).to eq("la procédure #{procedure.libelle} utilise encore le service service. Veuillez l'affecter à un autre service avant de pouvoir le supprimer") }
it { expect(flash.notice).to be_nil }
it { expect(response).to redirect_to(services_path(procedure_id: 12)) }
end
end
end

View file

@ -111,6 +111,15 @@ FactoryBot.define do
end end
end end
trait :with_notice do
after(:create) do |procedure, _evaluator|
procedure.notice.attach(
io: StringIO.new('Hello World'),
filename: 'hello.txt'
)
end
end
trait :with_all_champs_mandatory do trait :with_all_champs_mandatory do
after(:build) do |procedure, _evaluator| after(:build) do |procedure, _evaluator|
tdcs = [] tdcs = []

12
spec/factories/service.rb Normal file
View file

@ -0,0 +1,12 @@
FactoryBot.define do
factory :service do
nom 'service'
organisme 'organisme'
type_organisme 'commune'
administrateur { create(:administrateur) }
email 'email@toto.com'
telephone '1234'
horaires 'de 9 h à 18 h'
adresse 'adresse'
end
end

View file

@ -14,7 +14,6 @@ feature 'As an administrateur I wanna clone a procedure', js: true do
page.find_by_id('from-scratch').click page.find_by_id('from-scratch').click
fill_in 'procedure_libelle', with: 'libelle de la procedure' fill_in 'procedure_libelle', with: 'libelle de la procedure'
page.execute_script("$('#procedure_description').val('description de la procedure')") page.execute_script("$('#procedure_description').val('description de la procedure')")
fill_in 'procedure_organisation', with: 'organisme de la procedure'
page.find_by_id('save-procedure').click page.find_by_id('save-procedure').click
end end

View file

@ -39,7 +39,6 @@ feature 'As an administrateur I wanna create a new procedure', js: true do
page.find_by_id('flash_message').visible? page.find_by_id('flash_message').visible?
fill_in 'procedure_libelle', with: 'libelle de la procedure' fill_in 'procedure_libelle', with: 'libelle de la procedure'
page.execute_script("$('#procedure_description').val('description de la procedure')") page.execute_script("$('#procedure_description').val('description de la procedure')")
fill_in 'procedure_organisation', with: 'organisme de la procedure'
page.find_by_id('save-procedure').click page.find_by_id('save-procedure').click
expect(page).to have_current_path(admin_procedure_types_de_champ_path(Procedure.first.id.to_s)) expect(page).to have_current_path(admin_procedure_types_de_champ_path(Procedure.first.id.to_s))
end end
@ -51,8 +50,10 @@ feature 'As an administrateur I wanna create a new procedure', js: true do
page.find_by_id('from-scratch').click page.find_by_id('from-scratch').click
fill_in 'procedure_libelle', with: 'libelle de la procedure' fill_in 'procedure_libelle', with: 'libelle de la procedure'
page.execute_script("$('#procedure_description').val('description de la procedure')") page.execute_script("$('#procedure_description').val('description de la procedure')")
fill_in 'procedure_organisation', with: 'organisme de la procedure'
page.find_by_id('save-procedure').click page.find_by_id('save-procedure').click
procedure = Procedure.last
procedure.update(service: create(:service))
end end
scenario 'Add champ, add file, visualize them in procedure preview' do scenario 'Add champ, add file, visualize them in procedure preview' do

View file

@ -18,16 +18,4 @@ describe Carto::GeoAPI::Driver do
it { is_expected.to eq File.open('app/lib/carto/geo_api/pays.json').read } it { is_expected.to eq File.open('app/lib/carto/geo_api/pays.json').read }
end end
describe '.departements_url' do
subject { described_class.departements_url }
it { is_expected.to eq 'https://geo.api.gouv.fr/departements' }
end
describe '.regions_url' do
subject { described_class.regions_url }
it { is_expected.to eq 'https://geo.api.gouv.fr/regions' }
end
end end

View file

@ -171,8 +171,6 @@ describe Procedure do
end end
context 'organisation' do context 'organisation' do
it { is_expected.not_to allow_value(nil).for(:organisation) }
it { is_expected.not_to allow_value('').for(:organisation) }
it { is_expected.to allow_value('URRSAF').for(:organisation) } it { is_expected.to allow_value('URRSAF').for(:organisation) }
end end
end end
@ -262,7 +260,8 @@ describe Procedure do
describe 'clone' do describe 'clone' do
let(:archived_at) { nil } let(:archived_at) { nil }
let(:published_at) { nil } let(:published_at) { nil }
let(:procedure) { create(:procedure, archived_at: archived_at, published_at: published_at, received_mail: received_mail) } let!(:service) { create(:service) }
let(:procedure) { create(:procedure, archived_at: archived_at, published_at: published_at, received_mail: received_mail, service: service) }
let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) } let!(:type_de_champ_0) { create(:type_de_champ, procedure: procedure, order_place: 0) }
let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) } let!(:type_de_champ_1) { create(:type_de_champ, procedure: procedure, order_place: 1) }
let!(:type_de_champ_2) { create(:type_de_champ_drop_down_list, procedure: procedure, order_place: 2) } let!(:type_de_champ_2) { create(:type_de_champ_drop_down_list, procedure: procedure, order_place: 2) }
@ -328,6 +327,10 @@ describe Procedure do
it { expect(subject.cloned_from_library).to be(true) } it { expect(subject.cloned_from_library).to be(true) }
end end
it 'should keep service_id' do
expect(subject.service).to eq(service)
end
it 'should duplicate existing mail_templates' do it 'should duplicate existing mail_templates' do
expect(subject.received_mail.attributes.except("id", "procedure_id", "created_at", "updated_at")).to eq procedure.received_mail.attributes.except("id", "procedure_id", "created_at", "updated_at") expect(subject.received_mail.attributes.except("id", "procedure_id", "created_at", "updated_at")).to eq procedure.received_mail.attributes.except("id", "procedure_id", "created_at", "updated_at")
expect(subject.received_mail.id).not_to eq procedure.received_mail.id expect(subject.received_mail.id).not_to eq procedure.received_mail.id

View file

@ -0,0 +1,51 @@
describe Service, type: :model do
describe 'validation' do
let(:administrateur) { create(:administrateur) }
let(:params) do
{
nom: 'service des jardins',
organisme: 'mairie des iles',
type_organisme: 'commune',
email: 'super@email.com',
telephone: '1212202',
horaires: 'du lundi au vendredi',
adresse: '12 rue des schtroumpfs',
administrateur_id: administrateur.id
}
end
it { expect(Service.new(params).valid?).to be_truthy }
context 'when a first service exists' do
before { Service.create(params) }
context 'checks uniqueness of administrateur, name couple' do
it { expect(Service.create(params).valid?).to be_falsey }
end
end
context 'of type_organisme' do
it 'should be set' do
expect(Service.new(params.except(:type_organisme)).valid?).to be_falsey
end
end
context 'of nom' do
it 'should be set' do
expect(Service.new(params.except(:nom)).valid?).to be_falsey
end
end
context 'of administrateur' do
it 'should be set' do
expect(Service.new(params.except(:administrateur_id)).valid?).to be_falsey
end
end
context 'of type_organisme' do
it 'should belong to the enum' do
expect{ Service.new(params.merge(type_organisme: 'choucroute')) }.to raise_error(ArgumentError)
end
end
end
end

View file

@ -64,6 +64,7 @@ VCR.configure do |c|
c.hook_into :webmock c.hook_into :webmock
c.cassette_library_dir = 'spec/fixtures/cassettes' c.cassette_library_dir = 'spec/fixtures/cassettes'
c.configure_rspec_metadata! c.configure_rspec_metadata!
c.ignore_hosts 'test.host'
end end
DatabaseCleaner.strategy = :transaction DatabaseCleaner.strategy = :transaction
@ -119,6 +120,8 @@ RSpec.configure do |config|
config.before(:all) { config.before(:all) {
Warden.test_mode! Warden.test_mode!
Typhoeus::Expectation.clear
if Flipflop.remote_storage? if Flipflop.remote_storage?
VCR.use_cassette("ovh_storage_init") do VCR.use_cassette("ovh_storage_init") do
CarrierWave.configure do |config| CarrierWave.configure do |config|