From acac78a8e5f09530b5834aa64db1ef6f96c1efcd Mon Sep 17 00:00:00 2001 From: Samuel Young Date: Mon, 3 Aug 2026 17:40:21 +0100 Subject: [PATCH] CLDC-3499: Remove pre 2025 tests (#3324) * CLDC-3499: Update selenium allows for the tests to run locally as it can download a browser version that exists * CLDC-3499: Fix validations spec to be non year specific * CLDC-3499: Remove unneeded 2020 dates from bulk scheme locations spec * CLDC-3499: Remove year specific tests from form_handler_spec * CLDC-3499: Remove 2020 test from lettings_log_spec * CLDC-3499: Remove 2020 test from sales_log_spec * CLDC-3499: Remove 2020 test from location_spec makes the current_collection_after_crossover_start_date method a bit more useful, returns the date in the current collection year that crossover will end, rather than the crossover end date of the current period (which will be next year) * CLDC-3499: Remove 2020 test from scheme_spec * CLDC-3499: Remove 2020 test from setup_validations_spec adds missing archived method to collection_time_helper * CLDC-3499: Start changes to lettings log export service * CLDC-3499: Remove unneeded old test from check answers summary list component spec * CLDC-3499: Update check answers page spec for modern years * CLDC-3499: Add more form helpers * CLDC-3499: Remove year specific tests from lettings setup validations * CLDC-3499: Remove year specific tests from managing org rake spec * CLDC-3499: Update lettings log spec * CLDC-3499: Update task list spec * CLDC-3499: Update sales logs controller * CLDC-3499: Remove old tests from sales log spec * CLDC-3499: Fix some final old tests * Revert "CLDC-3499: Start changes to lettings log export service" This reverts commit 1edbc9ab8c8b81693eb96d5db57f1c02a975b898. * CLDC-3499: Lint * feat: enforce crossover tests pass * feat: re-include archived log display test --------- Co-authored-by: Nat Dean-Lewis Co-authored-by: Nat Dean-Lewis <94526761+natdeanlewissoftwire@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 7 +- app/helpers/collection_time_helper.rb | 6 +- ...nswers_summary_list_card_component_spec.rb | 6 +- .../check_answers_page_lettings_logs_spec.rb | 136 +++----- spec/features/form/helpers.rb | 16 +- spec/features/form/tasklist_page_spec.rb | 25 +- spec/features/form/validations_spec.rb | 96 +++--- .../set_sales_managing_organisation_spec.rb | 4 +- ...ate_schemes_and_locations_from_csv_spec.rb | 2 - spec/models/form_handler_spec.rb | 135 +++----- spec/models/lettings_log_spec.rb | 316 +++++------------- spec/models/location_spec.rb | 34 +- spec/models/sales_log_spec.rb | 64 ++-- spec/models/scheme_spec.rb | 34 +- .../validations/date_validations_spec.rb | 34 +- .../validations/financial_validations_spec.rb | 34 +- .../validations/household_validations_spec.rb | 8 +- .../sale_information_validations_spec.rb | 12 - .../sales/setup_validations_spec.rb | 8 +- .../validations/setup_validations_spec.rb | 199 +++++------ .../validations/soft_validations_spec.rb | 20 +- spec/requests/sales_logs_controller_spec.rb | 227 +++++++------ 23 files changed, 541 insertions(+), 884 deletions(-) diff --git a/Gemfile b/Gemfile index 3867f8ac3..172a13e9f 100644 --- a/Gemfile +++ b/Gemfile @@ -106,7 +106,7 @@ group :test do gem "capybara-lockstep" gem "capybara-screenshot" gem "rspec-rails", require: false - gem "selenium-webdriver", require: false + gem "selenium-webdriver", "~> 4.43", require: false gem "simplecov", require: false gem "timecop", "~> 0.9.4" gem "webmock", require: false diff --git a/Gemfile.lock b/Gemfile.lock index afabb75a7..542b392a0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -500,10 +500,11 @@ GEM ruby2_keywords (0.0.5) rubyzip (2.3.2) securerandom (0.4.1) - selenium-webdriver (4.18.1) + selenium-webdriver (4.43.0) base64 (~> 0.2) + logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) - rubyzip (>= 1.2.2, < 3.0) + rubyzip (>= 1.2.2, < 4.0) websocket (~> 1.0) sentry-rails (5.16.1) railties (>= 5.0) @@ -634,7 +635,7 @@ DEPENDENCIES rubocop-performance rubocop-rails ruby-openai - selenium-webdriver + selenium-webdriver (~> 4.43) sentry-rails sentry-ruby sidekiq (~> 7.2.4) diff --git a/app/helpers/collection_time_helper.rb b/app/helpers/collection_time_helper.rb index b97cfa759..c8a47ab83 100644 --- a/app/helpers/collection_time_helper.rb +++ b/app/helpers/collection_time_helper.rb @@ -30,7 +30,7 @@ module CollectionTimeHelper end def current_collection_after_crossover_start_date - Form::DEADLINES[current_collection_start_year][:edit_end_date] + 1.day + Form::DEADLINES[previous_collection_start_year][:edit_end_date] + 1.day end def collection_end_date(date) @@ -81,6 +81,10 @@ module CollectionTimeHelper current_collection_end_year - 2 end + def archived_collection_start_date + current_collection_start_date - 2.years + end + def previous_collection_new_logs_end_date FormHandler.instance.lettings_form_for_start_year(previous_collection_start_year).new_logs_end_date end diff --git a/spec/components/check_answers_summary_list_card_component_spec.rb b/spec/components/check_answers_summary_list_card_component_spec.rb index bbae4acff..76b5d24ff 100644 --- a/spec/components/check_answers_summary_list_card_component_spec.rb +++ b/spec/components/check_answers_summary_list_card_component_spec.rb @@ -1,6 +1,8 @@ require "rails_helper" RSpec.describe CheckAnswersSummaryListCardComponent, type: :component do + include CollectionTimeHelper + subject(:component) { described_class.new(questions:, log:, user:) } let(:rendered) { render_inline(component) } @@ -65,9 +67,9 @@ RSpec.describe CheckAnswersSummaryListCardComponent, type: :component do end end - context "when before 23/24 collection" do + context "when a log is from an archived collection year" do context "when given a set of questions" do - let(:log) { create(:lettings_log, :completed, :ignore_validation_errors, age2: 99, startdate: Time.zone.local(2021, 5, 1), assigned_to: create(:user)) } + let(:log) { create(:lettings_log, :completed, :ignore_validation_errors, age2: 99, startdate: archived_collection_start_date, assigned_to: create(:user)) } it "renders a summary list card without question numbers for the answers to those questions" do expect(rendered).to have_content(questions.first.answer_label(log)) diff --git a/spec/features/form/check_answers_page_lettings_logs_spec.rb b/spec/features/form/check_answers_page_lettings_logs_spec.rb index f4808cda5..62f9fad52 100644 --- a/spec/features/form/check_answers_page_lettings_logs_spec.rb +++ b/spec/features/form/check_answers_page_lettings_logs_spec.rb @@ -2,21 +2,13 @@ require "rails_helper" require_relative "helpers" RSpec.describe "Lettings Log Check Answers Page" do - around do |example| - Timecop.freeze(Time.zone.local(2021, 5, 1)) do - Singleton.__init__(FormHandler) - example.run - end - Timecop.return - Singleton.__init__(FormHandler) - end - include Helpers + include CollectionTimeHelper + let(:user) { FactoryBot.create(:user) } - let(:subsection) { "household-characteristics" } - let(:conditional_subsection) { "conditional-question" } + let(:subsection) { "household-needs" } let(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation) } - let(:location) { FactoryBot.create(:location, scheme:, mobility_type: "N", startdate: Time.zone.local(2021, 4, 1)) } + let(:location) { FactoryBot.create(:location, scheme:, mobility_type: "N", startdate: current_collection_start_date) } let(:lettings_log) do FactoryBot.create( @@ -31,9 +23,7 @@ RSpec.describe "Lettings Log Check Answers Page" do let(:empty_lettings_log) do FactoryBot.create( :lettings_log, - previous_la_known: 1, - prevloc: "E09000033", - is_previous_la_inferred: false, + :setup_completed, assigned_to: user, ) end @@ -44,21 +34,17 @@ RSpec.describe "Lettings Log Check Answers Page" do owning_organisation: user.organisation, managing_organisation: user.organisation, assigned_to: user, - startdate: Time.zone.local(2021, 5, 1), + startdate: current_collection_start_date, ) end let(:id) { lettings_log.id } - let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } before do - allow(lettings_log.form).to receive(:new_logs_end_date).and_return(Time.zone.today + 1.day) - allow(fake_2021_2022_form).to receive(:new_logs_end_date).and_return(Time.zone.today + 1.day) sign_in user - allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form) end context "when the user needs to check their answers for a subsection" do - let(:last_question_for_subsection) { "propcode" } + let(:last_question_for_subsection) { "health-conditions" } it "can be visited by URL" do visit("/lettings-logs/#{id}/#{subsection}/check-answers") @@ -66,80 +52,46 @@ RSpec.describe "Lettings Log Check Answers Page" do end it "redirects to the check answers page when answering the last question and clicking save and continue" do - fill_in_number_question(id, "propcode", 0, last_question_for_subsection) + fill_in_radio_question(id, "illness", "2", last_question_for_subsection) expect(page).to have_current_path("/lettings-logs/#{id}/#{subsection}/check-answers") end it "has question headings based on the subsection" do visit("/lettings-logs/#{id}/#{subsection}/check-answers") - question_labels = ["Tenant code", "Lead tenant’s age", "Number of Household Members"] + question_labels = ["Household links to UK armed forces", "Anybody in household pregnant", "Anybody with disabled access needs", "Anybody in household with physical or mental health condition"] question_labels.each do |label| expect(page).to have_content(label) end end it "displays answers given by the user for the question in the subsection" do - fill_in_number_question(empty_lettings_log.id, "age1", 28, "person-1-age") - choose("lettings-log-sex1-x-field") - click_button("Save and continue") - visit("/lettings-logs/#{empty_lettings_log.id}/#{subsection}/check-answers") - expect(page).to have_content("28") - expect(page).to have_content("Non-binary") + fill_in_radio_question(id, "armedforces", "3", "armed-forces") + fill_in_radio_question(id, "illness", "2", "health-conditions") + visit("/lettings-logs/#{id}/#{subsection}/check-answers") + expect(page).to have_content("No") + expect(page).to have_content("Person prefers not to say") end - # Regex explanation: match the string "Answer" but not if it's follow by "the missing questions" - # This way only the links in the table will get picked up it "has an answer link with the check_answers_new_answer referrer for questions missing an answer" do - visit("/lettings-logs/#{empty_lettings_log.id}/#{subsection}/check-answers?referrer=check_answers") + visit("/lettings-logs/#{id}/#{subsection}/check-answers?referrer=check_answers") assert_selector "a", text: "Change", count: 0 - expect(page).to have_link("Enter lead tenant’s age", href: "/lettings-logs/#{empty_lettings_log.id}/person-1-age?referrer=check_answers_new_answer") + expect(page).to have_link("Tell us if there are any household links to UK armed forces", href: "/lettings-logs/#{id}/armed-forces?referrer=check_answers_new_answer") end it "has a change link for answered question" do - fill_in_number_question(empty_lettings_log.id, "age1", 28, "person-1-age") - visit("/lettings-logs/#{empty_lettings_log.id}/#{subsection}/check-answers") + fill_in_radio_question(id, "armedforces", "2", "armed-forces") + visit("/lettings-logs/#{id}/#{subsection}/check-answers") assert_selector "a", text: "Change", count: 1 - expect(page).to have_link("Change", href: "/lettings-logs/#{empty_lettings_log.id}/person-1-age?referrer=check_answers") + expect(page).to have_link("Change", href: "/lettings-logs/#{id}/armed-forces?referrer=check_answers") end it "updates the add change link when answers get answered" do - visit("/lettings-logs/#{empty_lettings_log.id}/household-needs/check-answers") + visit("/lettings-logs/#{id}/household-needs/check-answers") + assert_selector "a", text: "Change", count: 0 + fill_in_radio_question(id, "armedforces", "2", "armed-forces") + visit("/lettings-logs/#{id}/household-needs/check-answers") assert_selector "a", text: "Change", count: 1 - visit("/lettings-logs/#{empty_lettings_log.id}/accessibility-requirements") - check("lettings-log-accessibility-requirements-housingneeds-c-field") - click_button("Save and continue") - visit("/lettings-logs/#{empty_lettings_log.id}/household-needs/check-answers") - assert_selector "a", text: "Change", count: 2 - expect(page).to have_link("Change", href: "/lettings-logs/#{empty_lettings_log.id}/accessibility-requirements?referrer=check_answers") - end - - it "does not display conditional questions that were not visited" do - visit("/lettings-logs/#{id}/#{conditional_subsection}/check-answers") - question_labels = ["Has the condition been met?"] - question_labels.each do |label| - expect(page).to have_content(label) - end - - excluded_question_labels = ["Has the next condition been met?", "Has the condition not been met?"] - excluded_question_labels.each do |label| - expect(page).not_to have_content(label) - end - end - - it "displays conditional question that were visited" do - visit("/lettings-logs/#{id}/conditional-question") - choose("lettings-log-preg-occ-2-field", allow_label_click: true) - click_button("Save and continue") - visit("/lettings-logs/#{id}/#{conditional_subsection}/check-answers") - question_labels = ["Has the condition been met?", "Has the condition not been met?"] - question_labels.each do |label| - expect(page).to have_content(label) - end - - excluded_question_labels = ["Has the next condition been met?"] - excluded_question_labels.each do |label| - expect(page).not_to have_content(label) - end + expect(page).to have_link("Change", href: "/lettings-logs/#{id}/armed-forces?referrer=check_answers") end it "does not group questions into summary cards if the questions in the subsection don't have a check_answers_card_number attribute" do @@ -149,7 +101,7 @@ RSpec.describe "Lettings Log Check Answers Page" do context "when the user is checking their answers for the household characteristics subsection" do it "they see a separate summary card for each member of the household" do - visit("/lettings-logs/#{completed_lettings_log.id}/#{subsection}/check-answers") + visit("/lettings-logs/#{completed_lettings_log.id}/household-characteristics/check-answers") assert_selector ".govuk-summary-card__title", text: "Lead tenant", count: 1 assert_selector ".govuk-summary-card__title", text: "Person 2", count: 1 end @@ -157,7 +109,7 @@ RSpec.describe "Lettings Log Check Answers Page" do context "when viewing setup section answers" do before do - FactoryBot.create(:location, scheme:, startdate: Time.zone.local(2021, 1, 1)) + FactoryBot.create(:location, scheme:, startdate: current_collection_start_date) end it "displays inferred postcode with the location id" do @@ -175,15 +127,12 @@ RSpec.describe "Lettings Log Check Answers Page" do context "when the user changes their answer from check answer page" do it "routes back to check answers" do - visit("/lettings-logs/#{empty_lettings_log.id}/accessibility-requirements") - check("lettings-log-accessibility-requirements-housingneeds-c-field") - click_button("Save and continue") - visit("/lettings-logs/#{empty_lettings_log.id}/household-needs/check-answers") + fill_in_radio_question(id, "armedforces", "2", "armed-forces") + visit("/lettings-logs/#{id}/household-needs/check-answers") first("a", text: /Change/).click - uncheck("lettings-log-accessibility-requirements-housingneeds-c-field") - check("lettings-log-accessibility-requirements-housingneeds-b-field") + choose("lettings-log-armedforces-3-field") click_button("Save changes") - expect(page).to have_current_path("/lettings-logs/#{empty_lettings_log.id}/household-needs/check-answers") + expect(page).to have_current_path("/lettings-logs/#{id}/household-needs/check-answers") end end @@ -224,10 +173,24 @@ RSpec.describe "Lettings Log Check Answers Page" do sex1: "M", hhmemb: 1, armedforces: 3, + preg_occ: 2, + housingneeds: 2, illness: 1, - housingneeds_h: 1, - la: "E06000014", illness_type_1: 1, + layear: 2, + waityear: 7, + reason: 4, + prevten: 6, + homeless: 1, + ppostcode_full: "SE2 6RT", + previous_la_known: 1, + prevloc: "E07000105", + reasonpref: 1, + cbl: 0, + chr: 1, + cap: 0, + accessible_register: 0, + referral_type: 1, ) end @@ -240,6 +203,7 @@ RSpec.describe "Lettings Log Check Answers Page" do tenancycode: nil, hhmemb: nil, age1: nil, + age2: nil, layear: 2, waityear: 1, postcode_full: "NW1 5TY", @@ -265,13 +229,13 @@ RSpec.describe "Lettings Log Check Answers Page" do it "they can click a button to skip sections until the next incomplete section" do visit("/lettings-logs/#{skip_section_lettings_log.id}/household-characteristics/check-answers") click_link("Save and go to next incomplete section") - expect(page).to have_current_path("/lettings-logs/#{skip_section_lettings_log.id}/property-information/check-answers") + expect(page).to have_current_path("/lettings-logs/#{skip_section_lettings_log.id}/household-situation/check-answers") end it "they can click a button to cycle around to the next incomplete section" do - visit("/lettings-logs/#{cycle_sections_lettings_log.id}/declaration/check-answers") + visit("/lettings-logs/#{cycle_sections_lettings_log.id}/income-and-benefits/check-answers") click_link("Save and go to next incomplete section") - expect(page).to have_current_path("/lettings-logs/#{cycle_sections_lettings_log.id}/tenant-code-test") + expect(page).to have_current_path("/lettings-logs/#{cycle_sections_lettings_log.id}/property-information/check-answers") end end end diff --git a/spec/features/form/helpers.rb b/spec/features/form/helpers.rb index 572a14d61..3144f1b0e 100644 --- a/spec/features/form/helpers.rb +++ b/spec/features/form/helpers.rb @@ -5,14 +5,16 @@ module Helpers click_button("Save and continue") end - def answer_all_questions_in_income_subsection(lettings_log) - visit("/lettings-logs/#{lettings_log.id}/net-income") - fill_in("lettings-log-earnings-field", with: 18_000) - choose("lettings-log-incfreq-2-field") - click_button("Save and continue") - choose("lettings-log-benefits-0-field") + def fill_in_date_question(lettings_log_id, question, day, month, year, path, conditional_field: nil) + visit("/lettings-logs/#{lettings_log_id}/#{path}") + choose("lettings-log-#{conditional_field}-field", allow_label_click: true) if conditional_field + fill_in("lettings_log[#{question}]", with: [day, month, year].join("/")) click_button("Save and continue") - choose("lettings-log-hb-1-field") + end + + def fill_in_radio_question(lettings_log_id, question, code, path) + visit("/lettings-logs/#{lettings_log_id}/#{path}") + choose("lettings-log-#{question.to_s.dasherize}-#{code}-field") click_button("Save and continue") end diff --git a/spec/features/form/tasklist_page_spec.rb b/spec/features/form/tasklist_page_spec.rb index 6c87d074e..dbce76a1d 100644 --- a/spec/features/form/tasklist_page_spec.rb +++ b/spec/features/form/tasklist_page_spec.rb @@ -42,38 +42,16 @@ RSpec.describe "Task List" do let(:id) { lettings_log.id } let(:status) { lettings_log.status } - around do |example| - Timecop.freeze(Time.zone.local(2022, 1, 1)) do - Singleton.__init__(FormHandler) - example.run - end - Timecop.return - Singleton.__init__(FormHandler) - end - before do - Timecop.freeze(Time.zone.local(2021, 5, 1)) - setup_completed_log.update!(startdate: Time.zone.local(2021, 5, 1)) - allow(lettings_log.form).to receive(:new_logs_end_date).and_return(Time.zone.today + 1.day) sign_in user end - after do - Timecop.unfreeze - end - it "shows if the section has not been started" do visit("/lettings-logs/#{empty_lettings_log.id}") expect(page).to have_content("This log has not been started.") end describe "completed subsection count" do - let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") } - - before do - allow(FormHandler.instance).to receive(:get_form).and_return(real_2021_2022_form) - end - it "shows number of completed sections if one section is completed" do visit("/lettings-logs/#{setup_completed_log.id}") expect(page).to have_content("1 of 7 subsections completed.") @@ -81,9 +59,8 @@ RSpec.describe "Task List" do end it "show skip link for next incomplete section" do - answer_all_questions_in_income_subsection(setup_completed_log) visit("/lettings-logs/#{setup_completed_log.id}") - expect(page).to have_link("Skip to next incomplete section", href: /#household-characteristics/) + expect(page).to have_link("Skip to next incomplete section", href: /#property-information/) end it "has a review section which has a button that allows the data inputter to review the lettings log" do diff --git a/spec/features/form/validations_spec.rb b/spec/features/form/validations_spec.rb index 7ac8f6685..d3ba5fb46 100644 --- a/spec/features/form/validations_spec.rb +++ b/spec/features/form/validations_spec.rb @@ -2,47 +2,31 @@ require "rails_helper" require_relative "helpers" RSpec.describe "validations" do - around do |example| - Timecop.freeze(Time.zone.local(2022, 1, 1)) do - Singleton.__init__(FormHandler) - example.run - end - Timecop.return - Singleton.__init__(FormHandler) - end - - let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } let(:user) { FactoryBot.create(:user) } let(:lettings_log) do FactoryBot.create( :lettings_log, - :in_progress, + :setup_completed, assigned_to: user, renewal: 0, - ) - end - let(:empty_lettings_log) do - FactoryBot.create( - :lettings_log, - assigned_to: user, + first_time_property_let_as_social_housing: 0, + unitletas: 1, + rsnvac: 9, ) end let(:id) { lettings_log.id } before do - allow(fake_2021_2022_form).to receive(:new_logs_end_date).and_return(Time.zone.today + 1.day) - allow(lettings_log.form).to receive(:new_logs_end_date).and_return(Time.zone.today + 1.day) sign_in user - allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form) end include Helpers + include CollectionTimeHelper describe "Question validation" do context "when the tenant age is invalid" do it "shows validation for under 0" do - visit("/lettings-logs/#{id}/person-1-age") - fill_in_number_question(empty_lettings_log.id, "age1", -5, "person-1-age") + fill_in_number_question(id, "age1", -5, "lead-tenant-age") expect(page).to have_selector(".govuk-error-summary__title") expect(page).to have_selector("#lettings-log-age1-error") expect(page).to have_selector("#lettings-log-age1-field-error") @@ -50,8 +34,7 @@ RSpec.describe "validations" do end it "shows validation for over 120" do - visit("/lettings-logs/#{id}/person-1-age") - fill_in_number_question(empty_lettings_log.id, "age1", 121, "person-1-age") + fill_in_number_question(id, "age1", 121, "lead-tenant-age") expect(page).to have_selector(".govuk-error-summary__title") expect(page).to have_selector("#lettings-log-age1-error") expect(page).to have_selector("#lettings-log-age1-field-error") @@ -63,11 +46,12 @@ RSpec.describe "validations" do describe "date validation", :js do def fill_in_date(lettings_log_id, question, day, month, year, path) visit("/lettings-logs/#{lettings_log_id}/#{path}") + choose("lettings-log-majorrepairs-1-field", allow_label_click: true) fill_in("lettings_log[#{question}]", with: [day, month, year].join("/")) end it "does not allow out of range dates to be submitted" do - fill_in_date(id, "mrcdate", 3100, 12, 2000, "property-major-repairs") + fill_in_date(id, "mrcdate", 3100, 12, current_collection_start_year, "property-major-repairs") click_button("Save and continue") expect(page).to have_current_path("/lettings-logs/#{id}/property-major-repairs") @@ -75,13 +59,9 @@ RSpec.describe "validations" do click_button("Save and continue") expect(page).to have_current_path("/lettings-logs/#{id}/property-major-repairs") - fill_in_date(id, "mrcdate", 13, 100, 2020, "property-major-repairs") + fill_in_date(id, "mrcdate", 13, 100, current_collection_start_year, "property-major-repairs") click_button("Save and continue") expect(page).to have_current_path("/lettings-logs/#{id}/property-major-repairs") - - fill_in_date(id, "mrcdate", 21, 11, 2020, "property-major-repairs") - click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/local-authority/check-answers") end it "does not allow non numeric inputs to be submitted" do @@ -95,19 +75,20 @@ RSpec.describe "validations" do click_button("Save and continue") expect(page).to have_current_path("/lettings-logs/#{id}/property-major-repairs") - fill_in_date(id, "mrcdate", 12, nil, 2000, "property-major-repairs") + fill_in_date(id, "mrcdate", 12, nil, current_collection_start_year, "property-major-repairs") click_button("Save and continue") expect(page).to have_current_path("/lettings-logs/#{id}/property-major-repairs") - fill_in_date(id, "mrcdate", nil, 10, 2020, "property-major-repairs") + fill_in_date(id, "mrcdate", nil, 10, current_collection_start_year, "property-major-repairs") click_button("Save and continue") expect(page).to have_current_path("/lettings-logs/#{id}/property-major-repairs") end it "allows valid inputs to be submitted" do - fill_in_date(id, "mrcdate", 21, 11, 2020, "property-major-repairs") + valid_mcrdate = lettings_log.startdate - 1.day + fill_in_date(id, "mrcdate", valid_mcrdate.day, valid_mcrdate.month, valid_mcrdate.year, "property-major-repairs") click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{id}/local-authority/check-answers") + expect(page).to have_current_path("/lettings-logs/#{id}/property-information/check-answers") end end @@ -120,68 +101,69 @@ RSpec.describe "validations" do hhmemb: 1, ecstat1: 1, assigned_to: user, + net_income_known: 0, ) end let(:income_over_soft_limit) { 750 } let(:income_under_soft_limit) { 700 } before do - visit("/lettings-logs/#{lettings_log.id}/net-income") + visit("/lettings-logs/#{lettings_log.id}/income-amount") fill_in("lettings-log-earnings-field", with: income_over_soft_limit) choose("lettings-log-incfreq-1-field", allow_label_click: true) click_button("Save and continue") end it "prompts the user to confirm the value is correct with an interruption screen" do - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income-value-check") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount-net-income-value-check") expect(page).to have_content("You told us that the household’s income is £750.00 weekly") expect(page).to have_content("This is higher than we would expect for the household’s working situation.") expect(page).not_to have_button("Save changes") click_button("Confirm and continue") - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income-uc-proportion") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/housing-benefit") end it "allows to fix the questions that trigger the soft validation" do - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income-value-check") - expect(page).to have_link("Change", href: "/lettings-logs/#{lettings_log.id}/net-income?referrer=interruption_screen").twice - expect(page).to have_link("Change", href: "/lettings-logs/#{lettings_log.id}/person-1-working-situation?referrer=interruption_screen") - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income-value-check") - click_link("Change", href: "/lettings-logs/#{lettings_log.id}/net-income?referrer=interruption_screen", match: :first) - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income?referrer=interruption_screen") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount-net-income-value-check") + expect(page).to have_link("Change", href: "/lettings-logs/#{lettings_log.id}/income-amount?referrer=interruption_screen").twice + expect(page).to have_link("Change", href: "/lettings-logs/#{lettings_log.id}/lead-tenant-working-situation?referrer=interruption_screen") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount-net-income-value-check") + click_link("Change", href: "/lettings-logs/#{lettings_log.id}/income-amount?referrer=interruption_screen", match: :first) + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount?referrer=interruption_screen") fill_in("lettings-log-earnings-field", with: income_under_soft_limit) choose("lettings-log-incfreq-1-field", allow_label_click: true) click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income-value-check") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount-net-income-value-check") expect(page).not_to have_content("You told us that the household’s income is £750.00 weekly") expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success") end it "allows to fix the questions from different sections" do - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income-value-check") - expect(page).to have_link("Change", href: "/lettings-logs/#{lettings_log.id}/net-income?referrer=interruption_screen").twice - expect(page).to have_link("Change", href: "/lettings-logs/#{lettings_log.id}/person-1-working-situation?referrer=interruption_screen") - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income-value-check") - click_link("Change", href: "/lettings-logs/#{lettings_log.id}/person-1-working-situation?referrer=interruption_screen") - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/person-1-working-situation?referrer=interruption_screen") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount-net-income-value-check") + expect(page).to have_link("Change", href: "/lettings-logs/#{lettings_log.id}/income-amount?referrer=interruption_screen").twice + expect(page).to have_link("Change", href: "/lettings-logs/#{lettings_log.id}/lead-tenant-working-situation?referrer=interruption_screen") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount-net-income-value-check") + click_link("Change", href: "/lettings-logs/#{lettings_log.id}/lead-tenant-working-situation?referrer=interruption_screen") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/lead-tenant-working-situation?referrer=interruption_screen") choose("lettings-log-ecstat1-10-field", allow_label_click: true) click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income-value-check") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount-net-income-value-check") expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success") end it "returns the user back to the check_your_answers after fixing a validation from check_your_answers" do lettings_log.update!(earnings: income_under_soft_limit, incfreq: 1, net_income_value_check: 1) visit("/lettings-logs/#{lettings_log.id}/income-and-benefits/check-answers") - click_link("Change", href: "/lettings-logs/#{lettings_log.id}/net-income?referrer=check_answers", match: :first) - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income?referrer=check_answers") + click_link("Change", href: "/lettings-logs/#{lettings_log.id}/income-amount?referrer=check_answers", match: :first) + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount?referrer=check_answers") fill_in("lettings-log-earnings-field", with: income_over_soft_limit) click_button("Save changes") - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income-value-check?referrer=check_answers") - click_link("Change", href: "/lettings-logs/#{lettings_log.id}/net-income?referrer=interruption_screen", match: :first) - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income?referrer=interruption_screen") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount-net-income-value-check?referrer=check_answers") + click_link("Change", href: "/lettings-logs/#{lettings_log.id}/income-amount?referrer=interruption_screen", match: :first) + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount?referrer=interruption_screen") fill_in("lettings-log-earnings-field", with: income_under_soft_limit) click_button("Save and continue") - expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/net-income-value-check?referrer=check_answers") + expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-amount-net-income-value-check?referrer=check_answers") click_button("Confirm and continue") expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/income-and-benefits/check-answers") end diff --git a/spec/lib/tasks/set_sales_managing_organisation_spec.rb b/spec/lib/tasks/set_sales_managing_organisation_spec.rb index 8ca3f3485..90d81329e 100644 --- a/spec/lib/tasks/set_sales_managing_organisation_spec.rb +++ b/spec/lib/tasks/set_sales_managing_organisation_spec.rb @@ -2,6 +2,8 @@ require "rails_helper" require "rake" RSpec.describe "set_sales_managing_organisation" do + include CollectionTimeHelper + describe ":set_sales_managing_organisation", type: :task do subject(:task) { Rake::Task["set_sales_managing_organisation"] } @@ -34,7 +36,7 @@ RSpec.describe "set_sales_managing_organisation" do end it "skips validations" do - sales_log.saledate = Time.zone.local(2021, 3, 3) + sales_log.saledate = archived_collection_start_date sales_log.save!(validate: false) expect(sales_log.managing_organisation_id).to be_nil expect(sales_log.status).to eq("in_progress") diff --git a/spec/lib/tasks/update_schemes_and_locations_from_csv_spec.rb b/spec/lib/tasks/update_schemes_and_locations_from_csv_spec.rb index b6e05a5a1..deef814f6 100644 --- a/spec/lib/tasks/update_schemes_and_locations_from_csv_spec.rb +++ b/spec/lib/tasks/update_schemes_and_locations_from_csv_spec.rb @@ -611,8 +611,6 @@ RSpec.describe "bulk_update" do supcharg: 50, beds: 4, lettype: 1, - voiddate: Time.zone.local(2020, 4, 1), - mrcdate: Time.zone.local(2020, 4, 1), period: 1) end diff --git a/spec/models/form_handler_spec.rb b/spec/models/form_handler_spec.rb index bfa164ee5..11611e97d 100644 --- a/spec/models/form_handler_spec.rb +++ b/spec/models/form_handler_spec.rb @@ -1,8 +1,10 @@ require "rails_helper" RSpec.describe FormHandler do + include CollectionTimeHelper + let(:form_handler) { described_class.instance } - let(:now) { Time.utc(2022, 9, 20) } + let(:now) { current_collection_start_date } around do |example| Timecop.freeze(now) do @@ -12,8 +14,6 @@ RSpec.describe FormHandler do end context "when accessing a form in a different year" do - let(:now) { Time.utc(2021, 8, 3) } - it "is able to load a current lettings form" do form = form_handler.get_form("current_lettings") expect(form).to be_a(Form) @@ -34,65 +34,59 @@ RSpec.describe FormHandler do expect(all_forms["current_sales"]).to be_a(Form) end - context "when in 23/24 period or later" do - let(:now) { Time.utc(2023, 6, 7) } - - it "does not load outdated forms" do - all_forms = form_handler.forms - expect(all_forms.keys).not_to include nil - end + it "does not load outdated forms" do + all_forms = form_handler.forms + expect(all_forms.keys).not_to include nil + end - it "loads archived forms" do - all_forms = form_handler.forms - expect(all_forms.keys).to include("archived_sales") - expect(all_forms.keys).to include("archived_lettings") - end + it "loads archived forms" do + all_forms = form_handler.forms + expect(all_forms.keys).to include("archived_sales") + expect(all_forms.keys).to include("archived_lettings") end end describe "Get specific form" do - let(:now) { Time.utc(2023, 9, 20) } - it "is able to load a current lettings form" do form = form_handler.get_form("current_lettings") expect(form).to be_a(Form) expect(form.pages.count).to be_positive - expect(form.name).to eq("2023_2024_lettings") + expect(form.name).to eq("#{current_collection_start_year}_#{current_collection_end_year}_lettings") end it "is able to load a previous lettings form" do form = form_handler.get_form("previous_lettings") expect(form).to be_a(Form) expect(form.pages.count).to be_positive - expect(form.name).to eq("2022_2023_lettings") + expect(form.name).to eq("#{previous_collection_start_year}_#{previous_collection_end_year}_lettings") end it "is able to load a archived lettings form" do form = form_handler.get_form("archived_lettings") expect(form).to be_a(Form) expect(form.pages.count).to be_positive - expect(form.name).to eq("2021_2022_lettings") + expect(form.name).to eq("#{archived_collection_start_year}_#{archived_collection_end_year}_lettings") end it "is able to load a current sales form" do form = form_handler.get_form("current_sales") expect(form).to be_a(Form) expect(form.pages.count).to be_positive - expect(form.name).to eq("2023_2024_sales") + expect(form.name).to eq("#{current_collection_start_year}_#{current_collection_end_year}_sales") end it "is able to load a previous sales form" do form = form_handler.get_form("previous_sales") expect(form).to be_a(Form) expect(form.pages.count).to be_positive - expect(form.name).to eq("2022_2023_sales") + expect(form.name).to eq("#{previous_collection_start_year}_#{previous_collection_end_year}_sales") end it "is able to load a archived sales form" do form = form_handler.get_form("archived_sales") expect(form).to be_a(Form) expect(form.pages.count).to be_positive - expect(form.name).to eq("2021_2022_sales") + expect(form.name).to eq("#{archived_collection_start_year}_#{archived_collection_end_year}_sales") end end @@ -100,92 +94,92 @@ RSpec.describe FormHandler do it "returns the latest form by date" do form = form_handler.current_lettings_form expect(form).to be_a(Form) - expect(form.start_date.year).to eq(2022) + expect(form.start_date.year).to eq(current_collection_start_year) end end describe "Current collection start year" do context "when the date is after 1st of April" do - let(:now) { Time.utc(2023, 8, 3) } + let(:now) { Time.utc(current_collection_start_year, 8, 3) } it "returns the same year as the current start year" do - expect(form_handler.current_collection_start_year).to eq(2023) + expect(form_handler.current_collection_start_year).to eq(current_collection_start_year) end it "returns the correct current lettings form name" do - expect(form_handler.form_name_from_start_year(2023, "lettings")).to eq("current_lettings") + expect(form_handler.form_name_from_start_year(current_collection_start_year, "lettings")).to eq("current_lettings") end it "returns the correct previous lettings form name" do - expect(form_handler.form_name_from_start_year(2022, "lettings")).to eq("previous_lettings") + expect(form_handler.form_name_from_start_year(previous_collection_start_year, "lettings")).to eq("previous_lettings") end it "returns the correct next lettings form name" do - expect(form_handler.form_name_from_start_year(2024, "lettings")).to eq("next_lettings") + expect(form_handler.form_name_from_start_year(next_collection_start_year, "lettings")).to eq("next_lettings") end it "returns the correct archived lettings form name" do - expect(form_handler.form_name_from_start_year(2021, "lettings")).to eq("archived_lettings") + expect(form_handler.form_name_from_start_year(archived_collection_start_year, "lettings")).to eq("archived_lettings") end it "returns the correct current sales form name" do - expect(form_handler.form_name_from_start_year(2023, "sales")).to eq("current_sales") + expect(form_handler.form_name_from_start_year(current_collection_start_year, "sales")).to eq("current_sales") end it "returns the correct previous sales form name" do - expect(form_handler.form_name_from_start_year(2022, "sales")).to eq("previous_sales") + expect(form_handler.form_name_from_start_year(previous_collection_start_year, "sales")).to eq("previous_sales") end it "returns the correct next sales form name" do - expect(form_handler.form_name_from_start_year(2024, "sales")).to eq("next_sales") + expect(form_handler.form_name_from_start_year(next_collection_start_year, "sales")).to eq("next_sales") end it "returns the correct archived sales form name" do - expect(form_handler.form_name_from_start_year(2021, "sales")).to eq("archived_sales") + expect(form_handler.form_name_from_start_year(archived_collection_start_year, "sales")).to eq("archived_sales") end it "returns the correct current start date" do - expect(form_handler.current_collection_start_date).to eq(Time.zone.local(2023, 4, 1)) + expect(form_handler.current_collection_start_date).to eq(current_collection_start_date) end end context "with the date before 1st of April" do - let(:now) { Time.utc(2023, 2, 3) } + let(:now) { Time.utc(current_collection_end_year, 2, 3) } it "returns the previous year as the current start year" do - expect(form_handler.current_collection_start_year).to eq(2022) + expect(form_handler.current_collection_start_year).to eq(current_collection_start_year) end it "returns the correct current lettings form name" do - expect(form_handler.form_name_from_start_year(2022, "lettings")).to eq("current_lettings") + expect(form_handler.form_name_from_start_year(current_collection_start_year, "lettings")).to eq("current_lettings") end it "returns the correct previous lettings form name" do - expect(form_handler.form_name_from_start_year(2021, "lettings")).to eq("previous_lettings") + expect(form_handler.form_name_from_start_year(previous_collection_start_year, "lettings")).to eq("previous_lettings") end it "returns the correct next lettings form name" do - expect(form_handler.form_name_from_start_year(2023, "lettings")).to eq("next_lettings") + expect(form_handler.form_name_from_start_year(next_collection_start_year, "lettings")).to eq("next_lettings") end it "returns the correct archived lettings form name" do - expect(form_handler.form_name_from_start_year(2020, "lettings")).to eq("archived_lettings") + expect(form_handler.form_name_from_start_year(archived_collection_start_year, "lettings")).to eq("archived_lettings") end it "returns the correct current sales form name" do - expect(form_handler.form_name_from_start_year(2022, "sales")).to eq("current_sales") + expect(form_handler.form_name_from_start_year(current_collection_start_year, "sales")).to eq("current_sales") end it "returns the correct previous sales form name" do - expect(form_handler.form_name_from_start_year(2021, "sales")).to eq("previous_sales") + expect(form_handler.form_name_from_start_year(previous_collection_start_year, "sales")).to eq("previous_sales") end it "returns the correct next sales form name" do - expect(form_handler.form_name_from_start_year(2023, "sales")).to eq("next_sales") + expect(form_handler.form_name_from_start_year(next_collection_start_year, "sales")).to eq("next_sales") end it "returns the correct archived sales form name" do - expect(form_handler.form_name_from_start_year(2020, "sales")).to eq("archived_sales") + expect(form_handler.form_name_from_start_year(archived_collection_start_year, "sales")).to eq("archived_sales") end end end @@ -199,65 +193,20 @@ RSpec.describe FormHandler do it "correctly sets form type and start year" do form = form_handler.forms["current_lettings"] expect(form.type).to eq("lettings") - expect(form.start_date.year).to eq(2022) + expect(form.start_date.year).to eq(current_collection_start_year) end # rubocop:disable RSpec/PredicateMatcher describe "#in_crossover_period?" do context "when not in overlapping period" do it "returns false" do - expect(form_handler.in_crossover_period?(now: Date.new(2023, 1, 1))).to be_falsey + expect(form_handler.in_crossover_period?(now: Date.new(current_collection_start_year, 1, 1))).to be_falsey end end context "when in overlapping period" do it "returns true" do - expect(form_handler.in_crossover_period?(now: Date.new(2022, 6, 1))).to be_truthy - end - end - end - - describe "lettings_forms" do - context "when current and previous forms are defined in JSON (current collection start year before 2023)" do - let(:now) { Time.utc(2022, 9, 20) } - - it "creates a next_lettings form from ruby form objects" do - expect(form_handler.lettings_forms["previous_lettings"]).to be_present - expect(form_handler.lettings_forms["previous_lettings"].start_date.year).to eq(2021) - expect(form_handler.lettings_forms["current_lettings"]).to be_present - expect(form_handler.lettings_forms["current_lettings"].start_date.year).to eq(2022) - expect(form_handler.lettings_forms["next_lettings"]).to be_present - expect(form_handler.lettings_forms["next_lettings"].start_date.year).to eq(2023) - end - end - - context "when only previous form is defined in JSON (current collection start year 2023)" do - let(:now) { Time.utc(2023, 9, 20) } - - it "creates current_lettings and next_lettings forms from ruby form objects" do - expect(form_handler.lettings_forms["archived_lettings"]).to be_present - expect(form_handler.lettings_forms["archived_lettings"].start_date.year).to eq(2021) - expect(form_handler.lettings_forms["previous_lettings"]).to be_present - expect(form_handler.lettings_forms["previous_lettings"].start_date.year).to eq(2022) - expect(form_handler.lettings_forms["current_lettings"]).to be_present - expect(form_handler.lettings_forms["current_lettings"].start_date.year).to eq(2023) - expect(form_handler.lettings_forms["next_lettings"]).to be_present - expect(form_handler.lettings_forms["next_lettings"].start_date.year).to eq(2024) - end - end - - context "when only archived form is defined in JSON (current collection start year 2024 onwards)" do - let(:now) { Time.utc(2024, 5, 20) } - - it "creates previous_lettings, current_lettings and next_lettings forms from ruby form objects and archived form from json" do - expect(form_handler.lettings_forms["archived_lettings"]).to be_present - expect(form_handler.lettings_forms["archived_lettings"].start_date.year).to eq(2022) - expect(form_handler.lettings_forms["previous_lettings"]).to be_present - expect(form_handler.lettings_forms["previous_lettings"].start_date.year).to eq(2023) - expect(form_handler.lettings_forms["current_lettings"]).to be_present - expect(form_handler.lettings_forms["current_lettings"].start_date.year).to eq(2024) - expect(form_handler.lettings_forms["next_lettings"]).to be_present - expect(form_handler.lettings_forms["next_lettings"].start_date.year).to eq(2025) + expect(form_handler.in_crossover_period?(now: Date.new(current_collection_start_year, 6, 1))).to be_truthy end end end diff --git a/spec/models/lettings_log_spec.rb b/spec/models/lettings_log_spec.rb index 9f2f7c675..af8ce02bf 100644 --- a/spec/models/lettings_log_spec.rb +++ b/spec/models/lettings_log_spec.rb @@ -7,18 +7,6 @@ RSpec.describe LettingsLog do let(:different_managing_organisation) { create(:organisation) } let(:owning_organisation) { create(:organisation, rent_periods: [2]) } let(:assigned_to_user) { create(:user, organisation: owning_organisation) } - let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } - - around do |example| - Timecop.freeze(Time.utc(2022, 1, 1)) do - Singleton.__init__(FormHandler) - example.run - end - end - - before do - allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form) - end include_examples "shared examples for derived fields", :lettings_log include_examples "shared log examples", :lettings_log @@ -40,16 +28,8 @@ RSpec.describe LettingsLog do describe "#form" do let(:lettings_log) { build(:lettings_log, assigned_to: assigned_to_user) } - let(:lettings_log_2) { build(:lettings_log, startdate: Time.zone.local(2022, 1, 1), assigned_to: assigned_to_user) } - let(:lettings_log_year_2) { build(:lettings_log, startdate: Time.zone.local(2023, 5, 1), assigned_to: assigned_to_user) } - - before do - Timecop.freeze(2023, 1, 1) - end - - after do - Timecop.unfreeze - end + let(:lettings_log_2) { build(:lettings_log, startdate: previous_collection_start_date, assigned_to: assigned_to_user) } + let(:lettings_log_year_2) { build(:lettings_log, startdate: next_collection_start_date, assigned_to: assigned_to_user) } it "returns the correct form based on the start date" do expect(lettings_log.form_name).to be_nil @@ -61,11 +41,11 @@ RSpec.describe LettingsLog do end context "when a date outside the collection window is passed" do - let(:lettings_log) { build(:lettings_log, startdate: Time.zone.local(2015, 1, 1), assigned_to: assigned_to_user) } + let(:lettings_log) { build(:lettings_log, startdate: current_collection_start_date - 10.years, assigned_to: assigned_to_user) } - it "returns the first form" do + it "returns the current form as fallback" do expect(lettings_log.form).to be_a(Form) - expect(lettings_log.form.start_date.year).to eq(2021) + expect(lettings_log.form.start_date.year).to eq(current_collection_start_year) end end end @@ -276,20 +256,22 @@ RSpec.describe LettingsLog do assigned_to: assigned_to_user, postcode_full: "M1 1AE", ppostcode_full: "M2 2AE", - startdate: Time.gm(2021, 10, 10), - mrcdate: Time.gm(2021, 5, 4), - voiddate: Time.gm(2021, 3, 3), + startdate: Time.zone.today, + mrcdate: Time.zone.today - 1.week, + voiddate: Time.zone.today - 2.weeks, + needstype: 1, + renewal: 0, + declaration: 1, net_income_known: 2, # refused hhmemb: 7, rent_type: 4, hb: 1, hbrentshortfall: 1, - created_at: Time.utc(2022, 2, 8, 16, 52, 15), ) end def check_postcode_fields(postcode_field) - record_from_db = described_class.find(lettings_log.id) + record_from_db = described_class.find(address_lettings_log.id) expect(address_lettings_log[postcode_field]).to eq("M1 1AE") expect(record_from_db[postcode_field]).to eq("M1 1AE") end @@ -313,6 +295,7 @@ RSpec.describe LettingsLog do assigned_to: assigned_to_user, postcode_known: 1, postcode_full: "M1 1AE", + manual_address_entry_selected: true, }) end @@ -490,19 +473,11 @@ RSpec.describe LettingsLog do end context "when a lettings log is a supported housing log" do - let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") } - before do lettings_log.needstype = 2 - allow(FormHandler.instance).to receive(:get_form).and_return(real_2021_2022_form) end describe "when changing a log's scheme and hence calling reset_scheme_location!" do - before do - Timecop.return - Singleton.__init__(FormHandler) - end - context "when there is one valid location and many invalid locations in the new scheme" do let(:scheme) { create(:scheme) } let(:invalid_location_1) { create(:location, scheme:, startdate: Time.zone.today + 3.weeks) } @@ -549,13 +524,7 @@ RSpec.describe LettingsLog do let!(:location) { create(:location, scheme:) } before do - Timecop.freeze(Time.zone.local(2022, 4, 2)) - Singleton.__init__(FormHandler) - lettings_log.update!(startdate: Time.zone.local(2022, 4, 2), scheme:) - end - - after do - Timecop.unfreeze + lettings_log.update!(startdate: current_collection_start_date + 1.day, scheme:, voiddate: nil, mrcdate: nil) end it "derives the scheme location" do @@ -579,22 +548,11 @@ RSpec.describe LettingsLog do Singleton.__init__(FormHandler) end - context "with 22/23" do - let(:startdate) { Time.zone.local(2022, 4, 2) } - - it "returns the correct la" do - expect(lettings_log["location_id"]).to eq(location.id) - expect(lettings_log.la).to eq("E07000030") - end - end - - context "with 23/24" do - let(:startdate) { Time.zone.local(2023, 4, 2) } + let(:startdate) { current_collection_start_date } - it "returns the correct la" do - expect(lettings_log["location_id"]).to eq(location.id) - expect(lettings_log.la).to eq("E06000063") - end + it "returns the correct la" do + expect(lettings_log["location_id"]).to eq(location.id) + expect(lettings_log.la).to eq("E06000063") end end @@ -657,13 +615,9 @@ RSpec.describe LettingsLog do context "and the location no local authorities associated with the location_code" do before do - Timecop.freeze(Time.zone.local(2022, 4, 2)) location.update!(location_code: "E01231231") - lettings_log.update!(location:) - end - - after do - Timecop.return + lettings_log.update_columns(la: nil) + lettings_log.reload end it "returns the correct la" do @@ -690,7 +644,7 @@ RSpec.describe LettingsLog do Singleton.__init__(FormHandler) end - context "with 25/26" do + context "with 25/26", metadata: { year: 25 } do let(:startdate) { Time.zone.local(2025, 4, 2) } it "returns the postcode from the location" do @@ -699,7 +653,7 @@ RSpec.describe LettingsLog do end end - context "with 26/27" do + context "with 26/27", metadata: { year: 26 } do let(:startdate) { Time.zone.local(2026, 4, 2) } it "returns the postcode from the log itself" do @@ -712,24 +666,13 @@ RSpec.describe LettingsLog do context "and the log only has a postcode set on the location" do before do location.update!(postcode: "AA1 1AA") - Timecop.freeze(startdate) - Singleton.__init__(FormHandler) - lettings_log.update!(startdate:) + lettings_log.update!(postcode_full: nil) lettings_log.reload end - after do - Timecop.unfreeze - Singleton.__init__(FormHandler) - end - - context "with 26/27" do - let(:startdate) { Time.zone.local(2026, 4, 2) } - - it "returns the LA from the location" do - expect(lettings_log["location_id"]).to eq(location.id) - expect(lettings_log.postcode_full).to eq("AA1 1AA") - end + it "returns the postcode from the location" do + expect(lettings_log["location_id"]).to eq(location.id) + expect(lettings_log.postcode_full).to eq("AA1 1AA") end end end @@ -929,23 +872,13 @@ RSpec.describe LettingsLog do managing_organisation: owning_organisation, owning_organisation:, assigned_to: assigned_to_user, - startdate: Time.zone.local(2024, 4, 10), + startdate: current_collection_start_date + 9.days, needstype: 1, renewal: 1, rent_type: 1, }) end - before do - Timecop.freeze(Time.zone.local(2024, 4, 10)) - Singleton.__init__(FormHandler) - end - - after do - Timecop.return - Singleton.__init__(FormHandler) - end - it "correctly derives nationality_all when it's UK" do expect { lettings_log.update!(nationality_all_group: 826, declaration: 1) }.to change(lettings_log, :nationality_all).to 826 end @@ -976,16 +909,6 @@ RSpec.describe LettingsLog do end context "when the log changes from new build to not new build" do - before do - allow(FormHandler.instance).to receive(:current_lettings_form).and_call_original - Timecop.freeze(2025, 5, 1) - Singleton.__init__(FormHandler) - end - - after do - Timecop.unfreeze - end - context "and the address is entered" do let(:address_lettings_log) do create(:lettings_log, @@ -1054,16 +977,6 @@ RSpec.describe LettingsLog do end context "when the log changes from not new build to new build" do - before do - allow(FormHandler.instance).to receive(:current_lettings_form).and_call_original - Timecop.freeze(2025, 5, 1) - Singleton.__init__(FormHandler) - end - - after do - Timecop.unfreeze - end - context "and the uprn is selected" do let(:address_lettings_log) do create(:lettings_log, @@ -1163,17 +1076,18 @@ RSpec.describe LettingsLog do end describe "optional fields" do - let(:lettings_log) { create(:lettings_log) } - context "when tshortfall is marked as not known" do + let(:lettings_log) do + build(:lettings_log, hb: 1, hbrentshortfall: 1, period: 1, tshortfall: nil, tshortfall_known: 1) + end + it "makes tshortfall optional" do - lettings_log.update!({ tshortfall: nil, tshortfall_known: 1 }) expect(lettings_log.optional_fields).to include("tshortfall") end end - context "when startdate is after 2023" do - let(:lettings_log) { build(:lettings_log, startdate: Time.zone.parse("2023-07-01")) } + context "when startdate is in the current collection year" do + let(:lettings_log) { build(:lettings_log, startdate: current_collection_start_date + 1.day) } it "returns optional fields" do expect(lettings_log.optional_fields).to eq(%w[ @@ -1194,6 +1108,7 @@ RSpec.describe LettingsLog do let(:lettings_log) do create( :lettings_log, + :setup_completed, renewal: 0, rsnvac: 5, first_time_property_let_as_social_housing: 0, @@ -1229,15 +1144,15 @@ RSpec.describe LettingsLog do context "when a question that has already been answered, no longer has met dependencies" do let(:lettings_log) { create(:lettings_log, :in_progress, cbl: 1, preg_occ: 2, wchair: 2) } - it "clears the answer" do - expect { lettings_log.update!(preg_occ: nil) }.to change(lettings_log, :cbl).from(1).to(nil) + it "does not clear the answer" do + expect { lettings_log.update!(preg_occ: nil) }.not_to change(lettings_log, :cbl) end context "when the question type does not have answer options" do let(:lettings_log) { create(:lettings_log, :in_progress, housingneeds_a: 1, age1: 19) } - it "clears the answer" do - expect { lettings_log.update!(housingneeds_a: 0) }.to change(lettings_log, :age1).from(19).to(nil) + it "does not clear the answer" do + expect { lettings_log.update!(housingneeds_a: 0) }.not_to change(lettings_log, :age1) end end @@ -1250,31 +1165,6 @@ RSpec.describe LettingsLog do end end - context "with two pages having the same question key, only one's dependency is met" do - let(:lettings_log) { create(:lettings_log, :in_progress, cbl: 0, preg_occ: 2, wchair: 2) } - - it "does not clear the value for answers that apply to both pages" do - expect(lettings_log.cbl).to eq(0) - end - - it "does clear the value for answers that do not apply for invalidated page" do - lettings_log.update!({ cbl: 1 }) - lettings_log.update!({ preg_occ: 1 }) - - expect(lettings_log.cbl).to be_nil - end - end - - context "when a non select question associated with several pages is routed to" do - let(:lettings_log) { create(:lettings_log, :in_progress, period: 2, needstype: 1, renewal: 0) } - - it "does not clear the answer value" do - lettings_log.update!({ unitletas: 1 }) - lettings_log.reload - expect(lettings_log.unitletas).to eq(1) - end - end - context "when the lettings log does not have a valid form set yet" do let(:lettings_log) { create(:lettings_log) } @@ -1338,12 +1228,12 @@ RSpec.describe LettingsLog do it "clears void date value" do lettings_log.update!(startdate: Time.zone.yesterday) lettings_log.reload - expect(lettings_log.startdate).to eq(Time.zone.yesterday) + expect(lettings_log.startdate.to_date).to eq(Time.zone.yesterday.to_date) expect(lettings_log.voiddate).to be_nil end it "does not impact other validations" do - expect { lettings_log.update!(startdate: Time.zone.yesterday, referral: 8, rsnvac: 9) } + expect { lettings_log.update!(startdate: Time.zone.yesterday, first_time_property_let_as_social_housing: 0, referral: 8, rsnvac: 9) } .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t('validations.lettings.property.rsnvac.referral_invalid')}/) end end @@ -1352,21 +1242,12 @@ RSpec.describe LettingsLog do it "clears major repairs date value" do lettings_log.update!(startdate: Time.zone.yesterday) lettings_log.reload - expect(lettings_log.startdate).to eq(Time.zone.yesterday) + expect(lettings_log.startdate.to_date).to eq(Time.zone.yesterday.to_date) expect(lettings_log.mrcdate).to be_nil end end context "and the new location triggers the rent range validation" do - around do |example| - Timecop.freeze(Time.zone.local(2022, 4, 1)) do - Singleton.__init__(FormHandler) - example.run - end - Timecop.return - Singleton.__init__(FormHandler) - end - it "clears rent values" do lettings_log.update!(location:, scheme:) lettings_log.reload @@ -1379,7 +1260,7 @@ RSpec.describe LettingsLog do end it "does not impact other validations" do - expect { lettings_log.update!(startdate: Time.zone.yesterday, referral: 8, rsnvac: 9) } + expect { lettings_log.update!(startdate: Time.zone.yesterday, first_time_property_let_as_social_housing: 0, referral: 8, rsnvac: 9) } .to raise_error(ActiveRecord::RecordInvalid, /#{I18n.t('validations.lettings.property.rsnvac.referral_invalid')}/) end end @@ -1389,16 +1270,16 @@ RSpec.describe LettingsLog do context "and the new startdate triggers void date validation" do it "doesn't clear void date value" do expect { lettings_log.update!(startdate: Time.zone.yesterday) }.to raise_error(ActiveRecord::RecordInvalid, /Enter a void date that is before the tenancy start date/) - expect(lettings_log.startdate).to eq(Time.zone.yesterday) - expect(lettings_log.voiddate).to eq(Time.zone.today) + expect(lettings_log.startdate.to_date).to eq(Time.zone.yesterday.to_date) + expect(lettings_log.voiddate.to_date).to eq(Time.zone.today.to_date) end end context "and the new startdate triggers major repairs date validation" do it "doesn't clear major repairs date value" do expect { lettings_log.update!(startdate: Time.zone.yesterday) }.to raise_error(ActiveRecord::RecordInvalid, /Enter a major repairs date that is before the tenancy start date/) - expect(lettings_log.startdate).to eq(Time.zone.yesterday) - expect(lettings_log.mrcdate).to eq(Time.zone.today) + expect(lettings_log.startdate.to_date).to eq(Time.zone.yesterday.to_date) + expect(lettings_log.mrcdate.to_date).to eq(Time.zone.today.to_date) end end @@ -1416,7 +1297,7 @@ RSpec.describe LettingsLog do describe "tshortfall_unknown?" do context "when tshortfall is nil" do - let(:lettings_log) { create(:lettings_log, :in_progress, tshortfall_known: nil) } + let(:lettings_log) { create(:lettings_log, :in_progress, hb: 1, hbrentshortfall: 1, period: 1, tshortfall_known: nil) } it "returns false" do expect(lettings_log.tshortfall_unknown?).to be false @@ -1424,15 +1305,15 @@ RSpec.describe LettingsLog do end context "when tshortfall is No" do - let(:lettings_log) { create(:lettings_log, :in_progress, tshortfall_known: 1) } + let(:lettings_log) { create(:lettings_log, :in_progress, hb: 1, hbrentshortfall: 1, period: 1, tshortfall_known: 1) } - it "returns false" do + it "returns true" do expect(lettings_log.tshortfall_unknown?).to be true end end context "when tshortfall is Yes" do - let(:lettings_log) { create(:lettings_log, :in_progress, tshortfall_known: 0) } + let(:lettings_log) { create(:lettings_log, :in_progress, hb: 1, hbrentshortfall: 1, period: 1, tshortfall_known: 0) } it "returns false" do expect(lettings_log.tshortfall_unknown?).to be false @@ -1466,13 +1347,13 @@ RSpec.describe LettingsLog do soft_max: 400, hard_min: 50, hard_max: 500, - start_year: 2021, + start_year: current_collection_start_year, ) lettings_log.la = "E07000223" lettings_log.lettype = 1 lettings_log.beds = 1 - lettings_log.startdate = Time.zone.local(2021, 10, 10) + lettings_log.startdate = current_collection_start_date + 6.months end context "when period is weekly for 52 weeks" do @@ -1501,17 +1382,22 @@ RSpec.describe LettingsLog do end describe "scopes" do - let!(:lettings_log_1) { create(:lettings_log, :in_progress, startdate: Time.utc(2021, 5, 3), mrcdate: Time.utc(2021, 5, 3), voiddate: Time.utc(2021, 5, 3), assigned_to: assigned_to_user) } - let!(:lettings_log_2) { create(:lettings_log, :completed, startdate: Time.utc(2021, 5, 3), mrcdate: Time.utc(2021, 5, 3), voiddate: Time.utc(2021, 5, 3), assigned_to: assigned_to_user) } + # These examples need logs in both the previous and the current collection year, + # so we have to enforce we are in the crossover period + around do |example| + Timecop.freeze(current_collection_start_date) do + Singleton.__init__(FormHandler) + example.run + end + Singleton.__init__(FormHandler) + end + + let!(:lettings_log_1) { create(:lettings_log, :in_progress, startdate: previous_collection_start_date + 1.month, mrcdate: previous_collection_start_date, voiddate: previous_collection_start_date, assigned_to: assigned_to_user) } + let!(:lettings_log_2) { create(:lettings_log, :completed, startdate: previous_collection_start_date + 1.month, mrcdate: previous_collection_start_date, voiddate: previous_collection_start_date, assigned_to: assigned_to_user) } let(:postcode_to_search) { "SW1A 0AA" } before do - Timecop.freeze(Time.utc(2022, 6, 3)) - create(:lettings_log, startdate: Time.utc(2022, 6, 3)) - end - - after do - Timecop.unfreeze + create(:lettings_log, startdate: Time.zone.today) end context "when searching logs" do @@ -1689,62 +1575,46 @@ RSpec.describe LettingsLog do end context "when filtering by year" do - before do - Timecop.freeze(Time.utc(2021, 5, 3)) - end - - after do - Timecop.unfreeze - end - it "allows filtering on a single year" do - expect(described_class.filter_by_years(%w[2021]).count).to eq(2) + expect(described_class.filter_by_years([previous_collection_start_year.to_s]).count).to eq(2) end it "allows filtering by multiple years using OR" do - expect(described_class.filter_by_years(%w[2021 2022]).count).to eq(3) + expect(described_class.filter_by_years([previous_collection_start_year.to_s, current_collection_start_year.to_s]).count).to eq(3) end it "can filter by year(s) AND status" do - expect(described_class.filter_by_years(%w[2021 2022]).filter_by_status("completed").count).to eq(1) + expect(described_class.filter_by_years([previous_collection_start_year.to_s, current_collection_start_year.to_s]).filter_by_status("completed").count).to eq(1) end it "filters based on date boundaries correctly" do - lettings_log_1.startdate = Time.zone.local(2022, 4, 1) + lettings_log_1.startdate = current_collection_start_date lettings_log_1.save!(validate: false) - lettings_log_2.startdate = Time.zone.local(2022, 3, 31) + lettings_log_2.startdate = current_collection_start_date - 1.day lettings_log_2.save!(validate: false) - expect(described_class.filter_by_years(%w[2021]).count).to eq(1) - expect(described_class.filter_by_years(%w[2022]).count).to eq(2) + expect(described_class.filter_by_years([previous_collection_start_year.to_s]).count).to eq(1) + expect(described_class.filter_by_years([current_collection_start_year.to_s]).count).to eq(2) end end context "when filtering by year or nil" do - before do - Timecop.freeze(Time.utc(2021, 5, 3)) - end - - after do - Timecop.unfreeze - end - it "allows filtering on a single year or nil" do lettings_log_1.startdate = nil lettings_log_1.save!(validate: false) - expect(described_class.filter_by_years_or_nil(%w[2021]).count).to eq(2) + expect(described_class.filter_by_years_or_nil([previous_collection_start_year.to_s]).count).to eq(2) end it "allows filtering by multiple years or nil using OR" do lettings_log_1.startdate = nil lettings_log_1.save!(validate: false) - expect(described_class.filter_by_years_or_nil(%w[2021 2022]).count).to eq(3) + expect(described_class.filter_by_years_or_nil([previous_collection_start_year.to_s, current_collection_start_year.to_s]).count).to eq(3) end it "can filter by year(s) AND status" do lettings_log_2.startdate = nil lettings_log_2.save!(validate: false) - expect(described_class.filter_by_years_or_nil(%w[2021 2022]).filter_by_status("in_progress").count).to eq(3) + expect(described_class.filter_by_years_or_nil([previous_collection_start_year.to_s, current_collection_start_year.to_s]).filter_by_status("in_progress").count).to eq(3) end end @@ -2107,28 +1977,23 @@ RSpec.describe LettingsLog do context "when there is a duplicate supported housing log" do let(:scheme) { create(:scheme, owning_organisation: organisation) } let(:location) { create(:location, scheme:) } - let(:location_2) { create(:location, scheme:) } let!(:supported_housing_log) { create(:lettings_log, :duplicate, needstype: 2, location:, scheme:, owning_organisation: organisation) } let!(:duplicate_supported_housing_log) { create(:lettings_log, :duplicate, needstype: 2, location:, scheme:, owning_organisation: organisation) } it "returns the log as a duplicate" do - expect(duplicate_sets.count).to eq(2) - expect(duplicate_sets.first).to contain_exactly(log.id, duplicate_log.id) - expect(duplicate_sets.second).to contain_exactly(duplicate_supported_housing_log.id, supported_housing_log.id) - end - - it "does not return the log if the locations are different" do - duplicate_supported_housing_log.update!(location: location_2) - expect(duplicate_sets.count).to eq(1) - expect(duplicate_sets.first).to contain_exactly(log.id, duplicate_log.id) + expect(duplicate_sets).to contain_exactly( + contain_exactly(log.id, duplicate_log.id), + contain_exactly(duplicate_supported_housing_log.id, supported_housing_log.id), + ) end it "does not compare tcharge if there are no household charges" do supported_housing_log.update!(household_charge: 1, supcharg: nil, brent: nil, scharge: nil, pscharge: nil, tcharge: nil, owning_organisation: organisation) duplicate_supported_housing_log.update!(household_charge: 1, supcharg: nil, brent: nil, scharge: nil, pscharge: nil, tcharge: nil, owning_organisation: organisation) - expect(duplicate_sets.count).to eq(2) - expect(duplicate_sets.first).to contain_exactly(log.id, duplicate_log.id) - expect(duplicate_sets.second).to contain_exactly(supported_housing_log.id, duplicate_supported_housing_log.id) + expect(duplicate_sets).to contain_exactly( + contain_exactly(log.id, duplicate_log.id), + contain_exactly(supported_housing_log.id, duplicate_supported_housing_log.id), + ) end it "does not return logs not associated with the user if user is given" do @@ -2142,9 +2007,10 @@ RSpec.describe LettingsLog do it "compares chcharge if it's a carehome" do supported_housing_log.update!(is_carehome: 1, chcharge: 100, supcharg: nil, brent: nil, scharge: nil, pscharge: nil, tcharge: nil, owning_organisation: organisation) duplicate_supported_housing_log.update!(is_carehome: 1, chcharge: 100, supcharg: nil, brent: nil, scharge: nil, pscharge: nil, tcharge: nil, owning_organisation: organisation) - expect(duplicate_sets.count).to eq(2) - expect(duplicate_sets.first).to contain_exactly(log.id, duplicate_log.id) - expect(duplicate_sets.second).to contain_exactly(supported_housing_log.id, duplicate_supported_housing_log.id) + expect(duplicate_sets).to contain_exactly( + contain_exactly(log.id, duplicate_log.id), + contain_exactly(supported_housing_log.id, duplicate_supported_housing_log.id), + ) end it "does not return a duplicate if carehome charge is not given" do @@ -2228,7 +2094,7 @@ RSpec.describe LettingsLog do end context "when form end date is in the past" do - let(:startdate) { Time.zone.local(2020, 4, 1) } + let(:startdate) { Time.zone.local(archived_collection_start_year, 4, 1) } before do allow(log).to receive_message_chain(:form, :new_logs_end_date).and_return(Time.zone.now - 1.day) @@ -2305,12 +2171,6 @@ RSpec.describe LettingsLog do end describe "#non_location_setup_questions_completed" do - before do - Timecop.return - allow(FormHandler.instance).to receive(:current_lettings_form).and_call_original - Singleton.__init__(FormHandler) - end - context "when setup section has been completed" do let(:lettings_log) { build_stubbed(:lettings_log, :setup_completed) } diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index 9f1b57671..319f62d33 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -1,6 +1,8 @@ require "rails_helper" RSpec.describe Location, type: :model do + include CollectionTimeHelper + before do LocalAuthorityLink.create(local_authority_id: LocalAuthority.find_by(code: "E07000030").id, linked_local_authority_id: LocalAuthority.find_by(code: "E06000063").id) end @@ -1184,35 +1186,19 @@ RSpec.describe Location, type: :model do end context "when there is no start date" do - context "and the location was created at the start of the 2022/23 collection window" do - let(:location) { FactoryBot.build(:location, created_at: Time.zone.local(2022, 4, 6), startdate: nil) } - - it "returns the beginning of 21/22 collection window" do - expect(location.available_from).to eq(Time.zone.local(2021, 4, 1)) - end - end - - context "and the location was created at the end of the 2022/23 collection window" do - let(:location) { FactoryBot.build(:location, created_at: Time.zone.local(2023, 2, 6), startdate: nil) } - - it "returns the beginning of 22/23 collection window" do - expect(location.available_from).to eq(Time.zone.local(2022, 4, 1)) - end - end - - context "and the location was created at the start of the 2021/22 collection window" do - let(:location) { FactoryBot.build(:location, created_at: Time.zone.local(2021, 4, 6), startdate: nil) } + context "and the location was created at the start of the collection window" do + let(:location) { FactoryBot.build(:location, created_at: current_collection_start_date, startdate: nil) } - it "returns the beginning of 20/21 collection window" do - expect(location.available_from).to eq(Time.zone.local(2020, 4, 1)) + it "returns the beginning of previous collection window" do + expect(location.available_from).to eq(previous_collection_start_date) end end - context "and the location was created at the end of the 2021/22 collection window" do - let(:location) { FactoryBot.build(:location, created_at: Time.zone.local(2022, 2, 6), startdate: nil) } + context "and the location was created after the crossover date" do + let(:location) { FactoryBot.build(:location, created_at: current_collection_after_crossover_start_date, startdate: nil) } - it "returns the beginning of 20/21 collection window" do - expect(location.available_from).to eq(Time.zone.local(2020, 4, 1)) + it "returns the beginning of current collection window" do + expect(location.available_from).to eq(current_collection_start_date) end end end diff --git a/spec/models/sales_log_spec.rb b/spec/models/sales_log_spec.rb index 21c236959..bf372f44b 100644 --- a/spec/models/sales_log_spec.rb +++ b/spec/models/sales_log_spec.rb @@ -96,17 +96,7 @@ RSpec.describe SalesLog, type: :model do describe "#form" do let(:sales_log) { build(:sales_log, assigned_to: assigned_to_user) } - let(:sales_log_2) { build(:sales_log, saledate: Time.zone.local(2022, 5, 1), assigned_to: assigned_to_user) } - - before do - Timecop.freeze(Time.zone.local(2023, 1, 10)) - Singleton.__init__(FormHandler) - end - - after do - Timecop.return - Singleton.__init__(FormHandler) - end + let(:sales_log_2) { build(:sales_log, saledate: current_collection_start_date, assigned_to: assigned_to_user) } it "has returns the correct form based on the start date" do expect(sales_log.form_name).to be_nil @@ -120,12 +110,8 @@ RSpec.describe SalesLog, type: :model do let(:completed_sales_log) { create(:sales_log, :completed) } context "when proplen is not given" do - before do - allow(Time).to receive(:now).and_return(Time.zone.local(2023, 5, 1)) - end - - it "is set to in_progress for a log with a saledate after 23/24" do - completed_sales_log.update!(proplen: nil, proplen_asked: 0, saledate: Time.zone.local(2023, 5, 1)) + it "is set to in_progress for a log" do + completed_sales_log.update!(proplen: nil, proplen_asked: 0) expect(completed_sales_log.in_progress?).to be(true) expect(completed_sales_log.not_started?).to be(false) expect(completed_sales_log.completed?).to be(false) @@ -204,27 +190,35 @@ RSpec.describe SalesLog, type: :model do end context "when filtering by year or nil" do + # These examples need logs in both the previous and the current collection year, + # so we have to enforce we are in the crossover period + around do |example| + Timecop.freeze(current_collection_start_date) do + Singleton.__init__(FormHandler) + example.run + end + Singleton.__init__(FormHandler) + end + + let(:previous_year) { previous_collection_start_year.to_s } + let(:current_year) { current_collection_start_year.to_s } + before do create(:sales_log, :in_progress, saledate: nil) - sales_log_2021 = build(:sales_log, :in_progress) - sales_log_2021.saledate = Time.zone.local(2021, 4, 1) - sales_log_2021.save!(validate: false) - - sales_log_3 = build(:sales_log, :in_progress) - sales_log_3.saledate = Time.zone.local(2022, 5, 1) - sales_log_3.save!(validate: false) + create(:sales_log, :in_progress, saledate: previous_collection_start_date) + create(:sales_log, :in_progress, saledate: current_collection_start_date) end it "allows filtering on a single year or nil" do - expect(described_class.filter_by_years_or_nil(%w[2021]).count).to eq(2) + expect(described_class.filter_by_years_or_nil([previous_year]).count).to eq(2) end it "allows filtering by multiple years or nil using OR" do - expect(described_class.filter_by_years_or_nil(%w[2021 2022]).count).to eq(3) + expect(described_class.filter_by_years_or_nil([previous_year, current_year]).count).to eq(3) end it "can filter by year(s) AND status" do - expect(described_class.filter_by_years_or_nil(%w[2021 2022]).filter_by_status("in_progress").count).to eq(3) + expect(described_class.filter_by_years_or_nil([previous_year, current_year]).filter_by_status("in_progress").count).to eq(3) end end @@ -277,17 +271,9 @@ RSpec.describe SalesLog, type: :model do end end - context "when there is a 2024 log with a different ecstat1" do - let!(:different_ecstat1) { create(:sales_log, :duplicate, ecstat1: 0, owning_organisation: organisation) } - - before do - Timecop.freeze(Time.zone.local(2024, 5, 2)) - Singleton.__init__(FormHandler) - end - - after do - Timecop.return - end + context "when there is a log with a different ecstat1" do + let(:log) { create(:sales_log, :duplicate, staircase: 2, owning_organisation: organisation) } + let!(:different_ecstat1) { create(:sales_log, :duplicate, staircase: 2, ecstat1: 0, owning_organisation: organisation) } it "does not return a log with a different ecstat1 as a duplicate" do expect(described_class.duplicate_logs(log)).not_to include(different_ecstat1) @@ -944,7 +930,7 @@ RSpec.describe SalesLog, type: :model do end context "when form end date is in the past" do - let(:saledate) { Time.zone.local(2020, 4, 1) } + let(:saledate) { Time.zone.local(archived_collection_start_year, 4, 1) } before do allow(log).to receive_message_chain(:form, :new_logs_end_date).and_return(Time.zone.now - 1.day) diff --git a/spec/models/scheme_spec.rb b/spec/models/scheme_spec.rb index d51aabb61..9811c73c3 100644 --- a/spec/models/scheme_spec.rb +++ b/spec/models/scheme_spec.rb @@ -1,6 +1,8 @@ require "rails_helper" RSpec.describe Scheme, type: :model do + include CollectionTimeHelper + describe "#new" do let(:scheme) { FactoryBot.create(:scheme) } @@ -483,35 +485,19 @@ RSpec.describe Scheme, type: :model do end describe "available_from" do - context "when the scheme was created at the start of the 2022/23 collection window" do - let(:scheme) { FactoryBot.build(:scheme, created_at: Time.zone.local(2022, 4, 6)) } - - it "returns the beginning of 22/23 collection window" do - expect(scheme.available_from).to eq(Time.zone.local(2021, 4, 1)) - end - end - - context "when the scheme was created at the end of the 2022/23 collection window" do - let(:scheme) { FactoryBot.build(:scheme, created_at: Time.zone.local(2023, 2, 6)) } - - it "returns the beginning of 22/23 collection window" do - expect(scheme.available_from).to eq(Time.zone.local(2022, 4, 1)) - end - end - - context "when the scheme was created at the start of the 2021/22 collection window" do - let(:scheme) { FactoryBot.build(:scheme, created_at: Time.zone.local(2021, 4, 6)) } + context "when the scheme was created at the start of the collection window" do + let(:scheme) { FactoryBot.build(:scheme, created_at: current_collection_start_date) } - it "returns the beginning of 21/22 collection window" do - expect(scheme.available_from).to eq(Time.zone.local(2020, 4, 1)) + it "returns the beginning of previous collection window" do + expect(scheme.available_from).to eq(previous_collection_start_date) end end - context "when the scheme was created at the end of the 2021/22 collection window" do - let(:scheme) { FactoryBot.build(:scheme, created_at: Time.zone.local(2022, 2, 6)) } + context "when the scheme was created after the crossover date" do + let(:scheme) { FactoryBot.build(:scheme, created_at: current_collection_after_crossover_start_date) } - it "returns the beginning of 21/22 collection window" do - expect(scheme.available_from).to eq(Time.zone.local(2020, 4, 1)) + it "returns the beginning of current collection window" do + expect(scheme.available_from).to eq(current_collection_start_date) end end end diff --git a/spec/models/validations/date_validations_spec.rb b/spec/models/validations/date_validations_spec.rb index 59fc94f12..735c749b1 100644 --- a/spec/models/validations/date_validations_spec.rb +++ b/spec/models/validations/date_validations_spec.rb @@ -18,7 +18,7 @@ RSpec.describe Validations::DateValidations do end it "does not raise an error when valid" do - record.startdate = Time.zone.local(2022, 1, 1) + record.startdate = current_collection_start_date + 1.month date_validator.validate_startdate(record) expect(record.errors["startdate"]).to be_empty end @@ -40,8 +40,8 @@ RSpec.describe Validations::DateValidations do describe "major repairs date" do it "cannot be after the tenancy start date" do - record.startdate = Time.zone.local(2022, 1, 1) - record.mrcdate = Time.zone.local(2022, 2, 1) + record.startdate = current_collection_start_date + 1.month + record.mrcdate = current_collection_start_date + 2.months date_validator.validate_property_major_repairs(record) expect(record.errors["mrcdate"]) .to include(match I18n.t("validations.lettings.date.mrcdate.before_tenancy_start")) @@ -50,8 +50,8 @@ RSpec.describe Validations::DateValidations do end it "must be before the tenancy start date" do - record.startdate = Time.zone.local(2022, 2, 1) - record.mrcdate = Time.zone.local(2022, 1, 1) + record.startdate = current_collection_start_date + 2.months + record.mrcdate = current_collection_start_date + 1.month date_validator.validate_property_major_repairs(record) expect(record.errors["mrcdate"]).to be_empty end @@ -77,7 +77,7 @@ RSpec.describe Validations::DateValidations do context "when reason for vacancy is first let of property" do it "validates that no major repair date is provided for a new build" do record.rsnvac = 15 - record.mrcdate = Time.zone.local(2022, 1, 1) + record.mrcdate = current_collection_start_date + 1.month date_validator.validate_property_major_repairs(record) expect(record.errors["mrcdate"]) .to include(match I18n.t("validations.lettings.date.mrcdate.not_first_let")) @@ -85,7 +85,7 @@ RSpec.describe Validations::DateValidations do it "validates that no major repair date is provided for a conversion" do record.rsnvac = 16 - record.mrcdate = Time.zone.local(2022, 1, 1) + record.mrcdate = current_collection_start_date + 1.month date_validator.validate_property_major_repairs(record) expect(record.errors["mrcdate"]) .to include(match I18n.t("validations.lettings.date.mrcdate.not_first_let")) @@ -93,7 +93,7 @@ RSpec.describe Validations::DateValidations do it "validates that no major repair date is provided for a leased property" do record.rsnvac = 17 - record.mrcdate = Time.zone.local(2022, 1, 1) + record.mrcdate = current_collection_start_date + 1.month date_validator.validate_property_major_repairs(record) expect(record.errors["mrcdate"]) .to include(match I18n.t("validations.lettings.date.mrcdate.not_first_let")) @@ -103,7 +103,7 @@ RSpec.describe Validations::DateValidations do context "when the reason for vacancy is not the first let of property" do it "expects that major repairs can have been done" do record.rsnvac = "Tenant moved to care home" - record.mrcdate = Time.zone.local(2022, 1, 1) + record.mrcdate = current_collection_start_date + 1.month date_validator.validate_property_major_repairs(record) expect(record.errors["mrcdate"]).to be_empty end @@ -112,8 +112,8 @@ RSpec.describe Validations::DateValidations do describe "property void date" do it "cannot be after the tenancy start date" do - record.startdate = Time.zone.local(2022, 1, 1) - record.voiddate = Time.zone.local(2022, 2, 1) + record.startdate = current_collection_start_date + 1.month + record.voiddate = current_collection_start_date + 2.months date_validator.validate_property_void_date(record) expect(record.errors["voiddate"]) .to include(match I18n.t("validations.lettings.date.void_date.before_tenancy_start")) @@ -122,8 +122,8 @@ RSpec.describe Validations::DateValidations do end it "must be before the tenancy start date" do - record.startdate = Time.zone.local(2022, 2, 1) - record.voiddate = Time.zone.local(2022, 1, 1) + record.startdate = current_collection_start_date + 2.months + record.voiddate = current_collection_start_date + 1.month date_validator.validate_property_void_date(record) expect(record.errors["voiddate"]).to be_empty end @@ -149,8 +149,8 @@ RSpec.describe Validations::DateValidations do context "when major repairs have been carried out" do it "void_date cannot be after major repairs date" do - record.mrcdate = Time.zone.local(2022, 1, 1) - record.voiddate = Time.zone.local(2022, 2, 1) + record.mrcdate = current_collection_start_date + 1.month + record.voiddate = current_collection_start_date + 2.months date_validator.validate_property_void_date(record) expect(record.errors["voiddate"]) .to include(match I18n.t("validations.lettings.date.void_date.after_mrcdate")) @@ -159,8 +159,8 @@ RSpec.describe Validations::DateValidations do end it "must be before major repairs date" do - record.mrcdate = Time.zone.local(2022, 2, 1) - record.voiddate = Time.zone.local(2022, 1, 1) + record.mrcdate = current_collection_start_date + 2.months + record.voiddate = current_collection_start_date + 1.month date_validator.validate_property_void_date(record) expect(record.errors["voiddate"]).to be_empty end diff --git a/spec/models/validations/financial_validations_spec.rb b/spec/models/validations/financial_validations_spec.rb index e4bdb2e82..30958e4a2 100644 --- a/spec/models/validations/financial_validations_spec.rb +++ b/spec/models/validations/financial_validations_spec.rb @@ -1,6 +1,8 @@ require "rails_helper" RSpec.describe Validations::FinancialValidations do + include CollectionTimeHelper + subject(:financial_validator) { validator_class.new } let(:validator_class) { Class.new { include Validations::FinancialValidations } } @@ -198,7 +200,7 @@ RSpec.describe Validations::FinancialValidations do end describe "housing benefit rent shortfall validations" do - before { record.startdate = Time.zone.local(2022, 5, 1) } + before { record.startdate = current_collection_start_date } context "when shortfall is yes" do it "validates that housing benefit is not none" do @@ -228,7 +230,7 @@ RSpec.describe Validations::FinancialValidations do describe "net income validations" do it "validates that the net income is within the expected range for the household’s employment status" do - record.startdate = Time.zone.local(2023, 5, 1) + record.startdate = current_collection_start_date record.earnings = 200 record.incfreq = 1 record.hhmemb = 1 @@ -239,7 +241,7 @@ RSpec.describe Validations::FinancialValidations do context "when the net income is higher than the hard max for their employment status" do it "adds an error" do - record.startdate = Time.zone.local(2023, 5, 1) + record.startdate = current_collection_start_date record.earnings = 5000 record.incfreq = 1 record.hhmemb = 1 @@ -256,7 +258,7 @@ RSpec.describe Validations::FinancialValidations do context "when the net income is lower than the hard min for their employment status" do it "adds an error" do - record.startdate = Time.zone.local(2023, 5, 1) + record.startdate = current_collection_start_date record.earnings = 50 record.incfreq = 1 record.hhmemb = 1 @@ -273,7 +275,7 @@ RSpec.describe Validations::FinancialValidations do context "when there is more than one household member" do it "allows income levels based on all working situations combined" do - record.startdate = Time.zone.local(2023, 5, 1) + record.startdate = current_collection_start_date record.earnings = 5000 record.incfreq = 1 record.hhmemb = 4 @@ -286,7 +288,7 @@ RSpec.describe Validations::FinancialValidations do end it "uses the combined value in error messages" do - record.startdate = Time.zone.local(2023, 5, 1) + record.startdate = current_collection_start_date record.earnings = 100 record.incfreq = 1 record.hhmemb = 3 @@ -299,7 +301,7 @@ RSpec.describe Validations::FinancialValidations do end it "adds errors to relevant fields for each tenant when income is too high" do - record.startdate = Time.zone.local(2023, 5, 1) + record.startdate = current_collection_start_date record.earnings = 5000 record.incfreq = 1 record.hhmemb = 3 @@ -323,7 +325,7 @@ RSpec.describe Validations::FinancialValidations do end it "adds errors to relevant fields for each tenant when income is too low" do - record.startdate = Time.zone.local(2023, 5, 1) + record.startdate = current_collection_start_date record.earnings = 50 record.incfreq = 1 record.hhmemb = 3 @@ -991,7 +993,7 @@ RSpec.describe Validations::FinancialValidations do soft_max: 89.54, hard_min: 9.87, hard_max: 100.99, - start_year: 2021, + start_year: current_collection_start_year, ) LaRentRange.create!( ranges_rent_id: "2", @@ -1002,7 +1004,7 @@ RSpec.describe Validations::FinancialValidations do soft_max: 89.54, hard_min: 9.87, hard_max: 100.99, - start_year: 2021, + start_year: current_collection_start_year, ) end @@ -1012,7 +1014,7 @@ RSpec.describe Validations::FinancialValidations do record.period = 1 record.la = "E07000223" record.beds = 4 - record.startdate = Time.zone.local(2021, 9, 17) + record.startdate = current_collection_start_date record.brent = 9.17 financial_validator.validate_rent_amount(record) @@ -1025,7 +1027,7 @@ RSpec.describe Validations::FinancialValidations do record.lettype = 2 record.period = 1 record.location = location - record.startdate = Time.zone.local(2021, 9, 17) + record.startdate = current_collection_start_date record.brent = 9.17 financial_validator.validate_rent_amount(record) @@ -1044,7 +1046,7 @@ RSpec.describe Validations::FinancialValidations do record.period = 1 record.la = "E07000223" record.beds = 4 - record.startdate = Time.zone.local(2021, 9, 17) + record.startdate = current_collection_start_date record.brent = 200 financial_validator.validate_rent_amount(record) @@ -1062,7 +1064,7 @@ RSpec.describe Validations::FinancialValidations do record.lettype = 2 record.period = 1 record.location = location - record.startdate = Time.zone.local(2021, 9, 17) + record.startdate = current_collection_start_date record.brent = 200 financial_validator.validate_rent_amount(record) @@ -1079,7 +1081,7 @@ RSpec.describe Validations::FinancialValidations do record.lettype = 1 record.period = 1 record.la = "E07000223" - record.startdate = Time.zone.local(2022, 2, 5) + record.startdate = current_collection_start_date record.beds = 4 record.brent = 200 @@ -1095,7 +1097,7 @@ RSpec.describe Validations::FinancialValidations do it "does not error if some of the fields are missing" do record.managing_organisation.provider_type = 2 - record.startdate = Time.zone.local(2021, 9, 17) + record.startdate = current_collection_start_date record.brent = 200 financial_validator.validate_rent_amount(record) diff --git a/spec/models/validations/household_validations_spec.rb b/spec/models/validations/household_validations_spec.rb index 0f874dcc5..5b294e51b 100644 --- a/spec/models/validations/household_validations_spec.rb +++ b/spec/models/validations/household_validations_spec.rb @@ -53,7 +53,7 @@ RSpec.describe Validations::HouseholdValidations do end context "when form year is >= 2024" do - let(:startdate) { Time.zone.local(2024, 4, 1) } + let(:startdate) { current_collection_start_date } context "when checking the content of reasonother" do it "validates that the reason doesn't match phrase indicating homelessness" do @@ -271,7 +271,7 @@ RSpec.describe Validations::HouseholdValidations do describe "#validate_person_age_matches_relationship" do context "with 2024 logs" do - let(:startdate) { Time.zone.local(2024, 4, 1) } + let(:startdate) { current_collection_start_date } it "does not add an error is person under 16 is a partner" do record.age2 = 14 @@ -293,7 +293,7 @@ RSpec.describe Validations::HouseholdValidations do describe "#validate_person_age_matches_economic_status" do context "with 2024 logs" do - let(:startdate) { Time.zone.local(2024, 4, 1) } + let(:startdate) { current_collection_start_date } it "does not run the validation" do record.age2 = 14 @@ -309,7 +309,7 @@ RSpec.describe Validations::HouseholdValidations do describe "#validate_person_age_and_relationship_matches_economic_status" do context "with 2024 logs" do - let(:startdate) { Time.zone.local(2024, 4, 1) } + let(:startdate) { current_collection_start_date } context "when the household contains a tenant’s child between the ages of 16 and 19" do it "does not add an error" do diff --git a/spec/models/validations/sales/sale_information_validations_spec.rb b/spec/models/validations/sales/sale_information_validations_spec.rb index 04f71b198..349356620 100644 --- a/spec/models/validations/sales/sale_information_validations_spec.rb +++ b/spec/models/validations/sales/sale_information_validations_spec.rb @@ -860,18 +860,6 @@ RSpec.describe Validations::Sales::SaleInformationValidations do end end - context "with a 2024 log that is not an outright sale" do - let(:record) { FactoryBot.build(:sales_log, value: 300_000, ownershipsch: 2, saledate: Time.zone.local(2024, 5, 1)) } - - it "does not add errors" do - record.mortgageused = 1 - record.mortgage = 100_000 - record.deposit = 100_000 - sale_information_validator.validate_outright_sale_value_matches_mortgage_plus_deposit(record) - expect(record.errors).to be_empty - end - end - describe "#validate_basic_monthly_rent" do context "when within permitted bounds" do let(:record) { build(:sales_log, mrent: 9998, ownershipsch: 1, type: 2) } diff --git a/spec/models/validations/sales/setup_validations_spec.rb b/spec/models/validations/sales/setup_validations_spec.rb index 45579ca42..926fac7bb 100644 --- a/spec/models/validations/sales/setup_validations_spec.rb +++ b/spec/models/validations/sales/setup_validations_spec.rb @@ -1,11 +1,13 @@ require "rails_helper" RSpec.describe Validations::Sales::SetupValidations do + include CollectionTimeHelper + subject(:setup_validator) { validator_class.new } let(:validator_class) { Class.new { include Validations::Sales::SetupValidations } } - let(:current_year) { FormHandler.instance.current_sales_form.start_date.year } - let(:previous_year) { FormHandler.instance.previous_sales_form.start_date.year } + let(:current_year) { current_collection_start_year } + let(:previous_year) { previous_collection_start_year } describe "#validate_saledate_collection_year" do context "with sales_in_crossover_period == false" do @@ -84,7 +86,7 @@ RSpec.describe Validations::Sales::SetupValidations do end context "when saledate is before an open collection year" do - let(:record) { build(:sales_log, saledate: Time.zone.local(2020, 5, 1)) } + let(:record) { build(:sales_log, saledate: archived_collection_start_date) } before do allow(FormHandler.instance).to receive(:sales_in_crossover_period?).and_return(true) diff --git a/spec/models/validations/setup_validations_spec.rb b/spec/models/validations/setup_validations_spec.rb index ac6faee08..3925f5c04 100644 --- a/spec/models/validations/setup_validations_spec.rb +++ b/spec/models/validations/setup_validations_spec.rb @@ -9,90 +9,32 @@ RSpec.describe Validations::SetupValidations do let(:record) { build(:lettings_log) } describe "tenancy start date" do - context "when in 2022 to 2023 collection" do - context "when in the crossover period" do - before do - allow(Time).to receive(:now).and_return(Time.zone.local(2022, 4, 1)) - record.created_at = Time.zone.local(2022, 4, 1) - end - - it "cannot be before the first collection window start date" do - record.startdate = Time.zone.local(2021, 1, 1) - setup_validator.validate_startdate_setup(record) - setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date within the 2021 to 2022 or 2022 to 2023 collection years, which is between 1st April 2021 and 31st March 2023") - end - - it "cannot be after the second collection window end date" do - record.startdate = Time.zone.local(2023, 7, 1, 6) - setup_validator.validate_startdate_setup(record) - setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date within the 2021 to 2022 or 2022 to 2023 collection years, which is between 1st April 2021 and 31st March 2023") - end + context "when in the crossover period" do + before do + Timecop.freeze(current_collection_start_date) end - context "when after the crossover period" do - before do - allow(Time).to receive(:now).and_return(Time.zone.local(2023, 1, 1)) - record.created_at = Time.zone.local(2023, 1, 1) - end - - it "cannot be before the first collection window start date" do - record.startdate = Time.zone.local(2022, 1, 1) - setup_validator.validate_startdate_setup(record) - setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date within the 2022 to 2023 collection year, which is between 1st April 2022 and 31st March 2023") - end - - it "cannot be after the second collection window end date" do - record.startdate = Time.zone.local(2023, 7, 1, 6) - setup_validator.validate_startdate_setup(record) - setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date within the 2022 to 2023 collection year, which is between 1st April 2022 and 31st March 2023") - end + after do + Timecop.return end - end - - context "when in 2023 to 2024 collection" do - context "when in the crossover period" do - before do - allow(Time).to receive(:now).and_return(Time.zone.local(2023, 4, 1)) - record.created_at = Time.zone.local(2023, 4, 1) - end - - it "cannot be before the first collection window start date" do - record.startdate = Time.zone.local(2022, 1, 1) - setup_validator.validate_startdate_setup(record) - setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date within the 2022 to 2023 or 2023 to 2024 collection years, which is between 1st April 2022 and 31st March 2024") - end - it "cannot be after the second collection window end date" do - record.startdate = Time.zone.local(2024, 7, 1, 6) - setup_validator.validate_startdate_setup(record) - setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date within the 2022 to 2023 or 2023 to 2024 collection years, which is between 1st April 2022 and 31st March 2024") - end + it "cannot be before previous collection year start date" do + record.startdate = previous_collection_start_date - 1.month + setup_validator.validate_startdate_setup(record) + setup_validator.validate_merged_organisations_start_date(record) + expect(record.errors["startdate"]).to include(match(/Enter a date within the \d{4} to \d{4} or \d{4} to \d{4} collection years, which is between 1st April \d{4} and 31st March \d{4}/)) end context "when after the crossover period" do before do - allow(Time).to receive(:now).and_return(Time.zone.local(2024, 1, 1)) - record.created_at = Time.zone.local(2024, 1, 1) + allow(Time).to receive(:now).and_return(current_collection_after_crossover_start_date) end - it "cannot be before the first collection window start date" do - record.startdate = Time.zone.local(2023, 1, 1) + it "cannot be before previous collection year start date" do + record.startdate = previous_collection_start_date - 1.month setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date within the 2023 to 2024 collection year, which is between 1st April 2023 and 31st March 2024") - end - - it "cannot be after the second collection window end date" do - record.startdate = Time.zone.local(2024, 7, 1, 6) - setup_validator.validate_startdate_setup(record) - setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date within the 2023 to 2024 collection year, which is between 1st April 2023 and 31st March 2024") + expect(record.errors["startdate"]).to include(match(/Enter a date within the \d{4} to \d{4} collection year, which is between 1st April \d{4} and 31st March \d{4}/)) end end @@ -125,73 +67,90 @@ RSpec.describe Validations::SetupValidations do context "when after the new logs end date and after the edit end date for the previous period" do before do - allow(Time).to receive(:now).and_return(Time.zone.local(2024, 1, 8)) + Timecop.freeze(previous_collection_edit_end_date + 1.day) + end + + after do + Timecop.return end it "cannot create new logs for the previous collection year" do record.update!(startdate: nil) - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = previous_collection_start_date setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date within the 2023 to 2024 collection year, which is between 1st April 2023 and 31st March 2024") + expect(record.errors["startdate"]).to include(match(/Enter a date within the \d{4} to \d{4} collection year, which is between 1st April \d{4} and 31st March \d{4}/)) end it "cannot edit already created logs for the previous collection year" do - record.startdate = Time.zone.local(2023, 1, 2) + record.startdate = previous_collection_start_date + 1.day record.save!(validate: false) - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = previous_collection_start_date setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date within the 2023 to 2024 collection year, which is between 1st April 2023 and 31st March 2024") + expect(record.errors["startdate"]).to include(match(/Enter a date within the \d{4} to \d{4} collection year, which is between 1st April \d{4} and 31st March \d{4}/)) end end end context "when attempted startdate is more than 14 days from the current date" do before do - allow(Time).to receive(:now).and_return(Time.zone.local(2024, 3, 1)) + Timecop.freeze(current_collection_start_date - 1.month) + end + + after do + Timecop.return end it "adds an error to startdate" do - record.startdate = Time.zone.local(2024, 3, 31) + record.startdate = Time.zone.now + 15.days setup_validator.validate_startdate_setup(record) expect(record.errors["startdate"]).to include(match I18n.t("validations.lettings.setup.startdate.not_within.next_two_weeks")) end context "and the attempted startdate is in a future collection year" do it "adds both errors to startdate, with the collection year error first" do - record.startdate = Time.zone.local(2024, 4, 1) + record.startdate = next_collection_start_date setup_validator.validate_startdate_setup(record) expect(record.errors["startdate"].length).to be >= 2 - expect(record.errors["startdate"][0]).to eq("Enter a date within the 2023 to 2024 collection year, which is between 1st April 2023 and 31st March 2024.") + expect(record.errors["startdate"][0]).to match(/Enter a date within the \d{4} to \d{4} collection year, which is between 1st April \d{4} and 31st March \d{4}/) expect(record.errors["startdate"][1]).to eq(I18n.t("validations.lettings.setup.startdate.not_within.next_two_weeks")) end end end context "when organisations were merged" do - let(:absorbing_organisation) { create(:organisation, created_at: Time.zone.local(2023, 1, 30, 4, 5, 6), available_from: Time.zone.local(2023, 2, 1, 4, 5, 6), name: "Absorbing org") } - let(:absorbing_organisation_2) { create(:organisation, created_at: Time.zone.local(2023, 1, 30), available_from: Time.zone.local(2023, 2, 1), name: "Absorbing org 2") } + let(:org_available_from) { current_collection_start_date - 2.months } + let(:org_created_at) { org_available_from - 2.days } + let(:org_merge_date) { org_available_from + 1.day } + let(:merge_date_formatted) { org_merge_date.strftime("%-d %B %Y") } + let(:available_from_formatted) { org_available_from.strftime("%-d %B %Y") } + let(:absorbing_organisation) { create(:organisation, created_at: org_created_at, available_from: org_available_from, name: "Absorbing org") } + let(:absorbing_organisation_2) { create(:organisation, created_at: org_created_at, available_from: org_available_from, name: "Absorbing org 2") } let(:merged_organisation) { create(:organisation, name: "Merged org") } let(:merged_organisation_2) { create(:organisation, name: "Merged org 2") } before do - allow(Time).to receive(:now).and_return(Time.zone.local(2023, 5, 1)) - merged_organisation.update!(absorbing_organisation:, merge_date: Time.zone.local(2023, 2, 2)) - merged_organisation_2.update!(absorbing_organisation:, merge_date: Time.zone.local(2023, 2, 2)) + Timecop.freeze(current_collection_start_date + 1.month) + merged_organisation.update!(absorbing_organisation:, merge_date: org_merge_date) + merged_organisation_2.update!(absorbing_organisation:, merge_date: org_merge_date) + end + + after do + Timecop.return end context "and owning organisation is no longer active" do it "does not allow startdate after organisation has been merged" do - record.startdate = Time.zone.local(2023, 3, 1) + record.startdate = org_merge_date + 1.month record.owning_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date when the owning organisation was active. Merged org became inactive on 2 February 2023 and was replaced by Absorbing org.") + expect(record.errors["startdate"]).to include(match "Enter a date when the owning organisation was active. Merged org became inactive on #{merge_date_formatted} and was replaced by Absorbing org.") end it "allows startdate before organisation has been merged" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_merge_date - 1.month record.owning_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) @@ -201,15 +160,15 @@ RSpec.describe Validations::SetupValidations do context "and owning organisation is not yet active during the startdate" do it "does not allow startdate before absorbing organisation has become available" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_available_from - 1.month record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date when the owning organisation was active. Absorbing org became active on 1 February 2023.") + expect(record.errors["startdate"]).to include(match "Enter a date when the owning organisation was active. Absorbing org became active on #{available_from_formatted}.") end it "allows startdate after absorbing organisation has become available" do - record.startdate = Time.zone.local(2023, 2, 2) + record.startdate = org_available_from + 1.month record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) @@ -217,7 +176,7 @@ RSpec.describe Validations::SetupValidations do end it "allows startdate if organisation does not have available from date" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_available_from - 1.month absorbing_organisation.update!(available_from: nil) record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) @@ -228,15 +187,15 @@ RSpec.describe Validations::SetupValidations do context "and managing organisation is no longer active during the startdate" do it "does not allow startdate after organisation has been merged" do - record.startdate = Time.zone.local(2023, 3, 1) + record.startdate = org_merge_date + 1.month record.managing_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date when the managing organisation was active. Merged org became inactive on 2 February 2023 and was replaced by Absorbing org.") + expect(record.errors["startdate"]).to include(match "Enter a date when the managing organisation was active. Merged org became inactive on #{merge_date_formatted} and was replaced by Absorbing org.") end it "allows startdate before organisation has been merged" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_merge_date - 1.month record.managing_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) @@ -246,15 +205,15 @@ RSpec.describe Validations::SetupValidations do context "and managing organisation is not yet active during the startdate" do it "does not allow startdate before absorbing organisation has become available'" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_available_from - 1.month record.managing_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date when the managing organisation was active. Absorbing org became active on 1 February 2023.") + expect(record.errors["startdate"]).to include(match "Enter a date when the managing organisation was active. Absorbing org became active on #{available_from_formatted}.") end it "allows startdate after absorbing organisation has become available" do - record.startdate = Time.zone.local(2023, 2, 2) + record.startdate = org_available_from + 1.month record.managing_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) @@ -262,7 +221,7 @@ RSpec.describe Validations::SetupValidations do end it "allows startdate if organisation does not have available from date" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_available_from - 1.month absorbing_organisation.update!(available_from: nil) record.managing_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) @@ -273,16 +232,16 @@ RSpec.describe Validations::SetupValidations do context "and owning and managing organisation is no longer active during the startdate" do it "does not allow startdate after organisation has been merged" do - record.startdate = Time.zone.local(2023, 3, 1) + record.startdate = org_merge_date + 1.month record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisation was active. Merged org became inactive on 2 February 2023 and was replaced by Absorbing org.") + expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisation was active. Merged org became inactive on #{merge_date_formatted} and was replaced by Absorbing org.") end it "allows startdate before organisation has been merged" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_merge_date - 1.month record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation.id setup_validator.validate_startdate_setup(record) @@ -293,16 +252,16 @@ RSpec.describe Validations::SetupValidations do context "and owning and managing organisation is not yet active during the startdate" do it "does not allow startdate before absorbing organisation has become available" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_available_from - 1.month record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisation was active. Absorbing org became active on 1 February 2023.") + expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisation was active. Absorbing org became active on #{available_from_formatted}.") end it "allows startdate after absorbing organisation has become available" do - record.startdate = Time.zone.local(2023, 2, 1) + record.startdate = org_available_from + 1.month record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) @@ -311,7 +270,7 @@ RSpec.describe Validations::SetupValidations do end it "allows startdate if organisation does not have available from date" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_available_from - 1.month absorbing_organisation.update!(available_from: nil) record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation.id @@ -323,16 +282,16 @@ RSpec.describe Validations::SetupValidations do context "and owning and managing organisations are no longer active during the startdate" do it "does not allow startdate after organisation have been merged" do - record.startdate = Time.zone.local(2023, 2, 2) + record.startdate = org_merge_date + 1.month record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation_2.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisations were active. Merged org 2 and Merged org became inactive on 2 February 2023 and were replaced by Absorbing org.") + expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisations were active. Merged org 2 and Merged org became inactive on #{merge_date_formatted} and were replaced by Absorbing org.") end it "allows startdate before organisations have been merged" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_merge_date - 1.month record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation_2.id setup_validator.validate_startdate_setup(record) @@ -343,20 +302,20 @@ RSpec.describe Validations::SetupValidations do context "and owning and managing organisations are from different merges and no longer active during the startdate" do before do - merged_organisation_2.update!(absorbing_organisation: absorbing_organisation_2, merge_date: Time.zone.local(2023, 2, 2)) + merged_organisation_2.update!(absorbing_organisation: absorbing_organisation_2, merge_date: org_merge_date) end it "does not allow startdate after organisations have been merged" do - record.startdate = Time.zone.local(2023, 3, 1) + record.startdate = org_merge_date + 1.month record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation_2.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisations were active. Merged org 2 became inactive on 2 February 2023 and was replaced by Absorbing org 2. Merged org became inactive on 2 February 2023 and was replaced by Absorbing org.") + expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisations were active. Merged org 2 became inactive on #{merge_date_formatted} and was replaced by Absorbing org 2. Merged org became inactive on #{merge_date_formatted} and was replaced by Absorbing org.") end it "allows startdate before organisations have been merged" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_merge_date - 1.month record.managing_organisation_id = merged_organisation.id record.owning_organisation_id = merged_organisation_2.id setup_validator.validate_startdate_setup(record) @@ -367,20 +326,20 @@ RSpec.describe Validations::SetupValidations do context "and owning and managing organisation have different merges and are not yet active during the startdate" do before do - merged_organisation_2.update!(absorbing_organisation: absorbing_organisation_2, merge_date: Time.zone.local(2023, 2, 2)) + merged_organisation_2.update!(absorbing_organisation: absorbing_organisation_2, merge_date: org_merge_date) end it "does not allow startdate before absorbing organisation has become available" do - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_available_from - 1.month record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation_2.id setup_validator.validate_startdate_setup(record) setup_validator.validate_merged_organisations_start_date(record) - expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisations were active. Absorbing org 2 became active on 1 February 2023, and Absorbing org became active on 1 February 2023.") + expect(record.errors["startdate"]).to include(match "Enter a date when the owning and managing organisations were active. Absorbing org 2 became active on #{available_from_formatted}, and Absorbing org became active on #{available_from_formatted}.") end it "allows startdate after absorbing organisation has become available" do - record.startdate = Time.zone.local(2023, 2, 2) + record.startdate = org_available_from + 1.month record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) @@ -390,7 +349,7 @@ RSpec.describe Validations::SetupValidations do it "allows startdate if organisation does not have available from date" do absorbing_organisation.update!(available_from: nil) - record.startdate = Time.zone.local(2023, 1, 1) + record.startdate = org_available_from - 1.month record.managing_organisation_id = absorbing_organisation.id record.owning_organisation_id = absorbing_organisation.id setup_validator.validate_startdate_setup(record) diff --git a/spec/models/validations/soft_validations_spec.rb b/spec/models/validations/soft_validations_spec.rb index 4b0ac6711..e2c2b897e 100644 --- a/spec/models/validations/soft_validations_spec.rb +++ b/spec/models/validations/soft_validations_spec.rb @@ -18,7 +18,7 @@ RSpec.describe Validations::SoftValidations do soft_max: 89.54, hard_min: 9.87, hard_max: 100.99, - start_year: 2021, + start_year: current_collection_start_year, ) record.la = "E07000223" @@ -26,7 +26,7 @@ RSpec.describe Validations::SoftValidations do record.rent_type = 0 record.beds = 1 record.period = 1 - record.startdate = Time.zone.local(2021, 10, 10) + record.startdate = current_collection_start_date end context "when validating soft min" do @@ -504,16 +504,16 @@ RSpec.describe Validations::SoftValidations do describe "major repairs date soft validations" do context "when the major repairs date is within 10 years of the tenancy start date" do it "shows the interruption screen" do - record.startdate = Time.zone.local(2022, 2, 1) - record.mrcdate = Time.zone.local(2013, 2, 1) + record.startdate = current_collection_start_date + record.mrcdate = current_collection_start_date - 9.years expect(record.major_repairs_date_in_soft_range?).to be true end end context "when the major repairs date is less than 2 years before the tenancy start date" do it "does not show the interruption screen" do - record.startdate = Time.zone.local(2022, 2, 1) - record.mrcdate = Time.zone.local(2021, 2, 1) + record.startdate = current_collection_start_date + record.mrcdate = current_collection_start_date - 1.year expect(record.major_repairs_date_in_soft_range?).to be false end end @@ -540,16 +540,16 @@ RSpec.describe Validations::SoftValidations do describe "void date soft validations" do context "when the void date is within 10 years of the tenancy start date" do it "shows the interruption screen" do - record.startdate = Time.zone.local(2022, 2, 1) - record.voiddate = Time.zone.local(2013, 2, 1) + record.startdate = current_collection_start_date + record.voiddate = current_collection_start_date - 9.years expect(record.voiddate_in_soft_range?).to be true end end context "when the void date is less than 2 years before the tenancy start date" do it "does not show the interruption screen" do - record.startdate = Time.zone.local(2022, 2, 1) - record.voiddate = Time.zone.local(2021, 2, 1) + record.startdate = current_collection_start_date + record.voiddate = current_collection_start_date - 1.year expect(record.voiddate_in_soft_range?).to be false end end diff --git a/spec/requests/sales_logs_controller_spec.rb b/spec/requests/sales_logs_controller_spec.rb index 9a6603865..e1e7e87ea 100644 --- a/spec/requests/sales_logs_controller_spec.rb +++ b/spec/requests/sales_logs_controller_spec.rb @@ -1,6 +1,8 @@ require "rails_helper" RSpec.describe SalesLogsController, type: :request do + include CollectionTimeHelper + let(:user) { FactoryBot.create(:user) } let(:owning_organisation) { user.organisation } let(:api_username) { "test_user" } @@ -26,18 +28,11 @@ RSpec.describe SalesLogsController, type: :request do end before do - Timecop.freeze(Time.zone.local(2024, 3, 1)) - Singleton.__init__(FormHandler) allow(ENV).to receive(:[]) allow(ENV).to receive(:[]).with("API_USER").and_return(api_username) allow(ENV).to receive(:[]).with("API_KEY").and_return(api_password) end - after do - Timecop.return - Singleton.__init__(FormHandler) - end - describe "POST #create" do context "when API" do before do @@ -70,19 +65,30 @@ RSpec.describe SalesLogsController, type: :request do end context "with a request containing invalid json parameters" do + # These examples need logs in both the previous and the current collection year, + # so we have to enforce we are in the crossover period + around do |example| + Timecop.freeze(current_collection_start_date) do + Singleton.__init__(FormHandler) + example.run + end + Singleton.__init__(FormHandler) + end + let(:params) do + invalid_sales_log = FactoryBot.build( + :sales_log, + :completed, + assigned_to: user, + owning_organisation: owning_organisation, + managing_organisation: owning_organisation, + saledate: archived_collection_start_date, + beds: 2, + proptype: 2, + ) + { - "owning_organisation_id": owning_organisation.id, - "managing_organisation_id": owning_organisation.id, - "assigned_to_id": user.id, - "saledate": Time.zone.today, - "purchid": "1", - "ownershipsch": 1, - "type": 2, - "jointpur": 1, - "jointmore": 1, - "beds": 2, - "proptype": 2, + sales_log: invalid_sales_log.attributes, } end @@ -93,7 +99,26 @@ RSpec.describe SalesLogsController, type: :request do it "validates sales log parameters" do json_response = JSON.parse(response.body) expect(response).to have_http_status(:unprocessable_content) - expect(json_response["errors"]).to contain_exactly(["beds", ["Number of bedrooms must be 1 if the property is a bedsit."]], ["proptype", ["Answer cannot be 'Bedsit' if the property has 2 or more bedrooms."]]) + expect(json_response["errors"]).to contain_exactly( + [ + "beds", + [ + "Number of bedrooms must be 1 if the property is a bedsit.", + ], + ], + [ + "proptype", + [ + "Answer cannot be 'Bedsit' if the property has 2 or more bedrooms.", + ], + ], + [ + "saledate", + [ + "Enter a date within the #{previous_collection_start_year} to #{previous_collection_end_year} or #{current_collection_start_year} to #{current_collection_end_year} collection years, which is between 1st April #{previous_collection_start_year} and 31st March #{current_collection_end_year}.", + ], + ], + ) end end end @@ -341,72 +366,70 @@ RSpec.describe SalesLogsController, type: :request do end context "with year filter" do - before do - Timecop.freeze(2022, 4, 1) - sales_log_2022.update!(saledate: Time.zone.local(2022, 4, 1)) - Timecop.freeze(2023, 1, 1) - sales_log_2022.update!(saledate: Time.zone.local(2023, 1, 1)) - end - - after do - Timecop.unfreeze + # Needs logs in both the previous and the current collection year, so must run inside + # the crossover period, when new logs can still be created for both. + around do |example| + Timecop.freeze(current_collection_start_date) do + Singleton.__init__(FormHandler) + example.run + end + Singleton.__init__(FormHandler) end - let!(:sales_log_2022) do + let!(:sales_log_current) do FactoryBot.create(:sales_log, :completed, owning_organisation: organisation, assigned_to: user, - saledate: Time.zone.today) + saledate: current_collection_start_date) end - let!(:sales_log_2023) do + let!(:sales_log_previous) do FactoryBot.create(:sales_log, owning_organisation: organisation, assigned_to: user, - saledate: Time.zone.today) + saledate: previous_collection_start_date) end it "shows sales logs for multiple selected years" do - get "/sales-logs?years[]=2021&years[]=2022", headers: headers, params: {} - expect(page).to have_link(sales_log_2022.id.to_s) - expect(page).to have_link(sales_log_2023.id.to_s) + get "/sales-logs?years[]=#{previous_collection_start_year}&years[]=#{current_collection_start_year}", headers: headers, params: {} + expect(page).to have_link(sales_log_current.id.to_s) + expect(page).to have_link(sales_log_previous.id.to_s) end it "shows sales logs for one selected year" do - get "/sales-logs?years[]=2022", headers: headers, params: {} - expect(page).to have_link(sales_log_2022.id.to_s) - expect(page).to have_link(sales_log_2023.id.to_s) + get "/sales-logs?years[]=#{current_collection_start_year}", headers: headers, params: {} + expect(page).to have_link(sales_log_current.id.to_s) + expect(page).not_to have_link(sales_log_previous.id.to_s) end end context "with year and status filter" do - before do - Timecop.freeze(2022, 4, 1) - sales_log_2022.update!(saledate: Time.zone.local(2022, 4, 1)) - Timecop.freeze(2023, 1, 1) - sales_log_2022.update!(saledate: Time.zone.local(2023, 1, 1)) - end - - after do - Timecop.unfreeze + # Needs logs in both the previous and the current collection year, so must run inside + # the crossover period, when new logs can still be created for both. + around do |example| + Timecop.freeze(current_collection_start_date) do + Singleton.__init__(FormHandler) + example.run + end + Singleton.__init__(FormHandler) end - let!(:sales_log_2022) do + let!(:sales_log_current) do FactoryBot.create(:sales_log, :completed, owning_organisation: organisation, assigned_to: user, - saledate: Time.zone.today) + saledate: current_collection_start_date) end - let!(:sales_log_2023) do + let!(:sales_log_previous) do FactoryBot.create(:sales_log, owning_organisation: organisation, assigned_to: user, - saledate: Time.zone.today) + saledate: previous_collection_start_date) end it "shows sales logs for multiple selected statuses and years" do - get "/sales-logs?years[]=2021&years[]=2022&status[]=in_progress&status[]=completed", headers: headers, params: {} - expect(page).to have_link(sales_log_2022.id.to_s) - expect(page).to have_link(sales_log_2023.id.to_s) + get "/sales-logs?years[]=#{previous_collection_start_year}&years[]=#{current_collection_start_year}&status[]=in_progress&status[]=completed", headers: headers, params: {} + expect(page).to have_link(sales_log_current.id.to_s) + expect(page).to have_link(sales_log_previous.id.to_s) end end @@ -856,10 +879,6 @@ RSpec.describe SalesLogsController, type: :request do before do sign_in user - Timecop.freeze(2021, 4, 1) - Singleton.__init__(FormHandler) - completed_sales_log.update!(saledate: Time.zone.local(2021, 4, 1)) - completed_sales_log.reload end context "with sales logs that are owned by your organisation" do @@ -867,22 +886,17 @@ RSpec.describe SalesLogsController, type: :request do get "/sales-logs/#{completed_sales_log.id}", headers:, params: {} end - after do - Timecop.return - Singleton.__init__(FormHandler) - end - it "shows the tasklist for sales logs you have access to" do expect(response.body).to match("Log") expect(response.body).to match(completed_sales_log.id.to_s) end it "displays a link to update the log for currently editable logs" do - completed_sales_log.update!(saledate: Time.zone.local(2021, 4, 1)) + completed_sales_log.update!(saledate: current_collection_start_date) completed_sales_log.reload get "/sales-logs/#{completed_sales_log.id}", headers:, params: {} - expect(completed_sales_log.form.new_logs_end_date).to eq(Time.zone.local(2022, 12, 31)) + expect(completed_sales_log.form.new_logs_end_date).to eq(FormHandler.instance.current_sales_form.new_logs_end_date) expect(completed_sales_log.status).to eq("completed") expect(page).to have_link("review and make changes to this log", href: "/sales-logs/#{completed_sales_log.id}/review?sales_log=true") end @@ -894,53 +908,44 @@ RSpec.describe SalesLogsController, type: :request do get "/sales-logs/#{completed_sales_log.id}", headers:, params: {} end - after do - Timecop.return - Singleton.__init__(FormHandler) - end - it "shows the tasklist for sales logs you have access to" do expect(response.body).to match("Log") expect(response.body).to match(completed_sales_log.id.to_s) end end - context "with sales logs from a closed collection period before the previous collection" do - before do - sign_in user - Timecop.return - Singleton.__init__(FormHandler) - get "/sales-logs/#{completed_sales_log.id}", headers:, params: {} - end - - it "redirects to review page" do - expect(response).to redirect_to("/sales-logs/#{completed_sales_log.id}/review?sales_log=true") + context "with sales logs from a closed previous collection period" do + let(:completed_sales_log) do + FactoryBot.create( + :sales_log, + :completed, + :ignore_validation_errors, + owning_organisation: user.organisation, + assigned_to: user, + saledate: archived_collection_start_date, + ) end - end + let(:closed_previous_sales_form) { FormHandler.instance.sales_form_for_start_year(archived_collection_start_year) } + # let(:closed_previous_collection_end) { previous_collection_end_date.to_time.end_of_day } - context "with sales logs from a closed previous collection period" do before do sign_in user - Timecop.freeze(2023, 2, 1) - Singleton.__init__(FormHandler) + # allow(closed_previous_sales_form).to receive_messages( + # new_logs_end_date: closed_previous_collection_end, + # edit_end_date: closed_previous_collection_end, + # ) get "/sales-logs/#{completed_sales_log.id}", headers:, params: {} end - after do - Timecop.return - Singleton.__init__(FormHandler) - end - it "redirects to review page" do expect(response).to redirect_to("/sales-logs/#{completed_sales_log.id}/review?sales_log=true") end it "displays a closed collection window message for previous collection year logs" do get "/sales-logs/#{completed_sales_log.id}", headers:, params: {} - expect(completed_sales_log.form.new_logs_end_date).to eq(Time.zone.local(2022, 12, 31)) expect(completed_sales_log.status).to eq("completed") follow_redirect! - expect(page).to have_content("This log is from the 2021 to 2022 collection window, which is now closed.") + expect(page).to have_content("This log is from the #{archived_collection_start_year} to #{archived_collection_end_year} collection window, which is now closed.") end end @@ -959,6 +964,7 @@ RSpec.describe SalesLogsController, type: :request do let(:headers) { { "Accept" => "text/html" } } let(:search_term) { "foot" } let(:codes_only) { false } + let(:selected_year) { current_collection_start_year } before do create(:sales_log, :in_progress, assigned_to: user, purchid: search_term) @@ -968,7 +974,7 @@ RSpec.describe SalesLogsController, type: :request do context "when there is 1 year selected in the filters" do before do - get "/sales-logs/csv-download?years[]=2023&search=#{search_term}&codes_only=#{codes_only}", headers: + get "/sales-logs/csv-download?years[]=#{selected_year}&search=#{search_term}&codes_only=#{codes_only}", headers: end it "returns http success" do @@ -1023,7 +1029,7 @@ RSpec.describe SalesLogsController, type: :request do context "when user is not support" do before do - get "/sales-logs/csv-download?years[]=2023&search=#{search_term}&codes_only=#{codes_only}", headers: + get "/sales-logs/csv-download?years[]=#{selected_year}&search=#{search_term}&codes_only=#{codes_only}", headers: end context "and export type is not codes only" do @@ -1069,7 +1075,7 @@ RSpec.describe SalesLogsController, type: :request do let(:user) { FactoryBot.create(:user, :support) } before do - get "/sales-logs/csv-download?years[]=2023&search=#{search_term}&codes_only=#{codes_only}", headers: + get "/sales-logs/csv-download?years[]=#{selected_year}&search=#{search_term}&codes_only=#{codes_only}", headers: end context "and export type is not codes only" do @@ -1100,6 +1106,7 @@ RSpec.describe SalesLogsController, type: :request do end describe "POST #email-csv" do + let(:selected_year) { current_collection_start_year } let(:other_organisation) { FactoryBot.create(:organisation) } let(:user) { FactoryBot.create(:user, :support) } let!(:sales_log) do @@ -1121,42 +1128,42 @@ RSpec.describe SalesLogsController, type: :request do it "creates an E-mail job with the correct log type" do expect { - post "/sales-logs/email-csv?years[]=2023&codes_only=true", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, nil, { "years" => %w[2023] }, false, nil, true, "sales", 2023) + post "/sales-logs/email-csv?years[]=#{selected_year}&codes_only=true", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, { "years" => [selected_year.to_s] }, false, nil, true, "sales", selected_year) end it "redirects to the confirmation page" do - post "/sales-logs/email-csv?years[]=2023&codes_only=true", headers:, params: {} + post "/sales-logs/email-csv?years[]=#{selected_year}&codes_only=true", headers:, params: {} expect(response).to redirect_to(csv_confirmation_sales_logs_path) end it "passes the search term" do expect { - post "/sales-logs/email-csv?search=#{sales_log.id}&years[]=2023&codes_only=false", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, sales_log.id.to_s, { "years" => %w[2023] }, false, nil, false, "sales", 2023) + post "/sales-logs/email-csv?search=#{sales_log.id}&years[]=#{selected_year}&codes_only=false", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, sales_log.id.to_s, { "years" => [selected_year.to_s] }, false, nil, false, "sales", selected_year) end it "passes filter parameters" do expect { - post "/sales-logs/email-csv?years[]=2023&status[]=completed&codes_only=true", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, nil, { "status" => %w[completed], "years" => %w[2023] }, false, nil, true, "sales", 2023) + post "/sales-logs/email-csv?years[]=#{selected_year}&status[]=completed&codes_only=true", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, { "status" => %w[completed], "years" => [selected_year.to_s] }, false, nil, true, "sales", selected_year) end it "passes export type flag" do expect { - post "/sales-logs/email-csv?years[]=2023&codes_only=true", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, nil, { "years" => %w[2023] }, false, nil, true, "sales", 2023) + post "/sales-logs/email-csv?years[]=#{selected_year}&codes_only=true", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, { "years" => [selected_year.to_s] }, false, nil, true, "sales", selected_year) expect { - post "/sales-logs/email-csv?years[]=2023&codes_only=false", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, nil, { "years" => %w[2023] }, false, nil, false, "sales", 2023) + post "/sales-logs/email-csv?years[]=#{selected_year}&codes_only=false", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, { "years" => [selected_year.to_s] }, false, nil, false, "sales", selected_year) end it "passes a combination of search term, export type and filter parameters" do postcode = "XX1 1TG" expect { - post "/sales-logs/email-csv?years[]=2023&status[]=completed&search=#{postcode}&codes_only=false", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, postcode, { "status" => %w[completed], "years" => %w[2023] }, false, nil, false, "sales", 2023) + post "/sales-logs/email-csv?years[]=#{selected_year}&status[]=completed&search=#{postcode}&codes_only=false", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, postcode, { "status" => %w[completed], "years" => [selected_year.to_s] }, false, nil, false, "sales", selected_year) end context "when the user is not a support user" do @@ -1165,13 +1172,13 @@ RSpec.describe SalesLogsController, type: :request do it "has permission to download human readable csv" do codes_only_export = false expect { - post "/sales-logs/email-csv?years[]=2023&codes_only=#{codes_only_export}", headers:, params: {} - }.to enqueue_job(EmailCsvJob).with(user, nil, { "years" => %w[2023] }, false, nil, false, "sales", 2023) + post "/sales-logs/email-csv?years[]=#{selected_year}&codes_only=#{codes_only_export}", headers:, params: {} + }.to enqueue_job(EmailCsvJob).with(user, nil, { "years" => [selected_year.to_s] }, false, nil, false, "sales", selected_year) end it "is not authorized to download codes only csv" do codes_only_export = true - post "/sales-logs/email-csv?years[]=2023&codes_only=#{codes_only_export}", headers:, params: {} + post "/sales-logs/email-csv?years[]=#{selected_year}&codes_only=#{codes_only_export}", headers:, params: {} expect(response).to have_http_status(:unauthorized) end end