Merge pull request #5106 from betagouv/dev

2020-04-30-01
This commit is contained in:
krichtof 2020-04-30 17:38:49 +02:00 committed by GitHub
commit ee46f67fb0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 839 additions and 55 deletions

View file

@ -42,6 +42,7 @@ gem 'groupdate'
gem 'haml-rails'
gem 'hashie'
gem 'jquery-rails' # Use jquery as the JavaScript library
gem 'jwt'
gem 'kaminari', '= 1.1.1' # Pagination
gem 'lograge'
gem 'logstash-event'

View file

@ -775,6 +775,7 @@ DEPENDENCIES
haml-rails
hashie
jquery-rails
jwt
kaminari (= 1.1.1)
launchy
letter_opener_web

View file

@ -19,12 +19,22 @@ module Instructeurs
end
end
def geo_data
send_data dossier.to_feature_collection.to_json,
type: 'application/json',
filename: "dossier-#{dossier.id}-features.json"
end
def apercu_attestation
@attestation = dossier.procedure.attestation_template.render_attributes_for(dossier: dossier)
render 'admin/attestation_templates/show', formats: [:pdf]
end
def bilans_bdf
render csv: dossier.etablissement.entreprise_bilans_bdf_to_csv
end
def show
@demande_seen_at = current_instructeur.follows.find_by(dossier: dossier)&.demande_seen_at

View file

@ -1,6 +1,6 @@
module NewAdministrateur
class ProceduresController < AdministrateurController
before_action :retrieve_procedure, only: [:champs, :annotations, :edit, :monavis, :update_monavis]
before_action :retrieve_procedure, only: [:champs, :annotations, :edit, :monavis, :update_monavis, :jeton, :update_jeton]
before_action :procedure_locked?, only: [:champs, :annotations]
def apercu
@ -57,6 +57,18 @@ module NewAdministrateur
render 'monavis'
end
def jeton
end
def update_jeton
if !@procedure.update(procedure_params)
flash.now.alert = @procedure.errors.full_messages
else
flash.notice = 'Le jeton a bien été mis à jour'
end
render 'jeton'
end
private
def apercu_tab
@ -68,7 +80,7 @@ module NewAdministrateur
end
def procedure_params
editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :web_hook_url, :declarative_with_state, :euro_flag, :logo, :auto_archive_on, :monavis_embed]
editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :web_hook_url, :declarative_with_state, :euro_flag, :logo, :auto_archive_on, :monavis_embed, :api_entreprise_token]
permited_params = if @procedure&.locked?
params.require(:procedure).permit(*editable_params)
else

View file

@ -104,7 +104,7 @@ module Users
sanitized_siret = siret_model.siret
begin
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(sanitized_siret, @dossier.procedure.id)
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(sanitized_siret, @dossier.procedure.id, current_user.id)
rescue ApiEntreprise::API::RequestFailed
return render_siret_error(t('errors.messages.siret_network_error'))
end
@ -112,7 +112,11 @@ module Users
return render_siret_error(t('errors.messages.siret_unknown'))
end
attestation_sociale_url = etablissement_attributes.delete(:entreprise_attestation_sociale_url)
attestation_fiscale_url = etablissement_attributes.delete(:entreprise_attestation_fiscale_url)
etablissement = @dossier.build_etablissement(etablissement_attributes)
etablissement.upload_attestation_sociale(attestation_sociale_url) if attestation_sociale_url.present?
etablissement.upload_attestation_fiscale(attestation_fiscale_url) if attestation_fiscale_url.present?
etablissement.save!
current_user.update!(siret: sanitized_siret)
@dossier.update!(autorisation_donnees: true)

View file

@ -5,6 +5,9 @@ class ApiEntreprise::API
RNA_RESOURCE_NAME = "associations"
EFFECTIFS_RESOURCE_NAME = "effectifs_mensuels_acoss_covid"
EFFECTIFS_ANNUELS_RESOURCE_NAME = "effectifs_annuels_acoss_covid"
ATTESTATION_SOCIALE_RESOURCE_NAME = "attestations_sociales_acoss"
ATTESTATION_FISCALE_RESOURCE_NAME = "attestations_fiscales_dgfip"
BILANS_BDF_RESOURCE_NAME = "bilans_entreprises_bdf"
TIMEOUT = 15
@ -39,11 +42,26 @@ class ApiEntreprise::API
call(EFFECTIFS_ANNUELS_RESOURCE_NAME, siren, procedure_id)
end
def self.attestation_sociale(siren, procedure_id)
procedure = Procedure.find(procedure_id)
call(ATTESTATION_SOCIALE_RESOURCE_NAME, siren, procedure_id) if procedure.api_entreprise_role?("attestations_sociales")
end
def self.attestation_fiscale(siren, procedure_id, user_id)
procedure = Procedure.find(procedure_id)
call(ATTESTATION_FISCALE_RESOURCE_NAME, siren, procedure_id, user_id) if procedure.api_entreprise_role?("attestations_fiscales")
end
def self.bilans_bdf(siren, procedure_id)
procedure = Procedure.find(procedure_id)
call(BILANS_BDF_RESOURCE_NAME, siren, procedure_id) if procedure.api_entreprise_role?("bilans_entreprise_bdf")
end
private
def self.call(resource_name, siret_or_siren, procedure_id)
def self.call(resource_name, siret_or_siren, procedure_id, user_id = nil)
url = url(resource_name, siret_or_siren)
params = params(siret_or_siren, procedure_id)
params = params(siret_or_siren, procedure_id, user_id)
response = Typhoeus.get(url,
params: params,
@ -68,17 +86,20 @@ class ApiEntreprise::API
base_url
end
def self.params(siret_or_siren, procedure_id)
{
def self.params(siret_or_siren, procedure_id, user_id)
params = {
context: "demarches-simplifiees.fr",
recipient: siret_or_siren,
object: "procedure_id: #{procedure_id}",
non_diffusables: true,
token: token
token: token_for_procedure(procedure_id)
}
params[:user_id] = user_id if user_id.present?
params
end
def self.token
Rails.application.secrets.api_entreprise[:key]
def self.token_for_procedure(procedure_id)
procedure = Procedure.find(procedure_id)
procedure.api_entreprise_token
end
end

View file

@ -0,0 +1,23 @@
class ApiEntreprise::AttestationFiscaleAdapter < ApiEntreprise::Adapter
def initialize(siren, procedure_id, user_id)
@siren = siren
@procedure_id = procedure_id
@user_id = user_id
end
private
def get_resource
ApiEntreprise::API.attestation_fiscale(@siren, @procedure_id, @user_id)
end
def process_params
if data_source[:url].present?
{
entreprise_attestation_fiscale_url: data_source[:url]
}
else
{}
end
end
end

View file

@ -0,0 +1,22 @@
class ApiEntreprise::AttestationSocialeAdapter < ApiEntreprise::Adapter
def initialize(siren, procedure_id)
@siren = siren
@procedure_id = procedure_id
end
private
def get_resource
ApiEntreprise::API.attestation_sociale(@siren, @procedure_id)
end
def process_params
if data_source[:url].present?
{
entreprise_attestation_sociale_url: data_source[:url]
}
else
{}
end
end
end

View file

@ -0,0 +1,23 @@
class ApiEntreprise::BilansBdfAdapter < ApiEntreprise::Adapter
def initialize(siren, procedure_id)
@siren = siren
@procedure_id = procedure_id
end
private
def get_resource
ApiEntreprise::API.bilans_bdf(@siren, @procedure_id)
end
def process_params
if data_source[:bilans].present?
{
entreprise_bilans_bdf: data_source[:bilans],
entreprise_bilans_bdf_monnaie: data_source[:monnaie]
}
else
{}
end
end
end

View file

@ -86,6 +86,10 @@ class Champ < ApplicationRecord
true
end
def stable_id
type_de_champ.stable_id
end
private
def needs_dossier_id?

View file

@ -74,7 +74,7 @@ class Champs::CarteChamp < Champ
def to_feature_collection
{
type: 'FeatureCollection',
id: type_de_champ.stable_id,
id: stable_id,
bbox: bounding_box,
features: (legacy_selections_utilisateur + except_selections_utilisateur).map(&:to_feature)
}

View file

@ -35,7 +35,7 @@ class Champs::RepetitionChamp < Champ
# We have to truncate the label here as spreadsheets have a (30 char) limit on length.
def libelle_for_export
str = "(#{type_de_champ.stable_id}) #{libelle}"
str = "(#{stable_id}) #{libelle}"
# /\*?[] are invalid Excel worksheet characters
ActiveStorage::Filename.new(str.delete('[]*?')).sanitized.truncate(30)
end

View file

@ -700,8 +700,36 @@ class Dossier < ApplicationRecord
{ id: self.id, procedure_libelle: self.procedure.libelle }
end
def geo_data?
geo_areas.present?
end
def to_feature_collection
{
type: 'FeatureCollection',
id: id,
bbox: bounding_box,
features: geo_areas.map(&:to_feature)
}
end
private
def geo_areas
champs.includes(:geo_areas).flat_map(&:geo_areas) + champs_private.includes(:geo_areas).flat_map(&:geo_areas)
end
def bounding_box
factory = RGeo::Geographic.simple_mercator_factory
bounding_box = RGeo::Cartesian::BoundingBox.new(factory)
geo_areas.each do |area|
bounding_box.add(area.rgeo_geometry)
end
[bounding_box.max_point, bounding_box.min_point].compact.flat_map(&:coordinates)
end
def log_dossier_operation(author, operation, subject = nil)
if log_operations?
DossierOperationLog.create_and_serialize(

View file

@ -4,6 +4,9 @@ class Etablissement < ApplicationRecord
has_one :champ, class_name: 'Champs::SiretChamp'
has_many :exercices, dependent: :destroy
has_one_attached :entreprise_attestation_sociale
has_one_attached :entreprise_attestation_fiscale
accepts_nested_attributes_for :exercices
validates :siret, presence: true
@ -114,6 +117,35 @@ class Etablissement < ApplicationRecord
)
end
def upload_attestation(url, attestation)
filename = File.basename(URI.parse(url).path)
response = Typhoeus.get(url)
if response.success?
attestation.attach(
io: StringIO.new(response.body),
filename: filename,
metadata: { virus_scan_result: ActiveStorage::VirusScanner::SAFE }
)
end
end
def upload_attestation_sociale(url)
upload_attestation(url, entreprise_attestation_sociale)
end
def upload_attestation_fiscale(url)
upload_attestation(url, entreprise_attestation_fiscale)
end
def entreprise_bilans_bdf_to_csv
headers = entreprise_bilans_bdf.flat_map(&:keys).uniq
data = entreprise_bilans_bdf.map do |bilan|
headers.map { |h| bilan[h] }
end
SpreadsheetArchitect.to_csv(headers: headers, data: data)
end
private
def dossier_id_for_export

View file

@ -36,7 +36,14 @@ class GeoArea < ApplicationRecord
{
type: 'Feature',
geometry: geometry,
properties: properties.merge(source: source, area: area, length: length).compact
properties: properties.symbolize_keys.merge(
source: source,
area: area,
length: length,
id: id,
champ_id: champ.stable_id,
dossier_id: champ.dossier_id
).compact
}
end

View file

@ -195,7 +195,11 @@ class Procedure < ApplicationRecord
def path_available?(administrateur, path)
procedure = other_procedure_with_path(path)
procedure.blank? || administrateur.owns?(procedure)
procedure.blank? || (administrateur.owns?(procedure) && canonical_procedure_child?(procedure))
end
def canonical_procedure_child?(procedure)
!canonical_procedure || canonical_procedure == procedure || canonical_procedure == procedure.canonical_procedure
end
def locked?
@ -306,6 +310,7 @@ class Procedure < ApplicationRecord
if is_different_admin
procedure.administrateurs = [admin]
procedure.api_entreprise_token = nil
else
procedure.administrateurs = administrateurs
end
@ -547,6 +552,18 @@ class Procedure < ApplicationRecord
"Procedure;#{id}"
end
def api_entreprise_roles
JWT.decode(api_entreprise_token, nil, false)[0]["roles"] if api_entreprise_token.present?
end
def api_entreprise_role?(role)
api_entreprise_roles.include?(role)
end
def api_entreprise_token
self[:api_entreprise_token].presence || Rails.application.secrets.api_entreprise[:key]
end
private
def move_type_de_champ_attributes(types_de_champ, type_de_champ, new_index)

View file

@ -6,7 +6,7 @@ class ApiEntrepriseService
#
# Raises a ApiEntreprise::API::RequestFailed exception on transcient errors
# (timeout, 5XX HTTP error code, etc.)
def self.get_etablissement_params_for_siret(siret, procedure_id)
def self.get_etablissement_params_for_siret(siret, procedure_id, user_id = nil)
etablissement_params = ApiEntreprise::EtablissementAdapter.new(siret, procedure_id).to_params
entreprise_params = ApiEntreprise::EntrepriseAdapter.new(siret, procedure_id).to_params
@ -35,6 +35,24 @@ class ApiEntrepriseService
rescue ApiEntreprise::API::RequestFailed
end
begin
attestation_sociale_params = ApiEntreprise::AttestationSocialeAdapter.new(entreprise_params[:entreprise_siren], procedure_id).to_params
etablissement_params.merge!(attestation_sociale_params)
rescue ApiEntreprise::API::RequestFailed
end
begin
attestation_fiscale_params = ApiEntreprise::AttestationFiscaleAdapter.new(entreprise_params[:entreprise_siren], procedure_id, user_id).to_params
etablissement_params.merge!(attestation_fiscale_params)
rescue ApiEntreprise::API::RequestFailed
end
begin
bilans_bdf_params = ApiEntreprise::BilansBdfAdapter.new(entreprise_params[:entreprise_siren], procedure_id).to_params
etablissement_params.merge!(bilans_bdf_params)
rescue ApiEntreprise::API::RequestFailed
end
etablissement_params.merge(entreprise_params)
end
end

View file

@ -1,9 +1,9 @@
= render partial: 'admin/closed_mail_template_attestation_inconsistency_alert'
.row.white-back
#procedure_show
= render 'modal_publish', procedure: @procedure, administrateur: @current_administrateur
= render partial: '/admin/procedures/modal_transfer'
= render 'modal_publish', procedure: @procedure, administrateur: @current_administrateur
= render 'modal_transfer'
#procedure_show
- if @procedure.brouillon?
- if @procedure.missing_steps.present?
- missing_elements = []
@ -12,20 +12,20 @@
- if @procedure.service.nil?
- missing_elements << 'un service'
- message = "Affectez #{missing_elements.join(' et ')} à votre démarche."
%a.action_button.btn.btn-success#disabled-publish-procedure{ data: { toggle: :tooltip, placement: :bottom }, style: 'float: right; margin-top: 10px;', disabled: true, title: message }
%button.action_button.btn.btn-success#disabled-publish-procedure{ data: { toggle: :tooltip, placement: :bottom }, style: 'float: right; margin-top: 10px;', disabled: true, title: message }
%i.fa.fa-eraser
Publier
- else
%a.btn.btn-success#publish-procedure{ data: { target: '#publish-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px;' }
%button.btn.btn-success#publish-procedure{ data: { target: '#publish-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px;' }
%i.fa.fa-eraser
Publier
%a.btn.btn-default#transfer-procedure{ data: { target: '#transfer-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px; margin-right: 10px;' }
%button.btn.btn-default#transfer-procedure{ data: { target: '#transfer-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px; margin-right: 10px;' }
%i.fa.fa-exchange
Envoyer une copie
- if @procedure.close?
%a.btn.btn-default#reopen-procedure{ data: { target: '#publish-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px; margin-right: 10px;' }
- if @procedure.close? || @procedure.depubliee?
%button.btn.btn-default#reopen-procedure{ data: { target: '#publish-modal', toggle: :modal }, type: 'button', style: 'float: right; margin-top: 10px; margin-right: 10px;' }
%i.fa.fa-rocket
Réactiver

View file

@ -8,6 +8,9 @@
= link_to "Uniquement cet onglet", "#", onclick: "window.print()", class: "menu-item menu-link"
%li
= link_to "Export PDF", instructeur_dossier_path(dossier.procedure, dossier, format: :pdf), target: "_blank", rel: "noopener", class: "menu-item menu-link"
- if dossier.geo_data?
%li
= link_to "Export GeoJSON", geo_data_instructeur_dossier_path(dossier.procedure, dossier), target: "_blank", rel: "noopener", class: "menu-item menu-link"
- if !PiecesJustificativesService.liste_pieces_justificatives(dossier).empty?
%span.dropdown.print-menu-opener

View file

@ -68,6 +68,10 @@
.procedure-list-element{ class: ('active' if active == 'MonAvis') }
MonAvis
%a#onglet-description{ href: url_for(admin_procedure_jeton_path(@procedure)) }
.procedure-list-element
Jeton
%a#onglet-description{ href: url_for(admin_procedures_path()) }
.procedure-list-element
Sortir

View file

@ -0,0 +1,24 @@
= render partial: 'new_administrateur/breadcrumbs',
locals: { steps: [link_to('Démarches', admin_procedures_path),
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
'Jeton'] }
.container
%h1.page-title
Configurer le jeton API Entreprise
.container
%h1
= form_with model: @procedure, url: url_for({ controller: 'new_administrateur/procedures', action: :update_jeton }), html: { class: 'form' } do |f|
%p.explication
Démarches Simplifiées utilise
= link_to 'API Entreprise', "https://entreprise.api.gouv.fr/"
qui permet de récupérer les informations administratives des entreprises et des associations.
Si votre démarche nécessite des autorisations spécifiques que Démarches Simplifiées n'a pas par défaut, merci de renseigner ici le jeton
= link_to 'API Entreprise', "https://entreprise.api.gouv.fr/demander_un_acces/"
propre à votre démarche.
= f.label :api_entreprise_token, "Jeton"
= f.password_field :api_entreprise_token, class: 'form-control'
.text-right
= f.button 'Enregistrer', class: 'button primary send'

View file

@ -67,6 +67,24 @@
- elsif etablissement.exercices.present?
= t('activemodel.models.exercices_summary', count: etablissement.exercices.count)
- if profile == 'instructeur'
- if etablissement.entreprise_attestation_sociale.attached?
%tr
%th.libelle Attestation sociale
%td= link_to "Consulter l'attestation", url_for(etablissement.entreprise_attestation_sociale)
- if etablissement.entreprise_attestation_fiscale.attached?
%tr
%th.libelle Attestation fiscale
%td= link_to "Consulter l'attestation", url_for(etablissement.entreprise_attestation_fiscale)
- if etablissement.entreprise_bilans_bdf.present?
%tr
%th.libelle
Bilans Banque de France
= "en #{etablissement.entreprise_bilans_bdf_monnaie}"
%td= link_to "Consulter les bilans", bilans_bdf_instructeur_dossier_path
- if etablissement.association?
%tr
%th.libelle Numéro RNA :

View file

@ -10,4 +10,4 @@
= render partial: 'shared/champs/carte/geo_areas', locals: { champ: champ, error: false }
= form.hidden_field :value,
data: { remote: true, feature_collection_id: champ.type_de_champ.stable_id, url: champs_carte_path(form.index), params: champ_carte_params(champ).to_query, method: 'post' }
data: { remote: true, feature_collection_id: champ.stable_id, url: champs_carte_path(form.index), params: champ_carte_params(champ).to_query, method: 'post' }

View file

@ -1,6 +1,6 @@
Rails.application.config.content_security_policy do |policy|
# Whitelist image
policy.img_src :self, "*.openstreetmap.org", "static.demarches-simplifiees.fr", "*.cloud.ovh.net", "stats.data.gouv.fr", "*", :data
policy.img_src :self, "*.openstreetmap.org", "static.demarches-simplifiees.fr", "*.cloud.ovh.net", "stats.data.gouv.fr", "*", :data, :blob
# Whitelist JS: nous, sendinblue et matomo
# miniprofiler et nous avons quelques boutons inline :(
policy.script_src :self, "stats.data.gouv.fr", "*.sendinblue.com", "*.crisp.chat", "crisp.chat", "*.sibautomation.com", "sibautomation.com", :unsafe_eval, :unsafe_inline, :blob
@ -11,7 +11,7 @@ Rails.application.config.content_security_policy do |policy|
policy.connect_src :self, "wss://*.crisp.chat", "*.crisp.chat", "*.demarches-simplifiees.fr", "in-automate.sendinblue.com", "app.franceconnect.gouv.fr", "sentry.io", "geo.api.gouv.fr", "api-adresse.data.gouv.fr", "openmaptiles.geo.data.gouv.fr", "openmaptiles.github.io", "tiles.geo.api.gouv.fr"
# Pour tout le reste, par défaut on accepte uniquement ce qui vient de chez nous
# et dans la notification on inclue la source de l'erreur
policy.default_src :self, :data, :report_sample, "fonts.gstatic.com", "in-automate.sendinblue.com", "player.vimeo.com", "app.franceconnect.gouv.fr", "sentry.io", "static.demarches-simplifiees.fr", "*.crisp.chat", "crisp.chat", "*.crisp.help", "*.sibautomation.com", "sibautomation.com", "data"
policy.default_src :self, :data, :blob, :report_sample, "fonts.gstatic.com", "in-automate.sendinblue.com", "player.vimeo.com", "app.franceconnect.gouv.fr", "sentry.io", "static.demarches-simplifiees.fr", "*.crisp.chat", "crisp.chat", "*.crisp.help", "*.sibautomation.com", "sibautomation.com", "data"
if Rails.env.development?
# Les CSP ne sont pas appliquées en dev: on notifie cependant une url quelconque de la violation
# pour détecter les erreurs lors de l'ajout d'une nouvelle brique externe durant le développement

View file

@ -166,6 +166,8 @@ Rails.application.routes.draw do
post 'admin/procedures' => 'new_administrateur/procedures#create'
get 'admin/procedures/:id/monavis' => 'new_administrateur/procedures#monavis', as: :admin_procedure_monavis
patch 'admin/procedures/:id/monavis' => 'new_administrateur/procedures#update_monavis', as: :update_monavis
get 'admin/procedures/:id/jeton' => 'new_administrateur/procedures#jeton', as: :admin_procedure_jeton
patch 'admin/procedures/:id/jeton' => 'new_administrateur/procedures#update_jeton', as: :update_jeton
namespace :admin do
get 'activate' => '/administrateurs/activate#new'
@ -314,7 +316,9 @@ Rails.application.routes.draw do
resources :dossiers, only: [:show], param: :dossier_id do
member do
get 'attestation'
get 'geo_data'
get 'apercu_attestation'
get 'bilans_bdf'
get 'messagerie'
get 'annotations-privees' => 'dossiers#annotations_privees'
get 'avis'

View file

@ -0,0 +1,5 @@
class AddAPIEntrepriseTokenToProcedures < ActiveRecord::Migration[5.2]
def change
add_column :procedures, :api_entreprise_token, :string
end
end

View file

@ -0,0 +1,6 @@
class AddBilansBdfToEtablissements < ActiveRecord::Migration[5.2]
def change
add_column :etablissements, :entreprise_bilans_bdf, :jsonb
add_column :etablissements, :entreprise_bilans_bdf_monnaie, :string
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_04_22_090426) do
ActiveRecord::Schema.define(version: 2020_04_29_191305) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -316,6 +316,8 @@ ActiveRecord::Schema.define(version: 2020_04_22_090426) do
t.decimal "entreprise_effectif_mensuel"
t.decimal "entreprise_effectif_annuel"
t.string "entreprise_effectif_annuel_annee"
t.jsonb "entreprise_bilans_bdf"
t.string "entreprise_bilans_bdf_monnaie"
t.index ["dossier_id"], name: "index_etablissements_on_dossier_id"
end
@ -515,6 +517,7 @@ ActiveRecord::Schema.define(version: 2020_04_22_090426) do
t.datetime "closed_at"
t.datetime "unpublished_at"
t.bigint "canonical_procedure_id"
t.string "api_entreprise_token"
t.index ["declarative_with_state"], name: "index_procedures_on_declarative_with_state"
t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id"

View file

@ -21,7 +21,7 @@
"email-butler": "^1.0.13",
"highcharts": "^8.0.0",
"intersection-observer": "^0.7.0",
"jquery": "^3.4.1",
"jquery": "^3.5.0",
"leaflet": "^1.6.0",
"leaflet-freedraw": "^2.12.0",
"mapbox-gl": "^1.9.0",

View file

@ -301,4 +301,21 @@ describe NewAdministrateur::ProceduresController, type: :controller do
end
end
end
describe 'GET #jeton' do
let(:procedure) { create(:procedure, administrateur: admin) }
subject { get :jeton, params: { id: procedure.id } }
it { is_expected.to have_http_status(:success) }
end
describe 'PATCH #jeton' do
let(:procedure) { create(:procedure, administrateur: admin) }
it "update api_entreprise_token" do
patch :update_jeton, params: { id: procedure.id, procedure: { api_entreprise_token: 'ceci-est-un-jeton' } }
expect(procedure.reload.api_entreprise_token).to eq('ceci-est-un-jeton')
end
end
end

View file

@ -221,6 +221,15 @@ describe Users::DossiersController, type: :controller do
let(:api_association_status) { 200 }
let(:api_association_body) { File.read('spec/fixtures/files/api_entreprise/associations.json') }
let(:api_entreprise_attestation_sociale_status) { 200 }
let(:api_entreprise_attestation_sociale_body) { File.read('spec/fixtures/files/api_entreprise/attestation_sociale.json') }
let(:api_entreprise_attestation_fiscale_status) { 200 }
let(:api_entreprise_attestation_fiscale_body) { File.read('spec/fixtures/files/api_entreprise/attestation_fiscale.json') }
let(:api_entreprise_bilans_bdf_status) { 200 }
let(:api_entreprise_bilans_bdf_body) { File.read('spec/fixtures/files/api_entreprise/bilans_entreprise_bdf.json') }
def stub_api_entreprise_requests
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/)
.to_return(status: api_etablissement_status, body: api_etablissement_body)
@ -234,11 +243,23 @@ describe Users::DossiersController, type: :controller do
.to_return(body: api_entreprise_effectifs_mensuels_body, status: api_entreprise_effectifs_mensuels_status)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/effectifs_annuels_acoss_covid\/#{siren}?.*token=/)
.to_return(body: api_entreprise_effectifs_annuels_body, status: api_entreprise_effectifs_annuels_status)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_sociales_acoss\/#{siren}?.*token=/)
.to_return(body: api_entreprise_attestation_sociale_body, status: api_entreprise_attestation_sociale_status)
stub_request(:get, "https://storage.entreprise.api.gouv.fr/siade/1569156881-f749d75e2bfd443316e2e02d59015f-attestation_vigilance_acoss.pdf")
.to_return(body: "body attestation", status: 200)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_fiscales_dgfip\/#{siren}?.*token=/)
.to_return(body: api_entreprise_attestation_fiscale_body, status: api_entreprise_attestation_fiscale_status)
stub_request(:get, "https://storage.entreprise.api.gouv.fr/siade/1569156756-f6b7779f99fa95cd60dc03c04fcb-attestation_fiscale_dgfip.pdf")
.to_return(body: "body attestation", status: 200)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/bilans_entreprises_bdf\/#{siren}?.*token=/)
.to_return(body: api_entreprise_bilans_bdf_body, status: api_entreprise_bilans_bdf_status)
end
before do
sign_in(user)
stub_api_entreprise_requests
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles)
.and_return(["attestations_fiscales", "attestations_sociales", "bilans_entreprise_bdf"])
end
before { Timecop.freeze(Time.zone.local(2020, 3, 14)) }
after { Timecop.return }
@ -334,6 +355,9 @@ describe Users::DossiersController, type: :controller do
expect(dossier.etablissement.association?).to be(true)
expect(dossier.etablissement.entreprise_effectif_mensuel).to be_present
expect(dossier.etablissement.entreprise_effectif_annuel).to be_present
expect(dossier.etablissement.entreprise_attestation_sociale).to be_attached
expect(dossier.etablissement.entreprise_attestation_fiscale).to be_attached
expect(dossier.etablissement.entreprise_bilans_bdf).to be_present
end
end
end

View file

@ -1,8 +1,10 @@
FactoryBot.define do
factory :geo_area do
source { GeoArea.sources.fetch(:cadastre) }
numero { '42' }
feuille { 'A11' }
trait :cadastre do
source { GeoArea.sources.fetch(:cadastre) }
numero { '42' }
feuille { 'A11' }
end
trait :quartier_prioritaire do
source { GeoArea.sources.fetch(:quartier_prioritaire) }
@ -13,5 +15,25 @@ FactoryBot.define do
trait :selection_utilisateur do
source { GeoArea.sources.fetch(:selection_utilisateur) }
end
trait :polygon do
geometry do
{
"type": "Polygon",
"coordinates": [
[
[2.428439855575562, 46.538476837725796],
[2.4284291267395024, 46.53842148758162],
[2.4282521009445195, 46.53841410755813],
[2.42824137210846, 46.53847314771794],
[2.428284287452698, 46.53847314771794],
[2.428364753723145, 46.538487907747864],
[2.4284291267395024, 46.538491597754714],
[2.428439855575562, 46.538476837725796]
]
]
}
end
end
end
end

View file

@ -0,0 +1,97 @@
require 'features/admin/procedure_spec_helper'
feature 'Publication de démarches', js: true do
include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) }
let(:instructeurs) { [administrateur.user.instructeur] }
let!(:procedure) do
create(:procedure_with_dossiers,
:with_path,
:with_type_de_champ,
:with_service,
instructeurs: instructeurs,
administrateur: administrateur)
end
before do
login_as administrateur.user, scope: :user
end
context 'lorsquune démarche est en test' do
scenario 'un administrateur peut la publier' do
visit admin_procedures_draft_path
click_on procedure.libelle
within "#procedure_show" do
click_on "Publier"
end
within '#publish-modal' do
expect(find_field('procedure_path').value).to eq procedure.path
fill_in 'lien_site_web', with: 'http://some.website'
click_on 'publish'
end
expect(page).to have_text('Démarche publiée')
expect(page).to have_selector('.procedure-lien')
end
end
context 'lorsquune démarche est close' do
let!(:procedure) do
create(:procedure_with_dossiers,
:closed,
:with_path,
:with_type_de_champ,
:with_service,
instructeurs: instructeurs,
administrateur: administrateur)
end
scenario 'un administrateur peut la publier' do
visit admin_procedures_archived_path
click_on procedure.libelle
within "#procedure_show" do
click_on "Réactiver"
end
within '#publish-modal' do
expect(find_field('procedure_path').value).to eq procedure.path
fill_in 'lien_site_web', with: 'http://some.website'
click_on 'publish'
end
expect(page).to have_text('Démarche publiée')
expect(page).to have_selector('.procedure-lien')
end
end
context 'lorsquune démarche est dépublié' do
let!(:procedure) do
create(:procedure_with_dossiers,
:unpublished,
:with_path,
:with_type_de_champ,
:with_service,
instructeurs: instructeurs,
administrateur: administrateur)
end
scenario 'un administrateur peut la publier' do
visit admin_procedures_archived_path
click_on procedure.libelle
within "#procedure_show" do
click_on "Réactiver"
end
within '#publish-modal' do
expect(find_field('procedure_path').value).to eq procedure.path
fill_in 'lien_site_web', with: 'http://some.website'
click_on 'publish'
end
expect(page).to have_text('Démarche publiée')
expect(page).to have_selector('.procedure-lien')
end
end
end

View file

@ -78,6 +78,7 @@ feature 'Creating a new dossier:' do
.to_return(status: 404, body: '')
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/effectifs_annuels_acoss_covid\/#{siren}?.*token=/)
.to_return(status: 404, body: '')
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return([])
end
before { Timecop.freeze(Time.zone.local(2020, 3, 14)) }
after { Timecop.return }

View file

@ -0,0 +1,4 @@
{
"url":
"https://storage.entreprise.api.gouv.fr/siade/1569156756-f6b7779f99fa95cd60dc03c04fcb-attestation_fiscale_dgfip.pdf"
}

View file

@ -0,0 +1,4 @@
{
"url":
"https://storage.entreprise.api.gouv.fr/siade/1569156881-f749d75e2bfd443316e2e02d59015f-attestation_vigilance_acoss.pdf"
}

View file

@ -0,0 +1,51 @@
{
"monnaie": "kEuros",
"bilans": [
{
"duree_exercice": "12",
"valeur_ajoutee_bdf": "7848792",
"resultat_exercice": "347126",
"capitaux_propres_et_assimiles": "5928663",
"total_provisions_pour_risques_et_charges": "1957919",
"dettes1_emprunts_obligataires_et_convertibles": "0",
"dettes2_autres_emprunts_obligataires": "6552306",
"total_dettes_stables": "6552306",
"emprunts_et_dettes_financieres_divers": "430634",
"groupes_et_associes": "0",
"besoin_en_fonds_de_roulement": "-721507",
"disponibilites": "1983051",
"total_passif": "18478051",
"evolution_valeur_ajoutee_bdf": "",
"evolution_resultat_exercice": "",
"evolution_capitaux_propres_et_assimiles": "",
"evolution_total_provisions_pour_risques_et_charges": "",
"evolution_dettes1_emprunts_obligataires_et_convertibles": "",
"evolution_dettes2_autres_emprunts_obligataires": "",
"evolution_emprunts_et_dettes_financieres_divers": "",
"evolution_groupes_et_associes": "",
"evolution_besoin_en_fonds_de_roulement": "",
"evolution_disponibilites": "",
"evolution_total_passif": "",
"chiffre_affaires_ht": "12030700",
"capacite_autofinancement": "891914",
"date_arret_exercice": "201512",
"dettes3_emprunts_et_dettes_aupres_des_etablissements_de_credit": "0",
"dettes4_maturite_a_un_an_au_plus": "0",
"autres_fonds_propres": "0",
"capital_social_inclus_dans_capitaux_propres_et_assimiles": "3800000",
"excedent_brut_exploitation": "-1876863",
"evolution_chiffre_affaires_ht": "",
"evolution_capacite_autofinancement": "",
"evolution_dettes3_emprunts_et_dettes_aupres_des_etablissements_de_credit": "",
"evolution_dettes4_maturite_a_un_an_au_plus": "",
"evolution_autres_fonds_propres": "",
"evolution_capital_social_inclus_dans_capitaux_propres_et_assimiles": "",
"evolution_excedent_brut_exploitation": "",
"evolution_fonds_roulement_net_global": "",
"evolution_ratio_fonds_roulement_net_global_sur_besoin_en_fonds_de_roulement": "",
"evolution_total_dettes_stables": "",
"fonds_roulement_net_global": "2464585",
"ratio_fonds_roulement_net_global_sur_besoin_en_fonds_de_roulement": "-"
}, "bilan 2", "bilan 3"
]
}

View file

@ -1,11 +1,13 @@
describe ApiEntreprise::API do
let(:procedure_id) { 12 }
let(:procedure) { create(:procedure) }
let(:procedure_id) { procedure.id }
let(:token) { Rails.application.secrets.api_entreprise[:key] }
describe '.entreprise' do
subject { described_class.entreprise(siren, procedure_id) }
before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=/)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=#{token}/)
.to_return(status: status, body: body)
end
@ -47,6 +49,27 @@ describe ApiEntreprise::API do
it 'returns response body' do
expect(subject).to eq(JSON.parse(body, symbolize_names: true))
end
context 'with specific token for procedure' do
let(:token) { 'token-for-demarche' }
let(:procedure) { create(:procedure, api_entreprise_token: token) }
let(:procedure_id) { procedure.id }
it 'call api-entreprise with specfic token' do
subject
expect(WebMock).to have_requested(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=token-for-demarche/)
end
end
context 'without specific token for procedure' do
let(:procedure) { create(:procedure, api_entreprise_token: nil) }
let(:procedure_id) { procedure.id }
it 'call api-entreprise with specfic token' do
subject
expect(WebMock).to have_requested(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=#{token}/)
end
end
end
end
@ -135,4 +158,86 @@ describe ApiEntreprise::API do
it { expect(subject).to eq(JSON.parse(body, symbolize_names: true)) }
end
end
describe '.attestation_sociale' do
let(:procedure) { create(:procedure, api_entreprise_token: token) }
let(:siren) { '418166096' }
let(:status) { 200 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/attestation_sociale.json') }
before do
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return(roles)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_sociales_acoss\/#{siren}?.*token=/)
.to_return(body: body, status: status)
end
subject { described_class.attestation_sociale(siren, procedure.id) }
context 'when token not authorized' do
let(:roles) { ["entreprises"] }
it { expect(subject).to eq(nil) }
end
context 'when token is authorized' do
let(:roles) { ["attestations_sociales"] }
it { expect(subject).to eq(JSON.parse(body, symbolize_names: true)) }
end
end
describe '.attestation_fiscale' do
let(:procedure) { create(:procedure, api_entreprise_token: token) }
let(:siren) { '418166096' }
let(:user_id) { 1 }
let(:status) { 200 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/attestation_fiscale.json') }
before do
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return(roles)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_fiscales_dgfip\/#{siren}?.*token=#{token}&user_id=#{user_id}/)
.to_return(body: body, status: status)
end
subject { described_class.attestation_fiscale(siren, procedure.id, user_id) }
context 'when token not authorized' do
let(:roles) { ["entreprises"] }
it { expect(subject).to eq(nil) }
end
context 'when token is authorized' do
let(:roles) { ["attestations_fiscales"] }
it { expect(subject).to eq(JSON.parse(body, symbolize_names: true)) }
end
end
describe '.bilans_bdf' do
let(:procedure) { create(:procedure, api_entreprise_token: token) }
let(:siren) { '418166096' }
let(:status) { 200 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/bilans_entreprise_bdf.json') }
before do
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return(roles)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/bilans_entreprises_bdf\/#{siren}?.*token=#{token}/)
.to_return(body: body, status: status)
end
subject { described_class.bilans_bdf(siren, procedure.id) }
context 'when token not authorized' do
let(:roles) { ["entreprises"] }
it { expect(subject).to eq(nil) }
end
context 'when token is authorized' do
let(:roles) { ["bilans_entreprise_bdf"] }
it { expect(subject).to eq(JSON.parse(body, symbolize_names: true)) }
end
end
end

View file

@ -0,0 +1,26 @@
describe ApiEntreprise::AttestationFiscaleAdapter do
let(:siren) { '418166096' }
let(:procedure) { create(:procedure) }
let(:user_id) { 1 }
let(:adapter) { described_class.new(siren, procedure.id, user_id) }
subject { adapter.to_params }
before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_fiscales_dgfip\/#{siren}?.*token=/)
.to_return(body: body, status: status)
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return(["attestations_fiscales"])
end
context "when the SIREN is valid" do
let(:body) { File.read('spec/fixtures/files/api_entreprise/attestation_fiscale.json') }
let(:status) { 200 }
it '#to_params class est une Hash ?' do
expect(subject).to be_an_instance_of(Hash)
end
it "returns url of attestation_fiscale" do
expect(subject[:entreprise_attestation_fiscale_url]).to eq("https://storage.entreprise.api.gouv.fr/siade/1569156756-f6b7779f99fa95cd60dc03c04fcb-attestation_fiscale_dgfip.pdf")
end
end
end

View file

@ -0,0 +1,25 @@
describe ApiEntreprise::AttestationSocialeAdapter do
let(:siren) { '418166096' }
let(:procedure) { create(:procedure) }
let(:adapter) { described_class.new(siren, procedure.id) }
subject { adapter.to_params }
before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_sociales_acoss\/#{siren}?.*token=/)
.to_return(body: body, status: status)
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return(["attestations_sociales"])
end
context "when the SIREN is valid" do
let(:body) { File.read('spec/fixtures/files/api_entreprise/attestation_sociale.json') }
let(:status) { 200 }
it '#to_params class est une Hash ?' do
expect(subject).to be_an_instance_of(Hash)
end
it "renvoie l'url de l'attestation sociale" do
expect(subject[:entreprise_attestation_sociale_url]).to eq("https://storage.entreprise.api.gouv.fr/siade/1569156881-f749d75e2bfd443316e2e02d59015f-attestation_vigilance_acoss.pdf")
end
end
end

View file

@ -0,0 +1,26 @@
describe ApiEntreprise::BilansBdfAdapter do
let(:siren) { '418166096' }
let(:procedure) { create(:procedure) }
let(:procedure_id) { procedure.id }
let(:adapter) { described_class.new(siren, procedure_id) }
subject { adapter.to_params }
before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/bilans_entreprises_bdf\/#{siren}?.*token=/)
.to_return(body: body, status: status)
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles).and_return(["bilans_entreprise_bdf"])
end
context "when the SIREN is valid" do
let(:body) { File.read('spec/fixtures/files/api_entreprise/bilans_entreprise_bdf.json') }
let(:status) { 200 }
it '#to_params class est une Hash ?' do
expect(subject).to be_an_instance_of(Hash)
end
it "returns bilans bdf" do
expect(subject[:entreprise_bilans_bdf][0][:valeur_ajoutee_bdf]).to eq("7848792")
end
end
end

View file

@ -1,6 +1,7 @@
describe ApiEntreprise::EffectifsAdapter do
let(:siren) { '418166096' }
let(:procedure_id) { 22 }
let(:procedure) { create(:procedure) }
let(:procedure_id) { procedure.id }
let(:annee) { "2020" }
let(:mois) { "02" }
let(:adapter) { described_class.new(siren, procedure_id, annee, mois) }

View file

@ -1,6 +1,7 @@
describe ApiEntreprise::EffectifsAnnuelsAdapter do
let(:siren) { '418166096' }
let(:procedure_id) { 22 }
let(:procedure) { create(:procedure) }
let(:procedure_id) { procedure.id }
let(:adapter) { described_class.new(siren, procedure_id) }
subject { adapter.to_params }

View file

@ -1,6 +1,7 @@
describe ApiEntreprise::EntrepriseAdapter do
let(:siren) { '418166096' }
let(:procedure_id) { 22 }
let(:procedure) { create(:procedure) }
let(:procedure_id) { procedure.id }
let(:adapter) { described_class.new(siren, procedure_id) }
subject { adapter.to_params }

View file

@ -1,5 +1,6 @@
describe ApiEntreprise::EtablissementAdapter do
let(:procedure_id) { 33 }
let(:procedure) { create(:procedure) }
let(:procedure_id) { procedure.id }
context 'SIRET valide avec infos diffusables' do
let(:siret) { '41816609600051' }
@ -88,7 +89,7 @@ describe ApiEntreprise::EtablissementAdapter do
context 'when siret is not found' do
let(:bad_siret) { 11_111_111_111_111 }
subject { described_class.new(bad_siret, 12).to_params }
subject { described_class.new(bad_siret, procedure_id).to_params }
before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{bad_siret}?.*token=/)

View file

@ -1,7 +1,7 @@
describe ApiEntreprise::ExercicesAdapter do
let(:siret) { '41816609600051' }
let(:procedure_id) { 11 }
subject { described_class.new(siret, procedure_id).to_params }
let(:procedure) { create(:procedure) }
subject { described_class.new(siret, procedure.id).to_params }
before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/exercices\/.*token=/)

View file

@ -1,6 +1,7 @@
describe ApiEntreprise::RNAAdapter do
let(:siret) { '50480511000013' }
let(:procedure_id) { 22 }
let(:procedure) { create(:procedure) }
let(:procedure_id) { procedure.id }
let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') }
let(:status) { 200 }
let(:adapter) { described_class.new(siret, procedure_id) }

View file

@ -1234,4 +1234,34 @@ describe Dossier do
it { expect(procedure).not_to be_nil }
it { expect(procedure.discarded?).to be_truthy }
end
describe "to_feature_collection" do
let(:geo_area) { create(:geo_area, :selection_utilisateur, :polygon) }
let(:champ) { create(:champ_carte, geo_areas: [geo_area]) }
let(:dossier) { create(:dossier, champs: [champ]) }
it 'should have all champs carto' do
expect(dossier.to_feature_collection).to eq({
type: 'FeatureCollection',
id: dossier.id,
bbox: [2.428439855575562, 46.538491597754714, 2.42824137210846, 46.53841410755813],
features: [
{
type: 'Feature',
geometry: {
'coordinates' => [[[2.428439855575562, 46.538476837725796], [2.4284291267395024, 46.53842148758162], [2.4282521009445195, 46.53841410755813], [2.42824137210846, 46.53847314771794], [2.428284287452698, 46.53847314771794], [2.428364753723145, 46.538487907747864], [2.4284291267395024, 46.538491597754714], [2.428439855575562, 46.538476837725796]]],
'type' => 'Polygon'
},
properties: {
area: 219.0,
champ_id: champ.stable_id,
dossier_id: dossier.id,
id: geo_area.id,
source: 'selection_utilisateur'
}
}
]
})
end
end
end

View file

@ -35,4 +35,28 @@ describe Etablissement do
end
end
end
describe '.entreprise_bilans_bdf_to_csv' do
let(:etablissement) { build(:etablissement, entreprise_bilans_bdf: bilans) }
let(:bilans) do
[
{
"total_passif": "1200",
"chiffres_affaires_ht": "40000"
},
{
"total_passif": "0",
"evolution_total_dettes_stables": "30"
}
]
end
subject { etablissement.entreprise_bilans_bdf_to_csv.split("\n") }
it "build a csv with all keys" do
expect(subject[0].split(',').sort).to eq(["total_passif", "chiffres_affaires_ht", "evolution_total_dettes_stables"].sort)
expect(subject[1].split(',')).to eq(["1200", "40000"])
expect(subject[2].split(',')).to eq(["0", "", "30"])
end
end
end

View file

@ -461,6 +461,10 @@ describe Procedure do
end
end
it 'should discard specific api_entreprise_token' do
expect(subject.read_attribute(:api_entreprise_token)).to be_nil
end
it 'should have one administrateur' do
expect(subject.administrateurs).to eq([administrateur])
end

View file

@ -26,7 +26,7 @@ describe ChampSerializer do
context 'when type champ is carte' do
let(:champ) { create(:champ_carte, value: value, geo_areas: [geo_area].compact) }
let(:value) { nil }
let(:geo_area) { create(:geo_area, geometry: geo_json) }
let(:geo_area) { create(:geo_area, :cadastre, geometry: geo_json) }
let(:geo_json) do
{
"type" => 'MultiPolygon',

View file

@ -13,6 +13,14 @@ describe ApiEntrepriseService do
.to_return(body: effectifs_mensuels_body, status: effectifs_mensuels_status)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/effectifs_annuels_acoss_covid\/#{siren}?.*token=/)
.to_return(body: effectifs_annuels_body, status: effectifs_annuels_status)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_sociales_acoss\/#{siren}?.*token=/)
.to_return(body: attestation_sociale_body, status: attestation_sociale_status)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_sociales_acoss\/#{siren}?.*token=/)
.to_return(body: attestation_sociale_body, status: attestation_sociale_status)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/attestations_fiscales_dgfip\/#{siren}?.*token=/)
.to_return(body: attestation_fiscale_body, status: attestation_fiscale_status)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/bilans_entreprises_bdf\/#{siren}?.*token=/)
.to_return(body: bilans_bdf_body, status: bilans_bdf_status)
end
before { Timecop.freeze(Time.zone.local(2020, 3, 14)) }
@ -38,13 +46,31 @@ describe ApiEntrepriseService do
let(:effectifs_annuels_body) { File.read('spec/fixtures/files/api_entreprise/effectifs_annuels.json') }
let(:effectif_annuel) { 100.5 }
let(:attestation_sociale_status) { 200 }
let(:attestation_sociale_body) { File.read('spec/fixtures/files/api_entreprise/attestation_sociale.json') }
let(:attestation_sociale_url) { "https://storage.entreprise.api.gouv.fr/siade/1569156881-f749d75e2bfd443316e2e02d59015f-attestation_vigilance_acoss.pdf" }
let(:attestation_fiscale_status) { 200 }
let(:attestation_fiscale_body) { File.read('spec/fixtures/files/api_entreprise/attestation_fiscale.json') }
let(:attestation_fiscale_url) { "https://storage.entreprise.api.gouv.fr/siade/1569156756-f6b7779f99fa95cd60dc03c04fcb-attestation_fiscale_dgfip.pdf" }
let(:bilans_bdf_status) { 200 }
let(:bilans_bdf_body) { File.read('spec/fixtures/files/api_entreprise/bilans_entreprise_bdf.json') }
let(:bilans_bdf) { JSON.parse(bilans_bdf_body, symbolize_names: true)[:bilans] }
let(:exercices_status) { 200 }
let(:exercices_body) { File.read('spec/fixtures/files/api_entreprise/exercices.json') }
let(:associations_status) { 200 }
let(:associations_body) { File.read('spec/fixtures/files/api_entreprise/associations.json') }
let(:result) { ApiEntrepriseService.get_etablissement_params_for_siret(siret, '1') }
let(:procedure) { create(:procedure, api_entreprise_token: 'un-jeton') }
let(:result) { ApiEntrepriseService.get_etablissement_params_for_siret(siret, procedure.id) }
before do
allow_any_instance_of(Procedure).to receive(:api_entreprise_roles)
.and_return(["attestations_sociales", "attestations_fiscales", "bilans_entreprise_bdf"])
end
context 'when service is up' do
it 'should fetch etablissement params' do
@ -54,6 +80,9 @@ describe ApiEntrepriseService do
expect(result[:exercices_attributes]).to_not be_empty
expect(result[:entreprise_effectif_mensuel]).to eq(effectif_mensuel)
expect(result[:entreprise_effectif_annuel]).to eq(effectif_annuel)
expect(result[:entreprise_attestation_sociale_url]).to eq(attestation_sociale_url)
expect(result[:entreprise_attestation_fiscale_url]).to eq(attestation_fiscale_url)
expect(result[:entreprise_bilans_bdf]).to eq(bilans_bdf)
end
end

View file

@ -14,9 +14,9 @@ describe 'admin/procedures/show.html.haml', type: :view do
end
describe 'publish button is not visible' do
it { expect(rendered).not_to have_css('a#publish-procedure') }
it { expect(rendered).not_to have_css('button#publish-procedure') }
it { expect(rendered).not_to have_css('button#archive-procedure') }
it { expect(rendered).not_to have_css('a#reopen-procedure') }
it { expect(rendered).not_to have_css('button#reopen-procedure') }
end
end
@ -27,9 +27,9 @@ describe 'admin/procedures/show.html.haml', type: :view do
end
describe 'publish button is visible' do
it { expect(rendered).to have_css('a#publish-procedure') }
it { expect(rendered).to have_css('button#publish-procedure') }
it { expect(rendered).not_to have_css('button#archive-procedure') }
it { expect(rendered).not_to have_css('a#reopen-procedure') }
it { expect(rendered).not_to have_css('button#reopen-procedure') }
end
describe 'procedure path is not customized' do
@ -46,9 +46,9 @@ describe 'admin/procedures/show.html.haml', type: :view do
end
describe 'archive button is visible', js: true do
it { expect(rendered).not_to have_css('a#publish-procedure') }
it { expect(rendered).not_to have_css('button#publish-procedure') }
it { expect(rendered).to have_css('button#archive-procedure') }
it { expect(rendered).not_to have_css('a#reopen-procedure') }
it { expect(rendered).not_to have_css('button#reopen-procedure') }
end
describe 'procedure link is present' do
@ -65,9 +65,9 @@ describe 'admin/procedures/show.html.haml', type: :view do
end
describe 'Re-enable button is visible' do
it { expect(rendered).not_to have_css('a#publish-procedure') }
it { expect(rendered).not_to have_css('button#publish-procedure') }
it { expect(rendered).not_to have_css('button#archive-procedure') }
it { expect(rendered).to have_css('a#reopen-procedure') }
it { expect(rendered).to have_css('button#reopen-procedure') }
end
describe 'procedure link is present' do

View file

@ -5426,10 +5426,10 @@ jest-worker@^25.1.0:
merge-stream "^2.0.0"
supports-color "^7.0.0"
jquery@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2"
integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==
jquery@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.0.tgz#9980b97d9e4194611c36530e7dc46a58d7340fc9"
integrity sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ==
js-base64@^2.1.8:
version "2.5.2"