-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Split CbvApplicant into three STI subclasses #451
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class CbvApplicant::Ma < CbvApplicant | ||
# Massachusetts: 7 digits | ||
MA_AGENCY_ID_REGEX = /\A\d{7}\z/ | ||
|
||
# Massachusetts: 6 alphanumeric characters | ||
MA_BEACON_ID_REGEX = /\A[a-zA-Z0-9]{6}\z/ | ||
|
||
validates :agency_id_number, format: { with: MA_AGENCY_ID_REGEX, message: :invalid_format } | ||
validates :beacon_id, format: { with: MA_BEACON_ID_REGEX, message: :invalid_format } | ||
validates :snap_application_date, | ||
inclusion: { in: Date.current.prev_year..Date.current, message: :invalid_date }, | ||
if: -> { snap_application_date.present? } | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
class CbvApplicant::Nyc < CbvApplicant | ||
# New York City: 11 digits followed by 1 uppercase letter | ||
NYC_CASE_NUMBER_REGEX = /\A\d{11}[A-Z]\z/ | ||
|
||
# New York City: 2 uppercase letters, followed by 5 digits, followed by 1 uppercase letter | ||
NYC_CLIENT_ID_REGEX = /\A[A-Z]{2}\d{5}[A-Z]\z/ | ||
|
||
before_validation :format_case_number | ||
|
||
validates :case_number, format: { with: NYC_CASE_NUMBER_REGEX, message: :invalid_format } | ||
validates :client_id_number, format: { with: NYC_CLIENT_ID_REGEX, message: :invalid_format } | ||
validates :snap_application_date, | ||
inclusion: { in: (Date.current - 30.days)..Date.current, message: :invalid_date }, | ||
if: -> { snap_application_date.present? } | ||
|
||
def format_case_number | ||
return if case_number.blank? | ||
case_number.upcase! | ||
if case_number.length == 9 | ||
self.case_number = "000#{case_number}" | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
class CbvApplicant::Sandbox < CbvApplicant | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,24 +4,41 @@ en: | |
errors: | ||
models: | ||
cbv_applicant: | ||
attributes: | ||
first_name: | ||
blank: Enter the client's first name. | ||
last_name: | ||
blank: Enter the client's last name. | ||
snap_application_date: | ||
invalid_date: Enter today's date or the date you contacted the client. | ||
cbv_applicant/ma: | ||
attributes: | ||
agency_id_number: | ||
blank: Enter a valid agency ID number. | ||
invalid_format: Agency ID number must be 7 digits. | ||
beacon_id: | ||
invalid_format: Your WELID must be 6 characters. It can only include letters and numbers. | ||
snap_application_date: | ||
invalid_date: Enter today's date or the date you contacted the client. This date must be today or in the past year. | ||
cbv_applicant/nyc: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. my MDR sense is that this is "scary," but IDk why — it's unusual. Why does it work? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Rails i18n gem is mysterious and important. In this case, it's because the validation error message lookup logic is aware of potential STI ancestors and tries multiple different keys until it finds one that matches. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ahhh. i see. the inheriting model serializes its name with the slash. fascinating thx |
||
attributes: | ||
case_number: | ||
invalid_format: Enter the case number in the ANGIE/sPOS format, i.e. 00012345678A. | ||
client_id_number: | ||
invalid_format: Enter the client's CIN in the correct format, XX00000X. | ||
first_name: | ||
blank: Enter the client's first name. | ||
last_name: | ||
blank: Enter the client's last name. | ||
snap_application_date: | ||
default_invalid_date: Enter today's date or the date you contacted the client. | ||
ma_invalid_date: Enter today's date or the date you contacted the client. This date must be today or in the past year. | ||
nyc_invalid_date: SNAP interview date must be today or in the past 30 days. | ||
invalid_date: SNAP interview date must be today or in the past 30 days. | ||
cbv_applicant/sandbox: | ||
attributes: | ||
agency_id_number: | ||
blank: Enter a valid agency ID number. | ||
invalid_format: Agency ID number must be 7 digits. | ||
beacon_id: | ||
invalid_format: Your WELID must be 6 characters. It can only include letters and numbers. | ||
case_number: | ||
invalid_format: Enter the case number in the ANGIE/sPOS format, i.e. 00012345678A. | ||
client_id_number: | ||
invalid_format: Enter the client's CIN in the correct format, XX00000X. | ||
cbv_flow_invitation: | ||
attributes: | ||
email_address: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
require 'rails_helper' | ||
|
||
RSpec.describe CbvApplicant::Ma, type: :model do | ||
let(:ma_attributes) { attributes_for(:cbv_applicant, :ma) } | ||
|
||
context "user input is invalid" do | ||
it "requires agency_id_number" do | ||
applicant = CbvApplicant.new(ma_attributes.without(:agency_id_number)) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:agency_id_number]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/ma.attributes.agency_id_number.invalid_format'), | ||
) | ||
end | ||
|
||
it "requires beacon_id" do | ||
applicant = CbvApplicant.new(ma_attributes.without(:beacon_id)) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:beacon_id]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/ma.attributes.beacon_id.invalid_format') | ||
) | ||
end | ||
|
||
it "requires beacon_id to have 6 alphanumeric characters" do | ||
applicant = CbvApplicant.new(ma_attributes.merge(beacon_id: '12345')) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:beacon_id]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/ma.attributes.beacon_id.invalid_format') | ||
) | ||
end | ||
|
||
it "validates agency_id_number format" do | ||
applicant = CbvApplicant.new(ma_attributes.merge(agency_id_number: 'invalid')) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:agency_id_number]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/ma.attributes.agency_id_number.invalid_format') | ||
) | ||
end | ||
|
||
it "does not require client_id_number" do | ||
applicant = CbvApplicant.new(ma_attributes.merge(client_id_number: nil)) | ||
expect(applicant).to be_valid | ||
expect(applicant.errors[:client_id_number]).to be_empty | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
require 'rails_helper' | ||
|
||
RSpec.describe CbvApplicant::Nyc, type: :model do | ||
let(:nyc_attributes) { attributes_for(:cbv_applicant, :nyc) } | ||
|
||
context "user input is valid" do | ||
it "formats a 9-character case number with leading zeros" do | ||
applicant = CbvApplicant.new(nyc_attributes.merge(case_number: '12345678A')) | ||
expect(applicant).to be_valid | ||
expect(applicant.case_number).to eq('00012345678A') | ||
end | ||
|
||
it "converts case number to uppercase" do | ||
applicant = CbvApplicant.new(nyc_attributes.merge(case_number: '12345678a')) | ||
expect(applicant).to be_valid | ||
expect(applicant.case_number).to eq('00012345678A') | ||
end | ||
|
||
it "validates snap_application_date is not older than 30 days" do | ||
applicant = CbvApplicant.new(nyc_attributes.merge(snap_application_date: 31.days.ago)) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:snap_application_date]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/nyc.attributes.snap_application_date.invalid_date') | ||
) | ||
end | ||
end | ||
|
||
context "user input is invalid" do | ||
it "requires case_number" do | ||
applicant = CbvApplicant.new(nyc_attributes.merge(case_number: nil)) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:case_number]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/nyc.attributes.case_number.invalid_format'), | ||
) | ||
end | ||
|
||
it "validates invalid case_number format" do | ||
applicant = CbvApplicant.new(nyc_attributes.merge(case_number: 'invalid')) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:case_number]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/nyc.attributes.case_number.invalid_format') | ||
) | ||
end | ||
|
||
it "checks that a shorter case number is invalid" do | ||
applicant = CbvApplicant.new(nyc_attributes.merge(case_number: '123A')) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:case_number]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/nyc.attributes.case_number.invalid_format') | ||
) | ||
end | ||
|
||
it "validates an invalid 11 char string" do | ||
applicant = CbvApplicant.new(nyc_attributes.merge(case_number: '1234567890A')) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.case_number).to eq('1234567890A') | ||
end | ||
|
||
it "validates client_id_number format when present" do | ||
applicant = CbvApplicant.new(nyc_attributes.merge(client_id_number: 'invalid')) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:client_id_number]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/nyc.attributes.client_id_number.invalid_format') | ||
) | ||
end | ||
|
||
it "requires valid snap_application_date" do | ||
applicant = CbvApplicant.new(nyc_attributes.merge(snap_application_date: "invalid")) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:snap_application_date]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/nyc.attributes.snap_application_date.invalid_date') | ||
) | ||
end | ||
|
||
it "requires client_id_number" do | ||
applicant = CbvApplicant.new(nyc_attributes.merge(client_id_number: nil)) | ||
expect(applicant).not_to be_valid | ||
expect(applicant.errors[:client_id_number]).to include( | ||
I18n.t('activerecord.errors.models.cbv_applicant/nyc.attributes.client_id_number.invalid_format') | ||
) | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this would be the error that's given for agencies that are not STI? i.e.
sandbox
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it's the default used when an STI subclass doesn't override it (as
cbv_applicant/ma
andcbv_applicant/nyc
both do.)