diff --git a/app/models/school.rb b/app/models/school.rb index 0b005aaeb..8b575e3c5 100644 --- a/app/models/school.rb +++ b/app/models/school.rb @@ -30,6 +30,8 @@ class School < ApplicationRecord before_validation :normalize_reference + before_save :format_uk_postal_code, if: :should_format_uk_postal_code? + def self.find_for_user!(user) school = Role.find_by(user_id: user.id)&.school || find_by(creator_id: user.id) raise ActiveRecord::RecordNotFound unless school @@ -65,6 +67,10 @@ def reject update(rejected_at: Time.zone.now) end + def postal_code=(str) + super(str.to_s.upcase) + end + private # Ensure the reference is nil, not an empty string @@ -83,4 +89,15 @@ def rejected_at_cannot_be_changed def code_cannot_be_changed errors.add(:code, 'cannot be changed after verification') if code_was.present? && code_changed? end + + def should_format_uk_postal_code? + country_code == 'GB' && postal_code.to_s.length >= 5 + end + + def format_uk_postal_code + cleaned_postal_code = postal_code.delete(' ') + # insert a space as the third-from-last character in the postcode, eg. SW1A1AA -> SW1A 1AA + # ensures UK postcodes are always formatted correctly (as the inward code is always 3 chars long) + self.postal_code = "#{cleaned_postal_code[0..-4]} #{cleaned_postal_code[-3..]}" + end end diff --git a/spec/models/school_spec.rb b/spec/models/school_spec.rb index 6f69239db..0b180f9f6 100644 --- a/spec/models/school_spec.rb +++ b/spec/models/school_spec.rb @@ -331,6 +331,51 @@ end end + describe '#format_uk_postal_code' do + it 'retains correctly formatted UK postal_code' do + school.country_code = 'GB' + school.postal_code = 'SW1A 1AA' + school.save + expect(school.postal_code).to eq('SW1A 1AA') + end + + it 'corrects incorrectly formatted UK postal_code' do + school.country_code = 'GB' + school.postal_code = 'SW1 A1AA' + expect { school.save }.to change(school, :postal_code).to('SW1A 1AA') + end + + it 'formats UK postal_code with 4 char outcode' do + school.country_code = 'GB' + school.postal_code = 'SW1A1AA' + expect { school.save }.to change(school, :postal_code).to('SW1A 1AA') + end + + it 'formats UK postal_code with 3 char outcode' do + school.country_code = 'GB' + school.postal_code = 'SW11AA' + expect { school.save }.to change(school, :postal_code).to('SW1 1AA') + end + + it 'formats UK postal_code with 2 char outcode' do + school.country_code = 'GB' + school.postal_code = 'SW1AA' + expect { school.save }.to change(school, :postal_code).to('SW 1AA') + end + + it 'does not format UK postal_code for short / invalid codes' do + school.country_code = 'GB' + school.postal_code = 'SW1A' + expect { school.save }.not_to change(school, :postal_code) + end + + it 'does not format postal_code for non-UK countries' do + school.country_code = 'FR' + school.postal_code = '123456' + expect { school.save }.not_to change(school, :postal_code) + end + end + describe '#reject' do it 'sets rejected_at to the current time' do school.reject