Merge pull request #7790 from betagouv/feature/add_rna_type_de_champs

Ajouter champ RNA à une procédure
This commit is contained in:
Paul Chavard 2022-10-12 09:46:59 +02:00 committed by GitHub
commit 8499c0327d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 761 additions and 44 deletions

View file

@ -455,6 +455,13 @@
min-height: 1px;
}
.rna-info {
margin-top: -$default-fields-spacer;
margin-bottom: $default-fields-spacer;
// Ensure the bottom-margin is not collapsed when the element is empty
min-height: 1px;
}
.send-wrapper {
display: flex;
width: 100%;

View file

@ -0,0 +1,2 @@
class EditableChamp::RNAComponent < EditableChamp::EditableChampBaseComponent
end

View file

@ -0,0 +1,4 @@
---
en:
placeholder: "W503726238"
title: "The RNA number must begin with a capital W followed by 9 digits"

View file

@ -0,0 +1,4 @@
---
fr:
placeholder: "W503726238"
title: "Le numéro RNA doit commencer par un W majuscule suivi de 9 chiffres"

View file

@ -0,0 +1,12 @@
= @form.text_field :value,
id: @champ.input_id,
aria: { describedby: @champ.describedby_id },
placeholder: t(".placeholder"),
data: { controller: 'turbo-input', turbo_input_url_value: champs_rna_path(@champ.id) },
required: @champ.mandatory?,
pattern: "W[0-9]{9}",
title: t(".title"),
class: "width-33-desktop",
maxlength: 10
.rna-info{ id: dom_id(@champ, :rna_info) }
= render 'shared/champs/rna/association', champ: @champ, network_error: false, rna: @champ.value

View file

@ -0,0 +1,16 @@
class Champs::RNAController < ApplicationController
before_action :authenticate_logged_user!
def show
@champ = policy_scope(Champ).find(params[:champ_id])
@rna = read_param_value(@champ.input_name, 'value')
@network_error = false
begin
data = APIEntreprise::RNAAdapter.new(@rna, @champ.procedure_id).to_params
@champ.update!(data: data, value: @rna)
rescue APIEntreprise::API::Error, ActiveRecord::RecordInvalid => error
@network_error = true if error.try(:network_error?) && !APIEntrepriseService.api_up?
@champ.update(data: nil, value: nil)
end
end
end

View file

@ -448,7 +448,6 @@ module Users
if @dossier.champs.any?(&:changed_for_autosave?)
@dossier.last_champ_updated_at = Time.zone.now
end
if !@dossier.save(**validation_options)
errors += @dossier.errors.full_messages
elsif should_change_groupe_instructeur?

View file

@ -2205,6 +2205,11 @@ enum TypeDeChamp {
"""
repetition
"""
RNA
"""
rna
"""
SIRET
"""

View file

@ -1,7 +1,7 @@
class APIEntreprise::AssociationJob < APIEntreprise::Job
def perform(etablissement_id, procedure_id)
find_etablissement(etablissement_id)
etablissement_params = APIEntreprise::RNAAdapter.new(etablissement.siret, procedure_id).to_params
etablissement_params = APIEntreprise::RNAAdapter.new(etablissement.siret, procedure_id, true).to_params
etablissement.update!(etablissement_params)
end
end

View file

@ -1,9 +1,10 @@
class APIEntreprise::Adapter
UNAVAILABLE = 'Donnée indisponible'
def initialize(siret, procedure_id)
def initialize(siret, procedure_id, depreciated = false)
@siret = siret
@procedure_id = procedure_id
@depreciated = depreciated
end
def api(procedure_id = nil)

View file

@ -1,4 +1,12 @@
require 'json_schemer'
class APIEntreprise::RNAAdapter < APIEntreprise::Adapter
class InvalidSchemaError < ::StandardError
def initialize(errors)
super(errors.map(&:to_json).join("\n"))
end
end
private
def get_resource
@ -6,26 +14,23 @@ class APIEntreprise::RNAAdapter < APIEntreprise::Adapter
end
def process_params
# Sometimes the associations endpoints responses with a 206,
# and these response are often useable as the they only
# contain an error message.
# Therefore here we make sure that our response seems valid
# by checking that there is an association attribute.
if !data_source.key?(:association)
{}
else
association_id = data_source[:association][:id]
params = data_source[:association].slice(*attr_to_fetch)
params = data_source[:association]
params = params&.slice(*attr_to_fetch) if @depreciated
params[:rna] = data_source.dig(:association, :id)
if params[:rna].present? && valid_params?(params)
params = params.transform_keys { |k| :"association_#{k}" }.deep_stringify_keys
raise InvalidSchemaError.new(schemer.validate(params).to_a) unless schemer.valid?(params)
if association_id.present? && valid_params?(params)
params[:rna] = association_id
params.transform_keys { |k| :"association_#{k}" }
else
{}
end
params
else
{}
end
end
def schemer
@schemer ||= JSONSchemer.schema(Rails.root.join('app/schemas/association.json'))
end
def attr_to_fetch
[
:titre,

View file

@ -57,6 +57,7 @@ class Champ < ApplicationRecord
:dgfip?,
:pole_emploi?,
:mesri?,
:rna?,
:siret?,
:stable_id,
to: :type_de_champ

View file

@ -0,0 +1,44 @@
# == Schema Information
#
# Table name: champs
#
# id :integer not null, primary key
# data :jsonb
# fetch_external_data_exceptions :string is an Array
# private :boolean default(FALSE), not null
# rebased_at :datetime
# row :integer
# type :string
# value :string
# value_json :jsonb
# created_at :datetime
# updated_at :datetime
# dossier_id :integer not null
# etablissement_id :integer
# external_id :string
# parent_id :bigint
# type_de_champ_id :integer not null
#
class Champs::RNAChamp < Champ
validates :value, allow_blank: true, format: {
with: /\AW[0-9]{9}\z/, message: I18n.t(:not_a_rna, scope: 'activerecord.errors.messages')
}, if: -> { validation_context != :brouillon }
delegate :id, to: :procedure, prefix: true
def title
data&.dig("association_titre")
end
def identifier
title.present? ? "#{value} (#{title})" : value
end
def for_export
identifier
end
def search_terms
etablissement.present? ? etablissement.search_terms : [value]
end
end

View file

@ -55,6 +55,7 @@ class TypeDeChamp < ApplicationRecord
explication: CADRE,
dossier_link: CADRE,
piece_justificative: STANDARD,
rna: REFERENTIEL_EXTERNE,
siret: PAIEMENT_IDENTIFICATION,
carte: REFERENTIEL_EXTERNE,
repetition: CADRE,
@ -92,6 +93,7 @@ class TypeDeChamp < ApplicationRecord
explication: 'explication',
dossier_link: 'dossier_link',
piece_justificative: 'piece_justificative',
rna: 'rna',
carte: 'carte',
repetition: 'repetition',
titre_identite: 'titre_identite',
@ -311,6 +313,10 @@ class TypeDeChamp < ApplicationRecord
type_champ == TypeDeChamp.type_champs.fetch(:cnaf)
end
def rna?
type_champ == TypeDeChamp.type_champs.fetch(:rna)
end
def dgfip?
type_champ == TypeDeChamp.type_champs.fetch(:dgfip)
end

View file

@ -0,0 +1,5 @@
class TypesDeChamp::RNATypeDeChamp < TypesDeChamp::TypeDeChampBase
def estimated_fill_duration(revision)
FILL_DURATION_MEDIUM
end
end

View file

@ -0,0 +1,236 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://demarches-simplifiees.fr/association.schema.json",
"title": "Association",
"type": "object",
"properties": {
"association_titre": {
"type": "string"
},
"association_objet": {
"type": "string"
},
"association_rna": {
"type": "string"
},
"association_date_creation": {
"type": "string",
"format": "date"
},
"association_date_declaration": {
"type": "string",
"format": "date"
},
"association_date_publication": {
"type": "string",
"format": "date"
},
"association_date_dissolution": {
"anyOf": [
{
"type": "string",
"format": "date"
},
{
"type": "null"
}
]
},
"association_mise_a_jour": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string",
"format": "date"
},
{
"type": "null"
}
]
},
"association_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"association_siret": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"association_siret_siege_social": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"association_code_civilite_dirigeant": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"association_civilite_dirigeant": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"association_code_etat": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"association_etat": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"association_code_groupement": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"association_groupement": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"association_address_siege": {
"type": "object",
"properties": {
"complement": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"numero_voie": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"type_voie": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"libelle_voie": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"distribution": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"code_insee": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"code_postal": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"commune": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
}
}
},
"required": [
"association_titre",
"association_rna",
"association_date_creation",
"association_date_declaration",
"association_date_publication"
]
}

View file

@ -0,0 +1 @@
= turbo_stream.update dom_id(@champ, :rna_info), partial: 'shared/champs/rna/association', locals: { champ: @champ, network_error: @network_error, rna: @rna }

View file

@ -0,0 +1,6 @@
- if network_error
%p.pt-1= t('.network_error')
- elsif @rna.present? && champ.data.blank?
%p.pt-1= t('.not_found')
- elsif champ.value.present?
%p.pt-1= t('.data_fetched', title: champ.title)

View file

@ -0,0 +1,16 @@
- if champ.value.blank?
%p= t('.not_filled')
- elsif profile == 'instructeur'
- if champ.data.blank?
%p= t('.not_found', rna: champ.value)
- else
%p= t('.data_fetched_title', rna: champ.value)
%ul
- ['association_titre', 'association_objet', ].each do |scope|
- if champ.data[scope].present?
%li #{t("activemodel.attributes.rna_champ.data.#{scope}")} : #{champ.data[scope].capitalize}
- ['association_date_creation', 'association_date_declaration', 'association_date_publication'].each do |scope|
- if champ.data[scope].present?
%li #{t("activemodel.attributes.rna_champ.data.#{scope}")} : #{l(champ.data[scope].to_date)}
- else
%p= champ.identifier

View file

@ -50,6 +50,8 @@
= render partial: "shared/champs/communes/show", locals: { champ: c }
- when TypeDeChamp.type_champs.fetch(:regions)
= render partial: "shared/champs/regions/show", locals: { champ: c }
- when TypeDeChamp.type_champs.fetch(:rna)
= render partial: "shared/champs/rna/show", locals: { champ: c, profile: profile }
- when TypeDeChamp.type_champs.fetch(:date)
= c.to_s
- when TypeDeChamp.type_champs.fetch(:datetime)

View file

@ -311,6 +311,7 @@ en:
errors:
messages:
not_a_phone: 'Invalid phone number'
not_a_rna: 'Invalid RNA number'
models:
attestation_template:
attributes:

View file

@ -305,9 +305,12 @@ fr:
<< : *default_attributes
procedure:
zone: La démarche est mise en œuvre par
champs:
value: Valeur du champ
errors:
messages:
not_a_phone: 'Numéro de téléphone invalide'
not_a_rna: 'Numéro RNA invalide'
models:
attestation_template:
attributes:

View file

@ -0,0 +1,10 @@
en:
activemodel:
attributes:
rna_champ:
data:
association_titre: Association name
association_objet: Association purpose
association_date_creation: Creation date
association_date_declaration: Declaration date
association_date_publication: Publication date

View file

@ -0,0 +1,11 @@
fr:
activemodel:
attributes:
rna_champ:
value: Numéro RNA
data:
association_titre: Nom de l'association
association_objet: Objet de l'association
association_date_creation: Date de création
association_date_declaration: Date de déclaration
association_date_publication: Date de publication

View file

@ -0,0 +1,43 @@
fr:
activerecord:
models:
type_de_champ: 'Field type'
attributes:
type_de_champ:
type_champs:
text: 'Text'
textarea: 'Text area'
date: 'Date'
datetime: 'Datetime'
number: 'Number'
decimal_number: 'Decimal number'
integer_number: 'Integer number'
checkbox: 'Checkbox'
civilite: 'Civility'
email: 'Email'
phone: 'Phone'
address: 'Adress'
yes_no: 'Yes/No'
drop_down_list: 'Dropdown list'
multiple_drop_down_list: 'Multiple dropdown list'
linked_drop_down_list: 'Linked dropdown list'
pays: 'Country'
regions: 'Regions'
departements: 'County'
communes: 'Municipality'
engagement: 'Commitment'
header_section: 'Header section'
explication: 'Explication'
dossier_link: 'File link'
piece_justificative: 'Supporting document'
siret: 'SIRET'
rna: 'RNA'
carte: 'Card'
repetition: 'Repetition'
titre_identite: 'Identity title'
iban: 'Iban'
annuaire_education: 'Schooling directory'
cnaf: 'Data from Caisse nationale des allocations familiales'
dgfip: 'Data from Direction générale des Finances publiques'
pole_emploi: 'Pôle emploi status'
mesri: "Data from Ministère de l'Enseignement Supérieur, de la Recherche et de l'Innovation"

View file

@ -36,9 +36,11 @@ fr:
communes: 'Communes'
header_section: 'Titre de section'
explication: 'Explication'
engagement: 'Engagement'
dossier_link: 'Lien vers un autre dossier'
piece_justificative: 'Pièce justificative'
siret: 'SIRET'
rna: 'RNA'
carte: 'Carte'
repetition: 'Bloc répétable'
titre_identite: 'Titre identité'

View file

@ -20,6 +20,15 @@ en:
fetching_data: "Fetching data for recipient No. %{numero_allocataire} with postal code %{code_postal}."
data_fetched: "Data concerning %{sources} linked to the account Nº %{numero_allocataire} with the postal code %{code_postal} has been received from the CAF."
data_fetched_title: "Data received from la Caisse nationale dallocations familiales"
rna:
show:
not_filled: not filled
not_found: "RNA number %{rna} (no association found)"
data_fetched_title: Data received from RNA number "%{rna}"
association:
data_fetched: "This RNA number is linked to %{title}"
not_found: "No association found"
network_error: "A network error has prevented the association associated with this RNA to be fetched"
dgfip:
show:
not_filled: not filled

View file

@ -22,6 +22,15 @@ fr:
fetching_data: "La récupération automatique des données pour lallocataire Nº %{numero_allocataire} avec le code postal %{code_postal} est en cours."
data_fetched: "Des données concernant %{sources} liées au compte Nº %{numero_allocataire} avec le code postal %{code_postal} ont été reçues depuis la CAF."
data_fetched_title: "Données obtenues de la Caisse nationale dallocations familiales"
rna:
show:
not_filled: non renseigné
not_found: "RNA %{rna} (aucun établissement trouvé)"
data_fetched_title: Données obtenues grâce au RNA "%{rna}"
association:
data_fetched: "Ce RNA correspond à %{title}"
not_found: "Aucun établissement trouvé"
network_error: "Une erreur réseau a empêché l'association liée à ce RNA d'être trouvée"
dgfip:
show:
not_filled: non renseigné

View file

@ -153,6 +153,7 @@ Rails.application.routes.draw do
namespace :champs do
get ':champ_id/siret', to: 'siret#show', as: :siret
get ':champ_id/rna', to: 'rna#show', as: :rna
get ':champ_id/dossier_link', to: 'dossier_link#show', as: :dossier_link
post ':champ_id/repetition', to: 'repetition#add', as: :repetition
delete ':champ_id/repetition', to: 'repetition#remove'

View file

@ -185,7 +185,7 @@ ActiveRecord::Schema.define(version: 2022_10_07_113737) do
create_table "champs", id: :serial, force: :cascade do |t|
t.datetime "created_at"
t.jsonb "data"
t.integer "dossier_id"
t.integer "dossier_id", null: false
t.integer "etablissement_id"
t.string "external_id"
t.string "fetch_external_data_exceptions", array: true
@ -194,7 +194,7 @@ ActiveRecord::Schema.define(version: 2022_10_07_113737) do
t.datetime "rebased_at"
t.integer "row"
t.string "type"
t.integer "type_de_champ_id"
t.integer "type_de_champ_id", null: false
t.datetime "updated_at"
t.string "value"
t.jsonb "value_json"
@ -874,11 +874,11 @@ ActiveRecord::Schema.define(version: 2022_10_07_113737) do
end
create_table "zone_labels", force: :cascade do |t|
t.datetime "created_at", precision: 6, null: false
t.bigint "zone_id", null: false
t.date "designated_on", null: false
t.string "name", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.bigint "zone_id", null: false
t.index ["zone_id"], name: "index_zone_labels_on_zone_id"
end
@ -890,6 +890,7 @@ ActiveRecord::Schema.define(version: 2022_10_07_113737) do
t.index ["acronym"], name: "index_zones_on_acronym", unique: true
end
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "administrateurs", "users"
add_foreign_key "administrateurs_instructeurs", "administrateurs"
@ -906,6 +907,9 @@ ActiveRecord::Schema.define(version: 2022_10_07_113737) do
add_foreign_key "bulk_messages_groupe_instructeurs", "bulk_messages"
add_foreign_key "bulk_messages_groupe_instructeurs", "groupe_instructeurs"
add_foreign_key "champs", "champs", column: "parent_id"
add_foreign_key "champs", "dossiers"
add_foreign_key "champs", "etablissements"
add_foreign_key "champs", "types_de_champ"
add_foreign_key "closed_mails", "procedures"
add_foreign_key "commentaires", "dossiers"
add_foreign_key "commentaires", "experts"
@ -915,6 +919,7 @@ ActiveRecord::Schema.define(version: 2022_10_07_113737) do
add_foreign_key "dossiers", "groupe_instructeurs"
add_foreign_key "dossiers", "procedure_revisions", column: "revision_id"
add_foreign_key "dossiers", "users"
add_foreign_key "etablissements", "dossiers"
add_foreign_key "experts", "users"
add_foreign_key "experts_procedures", "experts"
add_foreign_key "experts_procedures", "procedures"

View file

@ -0,0 +1,159 @@
describe Champs::RNAController, type: :controller do
let(:user) { create(:user) }
let(:procedure) { create(:procedure, :published, :with_rna) }
describe '#show' do
let(:dossier) { create(:dossier, user: user, procedure: procedure) }
let(:champ) { dossier.champs.first }
let(:champs_attributes) do
champ_attributes = []
champ_attributes[champ.id] = { value: rna }
champ_attributes
end
let(:params) do
{
champ_id: champ.id,
dossier: {
champs_attributes: champs_attributes
}
}
end
context 'when the user is signed in' do
render_views
before do
sign_in user
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/associations\//)
.to_return(body: body, status: status)
allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(false)
end
context 'when the RNA is empty' do
let(:rna) { '' }
let(:status) { 422 }
let(:body) { '' }
subject! { get :show, params: params, format: :turbo_stream }
it 'clears the data and value on the model' do
champ.reload
expect(champ.data).to eq({})
expect(champ.value).to eq("")
end
it 'clears any information or error message' do
expect(response.body).to include(ActionView::RecordIdentifier.dom_id(champ, :rna_info))
end
end
context 'when the RNA is invalid' do
let(:rna) { '1234' }
let(:status) { 422 }
let(:body) { '' }
subject! { get :show, params: params, format: :turbo_stream }
it 'clears the data and value on the model' do
champ.reload
expect(champ.data).to be_nil
expect(champ.value).to be_nil
end
it 'displays a “RNA is invalid” error message' do
expect(response.body).to include("Aucun établissement trouvé")
end
end
context 'when the RNA is unknow' do
let(:rna) { 'W111111111' }
let(:status) { 404 }
let(:body) { '' }
subject! { get :show, params: params, format: :turbo_stream }
it 'clears the data on the model' do
champ.reload
expect(champ.data).to eq({})
end
it 'displays a “RNA is invalid” error message' do
expect(response.body).to include("Aucun établissement trouvé")
end
end
context 'when the API is unavailable due to network error' do
let(:rna) { 'W595001988' }
let(:status) { 503 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') }
before do
expect(APIEntrepriseService).to receive(:api_up?).and_return(false)
end
subject! { get :show, params: params, format: :turbo_stream }
it 'clears the data and value on the model' do
champ.reload
expect(champ.data).to be_nil
expect(champ.value).to be_nil
end
it 'displays a “API is unavailable” error message' do
expect(response.body).to include("Une erreur réseau a empêché l&#39;association liée à ce RNA d&#39;être trouvée")
end
end
context 'when the RNA informations are retrieved successfully' do
let(:rna) { 'W595001988' }
let(:status) { 200 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') }
let(:expected_data) do
{
"association_id" => "W595001988",
"association_titre" => "UN SUR QUATRE",
"association_objet" => "valoriser, transmettre et partager auprès des publics les plus larges possibles, les bienfaits de l'immigration, la richesse de la diversité et la curiosité de l'autre autrement",
"association_siret" => nil,
"association_date_creation" => "2014-01-23",
"association_date_declaration" => "2014-01-24",
"association_date_publication" => "2014-02-08",
"association_date_dissolution" => "0001-01-01",
"association_adresse_siege" => {
"complement" => "",
"numero_voie" => "61",
"type_voie" => "RUE",
"libelle_voie" => "des Noyers",
"distribution" => "_",
"code_insee" => "93063",
"code_postal" => "93230",
"commune" => "Romainville"
},
"association_code_civilite_dirigeant" => "PM",
"association_civilite_dirigeant" => "Monsieur le Président",
"association_code_etat" => "A",
"association_etat" => "Active",
"association_code_groupement" => "S",
"association_groupement" => "simple",
"association_mise_a_jour" => 1392295833,
"association_rna" => "W595001988"
}
end
subject! { get :show, params: params, format: :turbo_stream }
it 'populates the data and RNA on the model' do
champ.reload
expect(champ.value).to eq(rna)
expect(champ.data).to eq(expected_data)
end
end
end
context 'when user is not signed in' do
subject! { get :show, params: { champ_id: champ.id }, format: :turbo_stream }
it { expect(response.code).to eq('401') }
end
end
end

View file

@ -206,6 +206,12 @@ FactoryBot.define do
value { '44011762001530' }
end
factory :champ_rna, class: 'Champs::RNAChamp' do
type_de_champ { association :type_de_champ_rna, procedure: dossier.procedure }
association :etablissement, factory: [:etablissement]
value { 'W173847273' }
end
factory :champ_repetition, class: 'Champs::RepetitionChamp' do
type_de_champ { association :type_de_champ_repetition, procedure: dossier.procedure }

View file

@ -250,6 +250,12 @@ FactoryBot.define do
end
end
trait :with_rna do
after(:build) do |procedure, _evaluator|
build(:type_de_champ_rna, procedure: procedure)
end
end
trait :with_dgfip do
after(:build) do |procedure, _evaluator|
build(:type_de_champ_dgfip, procedure: procedure)

View file

@ -140,6 +140,9 @@ FactoryBot.define do
factory :type_de_champ_siret do
type_champ { TypeDeChamp.type_champs.fetch(:siret) }
end
factory :type_de_champ_rna do
type_champ { TypeDeChamp.type_champs.fetch(:rna) }
end
factory :type_de_champ_iban do
type_champ { TypeDeChamp.type_champs.fetch(:iban) }
end

View file

@ -0,0 +1,30 @@
{
"association": {
"id": "W595001988",
"titre": "UN SUR QUATRE",
"objet": "valoriser, transmettre et partager auprès des publics les plus larges possibles, les bienfaits de l'immigration, la richesse de la diversité et la curiosité de l'autre autrement",
"siret": null,
"date_creation": "test",
"date_declaration": "2014-01-24",
"date_publication": "2014-02-08",
"date_dissolution": "0001-01-01",
"adresse_siege": {
"complement": "",
"numero_voie": "61",
"type_voie": "RUE",
"libelle_voie": "des Noyers",
"distribution": "_",
"code_insee": "93063",
"code_postal": "93230",
"commune": "Romainville"
},
"code_civilite_dirigeant": "PM",
"civilite_dirigeant": "Monsieur le Président",
"code_etat": "A",
"etat": "Active",
"code_groupement": "S",
"groupement": "simple",
"mise_a_jour": 1392295833
},
"date_extraction_donnees": 1427210585
}

View file

@ -12,7 +12,7 @@ describe APIEducation::AnnuaireEducationAdapter do
let(:body) { File.read('spec/fixtures/files/api_education/annuaire_education.json') }
let(:status) { 200 }
it '#to_params return vaid hash' do
it '#to_params return valid hash' do
expect(subject).to be_an_instance_of(Hash)
expect(subject['identifiant_de_l_etablissement']).to eq(search_term)
expect(subject['code_type_contrat_prive']).to eq(99)
@ -23,7 +23,7 @@ describe APIEducation::AnnuaireEducationAdapter do
let(:body) { File.read('spec/fixtures/files/api_education/annuaire_education_bug.json') }
let(:status) { 200 }
it '#to_params return vaid hash' do
it '#to_params return valid hash' do
expect(subject).to be_an_instance_of(Hash)
expect(subject['identifiant_de_l_etablissement']).to eq(search_term)
expect(subject['code_type_contrat_prive']).to eq(99)

View file

@ -1,10 +1,8 @@
describe APIEntreprise::RNAAdapter do
let(:siret) { '50480511000013' }
let(:rna) { 'W111111111' }
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) }
let(:adapter) { described_class.new(rna, procedure_id) }
subject { adapter.to_params }
@ -14,27 +12,45 @@ describe APIEntreprise::RNAAdapter do
allow_any_instance_of(APIEntrepriseToken).to receive(:expired?).and_return(false)
end
context 'when siret is not valid' do
let(:siret) { '234567' }
context 'when rna is not valid' do
let(:rna) { '234567' }
let(:body) { '' }
let(:status) { 404 }
it { is_expected.to eq({}) }
end
it { expect(subject).to be_an_instance_of(Hash) }
context "when responds with valid schema" do
let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') }
let(:status) { 200 }
describe 'Attributs Associations' do
it { expect(subject[:association_rna]).to eq('W595001988') }
it '#to_params return valid hash' do
expect(subject).to be_an_instance_of(Hash)
expect(subject["association_rna"]).to eq('W595001988')
expect(subject["association_titre"]).to eq('UN SUR QUATRE')
expect(subject["association_objet"]).to eq("valoriser, transmettre et partager auprès des publics les plus larges possibles, les bienfaits de l'immigration, la richesse de la diversité et la curiosité de l'autre autrement")
expect(subject["association_date_creation"]).to eq('2014-01-23')
expect(subject["association_date_declaration"]).to eq('2014-01-24')
expect(subject["association_date_publication"]).to eq('2014-02-08')
end
end
it { expect(subject[:association_titre]).to eq('UN SUR QUATRE') }
context "when responds with invalid schema" do
let(:body) { File.read('spec/fixtures/files/api_entreprise/associations_invalid.json') }
let(:status) { 200 }
it { expect(subject[:association_objet]).to eq("valoriser, transmettre et partager auprès des publics les plus larges possibles, les bienfaits de l'immigration, la richesse de la diversité et la curiosité de l'autre autrement") }
it '#to_params raise exception' do
expect { subject }.to raise_exception(APIEntreprise::RNAAdapter::InvalidSchemaError)
end
end
it { expect(subject[:association_date_creation]).to eq('2014-01-23') }
context "when depreciated adapter is used" do
let(:adapter) { described_class.new(rna, procedure_id, true) }
let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') }
let(:status) { 200 }
it { expect(subject[:association_date_declaration]).to eq('2014-01-24') }
it { expect(subject[:association_date_publication]).to eq('2014-02-08') }
it '#to_params filter the keys' do
expect(subject.keys).to eq(["association_titre", "association_objet", "association_date_creation", "association_date_declaration", "association_date_publication", "association_rna"])
end
end
end

View file

@ -14,9 +14,9 @@ describe '20220705164551_remove_unused_champs' do
describe 'remove_unused_champs' do
it "with bad champs" do
expect(Champ.where(dossier: dossier).count).to eq(38)
expect(Champ.where(dossier: dossier).count).to eq(39)
run_task
expect(Champ.where(dossier: dossier).count).to eq(37)
expect(Champ.where(dossier: dossier).count).to eq(38)
end
end
end

View file

@ -0,0 +1,25 @@
describe Champs::RNAChamp do
let(:champ) { create(:champ_rna, value: "W182736273") }
describe '#valid?' do
it { expect(build(:champ_rna, value: nil)).to be_valid }
it { expect(build(:champ_rna, value: "2736251627")).to_not be_valid }
it { expect(build(:champ_rna, value: "A172736283")).to_not be_valid }
it { expect(build(:champ_rna, value: "W1827362718")).to_not be_valid }
it { expect(build(:champ_rna, value: "W182736273")).to be_valid }
end
describe "#export" do
context "with association title" do
before do
champ.update(data: { association_titre: "Super asso" })
end
it { expect(champ.for_export).to eq("W182736273 (Super asso)") }
end
context "no association title" do
it { expect(champ.for_export).to eq("W182736273") }
end
end
end

View file

@ -72,6 +72,7 @@ describe ProcedureExportService do
"pays",
"dossier_link",
"piece_justificative",
"rna",
"carte",
"titre_identite",
"iban",
@ -163,6 +164,7 @@ describe ProcedureExportService do
"pays",
"dossier_link",
"piece_justificative",
"rna",
"carte",
"titre_identite",
"iban",
@ -249,6 +251,7 @@ describe ProcedureExportService do
"pays",
"dossier_link",
"piece_justificative",
"rna",
"carte",
"titre_identite",
"iban",

View file

@ -17,7 +17,8 @@ describe 'shared/dossiers/champs.html.haml', type: :view do
let(:champ3) { create(:champ_explication, dossier: dossier, value: "mazette") }
let(:champ4) { create(:champ_dossier_link, dossier: dossier, value: dossier.id) }
let(:champ5) { create(:champ_textarea, dossier: dossier, value: "Some long text in a textarea.") }
let(:champs) { [champ1, champ2, champ3, champ4, champ5] }
let(:champ6) { create(:champ_rna, value: "W173847273") }
let(:champs) { [champ1, champ2, champ3, champ4, champ5, champ6] }
it "renders titles and values of champs" do
expect(subject).to include(champ1.libelle)
@ -29,7 +30,9 @@ describe 'shared/dossiers/champs.html.haml', type: :view do
expect(subject).to include(dossier.text_summary)
expect(subject).to include(champ5.libelle)
expect(subject).to include(champ5.libelle)
expect(subject).to include(champ5.value)
expect(subject).to include(champ6.libelle)
expect(subject).to include(champ6.value)
end
it "doesn't render explication champs" do