diff --git a/app/helpers/formatting_helper.rb b/app/helpers/formatting_helper.rb new file mode 100644 index 000000000..0675d42ba --- /dev/null +++ b/app/helpers/formatting_helper.rb @@ -0,0 +1,23 @@ +module FormattingHelper + def format_ending(text) + return text if text.blank? + + modified_text = lowercase_first_letter(text) + ensure_sentence_ending(modified_text) + end + + def ensure_sentence_ending(text) + return text if text.blank? + + ends_with_any_punctuation = text.match?(/[[:punct:]]\z/) + ends_with_special_char = text.match?(/[%(){}\[\]]\z/) + + ends_with_any_punctuation && !ends_with_special_char ? text : "#{text}." + end + + def lowercase_first_letter(text) + return text if text.blank? + + text[0].downcase + text[1..] + end +end diff --git a/app/models/form/question.rb b/app/models/form/question.rb index 1fbced841..d5d2b7f36 100644 --- a/app/models/form/question.rb +++ b/app/models/form/question.rb @@ -1,4 +1,6 @@ class Form::Question + include FormattingHelper + attr_accessor :id, :header, :hint_text, :description, :questions, :disable_clearing_if_not_routed_or_dynamic_answer_options, :type, :min, :max, :step, :width, :fields_to_add, :result_field, :conditional_for, :readonly, :answer_options, :page, :check_answer_label, @@ -204,11 +206,12 @@ class Form::Question end def error_display_label - error_label || check_answer_label || header || id.humanize + label = error_label || check_answer_label || header || id.humanize + format_ending(label) end def unanswered_error_message - question_text = error_display_label.presence || "this question" + question_text = error_display_label.presence || "this question." I18n.t("validations.not_answered", question: question_text.downcase) end diff --git a/app/services/bulk_upload/lettings/year2023/row_parser.rb b/app/services/bulk_upload/lettings/year2023/row_parser.rb index 481b399dd..8c435ad24 100644 --- a/app/services/bulk_upload/lettings/year2023/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2023/row_parser.rb @@ -2,6 +2,7 @@ class BulkUpload::Lettings::Year2023::RowParser include ActiveModel::Model include ActiveModel::Attributes include InterruptionScreenHelper + include FormattingHelper QUESTIONS = { field_1: "Which organisation owns this property?", @@ -284,12 +285,12 @@ class BulkUpload::Lettings::Year2023::RowParser validates :field_5, presence: { - message: I18n.t("validations.not_answered", question: "letting type"), + message: I18n.t("validations.not_answered", question: "letting type."), category: :setup, }, inclusion: { in: (1..12).to_a, - message: I18n.t("validations.invalid_option", question: "letting type"), + message: I18n.t("validations.invalid_option", question: "letting type."), unless: -> { field_5.blank? }, category: :setup, }, @@ -297,28 +298,28 @@ class BulkUpload::Lettings::Year2023::RowParser validates :field_6, presence: { - message: I18n.t("validations.not_answered", question: "property renewal"), + message: I18n.t("validations.not_answered", question: "property renewal."), category: :setup, }, on: :after_log validates :field_7, presence: { - message: I18n.t("validations.not_answered", question: "tenancy start date (day)"), + message: I18n.t("validations.not_answered", question: "tenancy start date (day)."), category: :setup, }, on: :after_log validates :field_8, presence: { - message: I18n.t("validations.not_answered", question: "tenancy start date (month)"), + message: I18n.t("validations.not_answered", question: "tenancy start date (month)."), category: :setup, }, on: :after_log validates :field_9, presence: { - message: I18n.t("validations.not_answered", question: "tenancy start date (year)"), + message: I18n.t("validations.not_answered", question: "tenancy start date (year)."), category: :setup, }, format: { @@ -332,7 +333,7 @@ class BulkUpload::Lettings::Year2023::RowParser validates :field_16, presence: { if: proc { supported_housing? }, - message: I18n.t("validations.not_answered", question: "scheme code"), + message: I18n.t("validations.not_answered", question: "scheme code."), category: :setup, }, on: :after_log @@ -344,7 +345,7 @@ class BulkUpload::Lettings::Year2023::RowParser }, inclusion: { in: [1, 2], - message: I18n.t("validations.invalid_option", question: "was the letting made under the Choice-Based Lettings (CBL)"), + message: I18n.t("validations.invalid_option", question: "was the letting made under the Choice-Based Lettings (CBL)?"), if: -> { field_116.present? }, }, on: :after_log @@ -356,7 +357,7 @@ class BulkUpload::Lettings::Year2023::RowParser }, inclusion: { in: [1, 2], - message: I18n.t("validations.invalid_option", question: "was the letting made under the Common Allocation Policy (CAP)"), + message: I18n.t("validations.invalid_option", question: "was the letting made under the Common Allocation Policy (CAP)?"), if: -> { field_117.present? }, }, on: :after_log @@ -368,7 +369,7 @@ class BulkUpload::Lettings::Year2023::RowParser }, inclusion: { in: [1, 2], - message: I18n.t("validations.invalid_option", question: "was the letting made under the Common Housing Register (CHR)"), + message: I18n.t("validations.invalid_option", question: "was the letting made under the Common Housing Register (CHR)?"), if: -> { field_118.present? }, }, on: :after_log @@ -543,9 +544,9 @@ private fields.each do |field| if setup_question?(question) - errors.add(field, I18n.t("validations.invalid_option", question: QUESTIONS[field]), category: :setup) + errors.add(field, I18n.t("validations.invalid_option", question: format_ending(QUESTIONS[field])), category: :setup) else - errors.add(field, I18n.t("validations.invalid_option", question: QUESTIONS[field])) + errors.add(field, I18n.t("validations.invalid_option", question: format_ending(QUESTIONS[field]))) end end end @@ -574,7 +575,7 @@ private def validate_uprn_exists_if_any_key_address_fields_are_blank if field_18.blank? && (field_19.blank? || field_21.blank?) - errors.add(:field_18, I18n.t("validations.not_answered", question: "UPRN"), category: :not_answered) + errors.add(:field_18, I18n.t("validations.not_answered", question: "UPRN."), category: :not_answered) end end @@ -613,7 +614,7 @@ private def validate_needs_type_present if field_4.blank? - errors.add(:field_4, I18n.t("validations.not_answered", question: "needs type"), category: :setup) + errors.add(:field_4, I18n.t("validations.not_answered", question: "needs type."), category: :setup) end end @@ -658,10 +659,10 @@ private def validate_no_housing_needs_questions_answered if [field_83, field_84, field_85, field_86, field_87, field_88].all?(&:blank?) - errors.add(:field_87, I18n.t("validations.not_answered", question: "anybody with disabled access needs"), category: :not_answered) - errors.add(:field_86, I18n.t("validations.not_answered", question: "other access needs"), category: :not_answered) + errors.add(:field_87, I18n.t("validations.not_answered", question: "anybody with disabled access needs."), category: :not_answered) + errors.add(:field_86, I18n.t("validations.not_answered", question: "other access needs."), category: :not_answered) %i[field_83 field_84 field_85].each do |field| - errors.add(field, I18n.t("validations.not_answered", question: "disabled access needs type"), category: :not_answered) + errors.add(field, I18n.t("validations.not_answered", question: "disabled access needs type."), category: :not_answered) end end end @@ -670,7 +671,7 @@ private reason_fields = %i[field_111 field_112 field_113 field_114 field_115] if field_110 == 1 && reason_fields.all? { |field| attributes[field.to_s].blank? } reason_fields.each do |field| - errors.add(field, I18n.t("validations.not_answered", question: "reason for reasonable preference"), category: :not_answered) + errors.add(field, I18n.t("validations.not_answered", question: "reason for reasonable preference."), category: :not_answered) end end end @@ -685,7 +686,7 @@ private end elsif illness_option_fields.all? { |field| attributes[field.to_s].blank? } illness_option_fields.each do |field| - errors.add(field, I18n.t("validations.not_answered", question: "how is person affected by condition or illness"), category: :not_answered) + errors.add(field, I18n.t("validations.not_answered", question: "how is person affected by condition or illness."), category: :not_answered) end end end @@ -746,7 +747,7 @@ private def validate_data_types unless attribute_set["field_5"].value_before_type_cast&.match?(/^\d+\.?0*$/) - errors.add(:field_5, I18n.t("validations.invalid_number", question: "letting type")) + errors.add(:field_5, I18n.t("validations.invalid_number", question: "letting type.")) end end @@ -762,15 +763,15 @@ private if setup_question?(question) fields.each do |field| if errors.select { |e| fields.include?(e.attribute) }.none? - question_text = question.error_display_label.presence || "this question" - errors.add(field, I18n.t("validations.not_answered", question: question_text.downcase), category: :setup) if field.present? + question_text = question.error_display_label.presence || "this question." + errors.add(field, I18n.t("validations.not_answered", question: format_ending(question_text)), category: :setup) if field.present? end end else fields.each do |field| unless errors.any? { |e| fields.include?(e.attribute) } - question_text = question.error_display_label.presence || "this question" - errors.add(field, I18n.t("validations.not_answered", question: question_text.downcase), category: :not_answered) + question_text = question.error_display_label.presence || "this question." + errors.add(field, I18n.t("validations.not_answered", question: format_ending(question_text)), category: :not_answered) end end end @@ -787,7 +788,7 @@ private def validate_location_data_given if supported_housing? && location_id.blank? && location_field.present? block_log_creation! - errors.add(location_field, I18n.t("validations.not_answered", question: "#{location_or_scheme} code"), category: :setup) + errors.add(location_field, I18n.t("validations.not_answered", question: "#{location_or_scheme} code."), category: :setup) end end @@ -801,7 +802,7 @@ private def validate_scheme_data_given if supported_housing? && scheme_field.present? && scheme_id.blank? block_log_creation! - errors.add(scheme_field, I18n.t("validations.not_answered", question: "#{scheme_or_management_group} code"), category: :setup) + errors.add(scheme_field, I18n.t("validations.not_answered", question: "#{scheme_or_management_group} code."), category: :setup) end end @@ -855,7 +856,7 @@ private def validate_owning_org_data_given if field_1.blank? block_log_creation! - errors.add(:field_1, I18n.t("validations.not_answered", question: "owning organisation"), category: :setup) + errors.add(:field_1, I18n.t("validations.not_answered", question: "owning organisation."), category: :setup) end end @@ -871,13 +872,13 @@ private def validate_correct_intermediate_rent_type if field_11.blank? || ![1, 2, 3].include?(field_11.to_i) - errors.add(:field_11, I18n.t("validations.not_answered", question: "intermediate rent type"), category: :setup) + errors.add(:field_11, I18n.t("validations.not_answered", question: "intermediate rent type."), category: :setup) end end def validate_correct_affordable_rent_type if field_10.blank? || ![1, 2, 3].include?(field_10.to_i) - errors.add(:field_10, I18n.t("validations.not_answered", question: "is this a London Affordable Rent letting"), category: :setup) + errors.add(:field_10, I18n.t("validations.not_answered", question: "is this a London Affordable Rent letting."), category: :setup) end end diff --git a/app/services/bulk_upload/lettings/year2024/row_parser.rb b/app/services/bulk_upload/lettings/year2024/row_parser.rb index 5002deac1..a40094e26 100644 --- a/app/services/bulk_upload/lettings/year2024/row_parser.rb +++ b/app/services/bulk_upload/lettings/year2024/row_parser.rb @@ -2,6 +2,7 @@ class BulkUpload::Lettings::Year2024::RowParser include ActiveModel::Model include ActiveModel::Attributes include InterruptionScreenHelper + include FormattingHelper QUESTIONS = { field_1: "Which organisation owns this property?", @@ -285,12 +286,12 @@ class BulkUpload::Lettings::Year2024::RowParser validates :field_11, presence: { - message: I18n.t("validations.not_answered", question: "rent type"), + message: I18n.t("validations.not_answered", question: "rent type."), category: :setup, }, inclusion: { in: (1..6).to_a, - message: I18n.t("validations.invalid_option", question: "rent type"), + message: I18n.t("validations.invalid_option", question: "rent type."), unless: -> { field_11.blank? }, category: :setup, }, @@ -298,28 +299,28 @@ class BulkUpload::Lettings::Year2024::RowParser validates :field_7, presence: { - message: I18n.t("validations.not_answered", question: "property renewal"), + message: I18n.t("validations.not_answered", question: "property renewal."), category: :setup, }, on: :after_log validates :field_8, presence: { - message: I18n.t("validations.not_answered", question: "tenancy start date (day)"), + message: I18n.t("validations.not_answered", question: "tenancy start date (day)."), category: :setup, }, on: :after_log validates :field_9, presence: { - message: I18n.t("validations.not_answered", question: "tenancy start date (month)"), + message: I18n.t("validations.not_answered", question: "tenancy start date (month)."), category: :setup, }, on: :after_log validates :field_10, presence: { - message: I18n.t("validations.not_answered", question: "tenancy start date (year)"), + message: I18n.t("validations.not_answered", question: "tenancy start date (year)."), category: :setup, }, format: { @@ -333,7 +334,7 @@ class BulkUpload::Lettings::Year2024::RowParser validates :field_5, presence: { if: proc { supported_housing? }, - message: I18n.t("validations.not_answered", question: "scheme code"), + message: I18n.t("validations.not_answered", question: "scheme code."), category: :setup, }, on: :after_log @@ -341,7 +342,7 @@ class BulkUpload::Lettings::Year2024::RowParser validates :field_6, presence: { if: proc { supported_housing? }, - message: I18n.t("validations.not_answered", question: "location code"), + message: I18n.t("validations.not_answered", question: "location code."), category: :setup, }, on: :after_log @@ -353,7 +354,7 @@ class BulkUpload::Lettings::Year2024::RowParser }, inclusion: { in: [1, 2], - message: I18n.t("validations.invalid_option", question: "was the letting made under the Choice-Based Lettings (CBL)"), + message: I18n.t("validations.invalid_option", question: "was the letting made under the Choice-Based Lettings (CBL)?"), if: -> { field_112.present? }, }, on: :after_log @@ -365,7 +366,7 @@ class BulkUpload::Lettings::Year2024::RowParser }, inclusion: { in: [1, 2], - message: I18n.t("validations.invalid_option", question: "was the letting made under the Common Allocation Policy (CAP)"), + message: I18n.t("validations.invalid_option", question: "was the letting made under the Common Allocation Policy (CAP)?"), if: -> { field_113.present? }, }, on: :after_log @@ -377,7 +378,7 @@ class BulkUpload::Lettings::Year2024::RowParser }, inclusion: { in: [1, 2], - message: I18n.t("validations.invalid_option", question: "was the letting made under the Common Housing Register (CHR)"), + message: I18n.t("validations.invalid_option", question: "was the letting made under the Common Housing Register (CHR)?"), if: -> { field_114.present? }, }, on: :after_log @@ -389,7 +390,7 @@ class BulkUpload::Lettings::Year2024::RowParser }, inclusion: { in: [1, 2], - message: I18n.t("validations.invalid_option", question: "was the letting made under the Accessible Register"), + message: I18n.t("validations.invalid_option", question: "was the letting made under the Accessible Register?"), if: -> { field_115.present? }, }, on: :after_log @@ -567,9 +568,9 @@ private fields.each do |field| if setup_question?(question) - errors.add(field, I18n.t("validations.invalid_option", question: QUESTIONS[field]), category: :setup) + errors.add(field, I18n.t("validations.invalid_option", question: format_ending(QUESTIONS[field])), category: :setup) else - errors.add(field, I18n.t("validations.invalid_option", question: QUESTIONS[field])) + errors.add(field, I18n.t("validations.invalid_option", question: format_ending(QUESTIONS[field]))) end end end @@ -604,7 +605,7 @@ private def validate_uprn_exists_if_any_key_address_fields_are_blank if field_16.blank? && !key_address_fields_provided? - errors.add(:field_16, I18n.t("validations.not_answered", question: "UPRN")) + errors.add(:field_16, I18n.t("validations.not_answered", question: "UPRN.")) end end @@ -623,19 +624,19 @@ private def validate_address_fields if field_16.blank? || log.errors.attribute_names.include?(:uprn) if field_17.blank? - errors.add(:field_17, I18n.t("validations.not_answered", question: "address line 1")) + errors.add(:field_17, I18n.t("validations.not_answered", question: "address line 1.")) end if field_19.blank? - errors.add(:field_19, I18n.t("validations.not_answered", question: "town or city")) + errors.add(:field_19, I18n.t("validations.not_answered", question: "town or city.")) end if field_21.blank? - errors.add(:field_21, I18n.t("validations.not_answered", question: "part 1 of postcode")) + errors.add(:field_21, I18n.t("validations.not_answered", question: "part 1 of postcode.")) end if field_22.blank? - errors.add(:field_22, I18n.t("validations.not_answered", question: "part 2 of postcode")) + errors.add(:field_22, I18n.t("validations.not_answered", question: "part 2 of postcode.")) end end end @@ -681,7 +682,7 @@ private def validate_needs_type_present if field_4.blank? - errors.add(:field_4, I18n.t("validations.not_answered", question: "needs type"), category: :setup) + errors.add(:field_4, I18n.t("validations.not_answered", question: "needs type."), category: :setup) end end @@ -726,10 +727,10 @@ private def validate_no_housing_needs_questions_answered if [field_79, field_80, field_81, field_82, field_83, field_84].all?(&:blank?) - errors.add(:field_83, I18n.t("validations.not_answered", question: "anybody with disabled access needs")) - errors.add(:field_82, I18n.t("validations.not_answered", question: "other access needs")) + errors.add(:field_83, I18n.t("validations.not_answered", question: "anybody with disabled access needs.")) + errors.add(:field_82, I18n.t("validations.not_answered", question: "other access needs.")) %i[field_79 field_80 field_81].each do |field| - errors.add(field, I18n.t("validations.not_answered", question: "disabled access needs type")) + errors.add(field, I18n.t("validations.not_answered", question: "disabled access needs type.")) end end end @@ -738,7 +739,7 @@ private reason_fields = %i[field_107 field_108 field_109 field_110 field_111] if field_106 == 1 && reason_fields.all? { |field| attributes[field.to_s].blank? } reason_fields.each do |field| - errors.add(field, I18n.t("validations.not_answered", question: "reason for reasonable preference")) + errors.add(field, I18n.t("validations.not_answered", question: "reason for reasonable preference.")) end end end @@ -753,7 +754,7 @@ private end elsif illness_option_fields.all? { |field| attributes[field.to_s].blank? } illness_option_fields.each do |field| - errors.add(field, I18n.t("validations.not_answered", question: "how is person affected by condition or illness")) + errors.add(field, I18n.t("validations.not_answered", question: "how is person affected by condition or illness.")) end end end @@ -800,7 +801,7 @@ private def validate_data_types unless attribute_set["field_11"].value_before_type_cast&.match?(/^\d+\.?0*$/) - errors.add(:field_11, I18n.t("validations.invalid_number", question: "rent type")) + errors.add(:field_11, I18n.t("validations.invalid_number", question: "rent type.")) end end @@ -866,7 +867,7 @@ private def validate_managing_org_data_given if field_2.blank? block_log_creation! - errors.add(:field_2, I18n.t("validations.not_answered", question: "managing organisation"), category: :setup) + errors.add(:field_2, I18n.t("validations.not_answered", question: "managing organisation."), category: :setup) end end @@ -893,7 +894,7 @@ private def validate_owning_org_data_given if field_1.blank? block_log_creation! - errors.add(:field_1, I18n.t("validations.not_answered", question: "owning organisation"), category: :setup) + errors.add(:field_1, I18n.t("validations.not_answered", question: "owning organisation."), category: :setup) end end @@ -923,12 +924,12 @@ private }.partition { |field, _| public_send(field).blank? }.map(&:to_h) blank_charge_fields.each do |field, charge| - errors.add(field, I18n.t("validations.financial.charges.missing_charges", question: charge)) + errors.add(field, I18n.t("validations.financial.charges.missing_charges", sentence_fragment: charge)) end other_charge_fields.each do |field, _charge| blank_charge_fields.each do |_blank_field, blank_charge| - errors.add(field, I18n.t("validations.financial.charges.missing_charges", question: blank_charge)) + errors.add(field, I18n.t("validations.financial.charges.missing_charges", sentence_fragment: blank_charge)) end end end diff --git a/app/services/bulk_upload/sales/year2023/row_parser.rb b/app/services/bulk_upload/sales/year2023/row_parser.rb index 715a8983a..6a18512aa 100644 --- a/app/services/bulk_upload/sales/year2023/row_parser.rb +++ b/app/services/bulk_upload/sales/year2023/row_parser.rb @@ -2,6 +2,7 @@ class BulkUpload::Sales::Year2023::RowParser include ActiveModel::Model include ActiveModel::Attributes include InterruptionScreenHelper + include FormattingHelper QUESTIONS = { field_1: "Which organisation owned this property before the sale?", @@ -310,20 +311,20 @@ class BulkUpload::Sales::Year2023::RowParser validates :field_3, presence: { - message: I18n.t("validations.not_answered", question: "sale completion date (day)"), + message: I18n.t("validations.not_answered", question: "sale completion date (day)."), category: :setup, }, on: :after_log validates :field_4, presence: { - message: I18n.t("validations.not_answered", question: "sale completion date (month)"), + message: I18n.t("validations.not_answered", question: "sale completion date (month)."), category: :setup, }, on: :after_log validates :field_5, presence: { - message: I18n.t("validations.not_answered", question: "sale completion date (year)"), + message: I18n.t("validations.not_answered", question: "sale completion date (year)."), category: :setup, }, format: { @@ -335,7 +336,7 @@ class BulkUpload::Sales::Year2023::RowParser validates :field_7, presence: { - message: I18n.t("validations.not_answered", question: "purchase made under ownership scheme"), + message: I18n.t("validations.not_answered", question: "purchase made under ownership scheme."), category: :setup, }, on: :after_log @@ -351,7 +352,7 @@ class BulkUpload::Sales::Year2023::RowParser validates :field_8, presence: { - message: I18n.t("validations.not_answered", question: "type of shared ownership sale"), + message: I18n.t("validations.not_answered", question: "type of shared ownership sale."), category: :setup, if: :shared_ownership?, }, @@ -368,7 +369,7 @@ class BulkUpload::Sales::Year2023::RowParser validates :field_9, presence: { - message: I18n.t("validations.not_answered", question: "type of discounted ownership sale"), + message: I18n.t("validations.not_answered", question: "type of discounted ownership sale."), category: :setup, if: :discounted_ownership?, }, @@ -385,7 +386,7 @@ class BulkUpload::Sales::Year2023::RowParser validates :field_10, presence: { - message: I18n.t("validations.not_answered", question: "type of outright sale"), + message: I18n.t("validations.not_answered", question: "type of outright sale."), category: :setup, if: :outright_sale?, }, @@ -393,7 +394,7 @@ class BulkUpload::Sales::Year2023::RowParser validates :field_11, presence: { - message: I18n.t("validations.not_answered", question: "type of outright sale"), + message: I18n.t("validations.not_answered", question: "type of outright sale."), category: :setup, if: proc { field_10 == 12 }, }, @@ -410,7 +411,7 @@ class BulkUpload::Sales::Year2023::RowParser validates :field_12, presence: { - message: I18n.t("validations.not_answered", question: "company buyer"), + message: I18n.t("validations.not_answered", question: "company buyer."), category: :setup, if: :outright_sale?, }, @@ -427,7 +428,7 @@ class BulkUpload::Sales::Year2023::RowParser validates :field_13, presence: { - message: I18n.t("validations.not_answered", question: "buyers living in property"), + message: I18n.t("validations.not_answered", question: "buyers living in property."), category: :setup, if: :outright_sale?, }, @@ -435,7 +436,7 @@ class BulkUpload::Sales::Year2023::RowParser validates :field_14, presence: { - message: I18n.t("validations.not_answered", question: "joint purchase"), + message: I18n.t("validations.not_answered", question: "joint purchase."), category: :setup, if: :joint_purchase_asked?, }, @@ -443,7 +444,7 @@ class BulkUpload::Sales::Year2023::RowParser validates :field_15, presence: { - message: I18n.t("validations.not_answered", question: "more than 2 joint buyers"), + message: I18n.t("validations.not_answered", question: "more than 2 joint buyers."), category: :setup, if: :joint_purchase?, }, @@ -567,7 +568,7 @@ private def validate_data_protection_answered unless field_29 == 1 - errors.add(:field_29, I18n.t("validations.not_answered", question: QUESTIONS[:field_29].downcase), category: :setup) + errors.add(:field_29, I18n.t("validations.not_answered", question: "Data Protection question."), category: :setup) end end @@ -599,18 +600,18 @@ private def validate_uprn_exists_if_any_key_address_fields_are_blank if field_19.blank? && (field_20.blank? || field_22.blank?) - errors.add(:field_19, I18n.t("validations.not_answered", question: "UPRN"), category: :not_answered) + errors.add(:field_19, I18n.t("validations.not_answered", question: "UPRN."), category: :not_answered) end end def validate_address_fields if field_19.blank? || log.errors.attribute_names.include?(:uprn) if field_20.blank? - errors.add(:field_20, I18n.t("validations.not_answered", question: "address line 1"), category: :not_answered) + errors.add(:field_20, I18n.t("validations.not_answered", question: "address line 1."), category: :not_answered) end if field_22.blank? - errors.add(:field_22, I18n.t("validations.not_answered", question: "town or city"), category: :not_answered) + errors.add(:field_22, I18n.t("validations.not_answered", question: "town or city."), category: :not_answered) end end end @@ -1242,13 +1243,13 @@ private if setup_question?(question) fields.each do |field| unless errors.any? { |e| fields.include?(e.attribute) } - errors.add(field, I18n.t("validations.not_answered", question: question.error_display_label&.downcase), category: :setup) + errors.add(field, I18n.t("validations.not_answered", question: question.error_display_label), category: :setup) end end else fields.each do |field| unless errors.any? { |e| fields.include?(e.attribute) } - errors.add(field, I18n.t("validations.not_answered", question: question.error_display_label&.downcase), category: :not_answered) + errors.add(field, I18n.t("validations.not_answered", question: question.error_display_label), category: :not_answered) end end end @@ -1270,13 +1271,13 @@ private fields.each do |field| if errors[field].none? block_log_creation! - errors.add(field, I18n.t("validations.invalid_option", question: QUESTIONS[field]), category: :setup) + errors.add(field, I18n.t("validations.invalid_option", question: format_ending(QUESTIONS[field])), category: :setup) end end else fields.each do |field| unless errors.any? { |e| fields.include?(e.attribute) } - errors.add(field, I18n.t("validations.invalid_option", question: QUESTIONS[field])) + errors.add(field, I18n.t("validations.invalid_option", question: format_ending(QUESTIONS[field]))) end end end diff --git a/app/services/bulk_upload/sales/year2024/row_parser.rb b/app/services/bulk_upload/sales/year2024/row_parser.rb index d024e9c86..44e81786b 100644 --- a/app/services/bulk_upload/sales/year2024/row_parser.rb +++ b/app/services/bulk_upload/sales/year2024/row_parser.rb @@ -2,6 +2,7 @@ class BulkUpload::Sales::Year2024::RowParser include ActiveModel::Model include ActiveModel::Attributes include InterruptionScreenHelper + include FormattingHelper QUESTIONS = { field_1: "Which organisation owned this property before the sale?", @@ -302,20 +303,20 @@ class BulkUpload::Sales::Year2024::RowParser validates :field_4, presence: { - message: I18n.t("validations.not_answered", question: "sale completion date (day)"), + message: I18n.t("validations.not_answered", question: "sale completion date (day)."), category: :setup, }, on: :after_log validates :field_5, presence: { - message: I18n.t("validations.not_answered", question: "sale completion date (month)"), + message: I18n.t("validations.not_answered", question: "sale completion date (month)."), category: :setup, }, on: :after_log validates :field_6, presence: { - message: I18n.t("validations.not_answered", question: "sale completion date (year)"), + message: I18n.t("validations.not_answered", question: "sale completion date (year)."), category: :setup, }, format: { @@ -327,7 +328,7 @@ class BulkUpload::Sales::Year2024::RowParser validates :field_8, presence: { - message: I18n.t("validations.not_answered", question: "purchase made under ownership scheme"), + message: I18n.t("validations.not_answered", question: "purchase made under ownership scheme."), category: :setup, }, on: :after_log @@ -343,7 +344,7 @@ class BulkUpload::Sales::Year2024::RowParser validates :field_9, presence: { - message: I18n.t("validations.not_answered", question: "type of shared ownership sale"), + message: I18n.t("validations.not_answered", question: "type of shared ownership sale."), category: :setup, if: :shared_ownership?, }, @@ -360,7 +361,7 @@ class BulkUpload::Sales::Year2024::RowParser validates :field_10, presence: { - message: I18n.t("validations.not_answered", question: "type of discounted ownership sale"), + message: I18n.t("validations.not_answered", question: "type of discounted ownership sale."), category: :setup, if: :discounted_ownership?, }, @@ -386,7 +387,7 @@ class BulkUpload::Sales::Year2024::RowParser validates :field_11, presence: { - message: I18n.t("validations.not_answered", question: "type of outright sale"), + message: I18n.t("validations.not_answered", question: "type of outright sale."), category: :setup, if: :outright_sale?, }, @@ -394,7 +395,7 @@ class BulkUpload::Sales::Year2024::RowParser validates :field_12, presence: { - message: I18n.t("validations.not_answered", question: "type of outright sale"), + message: I18n.t("validations.not_answered", question: "type of outright sale."), category: :setup, if: proc { field_11 == 12 }, }, @@ -411,7 +412,7 @@ class BulkUpload::Sales::Year2024::RowParser validates :field_13, presence: { - message: I18n.t("validations.not_answered", question: "company buyer"), + message: I18n.t("validations.not_answered", question: "company buyer."), category: :setup, if: :outright_sale?, }, @@ -428,7 +429,7 @@ class BulkUpload::Sales::Year2024::RowParser validates :field_14, presence: { - message: I18n.t("validations.not_answered", question: "buyers living in property"), + message: I18n.t("validations.not_answered", question: "buyers living in property."), category: :setup, if: :outright_sale?, }, @@ -436,7 +437,7 @@ class BulkUpload::Sales::Year2024::RowParser validates :field_15, presence: { - message: I18n.t("validations.not_answered", question: "joint purchase"), + message: I18n.t("validations.not_answered", question: "joint purchase."), category: :setup, if: :joint_purchase_asked?, }, @@ -444,7 +445,7 @@ class BulkUpload::Sales::Year2024::RowParser validates :field_16, presence: { - message: I18n.t("validations.not_answered", question: "more than 2 joint buyers"), + message: I18n.t("validations.not_answered", question: "more than 2 joint buyers."), category: :setup, if: :joint_purchase?, }, @@ -602,7 +603,7 @@ private def validate_uprn_exists_if_any_key_address_fields_are_blank if field_22.blank? && !key_address_fields_provided? - errors.add(:field_22, I18n.t("validations.not_answered", question: "UPRN")) + errors.add(:field_22, I18n.t("validations.not_answered", question: "UPRN.")) end end @@ -621,19 +622,19 @@ private def validate_address_fields if field_22.blank? || log.errors.attribute_names.include?(:uprn) if field_23.blank? - errors.add(:field_23, I18n.t("validations.not_answered", question: "address line 1")) + errors.add(:field_23, I18n.t("validations.not_answered", question: "address line 1.")) end if field_25.blank? - errors.add(:field_25, I18n.t("validations.not_answered", question: "town or city")) + errors.add(:field_25, I18n.t("validations.not_answered", question: "town or city.")) end if field_27.blank? - errors.add(:field_27, I18n.t("validations.not_answered", question: "part 1 of postcode")) + errors.add(:field_27, I18n.t("validations.not_answered", question: "part 1 of postcode.")) end if field_28.blank? - errors.add(:field_28, I18n.t("validations.not_answered", question: "part 2 of postcode")) + errors.add(:field_28, I18n.t("validations.not_answered", question: "part 2 of postcode.")) end end end @@ -1277,7 +1278,7 @@ private block_log_creation! if errors[:field_1].blank? - errors.add(:field_1, I18n.t("validations.not_answered", question: "owning organisation"), category: :setup) + errors.add(:field_1, I18n.t("validations.not_answered", question: "owning organisation."), category: :setup) end end end @@ -1406,13 +1407,13 @@ private fields.each do |field| if errors[field].none? block_log_creation! - errors.add(field, I18n.t("validations.invalid_option", question: QUESTIONS[field]), category: :setup) + errors.add(field, I18n.t("validations.invalid_option", question: format_ending(QUESTIONS[field])), category: :setup) end end else fields.each do |field| unless errors.any? { |e| fields.include?(e.attribute) } - errors.add(field, I18n.t("validations.invalid_option", question: QUESTIONS[field])) + errors.add(field, I18n.t("validations.invalid_option", question: format_ending(QUESTIONS[field]))) end end end diff --git a/app/services/uprn_client.rb b/app/services/uprn_client.rb index edc91ffb7..97dc4753f 100644 --- a/app/services/uprn_client.rb +++ b/app/services/uprn_client.rb @@ -13,10 +13,10 @@ class UprnClient def call unless response.is_a?(Net::HTTPSuccess) && result.present? - @error = "UPRN is not recognised. Check the number, or enter the address" + @error = "UPRN is not recognised. Check the number, or enter the address." end rescue JSON::ParserError - @error = "UPRN is not recognised. Check the number, or enter the address" + @error = "UPRN is not recognised. Check the number, or enter the address." end def result diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index e40af1d37..58d68497c 100644 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -3,56 +3,56 @@ en: devise: confirmations: - confirmed: "Your email address has been successfully confirmed" - send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes" - send_paranoid_instructions: "If your email address exists in our database, you will receive an email in a few minutes with instructions for how to confirm your email address" + confirmed: "Your email address has been successfully confirmed." + send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." + send_paranoid_instructions: "If your email address exists in our database, you will receive an email in a few minutes with instructions for how to confirm your email address." failure: - already_authenticated: "You are already signed in" - inactive: "Your account has not been activated yet" - invalid: "Incorrect %{authentication_keys} or password" + already_authenticated: "You are already signed in." + inactive: "Your account has not been activated yet." + invalid: "Incorrect %{authentication_keys} or password." locked: "Your account has been locked." - last_attempt: "You have one more attempt before your account is locked" - not_found_in_database: "Incorrect %{authentication_keys} or password" + last_attempt: "You have one more attempt before your account is locked." + not_found_in_database: "Incorrect %{authentication_keys} or password." timeout: "Your session expired. Sign in again to continue." - unauthenticated: "You need to sign in or sign up before continuing" - unconfirmed: "You must confirm your email address before continuing" + unauthenticated: "You need to sign in or sign up before continuing." + unconfirmed: "You must confirm your email address before continuing." mailer: confirmation_instructions: - subject: "Confirmation instructions" + subject: "Confirmation instructions." reset_password_instructions: - subject: "Reset password instructions" + subject: "Reset password instructions." unlock_instructions: - subject: "Unlock instructions" + subject: "Unlock instructions." email_changed: - subject: "Email successfully changed" + subject: "Email successfully changed." password_change: - subject: "Password successfully changed" + subject: "Password successfully changed." omniauth_callbacks: failure: 'We could not authenticate you from %{kind} because "%{reason}"' - success: "Successfully authenticated from %{kind} account" + success: "Successfully authenticated from %{kind} account." passwords: no_token: "You can’t access this page unless you’re trying to reset your password. Check you’re using the correct URL in the email we sent you." - send_instructions: "You will receive an email in a few minutes with instructions on how to reset your password" - send_paranoid_instructions: "If your email address exists in our database, you will receive an email in the next few minutes with a link to recover your password" + send_instructions: "You will receive an email in a few minutes with instructions on how to reset your password." + send_paranoid_instructions: "If your email address exists in our database, you will receive an email in the next few minutes with a link to recover your password." updated: "Your password has been successfully changed. You are now signed in." updated_2FA: "Your password has been successfully changed. We’ve sent you a security code." - updated_not_active: "Your password has been successfully changed" + updated_not_active: "Your password has been successfully changed." registrations: - destroyed: "Your account has been successfully cancelled" - signed_up: "You have successfully signed up for an account" + destroyed: "Your account has been successfully cancelled." + signed_up: "You have successfully signed up for an account." signed_up_but_inactive: "You have successfully signed up for an account. You won’t be able to sign in until your account is activated." signed_up_but_locked: "You have successfully signed up for an account. We could not sign you in because your account is locked." signed_up_but_unconfirmed: "We’ve sent a confirmation link to your email address. Follow the link to activate your account." update_needs_confirmation: "You successfully updated your account. We need to verify your new email address. Check your email and follow the confirmation link to confirm your new email address." - updated: "Your account has been successfully updated" + updated: "Your account has been successfully updated." updated_but_not_signed_in: "Your account has been successfully updated. You’ll need to sign in again." sessions: signed_in: "" signed_out: "" already_signed_out: "" unlocks: - send_instructions: "You will receive an email in a few minutes with instructions for how to unlock your account" - send_paranoid_instructions: "If your account exists, you will receive an email in a few minutes with instructions for how to unlock it" + send_instructions: "You will receive an email in a few minutes with instructions for how to unlock your account." + send_paranoid_instructions: "If your account exists, you will receive an email in a few minutes with instructions for how to unlock it." unlocked: "Your account has been successfully unlocked. Sign in to continue." activation: deactivated: "%{user_name} account has been deactivated." @@ -65,8 +65,8 @@ en: confirmation: "The passwords you entered do not match. Try again." confirmation_period_expired: "Email needs to be confirmed within %{period}. Request a new link below." expired: "Token has expired. Request a new token." - not_found: "was not found" - not_locked: "has not been locked" + not_found: "was not found." + not_locked: "has not been locked." not_saved: one: "One error stopped this %{resource} from being saved:" other: "%{count} errors stopped this %{resource} from being saved:" diff --git a/config/locales/en.yml b/config/locales/en.yml index 83fe1f292..764b5d687 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -446,7 +446,7 @@ en: above_hard_max: "Rent is higher than the absolute maximum expected for a property of this type based on this period." charges: complete_1_of_3: "Answer either the ‘household rent and charges’ question or ‘is this accommodation a care home‘, or select ‘no’ for ‘does the household pay rent or charges for the accommodation?’" - missing_charges: "Please enter the %{question}. If there is no %{question}, please enter '0'." + missing_charges: "Please enter the %{sentence_fragment}. If there is no %{sentence_fragment}, please enter '0'." tcharge: under_10: "Enter a total charge that is at least £10.00 per week." less_than_shortfall: "The total charge must be more than the outstanding amount." diff --git a/spec/models/form/question_spec.rb b/spec/models/form/question_spec.rb index ca67e1103..6129f46ad 100644 --- a/spec/models/form/question_spec.rb +++ b/spec/models/form/question_spec.rb @@ -375,4 +375,94 @@ RSpec.describe Form::Question, type: :model do end end end + + describe "#error_display_label" do + let(:question_with_error_label_no_punctuation) { described_class.new("address_line1_input", { "header" => "address line 1", "error_label" => "address line 1" }, page) } + let(:question_with_error_label_with_full_stop) { described_class.new("address_line1_input", { "header" => "address line 1", "error_label" => "address line 1." }, page) } + let(:question_with_error_label_with_question_mark) { described_class.new("address_line1_input", { "header" => "address line 1", "error_label" => "address line 1?" }, page) } + let(:question_with_error_label_with_brackets) { described_class.new("address_line1_input", { "header" => "address line 1", "error_label" => "(address line 1)" }, page) } + let(:question_with_error_label_with_percentage) { described_class.new("address_line1_input", { "header" => "address line 1", "error_label" => "address line 1%" }, page) } + + let(:question_with_check_answer_label_no_punctuation) { described_class.new("address_line1_input", { "header" => "address line 1", "check_answer_label" => "address line 1" }, page) } + let(:question_with_check_answer_label_with_full_stop) { described_class.new("address_line1_input", { "header" => "address line 1", "check_answer_label" => "address line 1." }, page) } + let(:question_with_check_answer_label_with_question_mark) { described_class.new("address_line1_input", { "header" => "address line 1", "check_answer_label" => "address line 1?" }, page) } + let(:question_with_check_answer_label_with_brackets) { described_class.new("address_line1_input", { "header" => "address line 1", "check_answer_label" => "(address line 1)" }, page) } + let(:question_with_check_answer_label_with_percentage) { described_class.new("address_line1_input", { "header" => "address line 1", "check_answer_label" => "address line 1%" }, page) } + + let(:question_with_header_no_punctuation) { described_class.new("address_line1_input", { "header" => "address line 1" }, page) } + let(:question_with_header_with_full_stop) { described_class.new("address_line1_input", { "header" => "address line 1." }, page) } + let(:question_with_header_with_question_mark) { described_class.new("address_line1_input", { "header" => "address line 1?" }, page) } + let(:question_with_header_with_brackets) { described_class.new("address_line1_input", { "header" => "(address line 1)" }, page) } + let(:question_with_header_with_percentage) { described_class.new("address_line1_input", { "header" => "address line 1%" }, page) } + + let(:question_with_id_only_no_punctuation) { described_class.new("address_line1_input", {}, page) } + + context "when the error label should stay the same" do + it "returns the error label unchanged with full stop" do + expect(question_with_error_label_with_full_stop.error_display_label).to eq("address line 1.") + end + + it "returns the error label unchanged with question mark" do + expect(question_with_error_label_with_question_mark.error_display_label).to eq("address line 1?") + end + + it "returns the check answer label unchanged with full stop" do + expect(question_with_check_answer_label_with_full_stop.error_display_label).to eq("address line 1.") + end + + it "returns the check answer label unchanged with question mark" do + expect(question_with_check_answer_label_with_question_mark.error_display_label).to eq("address line 1?") + end + + it "returns the header unchanged with full stop" do + expect(question_with_header_with_full_stop.error_display_label).to eq("address line 1.") + end + + it "returns the header unchanged with question mark" do + expect(question_with_header_with_question_mark.error_display_label).to eq("address line 1?") + end + end + + context "when the error label should have a full stop added" do + it "returns the error label with no punctuation changed to with a full stop" do + expect(question_with_error_label_no_punctuation.error_display_label).to eq("address line 1.") + end + + it "returns the error label with brackets changed to with a full stop" do + expect(question_with_error_label_with_brackets.error_display_label).to eq("(address line 1).") + end + + it "returns the error label with percentage changed to with a full stop" do + expect(question_with_error_label_with_percentage.error_display_label).to eq("address line 1%.") + end + + it "returns the check answer label with no punctuation changed with a full stop" do + expect(question_with_check_answer_label_no_punctuation.error_display_label).to eq("address line 1.") + end + + it "returns the check answer label with brackets changed with a full stop" do + expect(question_with_check_answer_label_with_brackets.error_display_label).to eq("(address line 1).") + end + + it "returns the check answer label with percentage changed with a full stop" do + expect(question_with_check_answer_label_with_percentage.error_display_label).to eq("address line 1%.") + end + + it "returns the header with no punctuation changed with a full stop" do + expect(question_with_header_no_punctuation.error_display_label).to eq("address line 1.") + end + + it "returns the header with brackets changed with a full stop" do + expect(question_with_header_with_brackets.error_display_label).to eq("(address line 1).") + end + + it "returns the header with percentage changed with a full stop" do + expect(question_with_header_with_percentage.error_display_label).to eq("address line 1%.") + end + + it "returns the id with no punctuation changed with a full stop" do + expect(question_with_id_only_no_punctuation.error_display_label).to eq("address line1 input.") + end + end + end end diff --git a/spec/services/bulk_upload/lettings/validator_spec.rb b/spec/services/bulk_upload/lettings/validator_spec.rb index a8773b63d..897010de6 100644 --- a/spec/services/bulk_upload/lettings/validator_spec.rb +++ b/spec/services/bulk_upload/lettings/validator_spec.rb @@ -118,7 +118,7 @@ RSpec.describe BulkUpload::Lettings::Validator do error = BulkUploadError.find_by(row: "2", field: "field_8", category: "setup") expect(error.field).to eql("field_8") - expect(error.error).to eql("You must answer tenancy start date (day)") + expect(error.error).to eql("You must answer tenancy start date (day).") expect(error.tenant_code).to eql(log.tenancycode) expect(error.property_ref).to eql(log.propcode) expect(error.row).to eql("2") @@ -161,7 +161,7 @@ RSpec.describe BulkUpload::Lettings::Validator do error = BulkUploadError.find_by(field: "field_4") expect(error.field).to eql("field_4") - expect(error.error).to eql("You must answer needs type") + expect(error.error).to eql("You must answer needs type.") expect(error.tenant_code).to eql(log.tenancycode) expect(error.property_ref).to eql(log.propcode) expect(error.row).to eql("2") diff --git a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb index 08109f4b9..6d3feffa9 100644 --- a/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb +++ b/spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb @@ -697,8 +697,8 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "fetches the question's check_answer_label if it exists" do parser.valid? - expect(parser.errors[:field_19]).to eql(["You must answer address line 1"]) - expect(parser.errors[:field_21]).to eql(["You must answer town or city"]) + expect(parser.errors[:field_19]).to eql(["You must answer address line 1."]) + expect(parser.errors[:field_21]).to eql(["You must answer town or city."]) end end end @@ -846,7 +846,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do parser.valid? expect(parser.errors[:field_5]).to be_present - expect(parser.errors[:field_11]).to eq(["You must answer intermediate rent type"]) + expect(parser.errors[:field_11]).to eq(["You must answer intermediate rent type."]) end end @@ -857,7 +857,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do parser.valid? expect(parser.errors[:field_5]).to be_present - expect(parser.errors[:field_11]).to eq(["You must answer intermediate rent type"]) + expect(parser.errors[:field_11]).to eq(["You must answer intermediate rent type."]) end end @@ -868,7 +868,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do parser.valid? expect(parser.errors[:field_5]).to be_present - expect(parser.errors[:field_10]).to eq(["You must answer is this a London Affordable Rent letting"]) + expect(parser.errors[:field_10]).to eq(["You must answer is this a London Affordable Rent letting."]) end end @@ -879,7 +879,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do parser.valid? expect(parser.errors[:field_5]).to be_present - expect(parser.errors[:field_10]).to eq(["You must answer is this a London Affordable Rent letting"]) + expect(parser.errors[:field_10]).to eq(["You must answer is this a London Affordable Rent letting."]) end end @@ -888,7 +888,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "adds error on field_12" do parser.valid? - expect(parser.errors[:field_12]).to eq(["You must answer product name"]) + expect(parser.errors[:field_12]).to eq(["You must answer product name."]) end end @@ -951,7 +951,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do parser.valid? expect(parser.errors[:field_15]).to be_blank - expect(parser.errors[:field_16]).to eq(["You must answer scheme code"]) + expect(parser.errors[:field_16]).to eq(["You must answer scheme code."]) expect(parser.errors[:field_17]).to be_blank end end @@ -992,7 +992,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do expect(parser.errors[:field_15]).to be_blank expect(parser.errors[:field_16]).to be_blank - expect(parser.errors.where(:field_17, category: :setup).map(&:message)).to eq(["You must answer location code"]) + expect(parser.errors.where(:field_17, category: :setup).map(&:message)).to eq(["You must answer location code."]) expect(parser.errors[:field_17].count).to eq(1) end end @@ -1005,7 +1005,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do expect(parser.errors[:field_16]).to be_blank expect(parser.errors[:field_17]).to be_blank - expect(parser.errors.where(:field_15, category: :setup).map(&:message)).to eq(["You must answer management group code"]) + expect(parser.errors.where(:field_15, category: :setup).map(&:message)).to eq(["You must answer management group code."]) expect(parser.errors[:field_15].count).to eq(1) end end @@ -1093,7 +1093,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do parser.valid? expect(parser.errors[:field_15]).to be_blank - expect(parser.errors[:field_16]).to include("You must answer scheme name") + expect(parser.errors[:field_16]).to include("You must answer scheme name.") expect(parser.errors[:field_17]).to be_blank end end @@ -1135,7 +1135,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do parser.valid? expect(parser.errors[:field_15]).to be_blank - expect(parser.errors.where(:field_16, category: :setup).map(&:message)).to eq(["You must answer scheme code"]) + expect(parser.errors.where(:field_16, category: :setup).map(&:message)).to eq(["You must answer scheme code."]) expect(parser.errors[:field_17]).to be_blank end end @@ -1212,7 +1212,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "clears the scheme answer" do parser.valid? - expect(parser.errors[:field_15]).to include("You must answer scheme name") + expect(parser.errors[:field_15]).to include("You must answer scheme name.") expect(parser.errors[:field_16]).to be_blank expect(parser.errors[:field_17]).to be_blank end @@ -1255,7 +1255,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "returns an error" do parser.valid? - expect(parser.errors[:field_102]).to include("Enter a valid value for What is the tenant’s main reason for the household leaving their last settled home?") + expect(parser.errors[:field_102]).to include("Enter a valid value for what is the tenant’s main reason for the household leaving their last settled home?") end end end @@ -1527,7 +1527,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "is not permitted as setup error" do parser.valid? - expect(parser.errors.where(:field_1, category: :setup).map(&:message)).to eql(["You must answer owning organisation"]) + expect(parser.errors.where(:field_1, category: :setup).map(&:message)).to eql(["You must answer owning organisation."]) end it "blocks log creation" do @@ -1692,7 +1692,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "is reported as a setup error" do parser.valid? - expect(parser.errors.where(:field_4, category: :setup).map(&:message)).to eql(["You must answer needs type"]) + expect(parser.errors.where(:field_4, category: :setup).map(&:message)).to eql(["You must answer needs type."]) end end end @@ -1703,7 +1703,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "has setup errors on the field" do parser.valid? - expect(parser.errors.where(:field_6, category: :setup).map(&:message)).to eql(["You must answer property renewal"]) + expect(parser.errors.where(:field_6, category: :setup).map(&:message)).to eql(["You must answer property renewal."]) end end @@ -1712,7 +1712,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "adds a setup error" do parser.valid? - expect(parser.errors.where(:field_6, category: :setup).map(&:message)).to include("Enter a valid value for Is this letting a renewal?") + expect(parser.errors.where(:field_6, category: :setup).map(&:message)).to include("Enter a valid value for is this letting a renewal?") end end end @@ -1723,7 +1723,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "adds an appropriate error" do parser.valid? - expect(parser.errors[:field_18]).to eql(["UPRN is not recognised. Check the number, or enter the address"]) + expect(parser.errors[:field_18]).to eql(["UPRN is not recognised. Check the number, or enter the address."]) end end @@ -1733,9 +1733,9 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "adds appropriate errors" do parser.valid? - expect(parser.errors[:field_18]).to eql(["You must answer UPRN"]) - expect(parser.errors[:field_19]).to eql(["You must answer address line 1"]) - expect(parser.errors[:field_21]).to eql(["You must answer town or city"]) + expect(parser.errors[:field_18]).to eql(["You must answer UPRN."]) + expect(parser.errors[:field_19]).to eql(["You must answer address line 1."]) + expect(parser.errors[:field_21]).to eql(["You must answer town or city."]) end end @@ -1811,7 +1811,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "populates with correct error message" do parser.valid? - expect(parser.errors[:field_30]).to eql(["You must answer type of building"]) + expect(parser.errors[:field_30]).to eql(["You must answer type of building."]) end end end @@ -2160,7 +2160,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "adds an error" do parser.valid? - expect(parser.errors[:field_116]).to include("Enter a valid value for was the letting made under the Choice-Based Lettings (CBL)") + expect(parser.errors[:field_116]).to include("Enter a valid value for was the letting made under the Choice-Based Lettings (CBL)?") end end end @@ -2187,7 +2187,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "adds an error" do parser.valid? - expect(parser.errors[:field_118]).to include("Enter a valid value for was the letting made under the Common Housing Register (CHR)") + expect(parser.errors[:field_118]).to include("Enter a valid value for was the letting made under the Common Housing Register (CHR)?") end end end @@ -2214,7 +2214,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do it "adds an error" do parser.valid? - expect(parser.errors[:field_117]).to include("Enter a valid value for was the letting made under the Common Allocation Policy (CAP)") + expect(parser.errors[:field_117]).to include("Enter a valid value for was the letting made under the Common Allocation Policy (CAP)?") end end end diff --git a/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb b/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb index 025d44d4a..596712162 100644 --- a/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb +++ b/spec/services/bulk_upload/lettings/year2024/row_parser_spec.rb @@ -770,7 +770,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "fetches the question's check_answer_label if it exists" do parser.valid? - expect(parser.errors[:field_43]).to eql(["You must answer lead tenant’s gender identity"]) + expect(parser.errors[:field_43]).to eql(["You must answer lead tenant’s gender identity."]) end end @@ -915,8 +915,8 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "cannot be nulled" do parser.valid? - expect(parser.errors[:field_5]).to eq(["You must answer scheme code"]) - expect(parser.errors[:field_6]).to eq(["You must answer location code"]) + expect(parser.errors[:field_5]).to eq(["You must answer scheme code."]) + expect(parser.errors[:field_6]).to eq(["You must answer location code."]) end end @@ -952,7 +952,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "returns a setup error" do expect(parser.errors[:field_5]).to be_blank - expect(parser.errors.where(:field_6, category: :setup).map(&:message)).to eq(["You must answer location code"]) + expect(parser.errors.where(:field_6, category: :setup).map(&:message)).to eq(["You must answer location code."]) expect(parser.errors[:field_6].count).to eq(1) end end @@ -1021,7 +1021,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do let(:attributes) { { bulk_upload:, field_4: "2", field_11: "2", field_5: "S#{managing_org_scheme.id}", field_6: managing_org_location.id, field_2: managing_org.old_visible_id } } it "clears the scheme answer" do - expect(parser.errors[:field_5]).to include("You must answer scheme name") + expect(parser.errors[:field_5]).to include("You must answer scheme name.") expect(parser.errors[:field_6]).to be_blank end end @@ -1091,7 +1091,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "returns an error" do parser.valid? - expect(parser.errors[:field_98]).to include("Enter a valid value for What is the tenant’s main reason for the household leaving their last settled home?") + expect(parser.errors[:field_98]).to include("Enter a valid value for what is the tenant’s main reason for the household leaving their last settled home?") end end end @@ -1358,7 +1358,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "is not permitted as setup error" do parser.valid? - expect(parser.errors.where(:field_1, category: :setup).map(&:message)).to eql(["You must answer owning organisation"]) + expect(parser.errors.where(:field_1, category: :setup).map(&:message)).to eql(["You must answer owning organisation."]) end it "blocks log creation" do @@ -1514,7 +1514,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do setup_errors = parser.errors.select { |e| e.options[:category] == :setup } - expect(setup_errors.find { |e| e.attribute == :field_2 }.message).to eql("You must answer managing organisation") + expect(setup_errors.find { |e| e.attribute == :field_2 }.message).to eql("You must answer managing organisation.") end it "blocks log creation" do @@ -1566,7 +1566,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "is reported as a setup error" do parser.valid? - expect(parser.errors.where(:field_4, category: :setup).map(&:message)).to eql(["You must answer needs type"]) + expect(parser.errors.where(:field_4, category: :setup).map(&:message)).to eql(["You must answer needs type."]) end end end @@ -1577,7 +1577,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "has setup errors on the field" do parser.valid? - expect(parser.errors.where(:field_7, category: :setup).map(&:message)).to eql(["You must answer property renewal"]) + expect(parser.errors.where(:field_7, category: :setup).map(&:message)).to eql(["You must answer property renewal."]) end end @@ -1586,7 +1586,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "adds a setup error" do parser.valid? - expect(parser.errors.where(:field_7, category: :setup).map(&:message)).to include("Enter a valid value for Is this letting a renewal?") + expect(parser.errors.where(:field_7, category: :setup).map(&:message)).to include("Enter a valid value for is this letting a renewal?") end end end @@ -1617,10 +1617,10 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "adds errors to missing key address fields" do parser.valid? - expect(parser.errors[:field_17]).to eql(["You must answer address line 1"]) - expect(parser.errors[:field_19]).to eql(["You must answer town or city"]) - expect(parser.errors[:field_21]).to eql(["You must answer part 1 of postcode"]) - expect(parser.errors[:field_22]).to eql(["You must answer part 2 of postcode"]) + expect(parser.errors[:field_17]).to eql(["You must answer address line 1."]) + expect(parser.errors[:field_19]).to eql(["You must answer town or city."]) + expect(parser.errors[:field_21]).to eql(["You must answer part 1 of postcode."]) + expect(parser.errors[:field_22]).to eql(["You must answer part 2 of postcode."]) end end @@ -1648,11 +1648,11 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "adds appropriate errors to UPRN and key address fields" do parser.valid? - expect(parser.errors[:field_16]).to eql(["You must answer UPRN"]) - expect(parser.errors[:field_17]).to eql(["You must answer address line 1"]) - expect(parser.errors[:field_19]).to eql(["You must answer town or city"]) - expect(parser.errors[:field_21]).to eql(["You must answer part 1 of postcode"]) - expect(parser.errors[:field_22]).to eql(["You must answer part 2 of postcode"]) + expect(parser.errors[:field_16]).to eql(["You must answer UPRN."]) + expect(parser.errors[:field_17]).to eql(["You must answer address line 1."]) + expect(parser.errors[:field_19]).to eql(["You must answer town or city."]) + expect(parser.errors[:field_21]).to eql(["You must answer part 1 of postcode."]) + expect(parser.errors[:field_22]).to eql(["You must answer part 2 of postcode."]) end end @@ -1661,8 +1661,8 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "adds errors to UPRN and the missing key address field" do parser.valid? - expect(parser.errors[:field_16]).to eql(["You must answer UPRN"]) - expect(parser.errors[:field_17]).to eql(["You must answer address line 1"]) + expect(parser.errors[:field_16]).to eql(["You must answer UPRN."]) + expect(parser.errors[:field_17]).to eql(["You must answer address line 1."]) expect(parser.errors[:field_19]).to be_empty expect(parser.errors[:field_21]).to be_empty expect(parser.errors[:field_22]).to be_empty @@ -1755,7 +1755,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "populates with correct error message" do parser.valid? - expect(parser.errors[:field_27]).to eql(["You must answer type of building"]) + expect(parser.errors[:field_27]).to eql(["You must answer type of building."]) end end end @@ -2175,7 +2175,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "adds an error" do parser.valid? - expect(parser.errors[:field_112]).to include("Enter a valid value for was the letting made under the Choice-Based Lettings (CBL)") + expect(parser.errors[:field_112]).to include("Enter a valid value for was the letting made under the Choice-Based Lettings (CBL)?") end end end @@ -2202,7 +2202,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "adds an error" do parser.valid? - expect(parser.errors[:field_114]).to include("Enter a valid value for was the letting made under the Common Housing Register (CHR)") + expect(parser.errors[:field_114]).to include("Enter a valid value for was the letting made under the Common Housing Register (CHR)?") end end end @@ -2229,7 +2229,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "adds an error" do parser.valid? - expect(parser.errors[:field_113]).to include("Enter a valid value for was the letting made under the Common Allocation Policy (CAP)") + expect(parser.errors[:field_113]).to include("Enter a valid value for was the letting made under the Common Allocation Policy (CAP)?") end end end @@ -2256,7 +2256,7 @@ RSpec.describe BulkUpload::Lettings::Year2024::RowParser do it "adds an error" do parser.valid? - expect(parser.errors[:field_115]).to include("Enter a valid value for was the letting made under the Accessible Register") + expect(parser.errors[:field_115]).to include("Enter a valid value for was the letting made under the Accessible Register?") end end end diff --git a/spec/services/bulk_upload/sales/validator_spec.rb b/spec/services/bulk_upload/sales/validator_spec.rb index f968f5661..d196126c9 100644 --- a/spec/services/bulk_upload/sales/validator_spec.rb +++ b/spec/services/bulk_upload/sales/validator_spec.rb @@ -137,7 +137,7 @@ RSpec.describe BulkUpload::Sales::Validator do error = BulkUploadError.find_by(row: "2", field: "field_1", category: "setup") expect(error.field).to eql("field_1") - expect(error.error).to eql("You must answer owning organisation") + expect(error.error).to eql("You must answer owning organisation.") expect(error.purchaser_code).to eql(log.purchaser_code) expect(error.row).to eql("2") expect(error.cell).to eql("B2") diff --git a/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb index 7d7c62885..d5b6aa718 100644 --- a/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2023/row_parser_spec.rb @@ -406,7 +406,7 @@ RSpec.describe BulkUpload::Sales::Year2023::RowParser do let(:attributes) { setup_section_params.merge(field_1: nil) } it "is not permitted as setup error" do - expect(parser.errors.where(:field_1, category: :setup).map(&:message)).to eql(["You must answer owning organisation"]) + expect(parser.errors.where(:field_1, category: :setup).map(&:message)).to eql(["You must answer owning organisation."]) end it "blocks log creation" do @@ -418,7 +418,7 @@ RSpec.describe BulkUpload::Sales::Year2023::RowParser do let(:attributes) { { bulk_upload:, field_1: "donotexist" } } it "is not permitted as a setup error" do - expect(parser.errors.where(:field_1, category: :setup).map(&:message)).to eql(["You must answer owning organisation"]) + expect(parser.errors.where(:field_1, category: :setup).map(&:message)).to eql(["You must answer owning organisation."]) end it "blocks log creation" do @@ -1041,7 +1041,7 @@ RSpec.describe BulkUpload::Sales::Year2023::RowParser do let(:attributes) { setup_section_params.merge(field_105: "4") } it "returns correct errors" do - expect(parser.errors[:field_105]).to include("Enter a valid value for Was a mortgage used for the purchase of this property? - Shared ownership") + expect(parser.errors[:field_105]).to include("Enter a valid value for was a mortgage used for the purchase of this property? - Shared ownership.") parser.log.blank_invalid_non_setup_fields! parser.log.save! expect(parser.log.mortgageused).to be_nil diff --git a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb index f68ec9e9a..3c4e71247 100644 --- a/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb +++ b/spec/services/bulk_upload/sales/year2024/row_parser_spec.rb @@ -301,7 +301,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do it "fetches the question's check_answer_label if it exists" do parser.valid? - expect(parser.errors[:field_32]).to eql(["You must answer buyer 1’s gender identity"]) + expect(parser.errors[:field_32]).to eql(["You must answer buyer 1’s gender identity."]) end end @@ -310,7 +310,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do it "only has one error added to the field" do parser.valid? - expect(parser.errors[:field_23]).to eql(["You must answer address line 1"]) + expect(parser.errors[:field_23]).to eql(["You must answer address line 1."]) end end @@ -463,7 +463,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do it "is not permitted as setup error" do parser.valid? - expect(parser.errors.where(:field_1, category: :setup).map(&:message)).to eql(["You must answer owning organisation"]) + expect(parser.errors.where(:field_1, category: :setup).map(&:message)).to eql(["You must answer owning organisation."]) end it "blocks log creation" do @@ -1001,10 +1001,10 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do it "adds errors to missing key address fields" do parser.valid? - expect(parser.errors[:field_23]).to eql(["You must answer address line 1"]) - expect(parser.errors[:field_25]).to eql(["You must answer town or city"]) - expect(parser.errors[:field_27]).to eql(["You must answer part 1 of postcode"]) - expect(parser.errors[:field_28]).to eql(["You must answer part 2 of postcode"]) + expect(parser.errors[:field_23]).to eql(["You must answer address line 1."]) + expect(parser.errors[:field_25]).to eql(["You must answer town or city."]) + expect(parser.errors[:field_27]).to eql(["You must answer part 1 of postcode."]) + expect(parser.errors[:field_28]).to eql(["You must answer part 2 of postcode."]) end end @@ -1032,11 +1032,11 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do it "adds appropriate errors to UPRN and key address fields" do parser.valid? - expect(parser.errors[:field_22]).to eql(["You must answer UPRN"]) - expect(parser.errors[:field_23]).to eql(["You must answer address line 1"]) - expect(parser.errors[:field_25]).to eql(["You must answer town or city"]) - expect(parser.errors[:field_27]).to eql(["You must answer part 1 of postcode"]) - expect(parser.errors[:field_28]).to eql(["You must answer part 2 of postcode"]) + expect(parser.errors[:field_22]).to eql(["You must answer UPRN."]) + expect(parser.errors[:field_23]).to eql(["You must answer address line 1."]) + expect(parser.errors[:field_25]).to eql(["You must answer town or city."]) + expect(parser.errors[:field_27]).to eql(["You must answer part 1 of postcode."]) + expect(parser.errors[:field_28]).to eql(["You must answer part 2 of postcode."]) end end @@ -1045,8 +1045,8 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do it "adds errors to UPRN and the missing key address field" do parser.valid? - expect(parser.errors[:field_22]).to eql(["You must answer UPRN"]) - expect(parser.errors[:field_23]).to eql(["You must answer address line 1"]) + expect(parser.errors[:field_22]).to eql(["You must answer UPRN."]) + expect(parser.errors[:field_23]).to eql(["You must answer address line 1."]) expect(parser.errors[:field_25]).to be_empty expect(parser.errors[:field_27]).to be_empty expect(parser.errors[:field_28]).to be_empty @@ -1323,7 +1323,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do it "returns correct errors" do parser.valid? - expect(parser.errors[:field_103]).to include("Enter a valid value for Was a mortgage used for the purchase of this property? - Shared ownership") + expect(parser.errors[:field_103]).to include("Enter a valid value for was a mortgage used for the purchase of this property? - Shared ownership.") parser.log.blank_invalid_non_setup_fields! parser.log.save! @@ -1973,7 +1973,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do parser.valid? setup_errors = parser.errors.select { |e| e.options[:category] == :setup } - expect(setup_errors.find { |e| e.attribute == :field_2 }.message).to eql("You must answer reported by") + expect(setup_errors.find { |e| e.attribute == :field_2 }.message).to eql("You must answer reported by.") end it "blocks log creation" do @@ -1989,7 +1989,7 @@ RSpec.describe BulkUpload::Sales::Year2024::RowParser do parser.valid? setup_errors = parser.errors.select { |e| e.options[:category] == :setup } - expect(setup_errors.find { |e| e.attribute == :field_2 }.message).to eql("You must answer reported by") + expect(setup_errors.find { |e| e.attribute == :field_2 }.message).to eql("You must answer reported by.") end it "blocks log creation" do diff --git a/spec/services/uprn_client_spec.rb b/spec/services/uprn_client_spec.rb index 3189c455b..b10ab7376 100644 --- a/spec/services/uprn_client_spec.rb +++ b/spec/services/uprn_client_spec.rb @@ -21,7 +21,7 @@ describe UprnClient do end it "returns error" do - expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address") + expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address.") end end @@ -33,7 +33,7 @@ describe UprnClient do end it "returns error" do - expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address") + expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address.") end end @@ -66,7 +66,7 @@ describe UprnClient do end it "returns error" do - expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address") + expect(client.error).to eq("UPRN is not recognised. Check the number, or enter the address.") end end end