From f94942a4e4e0d2083bec4dc8bcb7a7353257bac5 Mon Sep 17 00:00:00 2001 From: Richard Lynch Date: Mon, 18 Nov 2024 16:58:14 +0000 Subject: [PATCH] Move selectable_subject_symbols into the journey. There was a lot of duplicated business rules in this method. We were explicity checking for `nqt_in_academic_year_after_itt`, and if it was absent we were falling back to only the lup subjects. The ECP policy is ineligible for non `nqt_in_academic_year_after_itt` claims so it will be filtered out when we check for `potentially_still_eligible_policies`. We returned an empty array if the `current_academic_year` was outside the lup policy dates, however the LUP#subject_symbols method already returns an empty array of available subjects for years outside the policy. There's some weirdness in the `AdditionalPaymentsForTeaching.selectable_subject_symbols` method. If we're dealing with a trainee teacher, we return a hard coded list of subjects, however trainee teachers won't be eligible as the `EligibilityCheckable#common_ineligible_attributes?` checks if the claimant is a trainee teacher, and is thus ineligible. It seems weird to return a list of subjects if the claimant is ineligible. This was the existing behaviour so I've kept it in place but this likely needs revisiting. --- .../eligible_itt_subject_form.rb | 2 +- app/models/academic_year.rb | 6 +- app/models/concerns/eligibility_checkable.rb | 19 +- .../additional_payments_for_teaching.rb | 20 ++ .../answers_presenter.rb | 10 +- app/models/journeys/eligibility_checker.rb | 8 + app/models/journeys/page_sequence.rb | 2 +- app/models/policies/early_career_payments.rb | 35 +++ .../early_career_payments/dqt_record.rb | 7 +- .../policy_eligibility_checker.rb | 25 +- .../policies/levelling_up_premium_payments.rb | 41 +++- .../policy_eligibility_checker.rb | 2 +- lib/ineligibility_reason_checker.rb | 4 +- lib/journey_subject_eligibility_checker.rb | 22 +- .../eligible_itt_subject_form_spec.rb | 17 +- ...ourney_subject_eligibility_checker_spec.rb | 225 ------------------ spec/models/early_career_payments_spec.rb | 111 +++++++++ .../additional_payments_for_teaching_spec.rb | 198 +++++++++++++++ .../levelling_up_premium_payments_spec.rb | 109 +++++++++ .../early_career_payments/dqt_record_spec.rb | 6 +- 20 files changed, 593 insertions(+), 276 deletions(-) diff --git a/app/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form.rb b/app/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form.rb index 1904af7ab6..199a069f0a 100644 --- a/app/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form.rb +++ b/app/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form.rb @@ -50,7 +50,7 @@ def chemistry_or_physics_available? def subject_symbols @subject_symbols ||= - JourneySubjectEligibilityChecker.selectable_subject_symbols(answers) + AdditionalPaymentsForTeaching.selectable_subject_symbols(journey_session) end def save diff --git a/app/models/academic_year.rb b/app/models/academic_year.rb index 52180578b1..6aca6d23d8 100644 --- a/app/models/academic_year.rb +++ b/app/models/academic_year.rb @@ -107,8 +107,12 @@ def eql?(other) to_s == other.to_s end + def none? + [start_year, end_year].include? nil + end + def to_s(format = :default) - return "None" if [start_year, end_year].include? nil + return "None" if none? if format == :long "#{start_year} to #{end_year}" diff --git a/app/models/concerns/eligibility_checkable.rb b/app/models/concerns/eligibility_checkable.rb index 77cd0f2dda..c513a88fc6 100644 --- a/app/models/concerns/eligibility_checkable.rb +++ b/app/models/concerns/eligibility_checkable.rb @@ -49,7 +49,15 @@ def trainee_teacher? private def common_ineligible_attributes? - [indicated_ineligible_school?, trainee_teacher?, supply_teacher_lacking_either_long_contract_or_direct_employment?, poor_performance?, no_selectable_subjects?, ineligible_cohort?, insufficient_teaching?].any? + [ + indicated_ineligible_school?, + trainee_teacher?, + supply_teacher_lacking_either_long_contract_or_direct_employment?, + poor_performance?, + no_selectable_subjects?, + ineligible_cohort?, + insufficient_teaching? + ].any? end def indicated_ineligible_school? @@ -65,12 +73,13 @@ def poor_performance? end def no_selectable_subjects? - args = {claim_year: claim_year, itt_year: itt_academic_year} - - if args.values.any?(&:blank?) + if claim_year.blank? || itt_academic_year.blank? false else - JourneySubjectEligibilityChecker.new(**args).current_and_future_subject_symbols(policy).empty? + policy.current_and_future_subject_symbols( + claim_year: claim_year, + itt_year: itt_academic_year + ).empty? end end diff --git a/app/models/journeys/additional_payments_for_teaching.rb b/app/models/journeys/additional_payments_for_teaching.rb index a217a6abf4..5395dd4a04 100644 --- a/app/models/journeys/additional_payments_for_teaching.rb +++ b/app/models/journeys/additional_payments_for_teaching.rb @@ -42,5 +42,25 @@ def set_a_reminder?(itt_academic_year:, policy:) def requires_student_loan_details? true end + + def selectable_subject_symbols(journey_session) + return [] if journey_session.answers.itt_academic_year&.none? + + if journey_session.answers.nqt_in_academic_year_after_itt + EligibilityChecker.new(journey_session: journey_session) + .potentially_still_eligible.map do |policy| + policy.current_and_future_subject_symbols( + claim_year: journey_session.answers.policy_year, + itt_year: journey_session.answers.itt_academic_year + ) + end.flatten.uniq + elsif journey_session.answers.policy_year.in?(EligibilityCheckable::COMBINED_ECP_AND_LUP_POLICY_YEARS_BEFORE_FINAL_YEAR) + # they get the standard, unchanging LUP subject set because they won't have qualified in time for ECP by 2022/2023 + # and they won't have given an ITT year + Policies::LevellingUpPremiumPayments.fixed_subject_symbols + else + [] + end + end end end diff --git a/app/models/journeys/additional_payments_for_teaching/answers_presenter.rb b/app/models/journeys/additional_payments_for_teaching/answers_presenter.rb index 3e38d921f1..ba7c80d881 100644 --- a/app/models/journeys/additional_payments_for_teaching/answers_presenter.rb +++ b/app/models/journeys/additional_payments_for_teaching/answers_presenter.rb @@ -157,10 +157,11 @@ def itt_academic_year def text_for_subject_answer policy = eligibility.policy - subjects = JourneySubjectEligibilityChecker.new( + + subjects = policy.current_and_future_subject_symbols( claim_year: Journeys.for_policy(policy).configuration.current_academic_year, itt_year: journey_session.answers.itt_academic_year - ).current_and_future_subject_symbols(policy) + ) if subjects.many? t("additional_payments.forms.eligible_itt_subject.answers.#{journey_session.answers.eligible_itt_subject}") @@ -173,7 +174,10 @@ def text_for_subject_answer private def subject_symbols - @subject_symbols ||= JourneySubjectEligibilityChecker.current_and_future_subject_symbols(answers) + @subject_symbols ||= answers.policy.subject_symbols( + claim_year: answers.policy_year, + itt_year: answers.itt_academic_year + ) end def claim_submission_form diff --git a/app/models/journeys/eligibility_checker.rb b/app/models/journeys/eligibility_checker.rb index 7e5b8efc59..1d81576813 100644 --- a/app/models/journeys/eligibility_checker.rb +++ b/app/models/journeys/eligibility_checker.rb @@ -63,6 +63,14 @@ def policies_eligible_now_and_sorted policies_eligible_now_with_award_amount_and_sorted.map { |policy_with_award_amount| policy_with_award_amount.policy } end + def potentially_still_eligible + policies.select do |policy| + policy::PolicyEligibilityChecker.new( + answers: @journey_session.answers + ).status != :ineligible + end + end + private def policies_eligible_now_with_award_amount diff --git a/app/models/journeys/page_sequence.rb b/app/models/journeys/page_sequence.rb index 3bd345d712..7502598ff5 100644 --- a/app/models/journeys/page_sequence.rb +++ b/app/models/journeys/page_sequence.rb @@ -104,7 +104,7 @@ def handle_trainee_teacher @journey_session.answers.policy_year.in?(EligibilityCheckable::COMBINED_ECP_AND_LUP_POLICY_YEARS_BEFORE_FINAL_YEAR) ? "eligible-itt-subject" : "ineligible" end when "eligible-itt-subject" - if answers.eligible_itt_subject.to_sym.in? JourneySubjectEligibilityChecker.fixed_lup_subject_symbols + if answers.eligible_itt_subject.to_sym.in? Policies::LevellingUpPremiumPayments.fixed_subject_symbols "future-eligibility" else "eligible-degree-subject" diff --git a/app/models/policies/early_career_payments.rb b/app/models/policies/early_career_payments.rb index 554f466a2e..f5231c9cb3 100644 --- a/app/models/policies/early_career_payments.rb +++ b/app/models/policies/early_career_payments.rb @@ -110,6 +110,29 @@ def auto_check_student_loan_plan_task? true end + def current_subject_symbols(claim_year:, itt_year:) + subject_symbols(claim_year: claim_year, itt_year: itt_year) + end + + def future_subject_symbols(claim_year:, itt_year:) + future_years(claim_year).flat_map do |year| + subject_symbols(claim_year: year, itt_year: itt_year) + end + end + + def current_and_future_subject_symbols(claim_year:, itt_year:) + [ + *current_subject_symbols( + claim_year: claim_year, + itt_year: itt_year + ), + *future_subject_symbols( + claim_year: claim_year, + itt_year: itt_year + ) + ].uniq + end + def subject_symbols(claim_year:, itt_year:) case AcademicYear.wrap(claim_year) when AcademicYear.new(2022), AcademicYear.new(2024) @@ -134,5 +157,17 @@ def subject_symbols(claim_year:, itt_year:) [] end end + + def current_and_future_years(year) + fail "year before policy start year" if year < POLICY_START_YEAR + + [year] + future_years(year) + end + + def future_years(year) + fail "year before policy start year" if year < POLICY_START_YEAR + + year + 1..POLICY_END_YEAR + end end end diff --git a/app/models/policies/early_career_payments/dqt_record.rb b/app/models/policies/early_career_payments/dqt_record.rb index 24432f5cea..48d4ffe41d 100644 --- a/app/models/policies/early_career_payments/dqt_record.rb +++ b/app/models/policies/early_career_payments/dqt_record.rb @@ -49,10 +49,11 @@ def eligible_itt_subject_for_claim return :none_of_the_above if itt_subject_groups.empty? || !year - itt_subject_checker = JourneySubjectEligibilityChecker.new(claim_year: current_academic_year, itt_year: year) - itt_subject_groups.delete_if do |itt_subject_group| - !itt_subject_group.in?(itt_subject_checker.current_and_future_subject_symbols(EarlyCareerPayments)) + EarlyCareerPayments.current_and_future_subject_symbols( + claim_year: current_academic_year, + itt_year: year + ).exclude?(itt_subject_group) end.first.to_sym rescue # JourneySubjectEligibilityChecker can also raise an exception if itt_year is out of eligible range :none_of_the_above diff --git a/app/models/policies/early_career_payments/policy_eligibility_checker.rb b/app/models/policies/early_career_payments/policy_eligibility_checker.rb index f6420fe664..30ba961afc 100644 --- a/app/models/policies/early_career_payments/policy_eligibility_checker.rb +++ b/app/models/policies/early_career_payments/policy_eligibility_checker.rb @@ -47,8 +47,10 @@ def itt_subject_eligible_now? return false if itt_subject.blank? return false if itt_subject_none_of_the_above? - itt_subject_checker = JourneySubjectEligibilityChecker.new(claim_year: claim_year, itt_year: itt_academic_year) - itt_subject.to_sym.in?(itt_subject_checker.current_subject_symbols(policy)) + EarlyCareerPayments.current_subject_symbols( + claim_year: claim_year, + itt_year: itt_academic_year + ).include?(itt_subject.to_sym) end def specific_ineligible_attributes? @@ -60,8 +62,10 @@ def itt_subject_ineligible_now_and_in_the_future? return false if itt_subject.blank? return true if itt_subject_none_of_the_above? - itt_subject_checker = JourneySubjectEligibilityChecker.new(claim_year: claim_year, itt_year: itt_academic_year) - !itt_subject.to_sym.in?(itt_subject_checker.current_and_future_subject_symbols(policy)) + EarlyCareerPayments.current_and_future_subject_symbols( + claim_year: claim_year, + itt_year: itt_academic_year + ).exclude?(itt_subject.to_sym) end def specific_eligible_later_attributes? @@ -73,8 +77,10 @@ def itt_subject_eligible_later? return false if itt_subject.blank? return false if itt_subject_none_of_the_above? - itt_subject_checker = JourneySubjectEligibilityChecker.new(claim_year: claim_year, itt_year: itt_academic_year) - itt_subject.to_sym.in?(itt_subject_checker.future_subject_symbols(policy)) + EarlyCareerPayments.future_subject_symbols( + claim_year: claim_year, + itt_year: itt_academic_year + ).include?(itt_subject.to_sym) end # TODO: Is this used anywhere? @@ -94,9 +100,10 @@ def itt_subject_other_than_those_eligible_now_or_in_the_future? # can still rule some out itt_subject_none_of_the_above? else - itt_subject_checker = JourneySubjectEligibilityChecker.new(**args) - itt_subject_symbol = itt_subject.to_sym - !itt_subject_symbol.in?(itt_subject_checker.current_and_future_subject_symbols(policy)) + EarlyCareerPayments.current_and_future_subject_symbols( + claim_year: claim_year, + itt_year: itt_academic_year + ).exclude?(itt_subject_symbol) end end end diff --git a/app/models/policies/levelling_up_premium_payments.rb b/app/models/policies/levelling_up_premium_payments.rb index fb990dd6d8..04e2d468d8 100644 --- a/app/models/policies/levelling_up_premium_payments.rb +++ b/app/models/policies/levelling_up_premium_payments.rb @@ -100,16 +100,55 @@ def auto_check_student_loan_plan_task? true end + def current_subject_symbols(claim_year:, itt_year:) + subject_symbols(claim_year: claim_year, itt_year: itt_year) + end + + def future_subject_symbols(claim_year:, itt_year:) + future_years(claim_year).flat_map do |year| + subject_symbols(claim_year: year, itt_year: itt_year) + end + end + + def current_and_future_subject_symbols(claim_year:, itt_year:) + [ + *current_subject_symbols( + claim_year: claim_year, + itt_year: itt_year + ), + *future_subject_symbols( + claim_year: claim_year, + itt_year: itt_year + ) + ].uniq + end + + def fixed_subject_symbols + [:chemistry, :computing, :mathematics, :physics] + end + def subject_symbols(claim_year:, itt_year:) return [] unless (POLICY_START_YEAR..POLICY_END_YEAR).cover?(claim_year) previous_five_years = (claim_year - 5)...claim_year if previous_five_years.cover?(itt_year) - [:chemistry, :computing, :mathematics, :physics] + fixed_subject_symbols else [] end end + + def current_and_future_years(year) + fail "year before policy start year" if year < POLICY_START_YEAR + + [year] + future_years(year) + end + + def future_years(year) + fail "year before policy start year" if year < POLICY_START_YEAR + + year + 1..POLICY_END_YEAR + end end end diff --git a/app/models/policies/levelling_up_premium_payments/policy_eligibility_checker.rb b/app/models/policies/levelling_up_premium_payments/policy_eligibility_checker.rb index f753ba0ee7..3a0285a1cb 100644 --- a/app/models/policies/levelling_up_premium_payments/policy_eligibility_checker.rb +++ b/app/models/policies/levelling_up_premium_payments/policy_eligibility_checker.rb @@ -22,7 +22,7 @@ def indicated_ineligible_itt_subject? if args.values.any?(&:blank?) # trainee teacher who won't have given their ITT year - eligible_itt_subject.present? && !eligible_itt_subject.to_sym.in?(JourneySubjectEligibilityChecker.fixed_lup_subject_symbols) + eligible_itt_subject.present? && !eligible_itt_subject.to_sym.in?(policy.fixed_subject_symbols) else itt_subject_checker = JourneySubjectEligibilityChecker.new(**args) eligible_itt_subject.present? && !eligible_itt_subject.to_sym.in?(itt_subject_checker.current_subject_symbols(policy)) diff --git a/lib/ineligibility_reason_checker.rb b/lib/ineligibility_reason_checker.rb index 8362bbf821..20b34c42ea 100644 --- a/lib/ineligibility_reason_checker.rb +++ b/lib/ineligibility_reason_checker.rb @@ -154,10 +154,10 @@ def subject_invalid_for_ecp? end def ecp_subject_options - JourneySubjectEligibilityChecker.new( + Policies::EarlyCareerPayments.current_and_future_subject_symbols( claim_year: @answers.policy_year, itt_year: @answers.itt_academic_year - ).current_and_future_subject_symbols(Policies::EarlyCareerPayments) + ) end def bad_itt_year_for_ecp? diff --git a/lib/journey_subject_eligibility_checker.rb b/lib/journey_subject_eligibility_checker.rb index 0b432b03e0..3c94c59f7f 100644 --- a/lib/journey_subject_eligibility_checker.rb +++ b/lib/journey_subject_eligibility_checker.rb @@ -41,20 +41,6 @@ def self.selectable_itt_years_for_claim_year(claim_year) (AcademicYear.new(claim_year - 5)...AcademicYear.new(claim_year)).to_a end - def self.current_and_future_subject_symbols(answers) - return [] if answers.itt_academic_year.blank? - - if answers.nqt_in_academic_year_after_itt - JourneySubjectEligibilityChecker.new(claim_year: answers.policy_year, itt_year: answers.itt_academic_year).current_and_future_subject_symbols(answers.policy) - elsif answers.policy_year.in?(EligibilityCheckable::COMBINED_ECP_AND_LUP_POLICY_YEARS_BEFORE_FINAL_YEAR) - # they get the standard, unchanging LUP subject set because they won't have qualified in time for ECP by 2022/2023 - # and they won't have given an ITT year - JourneySubjectEligibilityChecker.fixed_lup_subject_symbols - else - [] - end.sort - end - # Ideally we wouldn't have this method at all. Unfortunately it was hardcoded like # this before we realised trainee teachers weren't as special a case as we # thought. @@ -62,6 +48,7 @@ def self.fixed_lup_subject_symbols [:chemistry, :computing, :mathematics, :physics] end + # FIXME RL - should be able to delete all the methods using this def current_and_future_subject_symbols(policy) (current_subject_symbols(policy) + future_subject_symbols(policy)).uniq end @@ -70,7 +57,11 @@ def current_subject_symbols(policy) if none_of_the_above_or_blank?(@itt_year) [] else - subject_symbols(policy: policy, claim_year: @claim_year, itt_year: @itt_year) + subject_symbols( + policy: policy, + claim_year: @claim_year, + itt_year: @itt_year + ) end end @@ -92,6 +83,7 @@ def selectable_subject_symbols(answers) private + # Move this def potentially_still_eligible_policies(answers) Journeys::AdditionalPaymentsForTeaching::POLICIES.select do |policy| policy::PolicyEligibilityChecker.new(answers: answers).status != :ineligible diff --git a/spec/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form_spec.rb b/spec/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form_spec.rb index 01ae9565a3..a6df607692 100644 --- a/spec/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form_spec.rb +++ b/spec/forms/journeys/additional_payments_for_teaching/eligible_itt_subject_form_spec.rb @@ -18,7 +18,10 @@ :additional_payments_answers, trainee_teacher, itt_academic_year: itt_academic_year, - current_school_id: create(:school, :early_career_payments_eligible).id + current_school_id: create( + :school, + :early_career_payments_eligible + ).id ) ) end @@ -160,8 +163,8 @@ context "when the subject list contains chemistry" do before do - allow(JourneySubjectEligibilityChecker).to( - receive(:fixed_lup_subject_symbols).and_return([:chemistry]) + allow(Policies::LevellingUpPremiumPayments).to( + receive(:fixed_subject_symbols).and_return([:chemistry]) ) end @@ -170,8 +173,8 @@ context "when the subject list contains physics" do before do - allow(JourneySubjectEligibilityChecker).to( - receive(:fixed_lup_subject_symbols).and_return([:physics]) + allow(Policies::LevellingUpPremiumPayments).to( + receive(:fixed_subject_symbols).and_return([:physics]) ) end @@ -180,8 +183,8 @@ context "when the subject list does not contain chemistry or physics" do before do - allow(JourneySubjectEligibilityChecker).to( - receive(:fixed_lup_subject_symbols).and_return([:mathematics]) + allow(Policies::LevellingUpPremiumPayments).to( + receive(:fixed_subject_symbols).and_return([:mathematics]) ) end diff --git a/spec/lib/journey_subject_eligibility_checker_spec.rb b/spec/lib/journey_subject_eligibility_checker_spec.rb index 9bf76d9aa4..5f3f22aa18 100644 --- a/spec/lib/journey_subject_eligibility_checker_spec.rb +++ b/spec/lib/journey_subject_eligibility_checker_spec.rb @@ -559,231 +559,6 @@ end end - describe "#current_and_future_subject_symbols" do - subject { described_class.new(claim_year: claim_year, itt_year: itt_year).current_and_future_subject_symbols(policy) } - - context "ECP" do - let(:policy) { Policies::EarlyCareerPayments } - - context "2022 claim year" do - let(:claim_year) { AcademicYear.new(2022) } - - context "None of the above ITT year" do - let(:itt_year) { AcademicYear.new } - - it { is_expected.to be_empty } - end - - context "2017 ITT year" do - let(:itt_year) { AcademicYear.new(2017) } - - it { is_expected.to be_empty } - end - - context "2018 ITT year" do - let(:itt_year) { AcademicYear.new(2018) } - - it { is_expected.to contain_exactly(:mathematics) } - end - - context "2019 ITT year" do - let(:itt_year) { AcademicYear.new(2019) } - - it { is_expected.to contain_exactly(:mathematics) } - end - - context "2020 ITT year" do - let(:itt_year) { AcademicYear.new(2020) } - - it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) } - end - end - - context "2023 claim year" do - let(:claim_year) { AcademicYear.new(2023) } - - context "2018 ITT year" do - let(:itt_year) { AcademicYear.new(2018) } - - it { is_expected.to contain_exactly(:mathematics) } - end - - context "2019 ITT year" do - let(:itt_year) { AcademicYear.new(2019) } - - it { is_expected.to contain_exactly(:mathematics) } - end - - context "2020 ITT year" do - let(:itt_year) { AcademicYear.new(2020) } - - it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) } - end - - context "2021 ITT year" do - let(:itt_year) { AcademicYear.new(2021) } - - it { is_expected.to be_empty } - end - - context "2022 ITT year" do - let(:itt_year) { AcademicYear.new(2022) } - - it { is_expected.to be_empty } - end - end - - context "2024 claim year" do - let(:claim_year) { AcademicYear.new(2024) } - - context "2019 ITT year" do - let(:itt_year) { AcademicYear.new(2019) } - - it { is_expected.to contain_exactly(:mathematics) } - end - - context "2020 ITT year" do - let(:itt_year) { AcademicYear.new(2020) } - - it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) } - end - - context "2021 ITT year" do - let(:itt_year) { AcademicYear.new(2021) } - - it { is_expected.to be_empty } - end - - context "2022 ITT year" do - let(:itt_year) { AcademicYear.new(2022) } - - it { is_expected.to be_empty } - end - - context "2023 ITT year" do - let(:itt_year) { AcademicYear.new(2023) } - - it { is_expected.to be_empty } - end - end - end - - context "LUP" do - let(:policy) { Policies::LevellingUpPremiumPayments } - let(:the_constant_lup_subjects) { [:chemistry, :computing, :mathematics, :physics] } - - context "2022 claim year" do - let(:claim_year) { AcademicYear.new(2022) } - - context "2017 ITT year" do - let(:itt_year) { AcademicYear.new(2017) } - - it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } - end - - context "2018 ITT year" do - let(:itt_year) { AcademicYear.new(2018) } - - it { is_expected.to contain_exactly(*the_constant_lup_subjects) } - end - - context "2019 ITT year" do - let(:itt_year) { AcademicYear.new(2019) } - - it { is_expected.to contain_exactly(*the_constant_lup_subjects) } - end - - context "2020 ITT year" do - let(:itt_year) { AcademicYear.new(2020) } - - it { is_expected.to contain_exactly(*the_constant_lup_subjects) } - end - - context "2021 ITT year" do - let(:itt_year) { AcademicYear.new(2021) } - - it { is_expected.to contain_exactly(*the_constant_lup_subjects) } - end - end - - context "2023 claim year" do - let(:claim_year) { AcademicYear.new(2023) } - - context "2018 ITT year" do - let(:itt_year) { AcademicYear.new(2018) } - - it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } - end - - context "2019 ITT year" do - let(:itt_year) { AcademicYear.new(2019) } - - it { is_expected.to contain_exactly(*the_constant_lup_subjects) } - end - - context "2020 ITT year" do - let(:itt_year) { AcademicYear.new(2020) } - - it { is_expected.to contain_exactly(*the_constant_lup_subjects) } - end - - context "2021 ITT year" do - let(:itt_year) { AcademicYear.new(2021) } - - it { is_expected.to contain_exactly(*the_constant_lup_subjects) } - end - - context "2022 ITT year" do - let(:itt_year) { AcademicYear.new(2022) } - - it { is_expected.to contain_exactly(*the_constant_lup_subjects) } - end - end - - context "2024 claim year" do - let(:claim_year) { AcademicYear.new(2024) } - - context "2019 ITT year" do - let(:itt_year) { AcademicYear.new(2019) } - - it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } - end - - context "2020 ITT year" do - let(:itt_year) { AcademicYear.new(2020) } - - it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } - end - - context "2021 ITT year" do - let(:itt_year) { AcademicYear.new(2021) } - - it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } - end - - context "2022 ITT year" do - let(:itt_year) { AcademicYear.new(2022) } - - it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } - end - end - end - - context "unsupported policy" do - let(:policy) { Policies::StudentLoans } - - context "2022 claim year" do - let(:claim_year) { AcademicYear.new(2022) } - - context "2017 ITT year" do - let(:itt_year) { AcademicYear.new(2017) } - - specify { expect { described_class.new(claim_year: claim_year, itt_year: itt_year).future_subject_symbols(policy) }.to raise_error("Unsupported policy: StudentLoans") } - end - end - end - end - describe "#selectable_subject_symbols" do subject do described_class.new( diff --git a/spec/models/early_career_payments_spec.rb b/spec/models/early_career_payments_spec.rb index 40f6498a9a..a73fe9c1a1 100644 --- a/spec/models/early_career_payments_spec.rb +++ b/spec/models/early_career_payments_spec.rb @@ -31,4 +31,115 @@ subject(:payroll_file_name) { described_class.payroll_file_name } it { is_expected.to eq("EarlyCareerPayments") } end + + describe ".current_and_future_subject_symbols" do + subject(:current_and_future_subject_symbols) do + described_class.current_and_future_subject_symbols( + claim_year: claim_year, + itt_year: itt_year + ) + end + + context "2022 claim year" do + let(:claim_year) { AcademicYear.new(2022) } + + context "None of the above ITT year" do + let(:itt_year) { AcademicYear.new } + + it { is_expected.to be_empty } + end + + context "2017 ITT year" do + let(:itt_year) { AcademicYear.new(2017) } + + it { is_expected.to be_empty } + end + + context "2018 ITT year" do + let(:itt_year) { AcademicYear.new(2018) } + + it { is_expected.to contain_exactly(:mathematics) } + end + + context "2019 ITT year" do + let(:itt_year) { AcademicYear.new(2019) } + + it { is_expected.to contain_exactly(:mathematics) } + end + + context "2020 ITT year" do + let(:itt_year) { AcademicYear.new(2020) } + + it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) } + end + end + + context "2023 claim year" do + let(:claim_year) { AcademicYear.new(2023) } + + context "2018 ITT year" do + let(:itt_year) { AcademicYear.new(2018) } + + it { is_expected.to contain_exactly(:mathematics) } + end + + context "2019 ITT year" do + let(:itt_year) { AcademicYear.new(2019) } + + it { is_expected.to contain_exactly(:mathematics) } + end + + context "2020 ITT year" do + let(:itt_year) { AcademicYear.new(2020) } + + it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) } + end + + context "2021 ITT year" do + let(:itt_year) { AcademicYear.new(2021) } + + it { is_expected.to be_empty } + end + + context "2022 ITT year" do + let(:itt_year) { AcademicYear.new(2022) } + + it { is_expected.to be_empty } + end + end + + context "2024 claim year" do + let(:claim_year) { AcademicYear.new(2024) } + + context "2019 ITT year" do + let(:itt_year) { AcademicYear.new(2019) } + + it { is_expected.to contain_exactly(:mathematics) } + end + + context "2020 ITT year" do + let(:itt_year) { AcademicYear.new(2020) } + + it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) } + end + + context "2021 ITT year" do + let(:itt_year) { AcademicYear.new(2021) } + + it { is_expected.to be_empty } + end + + context "2022 ITT year" do + let(:itt_year) { AcademicYear.new(2022) } + + it { is_expected.to be_empty } + end + + context "2023 ITT year" do + let(:itt_year) { AcademicYear.new(2023) } + + it { is_expected.to be_empty } + end + end + end end diff --git a/spec/models/journeys/additional_payments_for_teaching_spec.rb b/spec/models/journeys/additional_payments_for_teaching_spec.rb index f9be210508..dead026cd4 100644 --- a/spec/models/journeys/additional_payments_for_teaching_spec.rb +++ b/spec/models/journeys/additional_payments_for_teaching_spec.rb @@ -128,4 +128,202 @@ end end end + + describe ".selectable_subject_symbols" do + subject { described_class.selectable_subject_symbols(journey_session) } + + context "when academic year is 2022" do + before { create(:journey_configuration, :additional_payments, current_academic_year: claim_year) } + + context "2022 claim year" do + let(:claim_year) { AcademicYear.new(2022) } + + context "None of the above ITT year" do + let(:itt_year) { AcademicYear.new } + + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to be_empty } + end + + context "2017 ITT year" do + let(:itt_year) { AcademicYear.new(2017) } + + context "ineligible LUP" do + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + :ecp_eligible, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to be_empty } + end + + context "eligible LUP" do + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + :ecp_and_lup_eligible, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } + end + end + + context "2018 ITT year" do + let(:itt_year) { AcademicYear.new(2018) } + + context "ineligible LUP" do + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + :ecp_eligible, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to contain_exactly(:mathematics) } + end + + context "eligible LUP" do + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + :ecp_and_lup_eligible, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } + end + end + + context "2019 ITT year" do + let(:itt_year) { AcademicYear.new(2019) } + + context "ineligible LUP" do + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + :ecp_eligible, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to contain_exactly(:mathematics) } + end + + context "eligible LUP" do + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + :ecp_and_lup_eligible, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } + end + end + + context "2020 ITT year" do + let(:itt_year) { AcademicYear.new(2020) } + + context "ineligible LUP" do + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + :ecp_eligible, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to contain_exactly(:chemistry, :foreign_languages, :mathematics, :physics) } + end + + context "eligible LUP" do + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + :ecp_and_lup_eligible, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to contain_exactly(:chemistry, :computing, :foreign_languages, :mathematics, :physics) } + end + end + + context "2021 ITT year" do + let(:itt_year) { AcademicYear.new(2021) } + + context "ineligible LUP" do + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + :ecp_eligible, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to be_empty } + end + + context "eligible LUP" do + let(:journey_session) do + create( + :additional_payments_session, + answers: attributes_for( + :additional_payments_answers, + :ecp_and_lup_eligible, + itt_academic_year: itt_year + ) + ) + end + + it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } + end + end + end + end + end end diff --git a/spec/models/levelling_up_premium_payments_spec.rb b/spec/models/levelling_up_premium_payments_spec.rb index 702123cab7..2f3e8c93db 100644 --- a/spec/models/levelling_up_premium_payments_spec.rb +++ b/spec/models/levelling_up_premium_payments_spec.rb @@ -29,4 +29,113 @@ subject(:payroll_file_name) { described_class.payroll_file_name } it { is_expected.to eq("SchoolsLUP") } end + + describe ".current_and_future_subject_symbols" do + subject(:current_and_future_subject_symbols) do + described_class.current_and_future_subject_symbols( + claim_year: claim_year, + itt_year: itt_year + ) + end + + let(:the_constant_lup_subjects) do + [:chemistry, :computing, :mathematics, :physics] + end + + context "2022 claim year" do + let(:claim_year) { AcademicYear.new(2022) } + + context "2017 ITT year" do + let(:itt_year) { AcademicYear.new(2017) } + + it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } + end + + context "2018 ITT year" do + let(:itt_year) { AcademicYear.new(2018) } + + it { is_expected.to contain_exactly(*the_constant_lup_subjects) } + end + + context "2019 ITT year" do + let(:itt_year) { AcademicYear.new(2019) } + + it { is_expected.to contain_exactly(*the_constant_lup_subjects) } + end + + context "2020 ITT year" do + let(:itt_year) { AcademicYear.new(2020) } + + it { is_expected.to contain_exactly(*the_constant_lup_subjects) } + end + + context "2021 ITT year" do + let(:itt_year) { AcademicYear.new(2021) } + + it { is_expected.to contain_exactly(*the_constant_lup_subjects) } + end + end + + context "2023 claim year" do + let(:claim_year) { AcademicYear.new(2023) } + + context "2018 ITT year" do + let(:itt_year) { AcademicYear.new(2018) } + + it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } + end + + context "2019 ITT year" do + let(:itt_year) { AcademicYear.new(2019) } + + it { is_expected.to contain_exactly(*the_constant_lup_subjects) } + end + + context "2020 ITT year" do + let(:itt_year) { AcademicYear.new(2020) } + + it { is_expected.to contain_exactly(*the_constant_lup_subjects) } + end + + context "2021 ITT year" do + let(:itt_year) { AcademicYear.new(2021) } + + it { is_expected.to contain_exactly(*the_constant_lup_subjects) } + end + + context "2022 ITT year" do + let(:itt_year) { AcademicYear.new(2022) } + + it { is_expected.to contain_exactly(*the_constant_lup_subjects) } + end + end + + context "2024 claim year" do + let(:claim_year) { AcademicYear.new(2024) } + + context "2019 ITT year" do + let(:itt_year) { AcademicYear.new(2019) } + + it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } + end + + context "2020 ITT year" do + let(:itt_year) { AcademicYear.new(2020) } + + it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } + end + + context "2021 ITT year" do + let(:itt_year) { AcademicYear.new(2021) } + + it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } + end + + context "2022 ITT year" do + let(:itt_year) { AcademicYear.new(2022) } + + it { is_expected.to contain_exactly(:chemistry, :computing, :mathematics, :physics) } + end + end + end end diff --git a/spec/models/policies/early_career_payments/dqt_record_spec.rb b/spec/models/policies/early_career_payments/dqt_record_spec.rb index 24ddbc1e97..cc293c6786 100644 --- a/spec/models/policies/early_career_payments/dqt_record_spec.rb +++ b/spec/models/policies/early_career_payments/dqt_record_spec.rb @@ -2176,8 +2176,10 @@ context "with a valid ITT year" do before do - allow(JourneySubjectEligibilityChecker).to receive(:new) - .and_return(double(current_and_future_subject_symbols: eligible_subjects)) + allow(Policies::EarlyCareerPayments).to( + receive(:current_and_future_subject_symbols) + .and_return(eligible_subjects) + ) end let(:claim_academic_year) { AcademicYear.new(2023) }