diff --git a/spec/models/bulk_upload_spec.rb b/spec/models/bulk_upload_spec.rb index 74a96c427..ead0480f5 100644 --- a/spec/models/bulk_upload_spec.rb +++ b/spec/models/bulk_upload_spec.rb @@ -1,6 +1,8 @@ require "rails_helper" RSpec.describe BulkUpload, type: :model do + include CollectionTimeHelper + let(:bulk_upload) { create(:bulk_upload, log_type: "lettings") } describe "def bulk_upload.completed?" do @@ -21,7 +23,7 @@ RSpec.describe BulkUpload, type: :model do describe "value check clearing" do context "with a lettings log bulk upload" do - let(:log) { build(:lettings_log, startdate: Time.zone.local(2025, 4, 2), bulk_upload:) } + let(:log) { build(:lettings_log, startdate: current_collection_start_date, bulk_upload:) } it "has the correct number of value checks to be set as confirmed" do expect(bulk_upload.fields_to_confirm(log)).to match_array %w[rent_value_check void_date_value_check major_repairs_date_value_check pregnancy_value_check retirement_value_check referral_value_check net_income_value_check scharge_value_check pscharge_value_check supcharg_value_check multiple_partners_value_check partner_under_16_value_check reasonother_value_check] @@ -29,7 +31,7 @@ RSpec.describe BulkUpload, type: :model do end context "with a sales log bulk upload" do - let(:log) { build(:sales_log, saledate: Time.zone.local(2025, 4, 2), bulk_upload:) } + let(:log) { build(:sales_log, saledate: current_collection_start_date, bulk_upload:) } it "has the correct number of value checks to be set as confirmed" do expect(bulk_upload.fields_to_confirm(log)).to match_array %w[value_value_check monthly_charges_value_check percentage_discount_value_check income1_value_check income2_value_check combined_income_value_check retirement_value_check old_persons_shared_ownership_value_check buyer_livein_value_check wheel_value_check mortgage_value_check savings_value_check deposit_value_check staircase_bought_value_check stairowned_value_check hodate_check shared_ownership_deposit_value_check extrabor_value_check grant_value_check discounted_sale_value_check deposit_and_mortgage_value_check multiple_partners_value_check partner_under_16_value_check] @@ -42,6 +44,7 @@ RSpec.describe BulkUpload, type: :model do { year: 2023, expected_value: "2023 to 2024" }, { year: 2024, expected_value: "2024 to 2025" }, { year: 2025, expected_value: "2025 to 2026" }, + { year: 2026, expected_value: "2026 to 2027" }, ].each do |test_case| context "when the bulk upload year is #{test_case[:year]}" do let(:bulk_upload) { build(:bulk_upload, year: test_case[:year]) } diff --git a/spec/services/bulk_upload/lettings/log_creator_spec.rb b/spec/services/bulk_upload/lettings/log_creator_spec.rb index 85d2fb444..408d36c21 100644 --- a/spec/services/bulk_upload/lettings/log_creator_spec.rb +++ b/spec/services/bulk_upload/lettings/log_creator_spec.rb @@ -1,18 +1,22 @@ require "rails_helper" RSpec.describe BulkUpload::Lettings::LogCreator do + include CollectionTimeHelper + subject(:service) { described_class.new(bulk_upload:, path: "") } + let(:year) { current_collection_start_year } + let(:owning_org) { create(:organisation, old_visible_id: 123, rent_periods: [2]) } let(:user) { create(:user, organisation: owning_org) } - let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2024) } - let(:csv_parser) { instance_double(BulkUpload::Lettings::Year2024::CsvParser) } - let(:row_parser) { instance_double(BulkUpload::Lettings::Year2024::RowParser) } + let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year:) } + let(:csv_parser) { instance_double("BulkUpload::Lettings::Year#{year}::CsvParser") } + let(:row_parser) { instance_double("BulkUpload::Lettings::Year#{year}::RowParser") } let(:log) { build(:lettings_log, :completed, assigned_to: user, owning_organisation: owning_org, managing_organisation: owning_org) } before do - allow(BulkUpload::Lettings::Year2024::CsvParser).to receive(:new).and_return(csv_parser) + allow(Object.const_get("BulkUpload::Lettings::Year#{year}::CsvParser")).to receive(:new).and_return(csv_parser) allow(csv_parser).to receive(:row_parsers).and_return([row_parser]) allow(row_parser).to receive(:log).and_return(log) allow(row_parser).to receive(:bulk_upload=).and_return(true) diff --git a/spec/services/bulk_upload/lettings/validator_spec.rb b/spec/services/bulk_upload/lettings/validator_spec.rb index cfe654980..0a4a83fc4 100644 --- a/spec/services/bulk_upload/lettings/validator_spec.rb +++ b/spec/services/bulk_upload/lettings/validator_spec.rb @@ -1,8 +1,12 @@ require "rails_helper" RSpec.describe BulkUpload::Lettings::Validator do + include CollectionTimeHelper + subject(:validator) { described_class.new(bulk_upload:, path:) } + let(:year) { current_collection_start_year } + let(:date) { current_collection_start_date } let(:organisation) { create(:organisation, old_visible_id: "3", rent_periods: [2]) } let(:user) { create(:user, organisation:) } let(:log) { build(:lettings_log, :completed, period: 2, assigned_to: user) } @@ -73,14 +77,14 @@ RSpec.describe BulkUpload::Lettings::Validator do end end - context "when uploading a 2023 logs for 2024 bulk upload" do - let(:log) { build(:lettings_log, :completed, startdate: Time.zone.local(2023, 5, 6), tenancycode: "5234234234234") } - let(:bulk_upload) { build(:bulk_upload, user:, year: 2024) } + context "when uploading a previous logs for current bulk upload" do + let(:log) { build(:lettings_log, :completed, startdate: previous_collection_start_date, tenancycode: "5234234234234") } + let(:bulk_upload) { build(:bulk_upload, user:, year:) } context "with headers" do let(:seed) { rand } - let(:field_numbers) { log_to_csv.default_2024_field_numbers } - let(:field_values) { log_to_csv.to_2024_row } + let(:field_numbers) { log_to_csv.send("default_#{year}_field_numbers") } + let(:field_values) { log_to_csv.send("to_#{year}_row") } before do file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:)) @@ -97,13 +101,13 @@ RSpec.describe BulkUpload::Lettings::Validator do end describe "#call" do - context "with an invalid 2024 csv" do - let(:log) { build(:lettings_log, :completed, startdate: Time.zone.local(2024, 7, 1), period: 2, assigned_to: user) } + context "with an invalid csv" do + let(:log) { build(:lettings_log, :completed, startdate: date, period: 2, assigned_to: user) } before do - values = log_to_csv.to_2024_row + values = log_to_csv.send("to_#{year}_row") values[7] = nil - file.write(log_to_csv.default_field_numbers_row_for_year(2024)) + file.write(log_to_csv.default_field_numbers_row_for_year(year)) file.write(log_to_csv.to_custom_csv_row(seed: nil, field_values: values)) file.rewind end @@ -141,12 +145,12 @@ RSpec.describe BulkUpload::Lettings::Validator do context "with arbitrary ordered invalid csv" do let(:seed) { 321 } - let(:log) { build(:lettings_log, :completed, startdate: Time.zone.local(2024, 7, 1), period: 2, assigned_to: user) } + let(:log) { build(:lettings_log, :completed, startdate: date, period: 2, assigned_to: user) } before do log.needstype = nil - values = log_to_csv.to_2024_row - file.write(log_to_csv.default_field_numbers_row_for_year(2024, seed:)) + values = log_to_csv.send("to_#{year}_row") + file.write(log_to_csv.default_field_numbers_row_for_year(year, seed:)) file.write(log_to_csv.to_custom_csv_row(seed:, field_values: values)) file.close end @@ -165,8 +169,8 @@ RSpec.describe BulkUpload::Lettings::Validator do expect(error.tenant_code).to eql(log.tenancycode) expect(error.property_ref).to eql(log.propcode) expect(error.row).to eql("2") - expect(error.cell).to eql("CY2") - expect(error.col).to eql("CY") + expect(error.cell).to eql("CX2") + expect(error.col).to eql("CX") end end @@ -218,8 +222,8 @@ RSpec.describe BulkUpload::Lettings::Validator do end end - context "with a 2024 csv without headers" do - let(:log) { build(:lettings_log, :completed, startdate: Time.zone.local(2024, 7, 1), period: 2, assigned_to: user) } + context "with a csv without headers" do + let(:log) { build(:lettings_log, :completed, startdate: date, period: 2, assigned_to: user) } before do file.write(log_to_csv.to_csv_row) diff --git a/spec/services/bulk_upload/sales/log_creator_spec.rb b/spec/services/bulk_upload/sales/log_creator_spec.rb index e9fb8cc49..b4fe1f07a 100644 --- a/spec/services/bulk_upload/sales/log_creator_spec.rb +++ b/spec/services/bulk_upload/sales/log_creator_spec.rb @@ -1,187 +1,171 @@ require "rails_helper" RSpec.describe BulkUpload::Sales::LogCreator do + include CollectionTimeHelper + subject(:service) { described_class.new(bulk_upload:, path: "") } + let(:year) { current_collection_start_year } + let(:owning_org) { create(:organisation, old_visible_id: 123) } let(:user) { create(:user, organisation: owning_org) } let(:log) { build(:sales_log, :completed, assigned_to: user, owning_organisation: owning_org, managing_organisation: owning_org) } - [2023, 2024, 2025].each do |year| - context "when #{year}" do - let(:bulk_upload) { create(:bulk_upload, :sales, user:, year:) } - let(:year_csv_parser) { instance_double("BulkUpload::Sales::Year#{year}::CsvParser".constantize) } - let(:year_row_parser) { instance_double("BulkUpload::Sales::Year#{year}::RowParser".constantize) } + let(:bulk_upload) { create(:bulk_upload, :sales, user:, year:) } + let(:csv_parser) { instance_double("BulkUpload::Sales::Year#{year}::CsvParser".constantize) } + let(:row_parser) { instance_double("BulkUpload::Sales::Year#{year}::RowParser".constantize) } + + before do + allow("BulkUpload::Sales::Year#{year}::CsvParser".constantize).to receive(:new).and_return(csv_parser) + allow(csv_parser).to receive(:row_parsers).and_return([row_parser]) + allow(row_parser).to receive(:log).and_return(log) + allow(row_parser).to receive(:bulk_upload=).and_return(true) + allow(row_parser).to receive(:valid?).and_return(true) + allow(row_parser).to receive(:blank_row?).and_return(false) + end + + it "creates a parser for the correct year" do + # This would fail without parser stubs, so the parser must be for the expected year + expect { service.call }.to change(SalesLog, :count) + end + + describe "#call" do + context "when a valid csv with new log" do + it "creates a new log" do + expect { service.call }.to change(SalesLog, :count) + end + + it "create a log with pending status" do + service.call + expect(SalesLog.last.status).to eql("pending") + end + + it "associates log with bulk upload" do + service.call + + log = SalesLog.last + expect(log.bulk_upload).to eql(bulk_upload) + expect(bulk_upload.sales_logs).to include(log) + end + it "sets the creation method" do + service.call + + expect(SalesLog.last.creation_method_bulk_upload?).to be true + end + end + + context "when a valid csv with several blank rows" do before do - allow("BulkUpload::Sales::Year#{year}::CsvParser".constantize).to receive(:new).and_return(year_csv_parser) - allow(year_csv_parser).to receive(:row_parsers).and_return([year_row_parser]) - allow(year_row_parser).to receive(:log).and_return(log) - allow(year_row_parser).to receive(:bulk_upload=).and_return(true) - allow(year_row_parser).to receive(:valid?).and_return(true) - allow(year_row_parser).to receive(:blank_row?).and_return(false) + allow(row_parser).to receive(:blank_row?).and_return(true) end - it "creates a parser for the correct year" do - # This would fail without parser stubs, so the parser must be for the expected year - expect { service.call }.to change(SalesLog, :count) + it "ignores them and does not create the logs" do + expect { service.call }.not_to change(SalesLog, :count) end end - end - # Apart from picking the correct year's parser, everything else is year-independent - context "when 2024" do - let(:bulk_upload) { create(:bulk_upload, :sales, user:, year: 2024) } - let(:csv_parser) { instance_double(BulkUpload::Sales::Year2024::CsvParser) } - let(:row_parser) { instance_double(BulkUpload::Sales::Year2024::RowParser) } - - before do - allow(BulkUpload::Sales::Year2024::CsvParser).to receive(:new).and_return(csv_parser) - allow(csv_parser).to receive(:row_parsers).and_return([row_parser]) - allow(row_parser).to receive(:log).and_return(log) - allow(row_parser).to receive(:bulk_upload=).and_return(true) - allow(row_parser).to receive(:valid?).and_return(true) - allow(row_parser).to receive(:blank_row?).and_return(false) + context "when a valid csv with row with one invalid non setup field" do + let(:log) do + build( + :sales_log, + :completed, + age1: 5, + owning_organisation: owning_org, + assigned_to: user, + managing_organisation: owning_org, + ) + end + + it "creates the log" do + expect { service.call }.to change(SalesLog, :count).by(1) + end + + it "blanks invalid field" do + service.call + + record = SalesLog.last + expect(record.age1).to be_blank + end end - describe "#call" do - context "when a valid csv with new log" do - it "creates a new log" do - expect { service.call }.to change(SalesLog, :count) - end - - it "create a log with pending status" do - service.call - expect(SalesLog.last.status).to eql("pending") - end - - it "associates log with bulk upload" do - service.call - - log = SalesLog.last - expect(log.bulk_upload).to eql(bulk_upload) - expect(bulk_upload.sales_logs).to include(log) - end - - it "sets the creation method" do - service.call - - expect(SalesLog.last.creation_method_bulk_upload?).to be true - end - end - - context "when a valid csv with several blank rows" do - before do - allow(row_parser).to receive(:blank_row?).and_return(true) - end - - it "ignores them and does not create the logs" do - expect { service.call }.not_to change(SalesLog, :count) - end - end - - context "when a valid csv with row with one invalid non setup field" do - let(:log) do - build( - :sales_log, - :completed, - age1: 5, - owning_organisation: owning_org, - assigned_to: user, - managing_organisation: owning_org, - ) - end - - it "creates the log" do - expect { service.call }.to change(SalesLog, :count).by(1) - end - - it "blanks invalid field" do - service.call - - record = SalesLog.last - expect(record.age1).to be_blank - end - end - - context "when a valid csv with row with compound errors on non setup field" do - let(:log) do - build( - :sales_log, - :completed, - owning_organisation: owning_org, - assigned_to: user, - managing_organisation: owning_org, - ownershipsch: 2, - value: 200_000, - deposit: 10_000, - mortgageused: 1, - mortgage: 100_000, - grant: 10_000, - ) - end - - it "creates the log" do - expect { service.call }.to change(SalesLog, :count).by(1) - end - - it "blanks invalid field" do - service.call - - record = SalesLog.last - expect(record.value).to be_blank - expect(record.deposit).to be_blank - expect(record.mortgage).to be_blank - expect(record.grant).to be_blank - end - end - - context "when pre-creating logs" do - it "creates a new log" do - expect { service.call }.to change(SalesLog, :count) - end - - it "creates a log with correct states" do - service.call - - last_log = SalesLog.last - - expect(last_log.status).to eql("pending") - expect(last_log.status_cache).to eql("completed") - end - end - - context "with a valid csv and soft validations" do - let(:log) do - build( - :sales_log, - :completed, - age1: 30, - age1_known: 0, - ecstat1: 5, - owning_organisation: owning_org, - assigned_to: user, - managing_organisation: owning_org, - ) - end - - it "creates a new log" do - expect { service.call }.to change(SalesLog, :count) - end - - it "creates a log with pending status" do - service.call - expect(SalesLog.last.status).to eql("pending") - end - - it "does not set unanswered soft validations" do - service.call - - log = SalesLog.last - expect(log.age1).to be(30) - expect(log.ecstat1).to be(5) - expect(log.retirement_value_check).to be(nil) - end + context "when a valid csv with row with compound errors on non setup field" do + let(:log) do + build( + :sales_log, + :completed, + owning_organisation: owning_org, + assigned_to: user, + managing_organisation: owning_org, + ownershipsch: 2, + value: 200_000, + deposit: 10_000, + mortgageused: 1, + mortgage: 100_000, + grant: 10_000, + ) + end + + it "creates the log" do + expect { service.call }.to change(SalesLog, :count).by(1) + end + + it "blanks invalid field" do + service.call + + record = SalesLog.last + expect(record.value).to be_blank + expect(record.deposit).to be_blank + expect(record.mortgage).to be_blank + expect(record.grant).to be_blank + end + end + + context "when pre-creating logs" do + it "creates a new log" do + expect { service.call }.to change(SalesLog, :count) + end + + it "creates a log with correct states" do + service.call + + last_log = SalesLog.last + + expect(last_log.status).to eql("pending") + expect(last_log.status_cache).to eql("completed") + end + end + + context "with a valid csv and soft validations" do + let(:log) do + build( + :sales_log, + :completed, + age1: 30, + age1_known: 0, + ecstat1: 5, + owning_organisation: owning_org, + assigned_to: user, + managing_organisation: owning_org, + ) + end + + it "creates a new log" do + expect { service.call }.to change(SalesLog, :count) + end + + it "creates a log with pending status" do + service.call + expect(SalesLog.last.status).to eql("pending") + end + + it "does not set unanswered soft validations" do + service.call + + log = SalesLog.last + expect(log.age1).to be(30) + expect(log.ecstat1).to be(5) + expect(log.retirement_value_check).to be(nil) end end end diff --git a/spec/services/bulk_upload/sales/validator_spec.rb b/spec/services/bulk_upload/sales/validator_spec.rb index 49ac0e39f..cc750e50d 100644 --- a/spec/services/bulk_upload/sales/validator_spec.rb +++ b/spec/services/bulk_upload/sales/validator_spec.rb @@ -1,8 +1,12 @@ require "rails_helper" RSpec.describe BulkUpload::Sales::Validator do + include CollectionTimeHelper + subject(:validator) { described_class.new(bulk_upload:, path:) } + let(:year) { current_collection_start_year } + let(:date) { current_collection_start_date } let(:user) { create(:user, organisation:) } let(:organisation) { create(:organisation, old_visible_id: "123") } let(:log) { build(:sales_log, :completed, assigned_to: user) } @@ -15,7 +19,7 @@ RSpec.describe BulkUpload::Sales::Validator do context "when file is empty" do it "is not valid" do expect(validator).not_to be_valid - expect(validator.errors["base"]).to eql([I18n.t("validations.sales.2024.bulk_upload.blank_file")]) + expect(validator.errors["base"]).to eql([I18n.t("validations.sales.#{year}.bulk_upload.blank_file")]) end end @@ -27,50 +31,34 @@ RSpec.describe BulkUpload::Sales::Validator do it "is not valid" do expect(validator).not_to be_valid - expect(validator.errors["base"]).to eql([I18n.t("validations.sales.2024.bulk_upload.blank_file")]) + expect(validator.errors["base"]).to eql([I18n.t("validations.sales.#{year}.bulk_upload.blank_file")]) end end context "when file has too many columns" do before do - file.write((%w[a] * (BulkUpload::Sales::Year2023::CsvParser::MAX_COLUMNS + 1)).join(",")) - file.rewind - end - - it "is not valid" do - expect(validator).not_to be_valid - end - end - - context "when trying to upload 2023 logs for 2024 bulk upload" do - let(:bulk_upload) { create(:bulk_upload, user:, year: 2024) } - let(:log) { build(:sales_log, :completed, saledate: Time.zone.local(2023, 10, 10), assigned_to: user) } - - before do - file.write(log_to_csv.default_field_numbers_row_for_year(2024)) - file.write(log_to_csv.to_year_csv_row(2024)) + file.write((%w[a] * (Object.const_get("BulkUpload::Sales::Year#{year}::CsvParser::MAX_COLUMNS") + 1)).join(",")) file.rewind end it "is not valid" do expect(validator).not_to be_valid - expect(validator.errors["base"]).to eql([I18n.t("validations.sales.2024.bulk_upload.wrong_template.wrong_template")]) end end - context "when trying to upload 2024 logs for 2025 bulk upload" do - let(:bulk_upload) { create(:bulk_upload, user:, year: 2025) } - let(:log) { build(:sales_log, :completed, saledate: Time.zone.local(2024, 10, 10), assigned_to: user) } + context "when trying to upload previous logs for current bulk upload" do + let(:bulk_upload) { create(:bulk_upload, user:, year:) } + let(:log) { build(:sales_log, :completed, saledate: previous_collection_start_date, assigned_to: user) } before do - file.write(log_to_csv.default_field_numbers_row_for_year(2025)) - file.write(log_to_csv.to_year_csv_row(2025)) + file.write(log_to_csv.default_field_numbers_row_for_year(year)) + file.write(log_to_csv.to_year_csv_row(year)) file.rewind end it "is not valid" do expect(validator).not_to be_valid - expect(validator.errors["base"]).to eql([I18n.t("validations.sales.2025.bulk_upload.wrong_template.wrong_template")]) + expect(validator.errors["base"]).to eql([I18n.t("validations.sales.#{year}.bulk_upload.wrong_template.wrong_template")]) end end @@ -135,10 +123,10 @@ RSpec.describe BulkUpload::Sales::Validator do end end - context "with an invalid 2024 csv" do + context "with an invalid csv" do before do log.owning_organisation = nil - log.saledate = Time.zone.local(2024, 10, 10) + log.saledate = date file.write(log_to_csv.default_field_numbers_row) file.write(log_to_csv.to_csv_row) file.rewind @@ -151,14 +139,14 @@ RSpec.describe BulkUpload::Sales::Validator do it "create validation error with correct values" do validator.call - error = BulkUploadError.find_by(row: "2", field: "field_1", category: "setup") + error = BulkUploadError.find_by(row: "2", field: "field_4", category: "setup") - expect(error.field).to eql("field_1") + expect(error.field).to eql("field_4") expect(error.error).to eql("You must answer owning organisation.") expect(error.purchaser_code).to eql(log.purchaser_code) expect(error.row).to eql("2") - expect(error.cell).to eql("B2") - expect(error.col).to eql("B") + expect(error.cell).to eql("E2") + expect(error.col).to eql("E") end end