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