From c6df4e4eadb6883714909400c84ea91b4e78f95c Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Fri, 28 Jun 2024 10:33:59 +0100 Subject: [PATCH 1/2] Add eligibility check for contract start date We want to reject claimants if their contract start date is earlier than 6 months before the autumn term. This commit updates the eligibility checker to do so and also adds some missing tests. --- app/models/academic_year.rb | 14 +- .../eligibility.rb | 14 +- .../policy_eligibility_checker.rb | 12 ++ ...eligible_route_completing_the_form_spec.rb | 14 +- .../teacher_route_completing_the_form_spec.rb | 3 +- spec/models/academic_year_spec.rb | 6 + .../policy_eligibility_checker_spec.rb | 139 +++++++++++++++++- 7 files changed, 179 insertions(+), 23 deletions(-) diff --git a/app/models/academic_year.rb b/app/models/academic_year.rb index 069a282531..a0588564e7 100644 --- a/app/models/academic_year.rb +++ b/app/models/academic_year.rb @@ -15,6 +15,9 @@ class AcademicYear ACADEMIC_YEAR_REGEXP = /\A20\d{2}\/20\d{2}\z/ + AUTUMN_TERM_START_MONTH = 9 + AUTUMN_TERM_START_DAY = 1 + attr_reader :start_year, :end_year # Defines a custom ActiveRecord::Type for AcademicYear that means we can @@ -52,7 +55,12 @@ def next def for(date) return if date.nil? - start_of_autumn_term = Date.new(date.year, 9, 1) + start_of_autumn_term = Date.new( + date.year, + AUTUMN_TERM_START_MONTH, + AUTUMN_TERM_START_DAY + ) + if date < start_of_autumn_term new(date.year - 1) else @@ -132,4 +140,8 @@ def -(other) def +(other) AcademicYear.new(start_year + other) end + + def start_of_autumn_term + Date.new(start_year, AUTUMN_TERM_START_MONTH, AUTUMN_TERM_START_DAY) + end end diff --git a/app/models/policies/international_relocation_payments/eligibility.rb b/app/models/policies/international_relocation_payments/eligibility.rb index 932d3c009f..abe3ad997c 100644 --- a/app/models/policies/international_relocation_payments/eligibility.rb +++ b/app/models/policies/international_relocation_payments/eligibility.rb @@ -3,6 +3,15 @@ module InternationalRelocationPayments class Eligibility < ApplicationRecord self.table_name = "international_relocation_payments_eligibilities" + PRE_ACADEMIC_YEAR_WINDOW_LIMIT = 6.months + + def self.earliest_eligible_contract_start_date + Journeys::GetATeacherRelocationPayment + .configuration + .current_academic_year + .start_of_autumn_term - PRE_ACADEMIC_YEAR_WINDOW_LIMIT + end + has_one :claim, as: :eligibility, inverse_of: :eligibility def ineligible? @@ -12,11 +21,6 @@ def ineligible? def policy Policies::InternationalRelocationPayments end - - def self.earliest_eligible_contract_start_date - # FIXME RL - waiting on policy to get back to us for what this should - # be - end end end end diff --git a/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb b/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb index 300a3eda53..405f63f98d 100644 --- a/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb +++ b/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb @@ -35,6 +35,8 @@ def ineligible_reason "taught subject not accepted" in visa_type: "Other" "visa not accepted" + in start_date: Date unless contract_start_date_eligible? + "contract start date must be after #{earliest_eligible_contract_start_date}" in date_of_entry: Date, start_date: Date unless date_of_entry_eligible? "cannot enter the UK more than 3 months before your contract start date" else @@ -42,6 +44,16 @@ def ineligible_reason end end + def contract_start_date_eligible? + return false unless answers.start_date + + answers.start_date >= earliest_eligible_contract_start_date + end + + def earliest_eligible_contract_start_date + Eligibility.earliest_eligible_contract_start_date + end + def date_of_entry_eligible? return false unless answers.date_of_entry && answers.start_date diff --git a/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb b/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb index 7f3c9d0235..dcf61efe83 100644 --- a/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb +++ b/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb @@ -8,11 +8,8 @@ end let(:contract_start_date) do - Date.new( - journey_configuration.current_academic_year.start_year, - 1, - 1 - ) + Policies::InternationalRelocationPayments::Eligibility + .earliest_eligible_contract_start_date end before do @@ -63,9 +60,7 @@ end end - # FIXME RL waiting on feedback from policy team to determine what the cut - # off date is for contracts - xcontext "ineligible - contract start date" do + context "ineligible - contract start date" do it "shows the ineligible page" do when_i_start_the_form and_i_complete_application_route_question_with( @@ -74,7 +69,8 @@ and_i_complete_the_state_funded_secondary_school_step_with(option: "Yes") and_i_complete_the_contract_details_step_with(option: "Yes") and_i_complete_the_contract_start_date_step_with( - date: Polices::InternationalRelocationPayments.earliest_eligible_contract_start_date - 1.day + date: Policies::InternationalRelocationPayments::Eligibility + .earliest_eligible_contract_start_date - 1.day ) then_i_see_the_ineligible_page end diff --git a/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb b/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb index 2e4183a112..67c610239e 100644 --- a/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb +++ b/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb @@ -8,7 +8,8 @@ end let(:contract_start_date) do - Date.yesterday + Policies::InternationalRelocationPayments::Eligibility + .earliest_eligible_contract_start_date end let(:entry_date) do diff --git a/spec/models/academic_year_spec.rb b/spec/models/academic_year_spec.rb index 4724d09909..7a2f0f2816 100644 --- a/spec/models/academic_year_spec.rb +++ b/spec/models/academic_year_spec.rb @@ -186,4 +186,10 @@ expect(AcademicYear.new(2014).hash).not_to eql 2014.hash end end + + describe "#start_of_autumn_term" do + it "returns September 1st of the start year" do + expect(AcademicYear.new(2014).start_of_autumn_term).to eq Date.new(2014, 9, 1) + end + end end diff --git a/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb b/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb index 0a07362e28..758253ff2e 100644 --- a/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb +++ b/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb @@ -1,10 +1,14 @@ require "rails_helper" describe Policies::InternationalRelocationPayments::PolicyEligibilityChecker do + before do + create(:journey_configuration, :get_a_teacher_relocation_payment) + end + let(:answers) do build( :get_a_teacher_relocation_payment_answers, - application_route: application_route + attributes: attributes ) end @@ -14,19 +18,31 @@ subject { checker.status } context "when the application route is 'other'" do - let(:application_route) { "other" } + let(:attributes) do + { + application_route: "other" + } + end it { is_expected.to eq(:ineligible) } end context "when the application route is 'teacher'" do - let(:application_route) { "teacher" } + let(:attributes) do + { + application_route: "teacher" + } + end it { is_expected.to eq(:eligible_now) } end context "when the application route is 'salaried_trainee'" do - let(:application_route) { "salaried_trainee" } + let(:attributes) do + { + application_route: "salaried_trainee" + } + end it { is_expected.to eq(:ineligible) } end @@ -36,21 +52,130 @@ subject { checker.ineligible? } context "when the application route is 'other'" do - let(:application_route) { "other" } + let(:attributes) do + { + application_route: "other" + } + end it { is_expected.to eq(true) } end context "when the application route is 'teacher'" do - let(:application_route) { "teacher" } + let(:attributes) do + { + application_route: "teacher" + } + end it { is_expected.to eq(false) } end context "when the application route is 'salaried_trainee'" do - let(:application_route) { "salaried_trainee" } + let(:attributes) do + { + application_route: "salaried_trainee" + } + end + + it { is_expected.to eq(true) } + end + + context "with a non state funded secondary school" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: false + } + end + + it { is_expected.to eq(true) } + end + + context "with a contract duration of less than one year" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: false + } + end + + it { is_expected.to eq(true) } + end + + context "with a taught subject of 'other'" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + subject: "other" + } + end + + it { is_expected.to eq(true) } + end + + context "with a visa type of 'Other'" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + subject: "physics", + visa_type: "Other" + } + end + + it { is_expected.to eq(true) } + end + + context "with a contract start date before the earliest eligible date" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + subject: "physics", + visa_type: "British National (Overseas) visa", + start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 1.day + } + end it { is_expected.to eq(true) } end + + context "with an entry date more than 3 months before the contract start date" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + subject: "physics", + visa_type: "British National (Overseas) visa", + start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date, + date_of_entry: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 4.months + } + end + + it { is_expected.to eq(true) } + end + + context "with an eligible application" do + let(:attributes) do + { + application_route: "teacher", + state_funded_secondary_school: true, + one_year: true, + subject: "physics", + visa_type: "British National (Overseas) visa", + start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date, + date_of_entry: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 1.week + } + end + + it { is_expected.to eq(false) } + end end end From bceb2da17231faf5ad16f64b6c37ed4a8aa44cf3 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Mon, 1 Jul 2024 10:17:52 +0100 Subject: [PATCH 2/2] Move date to policy checker We eventually want to get rid of the policy models, storing their data on the claim itself, so the policy eligibility checker is a better home for this method. --- .../eligibility.rb | 9 --------- .../policy_eligibility_checker.rb | 15 +++++++++++---- .../ineligible_route_completing_the_form_spec.rb | 4 ++-- .../teacher_route_completing_the_form_spec.rb | 2 +- .../policy_eligibility_checker_spec.rb | 10 +++++----- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/app/models/policies/international_relocation_payments/eligibility.rb b/app/models/policies/international_relocation_payments/eligibility.rb index abe3ad997c..c5f1b73414 100644 --- a/app/models/policies/international_relocation_payments/eligibility.rb +++ b/app/models/policies/international_relocation_payments/eligibility.rb @@ -3,15 +3,6 @@ module InternationalRelocationPayments class Eligibility < ApplicationRecord self.table_name = "international_relocation_payments_eligibilities" - PRE_ACADEMIC_YEAR_WINDOW_LIMIT = 6.months - - def self.earliest_eligible_contract_start_date - Journeys::GetATeacherRelocationPayment - .configuration - .current_academic_year - .start_of_autumn_term - PRE_ACADEMIC_YEAR_WINDOW_LIMIT - end - has_one :claim, as: :eligibility, inverse_of: :eligibility def ineligible? diff --git a/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb b/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb index 405f63f98d..67bbb0e329 100644 --- a/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb +++ b/app/models/policies/international_relocation_payments/policy_eligibility_checker.rb @@ -1,10 +1,21 @@ module Policies module InternationalRelocationPayments class PolicyEligibilityChecker + PRE_ACADEMIC_YEAR_WINDOW_LIMIT = 6.months + + def self.earliest_eligible_contract_start_date + Journeys::GetATeacherRelocationPayment + .configuration + .current_academic_year + .start_of_autumn_term - PRE_ACADEMIC_YEAR_WINDOW_LIMIT + end + attr_reader :answers delegate_missing_to :answers + delegate :earliest_eligible_contract_start_date, to: :class + def initialize(answers:) @answers = answers end @@ -50,10 +61,6 @@ def contract_start_date_eligible? answers.start_date >= earliest_eligible_contract_start_date end - def earliest_eligible_contract_start_date - Eligibility.earliest_eligible_contract_start_date - end - def date_of_entry_eligible? return false unless answers.date_of_entry && answers.start_date diff --git a/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb b/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb index dcf61efe83..142384cbb3 100644 --- a/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb +++ b/spec/features/get_a_teacher_relocation_payment/ineligible_route_completing_the_form_spec.rb @@ -8,7 +8,7 @@ end let(:contract_start_date) do - Policies::InternationalRelocationPayments::Eligibility + Policies::InternationalRelocationPayments::PolicyEligibilityChecker .earliest_eligible_contract_start_date end @@ -69,7 +69,7 @@ and_i_complete_the_state_funded_secondary_school_step_with(option: "Yes") and_i_complete_the_contract_details_step_with(option: "Yes") and_i_complete_the_contract_start_date_step_with( - date: Policies::InternationalRelocationPayments::Eligibility + date: Policies::InternationalRelocationPayments::PolicyEligibilityChecker .earliest_eligible_contract_start_date - 1.day ) then_i_see_the_ineligible_page diff --git a/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb b/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb index 67c610239e..c9b9f22010 100644 --- a/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb +++ b/spec/features/get_a_teacher_relocation_payment/teacher_route_completing_the_form_spec.rb @@ -8,7 +8,7 @@ end let(:contract_start_date) do - Policies::InternationalRelocationPayments::Eligibility + Policies::InternationalRelocationPayments::PolicyEligibilityChecker .earliest_eligible_contract_start_date end diff --git a/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb b/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb index 758253ff2e..f43222143b 100644 --- a/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb +++ b/spec/models/policies/international_relocation_payments/policy_eligibility_checker_spec.rb @@ -139,7 +139,7 @@ one_year: true, subject: "physics", visa_type: "British National (Overseas) visa", - start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 1.day + start_date: Policies::InternationalRelocationPayments::PolicyEligibilityChecker.earliest_eligible_contract_start_date - 1.day } end @@ -154,8 +154,8 @@ one_year: true, subject: "physics", visa_type: "British National (Overseas) visa", - start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date, - date_of_entry: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 4.months + start_date: Policies::InternationalRelocationPayments::PolicyEligibilityChecker.earliest_eligible_contract_start_date, + date_of_entry: Policies::InternationalRelocationPayments::PolicyEligibilityChecker.earliest_eligible_contract_start_date - 4.months } end @@ -170,8 +170,8 @@ one_year: true, subject: "physics", visa_type: "British National (Overseas) visa", - start_date: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date, - date_of_entry: Policies::InternationalRelocationPayments::Eligibility.earliest_eligible_contract_start_date - 1.week + start_date: Policies::InternationalRelocationPayments::PolicyEligibilityChecker.earliest_eligible_contract_start_date, + date_of_entry: Policies::InternationalRelocationPayments::PolicyEligibilityChecker.earliest_eligible_contract_start_date - 1.week } end