Merge branch 'api_carto_dynamique' into develop

This commit is contained in:
Xavier J 2015-12-09 11:16:28 +01:00
commit f65c383623
30 changed files with 341 additions and 76 deletions

View file

@ -17,10 +17,7 @@ function initCarto() {
layers: [OSM]
});
freeDraw = new L.FreeDraw({
//mode: L.FreeDraw.MODES.CREATE
});
freeDraw = new L.FreeDraw();
map.addLayer(freeDraw);
if ($("#json_latlngs").val() != '' && $("#json_latlngs").val() != '[]') {
@ -35,13 +32,16 @@ function initCarto() {
add_event_freeDraw();
if (qp_active())
display_qp(JSON.parse($("#quartier_prioritaires").val()));
}
function add_event_freeDraw() {
freeDraw.on('markers', function (e) {
$("#json_latlngs").val(JSON.stringify(e.latLngs));
display_qp(get_qp(e.latLngs)['quartier_prioritaires']);
if (qp_active())
display_qp(get_qp(e.latLngs));
});
$("#new").on('click', function (e) {
@ -71,7 +71,14 @@ function get_position() {
return position;
}
function qp_active() {
return $("#map.qp").length > 0
}
function get_qp(coordinates) {
if (!qp_active())
return;
var qp;
$.ajax({
@ -84,10 +91,13 @@ function get_qp(coordinates) {
qp = data
});
return qp;
return qp['quartier_prioritaires'];
}
function display_qp(qp_list) {
if (!qp_active())
return;
qp_array = jsObject_to_array(qp_list);
$("#qp_list ul").html('');

View file

@ -0,0 +1,12 @@
$(document).on('page:load', buttons_api_carto);
$(document).ready(buttons_api_carto);
function buttons_api_carto () {
$("#procedure_module_api_carto_use_api_carto").on('change', function() {
$("#modules_api_carto").toggle()
});
if ($('#procedure_module_api_carto_use_api_carto').is(':checked'))
$("#modules_api_carto").show();
}

View file

@ -116,6 +116,10 @@ input#nom_projet {
max-width: 27px;
}
label {
font-weight: normal;
}
div.pagination {
padding-top: 20px;
display: block;

View file

@ -7,16 +7,25 @@ table {
font-size: 13px;
}
#map{
#carte_page {
#map {
@extend .col-md-12;
@extend .col-lg-12;
height:600px;
}
height: 600px;
}
#map.qp {
#map.qp {
@extend .col-md-9;
@extend .col-lg-9;
}
}
#infos_dossier {
#map.mini {
height: 300px;
width: 100%;
}
}
#qp_list {
@ -24,19 +33,14 @@ table {
@extend .col-lg-3;
h3 {
margin-top:0px;
margin-top: 0px;
}
ul li {
margin-bottom:10px;
margin-bottom: 10px;
}
}
#map.mini{
height:300px;
width:100%;
}
#map section.overlay {
position: absolute;
top: 0;
@ -107,16 +111,15 @@ table {
pointer-events: none;
}
.info {
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
background: rgba(255, 255, 255, 0.8);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
border-radius: 5px;
}
.info h4 {
margin: 0 0 5px;
color: #777;

View file

@ -0,0 +1,3 @@
#modules_api_carto {
display: none;
}

View file

@ -24,10 +24,12 @@ class Admin::ProceduresController < AdminController
def new
@procedure ||= Procedure.new
@procedure.module_api_carto ||= ModuleAPICarto.new
end
def create
@procedure = Procedure.new(create_procedure_params)
@procedure.module_api_carto = ModuleAPICarto.new(create_module_api_carto_params) if @procedure.valid?
unless @procedure.save
flash.now.alert = @procedure.errors.full_messages.join('<br />').html_safe
@ -64,7 +66,11 @@ class Admin::ProceduresController < AdminController
private
def create_procedure_params
params.require(:procedure).permit(:libelle, :description, :organisation, :direction, :lien_demarche, :use_api_carto).merge(administrateur_id: current_administrateur.id)
params.require(:procedure).permit(:libelle, :description, :organisation, :direction, :lien_demarche, module_api_carto_attributes: [:id, :use_api_carto, :quartiers_prioritaires, :cadastre]).merge(administrateur_id: current_administrateur.id)
end
def create_module_api_carto_params
params.require(:procedure).require(:module_api_carto_attributes).permit(:id, :use_api_carto, :quartiers_prioritaires, :cadastre)
end
def informations

View file

@ -3,6 +3,12 @@ class Users::CarteController < UsersController
def show
@dossier = current_user_dossier
unless @dossier.procedure.module_api_carto.use_api_carto
flash.alert = t('errors.messages.dossier_map_not_activated')
redirect_to url_for(root_path)
end
rescue ActiveRecord::RecordNotFound
flash.alert = t('errors.messages.dossier_not_found')
redirect_to url_for(root_path)
@ -61,7 +67,7 @@ class Users::CarteController < UsersController
coordinates.each_with_index do |coordinate, index|
coordinate = coordinates[index].map { |latlng| [latlng['lng'], latlng['lat']] }
qp = qp.merge CARTO::SGMAP::QuartierPrioritaireAdapter.new(coordinate).to_params
qp = qp.merge CARTO::SGMAP::QuartiersPrioritaires::Adapter.new(coordinate).to_params
end
qp

View file

@ -88,7 +88,7 @@ class Users::DossiersController < UsersController
if checked_autorisation_donnees?
@dossier.update_attributes(update_params)
if @dossier.procedure.use_api_carto
if @dossier.procedure.module_api_carto.use_api_carto
redirect_to url_for(controller: :carte, action: :show, dossier_id: @dossier.id)
else
redirect_to url_for(controller: :description, action: :show, dossier_id: @dossier.id)

View file

@ -16,6 +16,10 @@ class DossierDecorator < Draper::Decorator
DossierDecorator.case_state_fr state
end
def class_qp_active
'qp' if procedure.module_api_carto.quartiers_prioritaires
end
def state_color_class
return 'text-danger' if waiting_for_gestionnaire?
return 'text-info' if waiting_for_user?

View file

@ -0,0 +1,7 @@
class ModuleAPICarto < ActiveRecord::Base
belongs_to :procedure
validates :use_api_carto, presence: true, allow_blank: true, allow_nil: false
validates :quartiers_prioritaires, presence: true, allow_blank: true, allow_nil: false
validates :cadastre, presence: true, allow_blank: true, allow_nil: false
end

View file

@ -2,8 +2,10 @@ class Procedure < ActiveRecord::Base
has_many :types_de_piece_justificative
has_many :types_de_champ
has_many :dossiers
has_one :module_api_carto
accepts_nested_attributes_for :types_de_champ,:reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true
accepts_nested_attributes_for :types_de_piece_justificative, :reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true
accepts_nested_attributes_for :module_api_carto
belongs_to :administrateur
validates :libelle, presence: true, allow_blank: false, allow_nil: false

View file

@ -9,6 +9,22 @@
%br
%label{ style:'font-weight:normal' }
=f.check_box :use_api_carto
Utilisation de l'API Carto
%h4 Cartographie
= f.fields_for :module_api_carto, @procedure.module_api_carto do |ff|
%label
=ff.check_box :use_api_carto, {id: :procedure_module_api_carto_use_api_carto}
Utilisation de la cartographie
%ul#modules_api_carto
%li
%label
= ff.check_box :quartiers_prioritaires
Quartiers Prioritaires
%li
%label
= ff.check_box :cadastre, disabled: :disabled
Cadastre
%i
%strong
(bientôt disponible)

View file

@ -12,9 +12,11 @@
%br
- rescue
=''
- if @dossier.procedure.use_api_carto
- if @dossier.procedure.module_api_carto.use_api_carto
.col-lg-6.col-md-6
#map.mini
#map.mini{class: @dossier.class_qp_active}
%input{id: 'json_latlngs', type:'hidden', value: "#{@dossier.json_latlngs}"}
%input{id: 'quartier_prioritaires', type:'hidden', value: "#{@dossier.quartier_prioritaires.to_json}"}
%script{type: 'text/javascript'}
@ -39,7 +41,7 @@
%div.row{style: 'text-align:right'}
-unless gestionnaire_signed_in?
-if !@dossier.validated? && !@dossier.submitted? && !@dossier.closed?
-if @dossier.procedure.use_api_carto
-if @dossier.procedure.module_api_carto.use_api_carto
%a#maj_carte.btn.btn-primary{href: "/users/dossiers/#{@dossier.id}/carte"}
= 'Editer ma carte'
%a#maj_infos.btn.btn-info{href: "/users/dossiers/#{@dossier.id}/description"}

View file

@ -11,11 +11,14 @@
%br
%br
.row
#carte_page.row
- if @dossier.procedure.module_api_carto.quartiers_prioritaires
#map.qp
#qp_list
%h3 Quartiers prioritaites
%ul
-else
#map
= form_tag(url_for({controller: :carte, action: :save, dossier_id: @dossier.id}), class: 'form-inline', method: 'POST') do
%br

View file

@ -91,6 +91,7 @@ fr:
one: "1 erreur a empêché ce(tte) %{resource} d'être sauvegardé(e) :"
other: "%{count} erreurs ont empêché ce(tte) %{resource} d'être sauvegardé(e) :"
dossier_not_found: "Le dossier n'existe pas ou vous n'y avez pas accès."
dossier_map_not_activated: "Le dossier n'a pas accès à la cartographie."
invalid_siret: "Le siret est incorrect"
france_connect:
connexion: "Erreur lors de la connexion à France Connect."

View file

@ -0,0 +1,9 @@
class CreateModuleAPICarto < ActiveRecord::Migration
def change
create_table :module_api_cartos do |t|
t.string :name
end
add_reference :module_api_cartos, :procedure, references: :procedures
end
end

View file

@ -0,0 +1,47 @@
class UpdateModuleAPICarto < ActiveRecord::Migration
class Procedure < ActiveRecord::Base
end
class ModuleAPICarto < ActiveRecord::Base
end
def up
remove_column :module_api_cartos, :name
add_index :module_api_cartos, [:procedure_id], unique: true
add_column :module_api_cartos, :use_api_carto, :boolean, default: false
add_column :module_api_cartos, :quartiers_prioritaires, :boolean, default: false
add_column :module_api_cartos, :cadastre, :boolean, default: false
Procedure.all.each do |procedure|
module_api_carto = ModuleAPICarto.new(procedure_id: procedure.id)
module_api_carto.use_api_carto = procedure.use_api_carto
module_api_carto.quartiers_prioritaires = procedure.use_api_carto
module_api_carto.save!
end
remove_column :procedures, :use_api_carto
end
def down
add_column :procedures, :use_api_carto, :boolean, default: false
remove_index :module_api_cartos, [:procedure_id]
Procedure.all.each do |procedure|
procedure.use_api_carto = ModuleAPICarto.find_by(procedure_id: procedure.id).use_api_carto
procedure.save!
end
remove_column :module_api_cartos, :use_api_carto
remove_column :module_api_cartos, :quartiers_prioritaires
remove_column :module_api_cartos, :cadastre
add_column :module_api_cartos, :name, :string
ModuleAPICarto.destroy_all
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20151127103412) do
ActiveRecord::Schema.define(version: 20151207140202) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -132,6 +132,15 @@ ActiveRecord::Schema.define(version: 20151127103412) do
add_index "gestionnaires", ["email"], name: "index_gestionnaires_on_email", unique: true, using: :btree
add_index "gestionnaires", ["reset_password_token"], name: "index_gestionnaires_on_reset_password_token", unique: true, using: :btree
create_table "module_api_cartos", force: :cascade do |t|
t.integer "procedure_id"
t.boolean "use_api_carto", default: false
t.boolean "quartiers_prioritaires", default: false
t.boolean "cadastre", default: false
end
add_index "module_api_cartos", ["procedure_id"], name: "index_module_api_cartos_on_procedure_id", unique: true, using: :btree
create_table "pieces_justificatives", force: :cascade do |t|
t.string "content"
t.integer "dossier_id"
@ -149,7 +158,6 @@ ActiveRecord::Schema.define(version: 20151127103412) do
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "test"
t.boolean "use_api_carto", default: false
t.integer "administrateur_id"
t.boolean "archived", default: false
end

View file

@ -1,10 +1,10 @@
class CARTO::SGMAP::QuartierPrioritaireAdapter
class CARTO::SGMAP::QuartiersPrioritaires::Adapter
def initialize(coordinates)
@coordinates = GeojsonService.to_json_polygon(coordinates)
end
def data_source
@data_source ||= JSON.parse(CARTO::SGMAP::API.search_qp(@coordinates), symbolize_names: true)
@data_source ||= JSON.parse(CARTO::SGMAP::QuartiersPrioritaires::API.search_qp(@coordinates), symbolize_names: true)
end
def to_params

View file

@ -1,4 +1,4 @@
class CARTO::SGMAP::API
class CARTO::SGMAP::QuartiersPrioritaires::API
def initialize
end

View file

@ -10,7 +10,9 @@ describe Admin::ProceduresController, type: :controller do
let(:organisation) { 'Organisation de test' }
let(:direction) { 'Direction de test' }
let(:lien_demarche) { 'http://localhost.com' }
let(:use_api_carto) { '1' }
let(:use_api_carto) { '0' }
let(:quartiers_prioritaires) { '0' }
let(:cadastre) { '0' }
let(:procedure_params) {
{
@ -19,7 +21,11 @@ describe Admin::ProceduresController, type: :controller do
organisation: organisation,
direction: direction,
lien_demarche: lien_demarche,
use_api_carto: use_api_carto
module_api_carto_attributes: {
use_api_carto: use_api_carto,
quartiers_prioritaires: quartiers_prioritaires,
cadastre: cadastre
}
}
}
@ -89,11 +95,22 @@ describe Admin::ProceduresController, type: :controller do
it { expect(subject.organisation).to eq(organisation) }
it { expect(subject.direction).to eq(direction) }
it { expect(subject.lien_demarche).to eq(lien_demarche) }
it { expect(subject.use_api_carto).to be_truthy }
it { expect(subject.administrateur_id).to eq(admin.id) }
end
describe 'procedure module api carto attributs in database' do
let(:procedure) { Procedure.last }
let(:use_api_carto) { '1' }
let(:quartiers_prioritaires) { '1' }
subject { ModuleAPICarto.last }
it { expect(subject.procedure).to eq(procedure) }
it { expect(subject.use_api_carto).to be_truthy }
it { expect(subject.quartiers_prioritaires).to be_truthy }
end
it { expect(subject).to redirect_to(admin_procedure_types_de_champ_path(procedure_id: Procedure.last.id)) }
it { expect(flash[:notice]).to be_present }
@ -108,6 +125,10 @@ describe Admin::ProceduresController, type: :controller do
subject { post :create, procedure: procedure_params }
it { expect { subject }.to change { Procedure.count }.by(0) }
describe 'no new module api carto in database' do
it { expect { subject }.to change { ModuleAPICarto.count }.by(0) }
end
end
describe 'flash message is present' do
@ -145,7 +166,8 @@ describe Admin::ProceduresController, type: :controller do
let(:organisation) { 'plop' }
let(:direction) { 'plap' }
let(:lien_demarche) { 'http://plip.com' }
let(:use_api_carto) { '0' }
let(:use_api_carto) { '1' }
let(:cadastre) { '1' }
describe 'procedure attributs in database' do
subject { procedure }
@ -155,7 +177,14 @@ describe Admin::ProceduresController, type: :controller do
it { expect(subject.organisation).to eq(organisation) }
it { expect(subject.direction).to eq(direction) }
it { expect(subject.lien_demarche).to eq(lien_demarche) }
it { expect(subject.use_api_carto).to be_falsey }
end
describe 'procedure module api carto attributs in database' do
subject { procedure.module_api_carto }
it { expect(subject.use_api_carto).to be_truthy }
it { expect(subject.quartiers_prioritaires).to be_falsey }
it { expect(subject.cadastre).to be_truthy }
end
it { expect(subject).to redirect_to(admin_procedures_path) }
@ -169,6 +198,14 @@ describe Admin::ProceduresController, type: :controller do
describe 'flash message is present' do
it { expect(flash[:alert]).to be_present }
end
describe 'procedure module api carto attributs in database' do
subject { procedure.module_api_carto }
it { expect(subject.use_api_carto).to be_falsey }
it { expect(subject.quartiers_prioritaires).to be_falsey }
it { expect(subject.cadastre).to be_falsey }
end
end
end
end

View file

@ -3,7 +3,10 @@ require 'spec_helper'
RSpec.describe Users::CarteController, type: :controller do
let(:bad_adresse) { 'babouba' }
let(:dossier) { create(:dossier, :with_user, :with_procedure) }
let(:procedure) { create(:procedure, :with_api_carto) }
let(:dossier) { create(:dossier, :with_user, procedure: procedure) }
let(:dossier_with_no_carto) { create(:dossier, :with_user, :with_procedure) }
let!(:entreprise) { create(:entreprise, dossier: dossier) }
let!(:etablissement) { create(:etablissement, dossier: dossier) }
let(:bad_dossier_id) { Dossier.count + 1000 }
@ -25,15 +28,24 @@ RSpec.describe Users::CarteController, type: :controller do
end
end
it 'returns http success' do
it 'returns http success if carto is activated' do
get :show, dossier_id: dossier.id
expect(response).to have_http_status(:success)
end
it 'redirection vers la liste des dossiers du user si dossier ID n\'existe pas' do
context 'when procedure not have activate api carto' do
it 'redirection on user dossier list' do
get :show, dossier_id: dossier_with_no_carto.id
expect(response).to redirect_to(root_path)
end
end
context 'when dossier id not exist' do
it 'redirection on user dossier list' do
get :show, dossier_id: bad_dossier_id
expect(response).to redirect_to(root_path)
end
end
it_behaves_like "not owner of dossier", :show
end
@ -75,7 +87,7 @@ RSpec.describe Users::CarteController, type: :controller do
describe 'Save quartier prioritaire' do
before do
allow_any_instance_of(CARTO::SGMAP::QuartierPrioritaireAdapter).
allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter).
to receive(:to_params).
and_return({"QPCODE1234" => {:code => "QPCODE1234", :nom => "QP de test", :commune => "Paris", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}})
@ -170,7 +182,7 @@ RSpec.describe Users::CarteController, type: :controller do
describe 'POST #get_qp' do
before do
allow_any_instance_of(CARTO::SGMAP::QuartierPrioritaireAdapter).
allow_any_instance_of(CARTO::SGMAP::QuartiersPrioritaires::Adapter).
to receive(:to_params).
and_return({"QPCODE1234" => {:code => "QPCODE1234", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}})

View file

@ -3,8 +3,7 @@ require 'spec_helper'
describe Users::DossiersController, type: :controller do
let(:user) { create(:user) }
let(:use_api_carto) { false }
let(:procedure) { create(:procedure, use_api_carto: use_api_carto) }
let(:procedure) { create(:procedure) }
let(:procedure_id) { procedure.id }
let(:dossier) { create(:dossier, :with_entreprise, user: user, procedure: procedure) }
let(:dossier_id) { dossier.id }
@ -170,7 +169,7 @@ describe Users::DossiersController, type: :controller do
end
context 'procedure use api carto' do
let(:use_api_carto) { true }
let(:procedure) { create(:procedure, :with_api_carto) }
before do
put :update, id: dossier_id, dossier: {autorisation_donnees: autorisation_donnees}

View file

@ -0,0 +1,27 @@
FactoryGirl.define do
factory :module_api_carto do
use_api_carto false
quartiers_prioritaires false
cadastre false
trait :with_api_carto do
use_api_carto true
end
trait :with_quartiers_prioritaires do
use_api_carto true
quartiers_prioritaires true
end
trait :with_cadastre do
use_api_carto true
cadastre true
end
trait :with_qp_and_cadastre do
use_api_carto true
quartiers_prioritaires true
cadastre true
end
end
end

View file

@ -4,8 +4,17 @@ FactoryGirl.define do
libelle 'Demande de subvention'
description "Demande de subvention à l'intention des associations"
after(:build) do |procedure, _evaluator|
if procedure.module_api_carto.nil?
module_api_carto = create(:module_api_carto)
procedure.module_api_carto = module_api_carto
end
end
trait :with_api_carto do
use_api_carto true
after(:build) do |procedure, _evaluator|
procedure.module_api_carto.use_api_carto = true
end
end
trait :with_type_de_champ do

View file

@ -2,7 +2,9 @@ require 'spec_helper'
feature 'drawing a zone with freedraw' do
let(:user) { create(:user) }
let(:dossier) { create(:dossier, :with_procedure, :with_entreprise, user: user) }
let(:module_api_carto) { create(:module_api_carto, :with_api_carto) }
let(:procedure) { create(:procedure, module_api_carto: module_api_carto) }
let(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, user: user) }
context 'when user is not logged in' do
before do
@ -22,20 +24,41 @@ feature 'drawing a zone with freedraw' do
end
end
context 'when procedure have api carto activated' do
scenario 'he is redirected to carte page' do
expect(page).to have_css('.content #map')
end
end
context 'when procedure does not have api carto activated' do
let(:module_api_carto) { create(:module_api_carto) }
scenario 'he is redirect to user dossiers index' do
expect(page).to have_css('#users_index')
end
scenario 'alert message is present' do
expect(page).to have_content('Le dossier n\'a pas accès à la cartographie')
end
end
context 'when draw a zone on #map', js: true do
context 'when module quartiers prioritaires is activated' do
let(:module_api_carto) { create(:module_api_carto, :with_quartiers_prioritaires) }
before do
allow_any_instance_of(Users::CarteController).
to receive(:generate_qp).
and_return({"QPCODE1234" => { :code => "QPCODE1234", :nom => "Quartier de test", :commune => "Paris", :geometry => { :type=>"MultiPolygon", :coordinates=>[[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]] }}})
and_return({"QPCODE1234" => {:code => "QPCODE1234", :nom => "Quartier de test", :commune => "Paris", :geometry => {:type => "MultiPolygon", :coordinates => [[[[2.38715792094576, 48.8723062632126], [2.38724851642619, 48.8721392348061]]]]}}})
page.execute_script('freeDraw.fire("markers", {latLngs: []});')
wait_for_ajax
end
scenario 'div #map .qp is present' do
expect(page).to have_css('.content #map.qp')
end
scenario 'QP name is present on page' do
expect(page).to have_content('Quartier de test')
end
@ -46,4 +69,5 @@ feature 'drawing a zone with freedraw' do
end
end
end
end
end

View file

@ -1,6 +1,6 @@
require 'spec_helper'
describe CARTO::SGMAP::QuartierPrioritaireAdapter do
describe CARTO::SGMAP::QuartiersPrioritaires::Adapter do
subject { described_class.new(coordinates).to_params }
before do

View file

@ -1,6 +1,6 @@
require 'spec_helper'
describe CARTO::SGMAP::API do
describe CARTO::SGMAP::QuartiersPrioritaires::API do
describe '.search_qp' do
subject { described_class.search_qp(geojson) }

View file

@ -0,0 +1,13 @@
require 'spec_helper'
describe ModuleAPICarto do
describe 'assocations' do
it { is_expected.to belong_to(:procedure) }
end
describe 'attributes' do
it { is_expected.to have_db_column(:use_api_carto) }
it { is_expected.to have_db_column(:quartiers_prioritaires) }
it { is_expected.to have_db_column(:cadastre) }
end
end

View file

@ -5,6 +5,7 @@ describe Procedure do
it { is_expected.to have_many(:types_de_piece_justificative) }
it { is_expected.to have_many(:types_de_champ) }
it { is_expected.to have_many(:dossiers) }
it { is_expected.to have_one(:module_api_carto) }
it { is_expected.to belong_to(:administrateur) }
end