Skip to content

Commit

Permalink
Add adult consent to self reg, refs #2404
Browse files Browse the repository at this point in the history
  • Loading branch information
amaierhofer authored and mtnstar committed Feb 21, 2024
1 parent 8a33c12 commit 14dbfd3
Show file tree
Hide file tree
Showing 16 changed files with 134 additions and 32 deletions.
1 change: 1 addition & 0 deletions app/controllers/groups_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class GroupsController < CrudController
:remove_privacy_policy,
:self_registration_notification_email,
:self_registration_role_type,
:self_registration_require_adult_consent,
:main_self_registration_group,
:custom_self_registration_title
]
Expand Down
4 changes: 2 additions & 2 deletions app/models/self_registration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ def move_on
private

def validate_visited_partials
visited_partials.all? do |partial|
visited_partials.collect do |partial|
move_to_unless_valid?(partial, send("#{partial}_valid?"))
end
end.all?
end

def visited_partials
Expand Down
14 changes: 14 additions & 0 deletions app/models/self_registration/adult_consent.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module SelfRegistration::AdultConsent
extend ActiveSupport::Concern

included do
self.attrs += [:adult_consent]
self.active_model_only += [:adult_consent]

validates :adult_consent, acceptance: true, if: :requires_adult_consent?
end

def requires_adult_consent?
primary_group&.self_registration_require_adult_consent
end
end
5 changes: 4 additions & 1 deletion app/models/self_registration/main_person.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@


class SelfRegistration::MainPerson < SelfRegistration::Person

self.attrs = [
:first_name, :last_name, :nickname, :company_name, :company, :email,
:privacy_policy_accepted,
:primary_group
:primary_group,
]

self.required_attrs = [
:first_name, :last_name
]

include SelfRegistration::AdultConsent

delegate :phone_numbers, :privacy_policy_accepted?, to: :person
validate :assert_privacy_policy

Expand Down
5 changes: 5 additions & 0 deletions app/models/self_registration/person.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class SelfRegistration::Person
class_attribute :attrs, default: required_attrs + [
:gender, :primary_group, :household_key, :_destroy, :household_emails
]
class_attribute :active_model_only, default: []

def initialize(attributes = {})
# We call `define_attributes` here, because we want to be able to override the attributes
Expand Down Expand Up @@ -80,6 +81,10 @@ def household_emails

private

def attributes
super.except(*active_model_only.collect(&:to_s))
end

def assert_email
unless Truemail.validate(email.to_s, with: :regex).result.success
errors.add(:email, :invalid)
Expand Down
3 changes: 3 additions & 0 deletions app/views/groups/_self_registration_fields.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
= f.help_inline(t('groups.form.hint_external_registration'))
= f.labeled_input_fields(:custom_self_registration_title)
= f.labeled_input_fields(:self_registration_notification_email)
= f.labeled(:self_registration_require_adult_consent, class: 'd-flex') do
= f.boolean_field(:self_registration_require_adult_consent)
= f.help_inline(t('groups.form.help_self_registration_require_adult_consent'))
= f.labeled(:main_self_registration_group, class: 'd-flex') do
= f.boolean_field(:main_self_registration_group, disabled: !can?(:set_main_self_registration_group, entry))
= f.help_inline(t('groups.form.help_main_self_registration_group'))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-# Copyright (c) 2024, Schweizer Alpen-Club. This file is part of
-# hitobito_sac_cas and licensed under the Affero General Public License version 3
-# or later. See the COPYING file at the top-level directory or at
-# https://github.com/hitobito/hitobito.
- if f.object.requires_adult_consent?
= f.labeled(:adult_consent, '&nbsp'.html_safe) do
= f.boolean_field(:adult_consent, required: true, caption: t('.caption'))
49 changes: 25 additions & 24 deletions app/views/groups/self_registration/_main_person.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,51 @@
-# or later. See the COPYING file at the top-level directory or at
-# https://github.com/hitobito/hitobito_sac_cas.
= f.fields_for(:main_person_attributes, f.object.main_person) do |f|
= f.fields_for(:main_person_attributes, f.object.main_person) do |ff|
= field_set_tag do
= f.error_messages
= ff.error_messages

- [:first_name, :last_name, :nick_name, :company_name].each do |attr|
= f.labeled_input_field attr if f.object.attr?(attr)
= ff.labeled_input_field attr if ff.object.attr?(attr)

- if f.object.attr?(:company)
= f.labeled_boolean_field :company
- if ff.object.attr?(:company)
= ff.labeled_boolean_field :company

- if [:address, :zip_code, :town, :country].all? { |field| f.object.attr?(field) }
= render 'contactable/address_fields', f: f
- if [:address, :zip_code, :town, :country].all? { |field| ff.object.attr?(field) }
= render 'contactable/address_fields', f: ff

- if f.object.attr?(:email)
= f.labeled_input_field :email, help_inline: t('people.email_field.used_as_login'), class: 'd-inline'
- if ff.object.attr?(:email)
= ff.labeled_input_field :email, help_inline: t('people.email_field.used_as_login'), class: 'd-inline'

- if f.object.attr?(:gender)
- if ff.object.attr?(:gender)
= field_set_tag do
= f.labeled(:gender) do
= ff.labeled(:gender) do
- (Person::GENDERS + ['']).each do |key|
= f.inline_radio_button(:gender, key, f.object.gender_label(key))
= ff.inline_radio_button(:gender, key, ff.object.gender_label(key))


- if f.object.attr?(:birthday)
= f.labeled_date_field :birthday
- if ff.object.attr?(:birthday)
= ff.labeled_date_field :birthday

- if f.object.attr?(:phone_number_attributes)
- if ff.object.attr?(:phone_number_attributes)
= field_set_tag do
= f.labeled_inline_fields_for :phone_numbers do |ff|
= ff.labeled_inline_fields_for :phone_numbers do |ff|
%div.col-5.inline
= ff.input_field(:number, placeholder: PhoneNumber.human_attribute_name(:number))
= fff.input_field(:number, placeholder: PhoneNumber.human_attribute_name(:number))
%div.col-2.inline.row
= ff.collection_select(:translated_label, PhoneNumber.available_labels, :to_s, :to_s, {}, class: 'form-select form-select-sm h-100')
= ff.hidden_field(:public)
= fff.collection_select(:translated_label, PhoneNumber.available_labels, :to_s, :to_s, {}, class: 'form-select form-select-sm h-100')
= fff.hidden_field(:public)

- if f.object.attr?(:additional_information)
= f.labeled(:additional_information, t('.notes')) do
= f.text_area(:additional_information)
- if ff.object.attr?(:additional_information)
= ff.labeled(:additional_information, t('.notes')) do
= ff.text_area(:additional_information)

- if entry.partials.one?
= render 'adult_consent_field', f: ff
= field_set_tag(nil, class: 'privacy-policy-fields') do
= render('people/privacy_policy_acceptance_field', f: f, policy_finder: policy_finder)
= render('people/privacy_policy_acceptance_field', f: ff, policy_finder: policy_finder)

= render_extensions :main_person, locals: { f: f }
= render_extensions :main_person, locals: { f: ff }

.btn-toolbar.bottom.align-with-form
= c.next_button
Expand Down
1 change: 1 addition & 0 deletions config/locales/models.de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ de:
self_registration_role_type: Rollentyp
self_registration_link: Externe Registrierung
self_registration_notification_email: Benachrichtigungs-E-Mail
self_registration_require_adult_consent: Einverständnis von Erziehungsberechtigten
main_self_registration_group: Anzeige auf Loginseite
custom_self_registration_title: Titel bei der Registrierung
nextcloud_url: Link zu Nextcloud
Expand Down
6 changes: 6 additions & 0 deletions config/locales/views.de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,9 @@ de:
no_deleted_sub_groups: 'Keine gelöschten Gruppen vorhanden.'
form:
help_contact: 'Adresse und öffentliche Telefonnummern dieser Person verwenden.'
help_self_registration_require_adult_consent:
Bei der Registrierung abfragen, ob die Person schon 18 Jahre ist bzw. das Einverständnis der
Erziehungsberechtigten hat.
help_main_self_registration_group: 'Den Registrierungslink dieser Gruppe auf der Hauptloginseite anzeigen.'
hint_external_registration: 'Es sind keine Rollen mit Schreibrechten auswählbar'
form_tabs:
Expand Down Expand Up @@ -759,6 +762,9 @@ de:
to_login_page: Anmelden und Einschreiben
main_person:
notes: Bemerkungen
adult_consent_field:
caption: Ich bestätige dass ich mindestens 18 Jahre alt bin oder das Einverständnis meiner
Erziehungsberechtigten habe.
create:
email_taken: E-Mail wird bereits verwendet. Melde dich an oder registrier dich mit einer anderen E-Mail-Adresse.
flash:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class AddSelfRegistrationRequireAdultConsentToGroups < ActiveRecord::Migration[6.1]
def change
change_table(:groups) do |t|
t.boolean :self_registration_require_adult_consent, default: false, null: false
end
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2024_02_14_074832) do
ActiveRecord::Schema.define(version: 2024_02_14_155008) do

create_table "action_text_rich_texts", charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t|
t.string "name", null: false
Expand Down Expand Up @@ -433,6 +433,7 @@
t.string "text_message_provider", default: "aspsms", null: false
t.string "text_message_originator"
t.string "letter_address_position", default: "left", null: false
t.boolean "self_registration_require_adult_consent", default: false, null: false
t.index ["layer_group_id"], name: "index_groups_on_layer_group_id"
t.index ["lft", "rgt"], name: "index_groups_on_lft_and_rgt"
t.index ["parent_id"], name: "index_groups_on_parent_id"
Expand Down
2 changes: 1 addition & 1 deletion spec/components/steps_component/content_component_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
end
let(:iterator) { double(:iterator, index: 0, last?: false) }
let(:policy_finder) { double(:policy_finder, acceptance_needed?: true, groups: []) }
let(:entry) { double(:entry, partials: [:partial]) }
let(:entry) { double(:entry, partials: [:partial], require_adult_consent: false) }

subject(:html) { render_inline(component) }

Expand Down
5 changes: 3 additions & 2 deletions spec/components/steps_component_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

describe StepsComponent, type: :component do
let(:header_css) { '.row .step-headers.offset-md-1' }
subject(:component) { described_class.new(partials: [], form: :form, step: :step) }
let(:form) { double(:form_builder, object: double(:group, self_registration_require_adult_consent: false)) }
subject(:component) { described_class.new(partials: [], form: form, step: :step) }

before do
allow_any_instance_of(StepsComponent::ContentComponent).to receive(:markup) do |component|
Expand All @@ -18,7 +19,7 @@
end

def render(**args)
render_inline(described_class.new(**args.merge(form: :form)))
render_inline(described_class.new(**args.merge(form: form)))
end

it 'does not render when partials are empty' do
Expand Down
25 changes: 24 additions & 1 deletion spec/features/self_registration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,32 @@ def complete_main_person_form
expect(current_path).to eq("#{group_person_path(group_id: group, id: person)}.html")
end

describe 'with privacy policy' do
describe 'with adult consent' do
let(:adult_consent_field) { page.find_field(adult_consent_text) }
let(:adult_consent_text) do
'Ich bestätige dass ich mindestens 18 Jahre alt bin oder das Einverständnis meiner Erziehungsberechtigten habe.'
end

before do
group.update!(self_registration_require_adult_consent: true)
visit group_self_registration_path(group_id: group)
end

it 'cannot complete without accepting adult consent' do
complete_main_person_form
expect { click_on 'Registrieren' }.not_to(change { Person.count })
expect(adult_consent_field.native.attribute('validationMessage')).to eq 'Please check this box if you want to proceed.'
end

it 'can complete when accepting adult consent' do
complete_main_person_form
check adult_consent_text
expect { click_on 'Registrieren' }.to change { Person.count }.by(1)
end
end

describe 'with privacy policy' do
before do
file = Rails.root.join('spec', 'fixtures', 'files', 'images', 'logo.png')
image = ActiveStorage::Blob.create_and_upload!(io: File.open(file, 'rb'),
filename: 'logo.png',
Expand Down
28 changes: 28 additions & 0 deletions spec/models/self_registration/main_person_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

describe SelfRegistration::MainPerson do
subject(:model) { described_class.new }
let(:group) { groups(:top_group) }

it 'is a Housemate' do
expect(model).to be_kind_of(SelfRegistration::Person)
Expand All @@ -25,6 +26,33 @@
expect(model).not_to be_valid
expect(model.errors).to have(2).items
end

context 'with group requiring adult consent' do
let(:required_attrs) { { first_name: 'test', last_name: 'dummy' } }
before do
group.update!(
self_registration_require_adult_consent: true,
self_registration_role_type: group.role_types.first
)
model.primary_group = group
model.attributes = required_attrs
end

it 'is valid when adult consent is not explicitly denied' do
expect(model).to be_valid
end

it 'is valid when adult consent is explicitly set' do
model.adult_consent = '1'
expect(model).to be_valid
end

it 'is invalid when adult consent is explicitly denied' do
model.adult_consent = '0'
expect(model).not_to be_valid
expect(model).to have(1).error_on(:adult_consent)
end
end
end

describe 'privacy policy' do
Expand Down

0 comments on commit 14dbfd3

Please sign in to comment.