diff --git a/app/services/extended_socio_demographic_authorization_handler.rb b/app/services/extended_socio_demographic_authorization_handler.rb
new file mode 100644
index 00000000..bdc86483
--- /dev/null
+++ b/app/services/extended_socio_demographic_authorization_handler.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+# Allows to create a form for simple Socio Demographic authorization
+class ExtendedSocioDemographicAuthorizationHandler < Decidim::AuthorizationHandler
+ attribute :last_name, String
+ attribute :usual_last_name, String
+ attribute :first_name, String
+ attribute :usual_first_name, String
+ attribute :birth_date, Date
+ attribute :address, String
+ attribute :postal_code, String
+ attribute :city, String
+ attribute :certification, Boolean
+ attribute :news_cese, Boolean
+
+ validates :last_name, presence: true
+ validates :first_name, presence: true
+ validates :birth_date, presence: true
+ validates :address, presence: true
+ validates :postal_code, numericality: { only_integer: true }, presence: true, length: { is: 5 }
+ validates :city, presence: true
+ validates :certification, acceptance: true, presence: true
+
+ validate :over_16?
+
+ def metadata
+ super.merge(
+ last_name: last_name,
+ usual_last_name: usual_last_name,
+ first_name: first_name,
+ usual_first_name: usual_first_name,
+ address: address,
+ postal_code: postal_code,
+ city: city,
+ birth_date: birth_date,
+ certification: certification,
+ news_cese: news_cese
+ )
+ end
+
+ private
+
+ def over_16?
+ return if birth_date.blank?
+ return true if birth_date < 16.years.ago.to_date
+
+ errors.add :birth_date, I18n.t("extended_socio_demographic_authorization.errors.messages.over_16")
+ end
+end
diff --git a/app/views/extended_socio_demographic_authorization/_form.html.erb b/app/views/extended_socio_demographic_authorization/_form.html.erb
new file mode 100644
index 00000000..cd6bd848
--- /dev/null
+++ b/app/views/extended_socio_demographic_authorization/_form.html.erb
@@ -0,0 +1,74 @@
+<%= hidden_field :authorization_handler, :handler_name, value: "extended_socio_demographic_authorization_handler" %>
+
+
+
+
+
+ <%= form.text_field :first_name, minlength: 1, pattern: "[A-Za-z]+", autocomplete: "given-name", label: t(".name") %>
+
+
+
+
+ <%= form.text_field :last_name, minlength: 1, pattern: "[A-Za-z]+", autocomplete: "given-name", label: t(".lastname") %>
+
+
+
+
+
+
+ <%= form.text_field :usual_first_name, pattern: "[A-Za-z]+", autocomplete: "family-name", label: t(".usual_firstname") %>
+
+
+
+
+ <%= form.text_field :usual_last_name, pattern: "[A-Za-z]+", autocomplete: "family-name", label: t(".usual_lastname") %>
+
+
+
+
+
+
+ <%= form.date_select :birth_date, {label: t(".birth_date"), start_year: Date.today.year - 120, end_year: Date.today.year }, { class: "columns medium-3" } %>
+
+
+ <%= t(".birth_date_help") %>
+
+
+
+
+ <%= form.text_field :address, autocomplete: "street-address", label: t(".address") %>
+
+
+
+
+
+ <%= form.text_field :postal_code, pattern: "^[0-9]+$", minlength: 5, maxlength: 5, autocomplete: "postal-code", label: t(".code") %>
+
+
+
+
+ <%= form.text_field :city, label: t(".city") %>
+
+
+
+
+ <%= t(".postal_code.help_message") %>
+
+
+
+
+
+
+ <%= form.check_box :certification, label: t(".certification") %>
+
+
+
+
+ <%== form.check_box :news_cese, label: t(".news_cese") %>
+
+
+
+
+
+<%= javascript_pack_tag "extended_socio_demographic_authorization_handler" %>
+<%= stylesheet_pack_tag "extended_socio_demographic_css" %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 54f8c703..41a7d6c3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -191,8 +191,8 @@ en:
verifications:
authorizations:
create:
- error: Error
- success: Success
+ error: There was a problem creating the authorization.
+ success: You've been successfully authorized
first_login:
actions:
osp_authorization_handler: Verify with the identity verification form
@@ -225,6 +225,24 @@ en:
shared:
links:
forgot_your_password: Forgot your password
+ extended_socio_demographic_authorization:
+ errors:
+ messages:
+ over_16: You must be over 16 years old to access this service.
+ form:
+ address: Address
+ birth_date: Date of birth
+ birth_date_help: You must be over 16 years old to access this service.
+ certification: Certification CESE
+ city: City
+ code: Postal code
+ lastname: Last name
+ name: First name
+ news_cese: Do you want to receive news from CESE ?
+ postal_code:
+ help_message: Please fill the postal code field to be able to select your city
+ usual_firstname: Usual first name
+ usual_lastname: Usual last name
faker:
address:
country_code:
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 9a7b44db..1d940769 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -221,6 +221,24 @@ fr:
shared:
links:
forgot_your_password: Mot de passe oublié ?
+ extended_socio_demographic_authorization:
+ errors:
+ messages:
+ over_16: Vous devez avoir plus de 16 ans pour accéder à ce service.
+ form:
+ address: Addresse
+ birth_date: Date de naissance
+ birth_date_help: Vous devez avoir plus de 16 ans pour avoir accès à ce service.
+ certification: Certification CESE
+ city: Ville
+ code: Code postal
+ lastname: Nom
+ name: Prénom
+ news_cese: Souhaitez-vous recevoir les actualités du CESE ?
+ postal_code:
+ help_message: Veuillez renseigner votre code postal pour choisir la ville
+ usual_firstname: Prénom d'usage
+ usual_lastname: Nom d'usage
faker:
address:
country_code:
diff --git a/spec/services/extended_socio_demographic_authorization_handler/extended_socio_demographic_authorization_handler_spec.rb b/spec/services/extended_socio_demographic_authorization_handler/extended_socio_demographic_authorization_handler_spec.rb
new file mode 100644
index 00000000..cf6f4741
--- /dev/null
+++ b/spec/services/extended_socio_demographic_authorization_handler/extended_socio_demographic_authorization_handler_spec.rb
@@ -0,0 +1,123 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+describe ExtendedSocioDemographicAuthorizationHandler do
+ subject do
+ described_class.new(
+ last_name: last_name,
+ usual_last_name: usual_last_name,
+ first_name: first_name,
+ usual_first_name: usual_first_name,
+ address: address,
+ postal_code: postal_code,
+ city: city,
+ birth_date: birth_date,
+ certification: certification,
+ news_cese: news_cese
+ )
+ end
+
+ let(:user) { create(:user) }
+
+ let(:organization) { user.organization }
+
+ let(:last_name) { "Doe" }
+ let(:usual_last_name) { "Smith" }
+ let(:first_name) { "John" }
+ let(:usual_first_name) { "Jack" }
+ let(:address) { "21 Jump Street" }
+ let(:postal_code) { "75018" }
+ let(:city) { "Nowhere" }
+ let(:birth_date) { 20.years.ago.to_date }
+ let(:certification) { true }
+ let(:news_cese) { true }
+
+ context "when the information is valid" do
+ it "is valid" do
+ expect(subject).to be_valid
+ end
+ end
+
+ context "when name is nil" do
+ let(:last_name) { nil }
+
+ it "is invalid" do
+ expect(subject).to be_invalid
+ end
+ end
+
+ context "when first name is nil" do
+ let(:first_name) { nil }
+
+ it "is invalid" do
+ expect(subject).to be_invalid
+ end
+ end
+
+ context "with postal code" do
+ context "and nil" do
+ let(:postal_code) { nil }
+
+ it "is invalid" do
+ expect(subject).to be_invalid
+ end
+ end
+
+ context "and not a number" do
+ let(:postal_code) { "Some string" }
+
+ it "is invalid" do
+ expect(subject).to be_invalid
+ end
+ end
+
+ context "and length inferior than 5 chars" do
+ let(:postal_code) { "1234" }
+
+ it "is invalid" do
+ expect(subject).to be_invalid
+ end
+ end
+
+ context "and length greater than 5 chars" do
+ let(:postal_code) { "123456" }
+
+ it "is invalid" do
+ expect(subject).to be_invalid
+ end
+ end
+ end
+
+ context "when city is nil" do
+ let(:city) { nil }
+
+ it "is invalid" do
+ expect(subject).to be_invalid
+ end
+ end
+
+ context "when certification is unchecked" do
+ let(:certification) { "0" }
+
+ it "is invalid" do
+ expect(subject).to be_invalid
+ end
+ end
+
+ context "when birthdate is nil" do
+ let(:birth_date) { nil }
+
+ it "is invalid" do
+ expect(subject).to be_invalid
+ end
+ end
+
+ context "when the person is too young" do
+ let(:birth_date) { 14.years.ago.to_date }
+
+ it "is invalid" do
+ expect(subject).to be_invalid
+ end
+ end
+end
diff --git a/spec/system/user_manage_authorizations_spec.rb b/spec/system/user_manage_authorizations_spec.rb
new file mode 100644
index 00000000..6ab742f3
--- /dev/null
+++ b/spec/system/user_manage_authorizations_spec.rb
@@ -0,0 +1,117 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+describe "User authorizations", type: :system do
+ include Decidim::TranslatableAttributes
+
+ let!(:organization) do
+ create(:organization,
+ available_authorizations: ["extended_socio_demographic_authorization_handler"])
+ end
+
+ let(:user) { create(:user, :confirmed) }
+
+ before do
+ stub_request(:get, /datanova.laposte.fr/)
+ .with(headers: { "Accept" => "application/json" })
+ .to_return(status: 200, body: { nhits: 1, parameters: { dataset: "laposte_hexasmal", q: "75018", rows: 10, start: 0, facet: %w(code_postal ligne_10), format: "json", timezone: "UTC" }, records: [{ datasetid: "laposte_hexasmal", recordid: "29faec4345bff1b24c52cc6e6bc9ddfa899eb862", fields: { nom_de_la_commune: "PARIS 18", libelle_d_acheminement: "PARIS 18", code_postal: "75018", coordonnees_gps: [48.892570317, 2.3481765980000002], code_commune_insee: "75118" }, geometry: { type: "Point", coordinates: [2.3481765980000002, 48.892570317] }, record_timestamp: "2022-03-20T23:35:00Z" }], facet_groups: [{ name: "code_postal", facets: [{ name: "75018", count: 1, state: "displayed", path: "75018" }] }] }.to_json, headers: {})
+
+ switch_to_host(organization.host)
+ login_as user, scope: :user
+ visit decidim.root_path
+ click_link user.name
+ click_link "My account"
+ click_link "Authorizations"
+ end
+
+ it "displays the authorization item" do
+ within ".tabs-content.vertical" do
+ expect(page).to have_content("Additional informations")
+ end
+ end
+
+ context "when accessing authorization" do
+ before do
+ visit "/authorizations"
+
+ click_link "Additional informations"
+ end
+
+ it "displays authorization form" do
+ expect(page).to have_content "Additional informations"
+
+ within ".new_authorization_handler" do
+ expect(page).to have_content("Last name")
+ expect(page).to have_content("Usual last name")
+ expect(page).to have_field("First name")
+ expect(page).to have_field("Usual first name")
+ expect(page).to have_field("Address")
+ expect(page).to have_field("Postal code")
+ expect(page).to have_content("City")
+ expect(page).to have_content("Date of birth")
+ expect(page).to have_field("Certification")
+ expect(page).to have_content("Do you want to receive news from CESE ?")
+ end
+ end
+
+ context "verifies the removal of email field" do
+ it "does not display email field" do
+ expect(page).to_not have_field("Email")
+ end
+ end
+
+ it "allows user to fill form" do
+ fill_in :authorization_handler_last_name, with: "Doe"
+ fill_in :authorization_handler_usual_last_name, with: "Smith"
+ fill_in :authorization_handler_first_name, with: "John"
+ fill_in :authorization_handler_usual_first_name, with: "Jack"
+ fill_in :authorization_handler_address, with: "21 Jump Street"
+ fill_in :authorization_handler_postal_code, with: "75018"
+ fill_in :authorization_handler_city, with: "PARIS 18"
+
+ select "January", from: "authorization_handler_birth_date_2i"
+ select 1980, from: "authorization_handler_birth_date_1i"
+ select 22, from: "authorization_handler_birth_date_3i"
+ check :authorization_handler_certification
+ check :authorization_handler_news_cese
+ click_button "Send"
+
+ expect(page).to have_content("You've been successfully authorized")
+ end
+
+ it "allows to select a city when multiple cities are enabled" do
+ fill_in :authorization_handler_last_name, with: "Doe"
+ fill_in :authorization_handler_first_name, with: "John"
+ fill_in :authorization_handler_address, with: "21 Jump Street"
+ fill_in :authorization_handler_postal_code, with: "75018"
+ fill_in :authorization_handler_city, with: "PARIS 18"
+
+ select "January", from: "authorization_handler_birth_date_2i"
+ select 1980, from: "authorization_handler_birth_date_1i"
+ select 22, from: "authorization_handler_birth_date_3i"
+ check :authorization_handler_certification
+ check :authorization_handler_news_cese
+ click_button "Send"
+
+ expect(page).to have_content("You've been successfully authorized")
+ end
+
+ it "refuses to authorize when younger than 16" do
+ fill_in :authorization_handler_last_name, with: "Doe"
+ fill_in :authorization_handler_first_name, with: "John"
+ fill_in :authorization_handler_address, with: "21 Jump Street"
+ fill_in :authorization_handler_postal_code, with: "75018"
+ fill_in :authorization_handler_city, with: "PARIS 18"
+
+ select "January", from: "authorization_handler_birth_date_2i"
+ select 2010, from: "authorization_handler_birth_date_1i"
+ select 22, from: "authorization_handler_birth_date_3i"
+ check :authorization_handler_certification
+ check :authorization_handler_news_cese
+ click_button "Send"
+
+ expect(page).to have_content("You must be over 16 years old to access this service").twice
+ end
+ end
+end