diff --git a/app/helpers/event_helper.rb b/app/helpers/event_helper.rb index 25ac9f890a..92f4e8fdea 100644 --- a/app/helpers/event_helper.rb +++ b/app/helpers/event_helper.rb @@ -143,7 +143,7 @@ def resolve_answer_text(field, submitted_answer) case field&.field_identifier when *FormField::SECTOR_FIELD_IDENTIFIERS resolve.call(Sector) - when "primary_age_group", "additional_age_group" + when *FormField::AGE_GROUP_FIELD_IDENTIFIERS resolve.call(Category) else submitted_answer diff --git a/app/models/form_field.rb b/app/models/form_field.rb index c8ee2feba6..00dfa8b5c3 100644 --- a/app/models/form_field.rb +++ b/app/models/form_field.rb @@ -32,17 +32,28 @@ class FormField < ApplicationRecord # submitted value for these is a Sector id (as a string). SECTOR_FIELD_IDENTIFIERS = (ADDITIONAL_SECTOR_FIELD_IDENTIFIERS + PRIMARY_SECTOR_FIELD_IDENTIFIERS).freeze + # Single-select "primary age group" field identifiers. Primary has never been + # renamed, so this is just the canonical name — kept as a list for symmetry + # with the sector fields and the multi-select additional field below. + PRIMARY_AGE_GROUP_FIELD_IDENTIFIERS = %w[primary_age_group].freeze + + # Multi-select "additional age group(s)" field identifiers. "additional_age_group" + # is the canonical name new forms are built with; the pluralized + # "additional_age_groups" is also accepted so older forms carrying it keep + # resolving (mirrors the legacy coverage the sector fields have). + ADDITIONAL_AGE_GROUP_FIELD_IDENTIFIERS = %w[additional_age_group additional_age_groups].freeze + + # Every age-group field identifier, primary and additional. + AGE_GROUP_FIELD_IDENTIFIERS = (PRIMARY_AGE_GROUP_FIELD_IDENTIFIERS + ADDITIONAL_AGE_GROUP_FIELD_IDENTIFIERS).freeze + # Field identifiers whose selectable options are sourced dynamically from a # CategoryType's published categories. The submitted value is a Category id # (as a string). Maps the field identifier to its backing CategoryType name. - # Both the "primary" and "additional" age group fields are backed by the - # published AgeRange categories. Unlike the sector fields, age groups have no - # catch-all option — the additional sector field keeps "Other", but neither age - # field offers one. - DYNAMIC_FIELD_CATEGORY_TYPES = { - "primary_age_group" => "AgeRange", - "additional_age_group" => "AgeRange" - }.freeze + # Every "primary" and "additional" age group field (canonical or legacy) is + # backed by the published AgeRange categories. Unlike the sector fields, age + # groups have no catch-all option — the additional sector field keeps "Other", + # but no age field offers one. + DYNAMIC_FIELD_CATEGORY_TYPES = AGE_GROUP_FIELD_IDENTIFIERS.index_with { "AgeRange" }.freeze # The payment-method field. Its answer options ("Credit card (now)", etc.) are # wired to Stripe charge logic in the controllers, so they must not be edited diff --git a/app/models/person.rb b/app/models/person.rb index 424dd07d15..10b249a761 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -230,7 +230,7 @@ def remote_search_label # Field identifiers whose "Other" free text maps onto the category-backed # profile fields shown on the edit page. - OTHER_WORKSHOP_SETTING_IDENTIFIERS = %w[primary_age_group additional_age_group].freeze + OTHER_WORKSHOP_SETTING_IDENTIFIERS = FormField::AGE_GROUP_FIELD_IDENTIFIERS # Free-text "Other" sectors the person typed on registration forms. # They can't be Sector records, so they're surfaced beside the sector tags. diff --git a/app/services/event_registration_services/public_registration.rb b/app/services/event_registration_services/public_registration.rb index ff7c3e3e82..021832b852 100644 --- a/app/services/event_registration_services/public_registration.rb +++ b/app/services/event_registration_services/public_registration.rb @@ -273,10 +273,10 @@ def create_agency_address(organization) end def assign_tags(person, organization) - primary_sector_ids = collect_sector_ids(FormField::PRIMARY_SECTOR_FIELD_IDENTIFIERS) - additional_sector_ids = collect_sector_ids(FormField::ADDITIONAL_SECTOR_FIELD_IDENTIFIERS) - primary_age_ids = collect_ids_from_checkboxes("primary_age_group") - additional_age_ids = collect_ids_from_checkboxes("additional_age_group") + primary_sector_ids = collect_ids(FormField::PRIMARY_SECTOR_FIELD_IDENTIFIERS) + additional_sector_ids = collect_ids(FormField::ADDITIONAL_SECTOR_FIELD_IDENTIFIERS) + primary_age_ids = collect_ids(FormField::PRIMARY_AGE_GROUP_FIELD_IDENTIFIERS) + additional_age_ids = collect_ids(FormField::ADDITIONAL_AGE_GROUP_FIELD_IDENTIFIERS) if primary_sector_ids.any? || additional_sector_ids.any? person.tag_sectors(primary_ids: primary_sector_ids, additional_ids: additional_sector_ids) @@ -292,7 +292,7 @@ def assign_tags(person, organization) end end - def collect_sector_ids(identifiers) + def collect_ids(identifiers) identifiers.flat_map { |id| collect_ids_from_checkboxes(id) } end diff --git a/spec/requests/events/professional_field_identifiers_spec.rb b/spec/requests/events/professional_field_identifiers_spec.rb index d9581741f7..7848e2a969 100644 --- a/spec/requests/events/professional_field_identifiers_spec.rb +++ b/spec/requests/events/professional_field_identifiers_spec.rb @@ -29,19 +29,23 @@ let!(:sector_other) { create(:sector, :published, name: Sector::OTHER_SECTOR_NAME) } let!(:sector_hidden) { create(:sector, name: "Hidden sector") } - # Each scheme maps the two sector fields onto a canonical or legacy identifier; - # the age-group fields have never been renamed, so they stay constant. + # Each scheme maps the two sector fields and the additional-age field onto a + # canonical or legacy identifier. The primary age field has never been renamed, + # so it stays constant; the additional age field also accepts a pluralized + # legacy name (`additional_age_groups`) some older forms carry. { - "canonical identifiers" => { primary_sector: "primary_sector_single", additional_sector: "additional_sectors" }, - "legacy additional-sector name" => { primary_sector: "primary_sector_single", additional_sector: "primary_sector" }, - "legacy service-area names" => { primary_sector: "primary_service_area_single", additional_sector: "primary_service_area" } + "canonical identifiers" => { primary_sector: "primary_sector_single", additional_sector: "additional_sectors" }, + "legacy additional-sector name" => { primary_sector: "primary_sector_single", additional_sector: "primary_sector" }, + "legacy service-area names" => { primary_sector: "primary_service_area_single", additional_sector: "primary_service_area" }, + "pluralized additional-age name" => { primary_sector: "primary_sector_single", additional_sector: "additional_sectors", additional_age: "additional_age_groups" } }.each do |scheme_name, ids| context "with #{scheme_name}" do + let(:additional_age_identifier) { ids.fetch(:additional_age, "additional_age_group") } let(:form) { build_professional_form(ids) } let(:primary_sector_field) { form.form_fields.find_by!(field_identifier: ids[:primary_sector]) } let(:additional_sector_field) { form.form_fields.find_by!(field_identifier: ids[:additional_sector]) } let(:primary_age_field) { form.form_fields.find_by!(field_identifier: "primary_age_group") } - let(:additional_age_field) { form.form_fields.find_by!(field_identifier: "additional_age_group") } + let(:additional_age_field) { form.form_fields.find_by!(field_identifier: additional_age_identifier) } before { EventForm.create!(event: event, form: form, role: "registration") } @@ -98,7 +102,7 @@ ids[:primary_sector] => sector_education.id.to_s, ids[:additional_sector] => "#{sector_mh.id}, Other: Equine therapy", "primary_age_group" => age_adults.id.to_s, - "additional_age_group" => "#{age_teens.id}, #{age_children.id}" + additional_age_identifier => "#{age_teens.id}, #{age_children.id}" ) end @@ -150,8 +154,9 @@ # ---- Form construction ---- # Builds a registration form with just the identity + professional sections, - # then renames the two sector fields onto the scheme's identifiers (the age - # fields keep their canonical names — they were never renamed). + # then renames the two sector fields (and, when the scheme asks, the additional + # age field) onto the scheme's identifiers. The primary age field keeps its + # canonical name — it was never renamed. def build_professional_form(ids) form = FormBuilderService.new( name: "Reg #{ids[:primary_sector]} / #{ids[:additional_sector]}", @@ -160,6 +165,7 @@ def build_professional_form(ids) ).call rename_field(form, "primary_sector_single", ids[:primary_sector]) rename_field(form, "additional_sectors", ids[:additional_sector]) + rename_field(form, "additional_age_group", ids.fetch(:additional_age, "additional_age_group")) form end